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