1 /* 2 * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef ELF_SYMBOL_LOOKUP_H 6 #define ELF_SYMBOL_LOOKUP_H 7 8 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include <runtime_loader.h> 13 14 15 // values for SymbolLookupInfo::flags 16 #define LOOKUP_FLAG_DEFAULT_VERSION 0x01 17 18 19 uint32 elf_hash(const char* name); 20 21 22 struct SymbolLookupInfo { 23 const char* name; 24 int32 type; 25 uint32 hash; 26 uint32 flags; 27 const elf_version_info* version; 28 Elf32_Sym* requestingSymbol; 29 30 SymbolLookupInfo(const char* name, int32 type, uint32 hash, 31 const elf_version_info* version = NULL, uint32 flags = 0, 32 Elf32_Sym* requestingSymbol = NULL) 33 : 34 name(name), 35 type(type), 36 hash(hash), 37 flags(flags), 38 version(version), 39 requestingSymbol(requestingSymbol) 40 { 41 } 42 43 SymbolLookupInfo(const char* name, int32 type, 44 const elf_version_info* version = NULL, uint32 flags = 0, 45 Elf32_Sym* requestingSymbol = NULL) 46 : 47 name(name), 48 type(type), 49 hash(elf_hash(name)), 50 flags(flags), 51 version(version), 52 requestingSymbol(requestingSymbol) 53 { 54 } 55 }; 56 57 58 struct SymbolLookupCache { 59 SymbolLookupCache(image_t* image) 60 : 61 fTableSize(image->symhash[1]), 62 fValues(NULL), 63 fValuesResolved(NULL) 64 { 65 if (fTableSize > 0) { 66 fValues = (addr_t*)malloc(sizeof(addr_t) * fTableSize); 67 68 size_t elementCount = (fTableSize + 31) / 32; 69 fValuesResolved = (uint32*)malloc(4 * elementCount); 70 memset(fValuesResolved, 0, 4 * elementCount); 71 72 if (fValues == NULL || fValuesResolved == NULL) { 73 free(fValuesResolved); 74 free(fValues); 75 fTableSize = 0; 76 } 77 } 78 } 79 80 ~SymbolLookupCache() 81 { 82 free(fValuesResolved); 83 free(fValues); 84 } 85 86 bool IsSymbolValueCached(size_t index) const 87 { 88 return index < fTableSize 89 && (fValuesResolved[index / 32] & (1 << (index % 32))) != 0; 90 } 91 92 addr_t SymbolValueAt(size_t index) const 93 { 94 return fValues[index]; 95 } 96 97 void SetSymbolValueAt(size_t index, addr_t value) 98 { 99 if (index < fTableSize) { 100 fValues[index] = value; 101 fValuesResolved[index / 32] |= 1 << (index % 32); 102 } 103 } 104 105 private: 106 size_t fTableSize; 107 addr_t* fValues; 108 uint32* fValuesResolved; 109 }; 110 111 112 void patch_defined_symbol(image_t* image, const char* name, 113 void** symbol, int32* type); 114 void patch_undefined_symbol(image_t* rootImage, image_t* image, 115 const char* name, image_t** foundInImage, void** symbol, 116 int32* type); 117 118 Elf32_Sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo); 119 status_t find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo, 120 void** _location); 121 status_t find_symbol_breadth_first(image_t* image, 122 const SymbolLookupInfo& lookupInfo, image_t** _foundInImage, 123 void** _location); 124 Elf32_Sym* find_undefined_symbol_beos(image_t* rootImage, image_t* image, 125 const SymbolLookupInfo& lookupInfo, image_t** foundInImage); 126 Elf32_Sym* find_undefined_symbol_global(image_t* rootImage, image_t* image, 127 const SymbolLookupInfo& lookupInfo, image_t** foundInImage); 128 Elf32_Sym* find_undefined_symbol_add_on(image_t* rootImage, image_t* image, 129 const SymbolLookupInfo& lookupInfo, image_t** foundInImage); 130 131 132 #endif // ELF_SYMBOL_LOOKUP_H 133