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 elf_sym* requestingSymbol; 29 30 SymbolLookupInfo(const char* name, int32 type, uint32 hash, 31 const elf_version_info* version = NULL, uint32 flags = 0, 32 elf_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 elf_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 != NULL ? image->symhash[1] : 0), 62 fValues(NULL), 63 fDSOs(NULL), 64 fValuesResolved(NULL) 65 { 66 if (fTableSize > 0) { 67 fValues = (addr_t*)malloc(sizeof(addr_t) * fTableSize); 68 fDSOs = (image_t**)malloc(sizeof(image_t*) * fTableSize); 69 70 size_t elementCount = (fTableSize + 31) / 32; 71 fValuesResolved = (uint32*)malloc(4 * elementCount); 72 memset(fValuesResolved, 0, 4 * elementCount); 73 74 if (fValues == NULL || fDSOs == NULL || fValuesResolved == NULL) { 75 free(fValuesResolved); 76 free(fValues); 77 free(fDSOs); 78 fTableSize = 0; 79 } 80 } 81 } 82 83 ~SymbolLookupCache() 84 { 85 free(fValuesResolved); 86 free(fValues); 87 free(fDSOs); 88 } 89 90 bool IsSymbolValueCached(size_t index) const 91 { 92 return index < fTableSize 93 && (fValuesResolved[index / 32] & (1 << (index % 32))) != 0; 94 } 95 96 addr_t SymbolValueAt(size_t index) const 97 { 98 return fValues[index]; 99 } 100 101 addr_t SymbolValueAt(size_t index, image_t** image) const 102 { 103 if (image) 104 *image = fDSOs[index]; 105 return fValues[index]; 106 } 107 108 void SetSymbolValueAt(size_t index, addr_t value, image_t* image) 109 { 110 if (index < fTableSize) { 111 fValues[index] = value; 112 fDSOs[index] = image; 113 fValuesResolved[index / 32] |= 1 << (index % 32); 114 } 115 } 116 117 private: 118 size_t fTableSize; 119 addr_t* fValues; 120 image_t** fDSOs; 121 uint32* fValuesResolved; 122 }; 123 124 125 void patch_defined_symbol(image_t* image, const char* name, 126 void** symbol, int32* type); 127 void patch_undefined_symbol(image_t* rootImage, image_t* image, 128 const char* name, image_t** foundInImage, void** symbol, 129 int32* type); 130 131 elf_sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo, 132 bool allowLocal = false); 133 status_t find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo, 134 void** _location); 135 status_t find_symbol_breadth_first(image_t* image, 136 const SymbolLookupInfo& lookupInfo, image_t** _foundInImage, 137 void** _location); 138 elf_sym* find_undefined_symbol_beos(image_t* rootImage, image_t* image, 139 const SymbolLookupInfo& lookupInfo, image_t** foundInImage); 140 elf_sym* find_undefined_symbol_global(image_t* rootImage, image_t* image, 141 const SymbolLookupInfo& lookupInfo, image_t** foundInImage); 142 elf_sym* find_undefined_symbol_add_on(image_t* rootImage, image_t* image, 143 const SymbolLookupInfo& lookupInfo, image_t** foundInImage); 144 145 146 #endif // ELF_SYMBOL_LOOKUP_H 147