/* * Copyright 2005-2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef SYMBOL_LOOKUP_H #define SYMBOL_LOOKUP_H #include #include #include #include struct image_t; struct runtime_loader_debug_area; namespace BPrivate { namespace Debug { class Image; // Exception class Exception { public: Exception(status_t error) : fError(error) { } Exception(const Exception &other) : fError(other.fError) { } status_t Error() const { return fError; } private: status_t fError; }; // Area class Area : public DoublyLinkedListLinkImpl { public: Area(area_id id, const void *address, int32 size) : fRemoteID(id), fLocalID(-1), fRemoteAddress(address), fLocalAddress(NULL), fSize(size) { } ~Area() { if (fLocalID >= 0) delete_area(fLocalID); } const void* RemoteAddress() const { return fRemoteAddress; } const void* LocalAddress() const { return fLocalAddress; } int32 Size() const { return fSize; } bool ContainsAddress(const void *address, int32 size) const { return ((addr_t)fRemoteAddress <= (addr_t)address && (addr_t)address + size <= (addr_t)fRemoteAddress + fSize); } bool ContainsLocalAddress(const void* address) const { return (addr_t)address >= (addr_t)fLocalAddress && (addr_t)address < (addr_t)fLocalAddress + fSize; } const void *PrepareAddress(const void *address); private: area_id fRemoteID; area_id fLocalID; const void *fRemoteAddress; void *fLocalAddress; int32 fSize; }; // RemoteMemoryAccessor class RemoteMemoryAccessor { public: RemoteMemoryAccessor(team_id team); ~RemoteMemoryAccessor(); status_t Init(); const void *PrepareAddress(const void *remoteAddress, int32 size) const; const void *PrepareAddressNoThrow(const void *remoteAddress, int32 size) const; template inline const Type &Read( const Type &remoteData) const { const void *remoteAddress = &remoteData; const void *localAddress = PrepareAddress(remoteAddress, sizeof(remoteData)); return *(const Type*)localAddress; } Area* AreaForLocalAddress(const void* address) const; private: Area &_FindArea(const void *address, int32 size) const; Area* _FindAreaNoThrow(const void *address, int32 size) const; typedef DoublyLinkedList AreaList; protected: team_id fTeam; private: AreaList fAreas; }; // SymbolIterator struct SymbolIterator { const Image* image; int32 currentIndex; }; // SymbolLookup class SymbolLookup : private RemoteMemoryAccessor { public: SymbolLookup(team_id team, image_id image); ~SymbolLookup(); status_t Init(); status_t LookupSymbolAddress(addr_t address, addr_t *_baseAddress, const char **_symbolName, size_t *_symbolNameLen, const char **_imageName, bool *_exactMatch) const; status_t InitSymbolIterator(image_id imageID, SymbolIterator& iterator) const; status_t InitSymbolIteratorByAddress(addr_t address, SymbolIterator& iterator) const; status_t NextSymbol(SymbolIterator& iterator, const char** _symbolName, size_t* _symbolNameLen, addr_t* _symbolAddress, size_t* _symbolSize, int32* _symbolType) const; status_t GetSymbol(image_id imageID, const char* name, int32 symbolType, void** _symbolLocation, size_t* _symbolSize, int32* _symbolType) const; private: class LoadedImage; friend class LoadedImage; private: const image_t* _FindLoadedImageAtAddress(addr_t address) const; const image_t* _FindLoadedImageByID(image_id id) const; Image* _FindImageAtAddress(addr_t address) const; Image* _FindImageByID(image_id id) const; size_t _SymbolNameLen(const char* address) const; status_t _LoadImageInfo(const image_info& imageInfo); private: const runtime_loader_debug_area *fDebugArea; DoublyLinkedList fImages; image_id fImageID; }; } // namespace Debug } // namespace BPrivate using BPrivate::Debug::SymbolLookup; #endif // SYMBOL_LOOKUP_H