xref: /haiku/src/kits/debugger/debugger_interface/DebuggerInterface.cpp (revision 385ee03ba83b7a40d315e17b03031b3ca37820c0)
1 /*
2  * Copyright 2009-2016, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2010-2016, Rene Gollent, rene@gollent.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include "DebuggerInterface.h"
9 
10 #include <algorithm>
11 
12 #include <AutoDeleter.h>
13 
14 #include "ElfSymbolLookup.h"
15 
16 
17 // #pragma mark - SymbolTableLookupSource
18 
19 
20 struct DebuggerInterface::SymbolTableLookupSource : ElfSymbolLookupSource {
21 public:
22 	SymbolTableLookupSource(const void* symbolTable, size_t symbolTableSize,
23 		const char* stringTable, size_t stringTableSize)
24 		:
25 		fSymbolTable((const uint8*)symbolTable),
26 		fStringTable(stringTable),
27 		fSymbolTableSize(symbolTableSize),
28 		fStringTableEnd(symbolTableSize + stringTableSize)
29 	{
30 	}
31 
32 	virtual ssize_t Read(uint64 address, void* buffer, size_t size)
33 	{
34 		ssize_t copied = 0;
35 
36 		if (address > fStringTableEnd)
37 			return B_BAD_VALUE;
38 
39 		if (address < fSymbolTableSize) {
40 			size_t toCopy = std::min(size, size_t(fSymbolTableSize - address));
41 			memcpy(buffer, fSymbolTable + address, toCopy);
42 			address -= toCopy;
43 			size -= toCopy;
44 			copied += toCopy;
45 		}
46 
47 		if (address < fStringTableEnd) {
48 			size_t toCopy = std::min(size, size_t(fStringTableEnd - address));
49 			memcpy(buffer, fStringTable + address - fSymbolTableSize, toCopy);
50 			address -= toCopy;
51 			size -= toCopy;
52 			copied += toCopy;
53 		}
54 
55 		return copied;
56 	}
57 
58 private:
59 	const uint8*	fSymbolTable;
60 	const char*		fStringTable;
61 	size_t			fSymbolTableSize;
62 	size_t			fStringTableEnd;
63 };
64 
65 
66 // #pragma mark - DebuggerInterface
67 
68 
69 DebuggerInterface::~DebuggerInterface()
70 {
71 }
72 
73 
74 bool
75 DebuggerInterface::IsPostMortem() const
76 {
77 	// only true for core file interfaces
78 	return false;
79 }
80 
81 
82 status_t
83 DebuggerInterface::GetElfSymbols(const char* filePath, int64 textDelta,
84 	BObjectList<SymbolInfo>& infos)
85 {
86 	// open the ELF file
87 	ElfFile elfFile;
88 	status_t error = elfFile.Init(filePath);
89 	if (error != B_OK)
90 		return error;
91 
92 	// create the symbol lookup
93 	ElfSymbolLookup* symbolLookup;
94 	error = elfFile.CreateSymbolLookup(textDelta, symbolLookup);
95 	if (error != B_OK)
96 		return error;
97 
98 	ObjectDeleter<ElfSymbolLookup> symbolLookupDeleter(symbolLookup);
99 
100 	// get the symbols
101 	return GetElfSymbols(symbolLookup, infos);
102 }
103 
104 
105 status_t
106 DebuggerInterface::GetElfSymbols(const void* symbolTable, uint32 symbolCount,
107 	uint32 symbolTableEntrySize, const char* stringTable,
108 	uint32 stringTableSize, bool is64Bit, bool swappedByteOrder,
109 	int64 textDelta, BObjectList<SymbolInfo>& infos)
110 {
111 	size_t symbolTableSize = symbolCount * symbolTableEntrySize;
112 	SymbolTableLookupSource* source = new(std::nothrow) SymbolTableLookupSource(
113 		symbolTable, symbolTableSize, stringTable, stringTableSize);
114 	if (source == NULL)
115 		return B_NO_MEMORY;
116 	BReference<SymbolTableLookupSource> sourceReference(source, true);
117 
118 	ElfSymbolLookup* symbolLookup;
119 	status_t error = ElfSymbolLookup::Create(
120 		source, 0, 0, symbolTableSize, symbolCount, symbolTableEntrySize,
121 		textDelta, is64Bit, swappedByteOrder, false, symbolLookup);
122 	if (error != B_OK)
123 		return error;
124 
125 	ObjectDeleter<ElfSymbolLookup> symbolLookupDeleter(symbolLookup);
126 
127 	// get the symbols
128 	return GetElfSymbols(symbolLookup, infos);
129 }
130 
131 
132 status_t
133 DebuggerInterface::GetElfSymbols(ElfSymbolLookup* symbolLookup,
134 	BObjectList<SymbolInfo>& infos)
135 {
136 	SymbolInfo symbolInfo;
137 	uint32 index = 0;
138 	while (symbolLookup->NextSymbolInfo(index, symbolInfo) == B_OK) {
139 		SymbolInfo* info = new(std::nothrow) SymbolInfo(symbolInfo);
140 		if (info == NULL || !infos.AddItem(info)) {
141 			delete info;
142 			return B_NO_MEMORY;
143 		}
144 	}
145 
146 	return B_OK;
147 }
148