labath created this revision. labath added reviewers: clayborg, zturner, lemo. Herald added subscribers: arichardson, emaste. Herald added a reviewer: espindola.
Object files generally have a "base" address, which is their preferred address to be loaded into memory (in the sense that if they are loaded at this address, then no runtime relocation is required). This is often the lowest address corresponding to that object file, and various other addresses are expressed relative to this base (relative virtual addresses (RVAs) in PE/COFF parlor). All three of our main object file formats already had such a concept (it's usually needed to implement SetLoadAddress), but it was not exposed in any way. The motivation for making this public is that the symbol address in the breakpad format are written relative to this address. https://reviews.llvm.org/D55356 Files: include/lldb/Symbol/ObjectFile.h lit/Modules/ELF/basic-info.yaml lit/Modules/MachO/basic-info.yaml lit/Modules/PECOFF/basic-info.yaml lit/Modules/build-id-case.yaml lit/Modules/compressed-sections.yaml lit/Modules/elf-section-types.yaml source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp source/Plugins/ObjectFile/ELF/ObjectFileELF.h source/Plugins/ObjectFile/JIT/ObjectFileJIT.h source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h tools/lldb-test/lldb-test.cpp
Index: tools/lldb-test/lldb-test.cpp =================================================================== --- tools/lldb-test/lldb-test.cpp +++ tools/lldb-test/lldb-test.cpp @@ -750,6 +750,7 @@ Printer.formatLine("Stripped: {0}", ObjectPtr->IsStripped()); Printer.formatLine("Type: {0}", ObjectPtr->GetType()); Printer.formatLine("Strata: {0}", ObjectPtr->GetStrata()); + Printer.formatLine("Base VM address: {0:x}", ObjectPtr->GetBaseFileAddress()); size_t Count = Sections->GetNumSections(0); Printer.formatLine("Showing {0} sections", Count); @@ -760,6 +761,7 @@ Printer.formatLine("Index: {0}", I); Printer.formatLine("Name: {0}", S->GetName().GetStringRef()); Printer.formatLine("Type: {0}", S->GetTypeAsCString()); + Printer.formatLine("VM address: {0:x}", S->GetFileAddress()); Printer.formatLine("VM size: {0}", S->GetByteSize()); Printer.formatLine("File size: {0}", S->GetFileSize()); Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h =================================================================== --- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -117,6 +117,8 @@ virtual lldb_private::Address GetEntryPointAddress() override; + lldb::addr_t GetBaseFileAddress() override { return m_image_base; } + ObjectFile::Type CalculateType() override; ObjectFile::Strata CalculateStrata() override; Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h =================================================================== --- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -106,6 +106,8 @@ lldb_private::Address GetHeaderAddress() override; + lldb::addr_t GetBaseFileAddress() override; + uint32_t GetNumThreadContexts() override; std::string GetIdentifierString() override; Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp =================================================================== --- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -5353,6 +5353,12 @@ return header_addr; } +addr_t ObjectFileMachO::GetBaseFileAddress() { + if (Section *sect = GetMachHeaderSection()) + return sect->GetFileAddress(); + return LLDB_INVALID_ADDRESS; +} + uint32_t ObjectFileMachO::GetNumThreadContexts() { ModuleSP module_sp(GetModule()); if (module_sp) { Index: source/Plugins/ObjectFile/JIT/ObjectFileJIT.h =================================================================== --- source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -91,6 +91,8 @@ lldb_private::Address GetHeaderAddress() override; + lldb::addr_t GetBaseFileAddress() override { return LLDB_INVALID_ADDRESS; } + ObjectFile::Type CalculateType() override; ObjectFile::Strata CalculateStrata() override; Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.h =================================================================== --- source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -134,6 +134,8 @@ lldb_private::Address GetEntryPointAddress() override; + lldb::addr_t GetBaseFileAddress() override; + ObjectFile::Type CalculateType() override; ObjectFile::Strata CalculateStrata() override; Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -805,21 +805,10 @@ SectionList *section_list = GetSectionList(); if (section_list) { if (!value_is_offset) { - bool found_offset = false; - for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) { - const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i); - if (header == nullptr) - continue; - - if (header->p_type != PT_LOAD || header->p_offset != 0) - continue; - - value = value - header->p_vaddr; - found_offset = true; - break; - } - if (!found_offset) + addr_t base = GetBaseFileAddress(); + if (base == LLDB_INVALID_ADDRESS) return false; + value -= base; } const size_t num_sections = section_list->GetSize(); @@ -1057,6 +1046,20 @@ return m_entry_point_address; } +addr_t ObjectFileELF::GetBaseFileAddress() { + for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) { + const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i); + if (header == nullptr) + continue; + + if (header->p_type != PT_LOAD || header->p_offset != 0) + continue; + + return header->p_vaddr; + } + return LLDB_INVALID_ADDRESS; +} + //---------------------------------------------------------------------- // ParseDependentModules //---------------------------------------------------------------------- Index: source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h =================================================================== --- source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h +++ source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h @@ -85,6 +85,8 @@ uint32_t GetDependentModules(FileSpecList &files) override { return 0; } + lldb::addr_t GetBaseFileAddress() override { return LLDB_INVALID_ADDRESS; } + Type CalculateType() override { return eTypeDebugInfo; } Strata CalculateStrata() override { return eStrataUser; } Index: lit/Modules/elf-section-types.yaml =================================================================== --- lit/Modules/elf-section-types.yaml +++ lit/Modules/elf-section-types.yaml @@ -6,23 +6,15 @@ # CHECK: Name: .debug_info # CHECK-NEXT: Type: dwarf-info -# CHECK-NEXT: VM size: 0 -# CHECK-NEXT: File size: 8 # CHECK: Name: .debug_types # CHECK-NEXT: Type: dwarf-types -# CHECK-NEXT: VM size: 0 -# CHECK-NEXT: File size: 8 # CHECK: Name: .debug_names # CHECK-NEXT: Type: dwarf-names -# CHECK-NEXT: VM size: 0 -# CHECK-NEXT: File size: 8 # CHECK: Name: .gnu_debugaltlink # CHECK-NEXT: Type: dwarf-gnu-debugaltlink -# CHECK-NEXT: VM size: 0 -# CHECK-NEXT: File size: 8 # CHECK: Name: __codesection # CHECK-NEXT: Type: code Index: lit/Modules/compressed-sections.yaml =================================================================== --- lit/Modules/compressed-sections.yaml +++ lit/Modules/compressed-sections.yaml @@ -19,6 +19,7 @@ # CHECK: Name: .hello_elf # CHECK-NEXT: Type: regular +# CHECK-NEXT: VM address: 0 # CHECK-NEXT: VM size: 0 # CHECK-NEXT: File size: 28 # CHECK-NEXT: Data: @@ -26,6 +27,7 @@ # CHECK: Name: .bogus # CHECK-NEXT: Type: regular +# CHECK-NEXT: VM address: 0 # CHECK-NEXT: VM size: 0 # CHECK-NEXT: File size: 8 # CHECK-NEXT: Data: () Index: lit/Modules/build-id-case.yaml =================================================================== --- lit/Modules/build-id-case.yaml +++ lit/Modules/build-id-case.yaml @@ -6,6 +6,7 @@ # CHECK: Name: .debug_frame # CHECK-NEXT: Type: dwarf-frame +# CHECK-NEXT: VM address: 0 # CHECK-NEXT: VM size: 0 # CHECK-NEXT: File size: 8 Index: lit/Modules/PECOFF/basic-info.yaml =================================================================== --- /dev/null +++ lit/Modules/PECOFF/basic-info.yaml @@ -0,0 +1,86 @@ +# RUN: yaml2obj %s > %t +# RUN: lldb-test object-file %t | FileCheck %s + +# CHECK: Plugin name: pe-coff +# CHECK: Architecture: x86_64-pc-windows-msvc +# CHECK: UUID: +# CHECK: Executable: true +# CHECK: Stripped: false +# CHECK: Type: executable +# CHECK: Strata: user +# CHECK: Base VM address: 0x40000000 + +--- !COFF +OptionalHeader: + AddressOfEntryPoint: 4096 + ImageBase: 1073741824 + SectionAlignment: 4096 + FileAlignment: 512 + MajorOperatingSystemVersion: 6 + MinorOperatingSystemVersion: 0 + MajorImageVersion: 0 + MinorImageVersion: 0 + MajorSubsystemVersion: 6 + MinorSubsystemVersion: 0 + Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI + DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ] + SizeOfStackReserve: 1048576 + SizeOfStackCommit: 4096 + SizeOfHeapReserve: 1048576 + SizeOfHeapCommit: 4096 + ExportTable: + RelativeVirtualAddress: 0 + Size: 0 + ImportTable: + RelativeVirtualAddress: 0 + Size: 0 + ResourceTable: + RelativeVirtualAddress: 0 + Size: 0 + ExceptionTable: + RelativeVirtualAddress: 0 + Size: 0 + CertificateTable: + RelativeVirtualAddress: 0 + Size: 0 + BaseRelocationTable: + RelativeVirtualAddress: 0 + Size: 0 + Debug: + RelativeVirtualAddress: 8192 + Size: 28 + Architecture: + RelativeVirtualAddress: 0 + Size: 0 + GlobalPtr: + RelativeVirtualAddress: 0 + Size: 0 + TlsTable: + RelativeVirtualAddress: 0 + Size: 0 + LoadConfigTable: + RelativeVirtualAddress: 0 + Size: 0 + BoundImport: + RelativeVirtualAddress: 0 + Size: 0 + IAT: + RelativeVirtualAddress: 0 + Size: 0 + DelayImportDescriptor: + RelativeVirtualAddress: 0 + Size: 0 + ClrRuntimeHeader: + RelativeVirtualAddress: 0 + Size: 0 +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 1073745920 + VirtualSize: 1 + SectionData: C3 +symbols: [] +... Index: lit/Modules/MachO/basic-info.yaml =================================================================== --- /dev/null +++ lit/Modules/MachO/basic-info.yaml @@ -0,0 +1,217 @@ +# RUN: yaml2obj %s > %t +# RUN: lldb-test object-file %t | FileCheck %s + +# CHECK: Plugin name: mach-o +# CHECK: Architecture: x86_64-apple-macosx10.4.0 +# CHECK: Executable: true +# CHECK: Stripped: true +# CHECK: Type: executable +# CHECK: Strata: user +# CHECK: Base VM address: 0x100000000 + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x00000002 + ncmds: 12 + sizeofcmds: 728 + flags: 0x00000085 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 4294967296 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 4096 + fileoff: 0 + filesize: 4096 + maxprot: 7 + initprot: 5 + nsects: 3 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000100000F30 + size: 22 + offset: 0x00000F30 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x0000000100000F48 + size: 76 + offset: 0x00000F48 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __eh_frame + segname: __TEXT + addr: 0x0000000100000F98 + size: 104 + offset: 0x00000F98 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x0000000B + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294971392 + vmsize: 4096 + fileoff: 4096 + filesize: 184 + maxprot: 7 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 4096 + rebase_size: 8 + bind_off: 4104 + bind_size: 8 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 0 + lazy_bind_size: 0 + export_off: 4112 + export_size: 64 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 4184 + nsyms: 3 + stroff: 4232 + strsize: 48 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 0 + iextdefsym: 0 + nextdefsym: 3 + iundefsym: 3 + nundefsym: 0 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 4232 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_LOAD_DYLINKER + cmdsize: 32 + name: 12 + PayloadString: '/usr/lib/dyld' + ZeroPadBytes: 7 + - cmd: LC_VERSION_MIN_MACOSX + cmdsize: 16 + version: 656384 + sdk: 656384 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_MAIN + cmdsize: 24 + entryoff: 3888 + stacksize: 0 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 4176 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 4184 + datasize: 0 +LinkEditData: + RebaseOpcodes: + - Opcode: REBASE_OPCODE_DONE + Imm: 0 + BindOpcodes: + - Opcode: BIND_OPCODE_DONE + Imm: 0 + Symbol: '' + ExportTrie: + TerminalSize: 0 + NodeOffset: 0 + Name: '' + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + Children: + - TerminalSize: 2 + NodeOffset: 48 + Name: __mh_execute_header + Flags: 0x0000000000000000 + Address: 0x0000000000000000 + Other: 0x0000000000000000 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 52 + Name: start + Flags: 0x0000000000000000 + Address: 0x0000000000000F30 + Other: 0x0000000000000000 + ImportName: '' + - TerminalSize: 3 + NodeOffset: 57 + Name: dyld_stub_binder + Flags: 0x0000000000000000 + Address: 0x0000000000000F40 + Other: 0x0000000000000000 + ImportName: '' + NameList: + - n_strx: 2 + n_type: 0x0F + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 22 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971200 + - n_strx: 39 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971184 + StringTable: + - ' ' + - __mh_execute_header + - dyld_stub_binder + - start + - '' + - '' + - '' +... Index: lit/Modules/ELF/basic-info.yaml =================================================================== --- /dev/null +++ lit/Modules/ELF/basic-info.yaml @@ -0,0 +1,27 @@ +# REQUIRES: lld + +# RUN: yaml2obj %s > %t.o +# RUN: ld.lld %t.o -o %t -image-base 0x47000 +# RUN: lldb-test object-file %t | FileCheck %s + +# CHECK: Plugin name: elf +# CHECK: Architecture: x86_64-- +# CHECK: Executable: true +# CHECK: Stripped: false +# CHECK: Type: executable +# CHECK: Strata: user +# CHECK: Base VM address: 0x47000 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 + Content: 554889E55DC3 +... Index: include/lldb/Symbol/ObjectFile.h =================================================================== --- include/lldb/Symbol/ObjectFile.h +++ include/lldb/Symbol/ObjectFile.h @@ -566,6 +566,11 @@ return Address(m_memory_addr); } + /// Returns the base file address of an object file (also known as the + /// preferred load address or image base address). This is typically the file + /// address of the first section in the file. + virtual lldb::addr_t GetBaseFileAddress() = 0; + virtual uint32_t GetNumThreadContexts() { return 0; } //------------------------------------------------------------------
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits