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
20struct DebuggerInterface::SymbolTableLookupSource : ElfSymbolLookupSource {
21public:
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
58private:
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
69DebuggerInterface::~DebuggerInterface()
70{
71}
72
73
74bool
75DebuggerInterface::IsPostMortem() const
76{
77	// only true for core file interfaces
78	return false;
79}
80
81
82status_t
83DebuggerInterface::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
105status_t
106DebuggerInterface::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
132status_t
133DebuggerInterface::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