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