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:
SymbolTableLookupSourceDebuggerInterface::SymbolTableLookupSource22 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
ReadDebuggerInterface::SymbolTableLookupSource32 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
~DebuggerInterface()69 DebuggerInterface::~DebuggerInterface()
70 {
71 }
72
73
74 bool
IsPostMortem() const75 DebuggerInterface::IsPostMortem() const
76 {
77 // only true for core file interfaces
78 return false;
79 }
80
81
82 status_t
GetElfSymbols(const char * filePath,int64 textDelta,BObjectList<SymbolInfo> & infos)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
GetElfSymbols(const void * symbolTable,uint32 symbolCount,uint32 symbolTableEntrySize,const char * stringTable,uint32 stringTableSize,bool is64Bit,bool swappedByteOrder,int64 textDelta,BObjectList<SymbolInfo> & infos)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
GetElfSymbols(ElfSymbolLookup * symbolLookup,BObjectList<SymbolInfo> & infos)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