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 uint32 elf_gnuhash(const char* name); 21 22 23 struct SymbolLookupInfo { 24 const char* name; 25 int32 type; 26 uint32 hash, gnuhash; 27 uint32 flags; 28 const elf_version_info* version; 29 elf_sym* requestingSymbol; 30 31 SymbolLookupInfo(const char* name, int32 type, 32 const elf_version_info* version = NULL, uint32 flags = 0, 33 elf_sym* requestingSymbol = NULL) 34 : 35 name(name), 36 type(type), 37 hash(0), 38 gnuhash(0), 39 flags(flags), 40 version(version), 41 requestingSymbol(requestingSymbol) 42 { 43 } 44 }; 45 46 47 struct SymbolLookupCache { 48 SymbolLookupCache(image_t* image) 49 : 50 fTableSize(image->symhash != NULL ? image->symhash[1] : 0), 51 fValues(NULL), 52 fDSOs(NULL), 53 fValuesResolved(NULL) 54 { 55 if (fTableSize > 0) { 56 fValues = (addr_t*)malloc(sizeof(addr_t) * fTableSize); 57 fDSOs = (image_t**)malloc(sizeof(image_t*) * fTableSize); 58 59 size_t elementCount = (fTableSize + 31) / 32; 60 fValuesResolved = (uint32*)malloc(4 * elementCount); 61 62 if (fValues == NULL || fDSOs == NULL || fValuesResolved == NULL) { 63 free(fValuesResolved); 64 fValuesResolved = NULL; 65 free(fValues); 66 fValues = NULL; 67 free(fDSOs); 68 fDSOs = NULL; 69 fTableSize = 0; 70 } else { 71 memset(fValuesResolved, 0, 4 * elementCount); 72 } 73 } 74 } 75 76 ~SymbolLookupCache() 77 { 78 free(fValuesResolved); 79 free(fValues); 80 free(fDSOs); 81 } 82 83 bool IsSymbolValueCached(size_t index) const 84 { 85 return index < fTableSize 86 && (fValuesResolved[index / 32] & (1 << (index % 32))) != 0; 87 } 88 89 addr_t SymbolValueAt(size_t index) const 90 { 91 return fValues[index]; 92 } 93 94 addr_t SymbolValueAt(size_t index, image_t** image) const 95 { 96 if (image) 97 *image = fDSOs[index]; 98 return fValues[index]; 99 } 100 101 void SetSymbolValueAt(size_t index, addr_t value, image_t* image) 102 { 103 if (index < fTableSize) { 104 fValues[index] = value; 105 fDSOs[index] = image; 106 fValuesResolved[index / 32] |= 1 << (index % 32); 107 } 108 } 109 110 private: 111 size_t fTableSize; 112 addr_t* fValues; 113 image_t** fDSOs; 114 uint32* fValuesResolved; 115 }; 116 117 118 void patch_defined_symbol(image_t* image, const char* name, 119 void** symbol, int32* type); 120 void patch_undefined_symbol(image_t* rootImage, image_t* image, 121 const char* name, image_t** foundInImage, void** symbol, 122 int32* type); 123 124 elf_sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo); 125 status_t find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo, 126 void** _location); 127 status_t find_symbol_breadth_first(image_t* image, 128 const SymbolLookupInfo& lookupInfo, image_t** _foundInImage, 129 void** _location); 130 elf_sym* find_undefined_symbol_beos(image_t* rootImage, image_t* image, 131 const SymbolLookupInfo& lookupInfo, image_t** foundInImage); 132 elf_sym* find_undefined_symbol_global(image_t* rootImage, image_t* image, 133 const SymbolLookupInfo& lookupInfo, image_t** foundInImage); 134 elf_sym* find_undefined_symbol_add_on(image_t* rootImage, image_t* image, 135 const SymbolLookupInfo& lookupInfo, image_t** foundInImage); 136 137 138 #endif // ELF_SYMBOL_LOOKUP_H 139