* 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 <stdio.h>
#include <image.h>
#include <OS.h>
#include <util/DoublyLinkedList.h>
struct debug_context;
struct image_t;
struct runtime_loader_debug_area;
namespace BPrivate {
namespace Debug {
class Image;
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;
};
class Area : public DoublyLinkedListLinkImpl<Area> {
public:
Area(area_id localID, addr_t remoteAddress, const void* localAddress, int32 size)
: fLocalID(localID),
fRemoteAddress(remoteAddress),
fLocalAddress(localAddress),
fSize(size)
{
}
~Area()
{
if (fLocalID >= 0)
delete_area(fLocalID);
}
addr_t RemoteAddress() const { return fRemoteAddress; }
const void* LocalAddress() const { return fLocalAddress; }
int32 Size() const { return fSize; }
bool ContainsAddress(const void *address, int32 size) const
{
return (fRemoteAddress <= (addr_t)address
&& (addr_t)address + size <= (fRemoteAddress + fSize));
}
bool ContainsLocalAddress(const void* address) const
{
return (addr_t)address >= (addr_t)fLocalAddress
&& (addr_t)address < (addr_t)fLocalAddress + fSize;
}
const void *TranslateAddress(const void *remoteAddress);
private:
area_id fLocalID;
addr_t fRemoteAddress;
const void *fLocalAddress;
int32 fSize;
};
class RemoteMemoryAccessor {
public:
RemoteMemoryAccessor(debug_context* debugContext);
~RemoteMemoryAccessor();
status_t InitCheck() const;
const void *PrepareAddress(const void *remoteAddress, int32 size);
const void *PrepareAddressNoThrow(const void *remoteAddress,
int32 size);
template<typename Type> inline const Type &Read(
const Type &remoteData)
{
const void *remoteAddress = &remoteData;
const void *localAddress = PrepareAddress(remoteAddress,
sizeof(remoteData));
return *(const Type*)localAddress;
}
Area* AreaForLocalAddress(const void* address) const;
private:
Area& _GetArea(const void *address, int32 size);
status_t _GetAreaNoThrow(const void *address, int32 size, Area *&_area);
typedef DoublyLinkedList<Area> AreaList;
protected:
debug_context* fDebugContext;
private:
AreaList fAreas;
};
struct SymbolIterator {
const Image* image;
int32 currentIndex;
};
class SymbolLookup : private RemoteMemoryAccessor {
public:
SymbolLookup(debug_context* debugContext, 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 image_t* _FindLoadedImageByID(image_id id);
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<Image> fImages;
image_id fImageID;
};
}
}
using BPrivate::Debug::SymbolLookup;
#endif