28 using namespace symbolize;
32 std::unique_ptr<DIContext> DICtx,
33 bool UntagAddresses) {
35 std::unique_ptr<SymbolizableObjectFile> res(
37 std::unique_ptr<DataExtractor> OpdExtractor;
47 if (*NameOrErr ==
".opd") {
53 OpdAddress = Section->getAddress();
58 std::vector<std::pair<SymbolRef, uint64_t>> Symbols =
60 for (
auto &
P : Symbols)
62 res->addSymbol(
P.first,
P.second, OpdExtractor.get(), OpdAddress))
67 if (Symbols.empty()) {
68 if (
auto *CoffObj = dyn_cast<COFFObjectFile>(Obj))
69 if (
Error E = res->addCoffExportSymbols(CoffObj))
73 std::vector<SymbolDesc> &
SS = res->Symbols;
78 auto I =
SS.begin(),
E =
SS.end(), J =
SS.begin();
81 while (++
I !=
E && OI->Addr ==
I->Addr) {
85 SS.erase(J,
SS.end());
90 SymbolizableObjectFile::SymbolizableObjectFile(
const ObjectFile *Obj,
91 std::unique_ptr<DIContext> DICtx,
94 UntagAddresses(UntagAddresses) {}
98 struct OffsetNamePair {
102 bool operator<(
const OffsetNamePair &R)
const {
103 return Offset < R.Offset;
109 Error SymbolizableObjectFile::addCoffExportSymbols(
110 const COFFObjectFile *CoffObj) {
112 std::vector<OffsetNamePair> ExportSyms;
113 for (
const ExportDirectoryEntryRef &Ref : CoffObj->export_directories()) {
116 if (
auto EC =
Ref.getSymbolName(Name))
118 if (
auto EC =
Ref.getExportRVA(Offset))
120 ExportSyms.push_back(OffsetNamePair{
Offset,
Name});
122 if (ExportSyms.empty())
130 uint64_t ImageBase = CoffObj->getImageBase();
131 for (
auto I = ExportSyms.begin(),
E = ExportSyms.end();
I !=
E; ++
I) {
137 Symbols.push_back({SymbolStart, SymbolSize,
Export.Name, 0});
142 Error SymbolizableObjectFile::addSymbol(
const SymbolRef &Symbol,
149 if (!SymbolNameOrErr)
154 Obj.isELF() ? ELFSymbolRef(Symbol).getRawDataRefImpl().d.b : 0;
156 if (!Sec || Obj.section_end() == *Sec) {
159 ELFSymbolRef ESym(Symbol);
161 FileSymbols.emplace_back(ELFSymIdx,
SymbolName);
167 if (!SymbolTypeOrErr)
173 if ((elf_section_iterator(*Sec)->getFlags() &
ELF::SHF_ALLOC) == 0)
178 uint8_t
Type = ELFSymbolRef(Symbol).getELFType();
193 if (!SymbolAddressOrErr)
195 uint64_t SymbolAddress = *SymbolAddressOrErr;
196 if (UntagAddresses) {
199 SymbolAddress &= (1ull << 56) - 1;
200 SymbolAddress = (int64_t(SymbolAddress) << 8) >> 8;
208 uint64_t OpdOffset = SymbolAddress - OpdAddress;
210 SymbolAddress = OpdExtractor->
getAddress(&OpdOffset);
216 if (Obj.isELF() && ELFSymbolRef(Symbol).getBinding() !=
ELF::STB_LOCAL)
218 Symbols.push_back({SymbolAddress, SymbolSize,
SymbolName, ELFSymIdx});
224 auto *CoffObject = dyn_cast<COFFObjectFile>(
Module);
229 if (
auto *CoffObject = dyn_cast<COFFObjectFile>(
Module))
230 return CoffObject->getImageBase();
234 bool SymbolizableObjectFile::getNameFromSymbolTable(
236 std::string &FileName)
const {
237 SymbolDesc SD{Address, UINT64_C(-1),
StringRef(), 0};
239 if (SymbolIterator == Symbols.begin())
242 if (SymbolIterator->Size != 0 &&
243 SymbolIterator->Addr + SymbolIterator->Size <= Address)
245 Name = SymbolIterator->Name.str();
246 Addr = SymbolIterator->Addr;
247 Size = SymbolIterator->Size;
249 if (SymbolIterator->ELFLocalSymIdx != 0) {
256 std::make_pair(SymbolIterator->ELFLocalSymIdx,
StringRef()));
257 if (It != FileSymbols.begin())
258 FileName = It[-1].second.str();
263 bool SymbolizableObjectFile::shouldOverrideWithSymbolTable(
270 isa<DWARFContext>(DebugInfoContext.get());
276 bool UseSymbolTable)
const {
279 getModuleSectionIndexForAddress(ModuleOffset.
Address);
281 DebugInfoContext->getLineInfoForAddress(ModuleOffset, LineInfoSpecifier);
284 if (shouldOverrideWithSymbolTable(LineInfoSpecifier.
FNKind, UseSymbolTable)) {
285 std::string FunctionName, FileName;
287 if (getNameFromSymbolTable(ModuleOffset.
Address, FunctionName, Start, Size,
303 getModuleSectionIndexForAddress(ModuleOffset.
Address);
305 ModuleOffset, LineInfoSpecifier);
312 if (shouldOverrideWithSymbolTable(LineInfoSpecifier.
FNKind, UseSymbolTable)) {
313 std::string FunctionName, FileName;
315 if (getNameFromSymbolTable(ModuleOffset.
Address, FunctionName, Start, Size,
332 std::string FileName;
338 DILineInfo DL = DebugInfoContext->getLineInfoForDataAddress(ModuleOffset);
350 getModuleSectionIndexForAddress(ModuleOffset.
Address);
351 return DebugInfoContext->getLocalsForAddress(ModuleOffset);
355 uint64_t SymbolizableObjectFile::getModuleSectionIndexForAddress(
359 if (!Sec.isText() || Sec.isVirtual())
362 if (Address >= Sec.getAddress() &&
363 Address < Sec.getAddress() + Sec.getSize())
364 return Sec.getIndex();