1 module bc.core.system.linux.elf; 2 3 version (D_BetterC) {} 4 else: 5 6 // Copy from normally unavailable https://github.com/dlang/druntime/blob/master/src/rt/backtrace/elf.d 7 8 version (linux) 9 { 10 import core.sys.linux.elf; 11 version = LinuxOrBSD; 12 } 13 else version (FreeBSD) 14 { 15 import core.sys.freebsd.sys.elf; 16 version = LinuxOrBSD; 17 } 18 else version (DragonFlyBSD) 19 { 20 import core.sys.dragonflybsd.sys.elf; 21 version = LinuxOrBSD; 22 } 23 24 version (LinuxOrBSD): 25 26 import core.internal.elf.dl; 27 import core.internal.elf.io; 28 29 struct Image 30 { 31 private ElfFile file; 32 33 nothrow @nogc: 34 35 static Image openSelf() 36 { 37 // see: https://github.com/dlang/druntime/commit/e3c8f38141cd148e92bc949fd88a3e50d0054807 38 // const(char)* selfPath = SharedObject.thisExecutable().name().ptr; 39 const(char)* selfPath; 40 foreach (object; SharedObjects) 41 { 42 // the first object is the main binary 43 selfPath = object.name().ptr; 44 break; 45 } 46 47 Image image; 48 if (!ElfFile.open(selfPath, image.file)) 49 image.file = ElfFile.init; 50 51 return image; 52 } 53 54 @property bool isValid() 55 { 56 return file != ElfFile.init; 57 } 58 59 T processDebugLineSectionData(S, T)(ref S sink, const(void*)[] callstack, const char** frameList, 60 scope T function(ref S, ref Image, const(void*)[], const char**, const(ubyte)[]) nothrow @nogc processor) 61 { 62 ElfSectionHeader dbgSectionHeader; 63 ElfSection dbgSection; 64 65 if (file.findSectionHeaderByName(".debug_line", dbgSectionHeader)) 66 { 67 // we don't support compressed debug sections 68 if (!(dbgSectionHeader.shdr.sh_flags & SHF_COMPRESSED)) 69 dbgSection = ElfSection(file, dbgSectionHeader); 70 } 71 72 return processor(sink, this, callstack, frameList, cast(const(ubyte)[])dbgSection.data()); 73 } 74 75 @property size_t baseAddress() 76 { 77 // the DWARF addresses for DSOs are relative 78 const isDynamicSharedObject = (file.ehdr.e_type == ET_DYN); 79 if (!isDynamicSharedObject) 80 return 0; 81 82 // see: https://github.com/dlang/druntime/commit/e3c8f38141cd148e92bc949fd88a3e50d0054807 83 // return cast(size_t) SharedObject.thisExecutable().baseAddress; 84 85 size_t base = 0; 86 foreach (object; SharedObjects) 87 { 88 // only take the first address as this will be the main binary 89 base = cast(size_t) object.baseAddress; 90 break; 91 } 92 93 return base; 94 } 95 }