Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/rt/backtrace/dwarf.d
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ int traceHandlerOpApplyImpl(const void*[] callstack, scope int delegate(ref size
foreach(size_t i; 0 .. callstack.length)
locations[i].address = cast(size_t) callstack[i];

resolveAddresses(debugLineSectionData, locations[]);
resolveAddresses(debugLineSectionData, locations[], image.baseAddress);
}
}

Expand Down Expand Up @@ -108,7 +108,7 @@ int traceHandlerOpApplyImpl(const void*[] callstack, scope int delegate(ref size
private:

// the lifetime of the Location data is the lifetime of the mmapped ElfSection
void resolveAddresses(const(ubyte)[] debugLineSectionData, Location[] locations) @nogc nothrow
void resolveAddresses(const(ubyte)[] debugLineSectionData, Location[] locations, size_t baseAddress) @nogc nothrow
{
debug(DwarfDebugMachine) import core.stdc.stdio;

Expand Down Expand Up @@ -202,6 +202,9 @@ void resolveAddresses(const(ubyte)[] debugLineSectionData, Location[] locations)
runStateMachine(lph, program, standardOpcodeLengths,
(size_t address, LocationInfo locInfo, bool isEndSequence)
{
// adjust to ASLR offset
address += baseAddress;
debug(DwarfDebugMachine) printf("-- offsetting 0x%x to 0x%x\n", address - baseAddress, address);
// If loc.line != -1, then it has been set previously.
// Some implementations (eg. dmd) write an address to
// the debug data multiple times, but so far I have found
Expand Down
55 changes: 55 additions & 0 deletions src/rt/backtrace/elf.d
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,61 @@ struct Image

return null;
}

@property size_t baseAddress()
{
version(linux)
{
import core.sys.linux.link;
import core.sys.linux.elf;
}
else version(FreeBSD)
{
import core.sys.freebsd.sys.link_elf;
import core.sys.freebsd.sys.elf;
}
else version(DragonFlyBSD)
{
import core.sys.dragonflybsd.sys.link_elf;
import core.sys.dragonflybsd.sys.elf;
}

static struct ElfAddress
{
size_t begin;
bool set;
}
ElfAddress elfAddress;

// the DWARF addresses for DSOs are relative
const isDynamicSharedObject = (file.ehdr.e_type == ET_DYN);
if (!isDynamicSharedObject)
return 0;

extern(C) int dl_iterate_phdr_cb_ngc_tracehandler(dl_phdr_info* info, size_t, void* elfObj) @nogc
{
auto obj = cast(ElfAddress*) elfObj;
// only take the first address as this will be the main binary
if (obj.set)
return 0;

obj.set = true;
// search for the executable code segment
foreach (const ref phdr; info.dlpi_phdr[0 .. info.dlpi_phnum])
{
if (phdr.p_type == PT_LOAD && phdr.p_flags & PF_X)
{
obj.begin = info.dlpi_addr + phdr.p_vaddr;
return 0;
}
}
// fall back to the base address of the object file
obj.begin = info.dlpi_addr;
return 0;
}
dl_iterate_phdr(&dl_iterate_phdr_cb_ngc_tracehandler, &elfAddress);
return elfAddress.begin;
}
}

private:
Expand Down
5 changes: 5 additions & 0 deletions src/rt/backtrace/macho.d
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,9 @@ struct Image
auto data = getsectiondata(self, "__DWARF", "__debug_line", &size);
return data[0 .. size];
}

@property size_t baseAddress()
{
return 0;
}
}