forked from xcore/tool_axe
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SymbolInfo.cpp
136 lines (120 loc) · 3.55 KB
/
SymbolInfo.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright (c) 2011, Richard Osborne, All rights reserved
// This software is freely distributable under a derivative of the
// University of Illinois/NCSA Open Source License posted in
// LICENSE.txt and at <http://github.xcore.com/>
#include "SymbolInfo.h"
#include "libelf.h"
#include <algorithm>
#include <cstring>
struct ElfSymbolLess {
bool operator()(const ElfSymbol *sym1, const ElfSymbol *sym2) {
return sym1->value < sym2->value;
}
};
struct ElfSymbolGreater {
bool operator()(const ElfSymbol *sym1, const ElfSymbol *sym2) {
return sym1->value > sym2->value;
}
};
const ElfSymbol *CoreSymbolInfo::getGlobalSymbol(const std::string &name) const
{
std::map<std::string,ElfSymbol*>::const_iterator it = symNameMap.find(name);
if (it == symNameMap.end())
return 0;
return it->second;
}
const ElfSymbol *CoreSymbolInfo::
getSymbol(const SymbolAddressMap &symbols, uint32_t address)
{
SymbolAddressMap::const_iterator it = symbols.lower_bound(address);
if (it == symbols.end())
return 0;
return it->second;
}
const ElfSymbol *CoreSymbolInfo::getFunctionSymbol(uint32_t address) const
{
return getSymbol(functionSymbols, address);
}
const ElfSymbol *CoreSymbolInfo::getDataSymbol(uint32_t address) const
{
return getSymbol(dataSymbols, address);
}
void CoreSymbolInfoBuilder::
addSymbol(const char *name, uint32_t value, unsigned char info)
{
symbols.push_back(ElfSymbol(name, value, info));
}
std::auto_ptr<CoreSymbolInfo> CoreSymbolInfoBuilder::getSymbolInfo()
{
std::auto_ptr<CoreSymbolInfo> retval(new CoreSymbolInfo);
std::swap(symbols, retval->symbols);
for (std::vector<ElfSymbol>::iterator it = retval->symbols.begin(),
e = retval->symbols.end(); it != e; ++it) {
ElfSymbol *sym = &*it;
switch (ELF32_ST_TYPE(sym->info)) {
case STT_FUNC:
// Could replace an existing symbol.
retval->functionSymbols[sym->value] = sym;
break;
case STT_OBJECT:
// Could replace an existing symbol.
retval->dataSymbols[sym->value] = sym;
break;
case STT_NOTYPE:
// Only inserted if no other symbol at that address.
retval->functionSymbols.insert(std::make_pair(sym->value, sym));
retval->dataSymbols.insert(std::make_pair(sym->value, sym));
break;
}
if (ELF32_ST_BIND(sym->info) != STB_LOCAL)
retval->symNameMap.insert(std::make_pair(sym->name, sym));
}
return retval;
}
SymbolInfo::~SymbolInfo()
{
for (std::map<const Core*,CoreSymbolInfo*>::iterator it = coreMap.begin(),
e = coreMap.end(); it != e; ++it) {
delete it->second;
}
}
void SymbolInfo::add(const Core *core, std::auto_ptr<CoreSymbolInfo> info)
{
CoreSymbolInfo *&entry = coreMap[core];
if (entry) {
delete entry;
}
entry = info.release();
}
CoreSymbolInfo *SymbolInfo::getCoreSymbolInfo(const Core *core) const
{
std::map<const Core*,CoreSymbolInfo*>::const_iterator it =
coreMap.find(core);
if (it == coreMap.end())
return 0;
return it->second;
}
const ElfSymbol *SymbolInfo::
getGlobalSymbol(const Core *core, const std::string &name) const
{
if (CoreSymbolInfo *CSI = getCoreSymbolInfo(core)) {
return CSI->getGlobalSymbol(name);
}
return 0;
}
const ElfSymbol *SymbolInfo::
getFunctionSymbol(const Core *core, uint32_t address) const
{
if (CoreSymbolInfo *CSI = getCoreSymbolInfo(core)) {
return CSI->getFunctionSymbol(address);
}
return 0;
}
const ElfSymbol *SymbolInfo::
getDataSymbol(const Core *core, uint32_t address) const
{
if (CoreSymbolInfo *CSI = getCoreSymbolInfo(core)) {
return CSI->getDataSymbol(address);
}
return 0;
}