1 /* 2 * Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #ifndef _SYMBOL_LOOKUP_H 7 #define _SYMBOL_LOOKUP_H 8 9 #include <stdio.h> 10 11 #include <image.h> 12 #include <OS.h> 13 14 #include <util/DoublyLinkedList.h> 15 16 17 struct image_t; 18 struct runtime_loader_debug_area; 19 struct Elf32_Sym; 20 21 22 namespace BPrivate { 23 24 // Exception 25 class Exception { 26 public: 27 Exception(status_t error) 28 : fError(error) 29 { 30 } 31 32 Exception(const Exception &other) 33 : fError(other.fError) 34 { 35 } 36 37 status_t Error() const { return fError; } 38 39 private: 40 status_t fError; 41 }; 42 43 44 // Area 45 class Area : public DoublyLinkedListLinkImpl<Area> { 46 public: 47 Area(area_id id, const void *address, int32 size) 48 : fRemoteID(id), 49 fLocalID(-1), 50 fRemoteAddress(address), 51 fLocalAddress(NULL), 52 fSize(size) 53 { 54 } 55 56 ~Area() 57 { 58 if (fLocalID >= 0) 59 delete_area(fLocalID); 60 } 61 62 const void* RemoteAddress() const { return fRemoteAddress; } 63 const void* LocalAddress() const { return fLocalAddress; } 64 int32 Size() const { return fSize; } 65 66 bool ContainsAddress(const void *address, int32 size) const 67 { 68 return ((addr_t)fRemoteAddress <= (addr_t)address 69 && (addr_t)address + size <= (addr_t)fRemoteAddress + fSize); 70 } 71 72 bool ContainsLocalAddress(const void* address) const 73 { 74 return (addr_t)address >= (addr_t)fLocalAddress 75 && (addr_t)address < (addr_t)fLocalAddress + fSize; 76 } 77 78 const void *PrepareAddress(const void *address); 79 80 private: 81 area_id fRemoteID; 82 area_id fLocalID; 83 const void *fRemoteAddress; 84 void *fLocalAddress; 85 int32 fSize; 86 }; 87 88 89 // RemoteMemoryAccessor 90 class RemoteMemoryAccessor { 91 public: 92 RemoteMemoryAccessor(team_id team); 93 ~RemoteMemoryAccessor(); 94 95 status_t Init(); 96 97 const void *PrepareAddress(const void *remoteAddress, int32 size) const; 98 const void *PrepareAddressNoThrow(const void *remoteAddress, 99 int32 size) const; 100 101 template<typename Type> inline const Type &Read( 102 const Type &remoteData) const 103 { 104 const void *remoteAddress = &remoteData; 105 const void *localAddress = PrepareAddress(remoteAddress, 106 sizeof(remoteData)); 107 return *(const Type*)localAddress; 108 } 109 110 Area* AreaForLocalAddress(const void* address) const; 111 112 private: 113 Area &_FindArea(const void *address, int32 size) const; 114 Area* _FindAreaNoThrow(const void *address, int32 size) const; 115 116 typedef DoublyLinkedList<Area> AreaList; 117 118 protected: 119 team_id fTeam; 120 121 private: 122 AreaList fAreas; 123 }; 124 125 126 // ImageFile 127 class ImageFile : public DoublyLinkedListLinkImpl<ImageFile> { 128 public: 129 ImageFile(const image_info& info); 130 ~ImageFile(); 131 132 const image_info& Info() const { return fInfo; } 133 134 status_t Load(); 135 136 const Elf32_Sym* LookupSymbol(addr_t address, addr_t* _baseAddress, 137 const char** _symbolName, size_t *_symbolNameLen, 138 bool *_exactMatch) const; 139 status_t NextSymbol(int32& iterator, const char** _symbolName, 140 size_t* _symbolNameLen, addr_t* _symbolAddress, size_t* _symbolSize, 141 int32* _symbolType) const; 142 143 private: 144 size_t _SymbolNameLen(const char* symbolName) const; 145 146 private: 147 image_info fInfo; 148 int fFD; 149 off_t fFileSize; 150 uint8* fMappedFile; 151 addr_t fLoadDelta; 152 const Elf32_Sym* fSymbolTable; 153 const char* fStringTable; 154 int32 fSymbolCount; 155 }; 156 157 158 // SymbolIterator 159 struct SymbolIterator { 160 const image_t* image; 161 const ImageFile* imageFile; 162 int32 symbolCount; 163 size_t textDelta; 164 int32 currentIndex; 165 }; 166 167 168 // SymbolLookup 169 class SymbolLookup : private RemoteMemoryAccessor { 170 public: 171 SymbolLookup(team_id team); 172 ~SymbolLookup(); 173 174 status_t Init(); 175 176 status_t LookupSymbolAddress(addr_t address, addr_t *_baseAddress, 177 const char **_symbolName, size_t *_symbolNameLen, 178 const char **_imageName, bool *_exactMatch) const; 179 180 status_t InitSymbolIterator(image_id imageID, 181 SymbolIterator& iterator) const; 182 status_t InitSymbolIteratorByAddress(addr_t address, 183 SymbolIterator& iterator) const; 184 status_t NextSymbol(SymbolIterator& iterator, const char** _symbolName, 185 size_t* _symbolNameLen, addr_t* _symbolAddress, size_t* _symbolSize, 186 int32* _symbolType) const; 187 188 private: 189 const image_t *_FindImageAtAddress(addr_t address) const; 190 const image_t *_FindImageByID(image_id id) const; 191 ImageFile* _FindImageFileAtAddress(addr_t address) const; 192 ImageFile* _FindImageFileByID(image_id id) const; 193 size_t _SymbolNameLen(const char* address) const; 194 195 private: 196 const runtime_loader_debug_area *fDebugArea; 197 DoublyLinkedList<ImageFile> fImageFiles; 198 }; 199 200 } // namespace BPrivate 201 202 using BPrivate::SymbolLookup; 203 204 #endif // _SYMBOL_LOOKUP_H 205