xref: /haiku/src/kits/debug/SymbolLookup.h (revision abb2df34ee5bc3fbb3f47fae3f7969dfe4126348)
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