mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
llvm-symbolizer: add support for .gnu_debuglink section
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188386 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dd34dc99fd
commit
6889483ca4
BIN
test/DebugInfo/Inputs/dwarfdump-test.elf-x86-64.debuglink
Executable file
BIN
test/DebugInfo/Inputs/dwarfdump-test.elf-x86-64.debuglink
Executable file
Binary file not shown.
@ -1,4 +1,5 @@
|
||||
RUN: echo "%p/Inputs/dwarfdump-test.elf-x86-64 0x400559" > %t.input
|
||||
RUN: echo "%p/Inputs/dwarfdump-test.elf-x86-64.debuglink 0x400559" >> %t.input
|
||||
RUN: echo "%p/Inputs/dwarfdump-test.elf-x86-64 0x400436" >> %t.input
|
||||
RUN: echo "%p/Inputs/dwarfdump-test4.elf-x86-64 0x62c" >> %t.input
|
||||
RUN: echo "%p/Inputs/dwarfdump-inl-test.elf-x86-64 0x710" >> %t.input
|
||||
@ -13,6 +14,9 @@ RUN: --default-arch=i386 < %t.input | FileCheck %s
|
||||
CHECK: main
|
||||
CHECK-NEXT: /tmp/dbginfo{{[/\\]}}dwarfdump-test.cc:16
|
||||
|
||||
CHECK: main
|
||||
CHECK-NEXT: /tmp/dbginfo{{[/\\]}}dwarfdump-test.cc:16
|
||||
|
||||
CHECK: _start
|
||||
|
||||
CHECK: _Z1cv
|
||||
|
@ -15,7 +15,10 @@
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compression.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
||||
#include <sstream>
|
||||
@ -215,6 +218,74 @@ static std::string getDarwinDWARFResourceForPath(const std::string &Path) {
|
||||
return ResourceName.str();
|
||||
}
|
||||
|
||||
static bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
|
||||
OwningPtr<MemoryBuffer> MB;
|
||||
if (MemoryBuffer::getFileOrSTDIN(Path, MB))
|
||||
return false;
|
||||
return !zlib::isAvailable() || CRCHash == zlib::crc32(MB->getBuffer());
|
||||
}
|
||||
|
||||
static bool findDebugBinary(const std::string &OrigPath,
|
||||
const std::string &DebuglinkName, uint32_t CRCHash,
|
||||
std::string &Result) {
|
||||
SmallString<16> OrigDir(OrigPath);
|
||||
llvm::sys::path::remove_filename(OrigDir);
|
||||
SmallString<16> DebugPath = OrigDir;
|
||||
// Try /path/to/original_binary/debuglink_name
|
||||
llvm::sys::path::append(DebugPath, DebuglinkName);
|
||||
if (checkFileCRC(DebugPath, CRCHash)) {
|
||||
Result = DebugPath.str();
|
||||
return true;
|
||||
}
|
||||
// Try /path/to/original_binary/.debug/debuglink_name
|
||||
DebugPath = OrigPath;
|
||||
llvm::sys::path::append(DebugPath, ".debug", DebuglinkName);
|
||||
if (checkFileCRC(DebugPath, CRCHash)) {
|
||||
Result = DebugPath.str();
|
||||
return true;
|
||||
}
|
||||
// Try /usr/lib/debug/path/to/original_binary/debuglink_name
|
||||
DebugPath = "/usr/lib/debug";
|
||||
llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir),
|
||||
DebuglinkName);
|
||||
if (checkFileCRC(DebugPath, CRCHash)) {
|
||||
Result = DebugPath.str();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool getGNUDebuglinkContents(const Binary *Bin, std::string &DebugName,
|
||||
uint32_t &CRCHash) {
|
||||
const ObjectFile *Obj = dyn_cast<ObjectFile>(Bin);
|
||||
if (!Obj)
|
||||
return false;
|
||||
error_code EC;
|
||||
for (section_iterator I = Obj->begin_sections(), E = Obj->end_sections();
|
||||
I != E; I.increment(EC)) {
|
||||
StringRef Name;
|
||||
I->getName(Name);
|
||||
Name = Name.substr(Name.find_first_not_of("._"));
|
||||
if (Name == "gnu_debuglink") {
|
||||
StringRef Data;
|
||||
I->getContents(Data);
|
||||
DataExtractor DE(Data, Obj->isLittleEndian(), 0);
|
||||
uint32_t Offset = 0;
|
||||
if (const char *DebugNameStr = DE.getCStr(&Offset)) {
|
||||
// 4-byte align the offset.
|
||||
Offset = (Offset + 3) & ~0x3;
|
||||
if (DE.isValidOffsetForDataOfSize(Offset, 4)) {
|
||||
DebugName = DebugNameStr;
|
||||
CRCHash = DE.getU32(&Offset);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LLVMSymbolizer::BinaryPair
|
||||
LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
|
||||
BinaryMapTy::iterator I = BinaryForPath.find(Path);
|
||||
@ -241,6 +312,18 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
|
||||
ParsedBinariesAndObjects.push_back(DbgBin);
|
||||
}
|
||||
}
|
||||
// Try to locate the debug binary using .gnu_debuglink section.
|
||||
if (DbgBin == 0) {
|
||||
std::string DebuglinkName;
|
||||
uint32_t CRCHash;
|
||||
std::string DebugBinaryPath;
|
||||
if (getGNUDebuglinkContents(Bin, DebuglinkName, CRCHash) &&
|
||||
findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath) &&
|
||||
!error(createBinary(DebugBinaryPath, ParsedDbgBinary))) {
|
||||
DbgBin = ParsedDbgBinary.take();
|
||||
ParsedBinariesAndObjects.push_back(DbgBin);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DbgBin == 0)
|
||||
DbgBin = Bin;
|
||||
|
Loading…
Reference in New Issue
Block a user