mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-03 01:48:15 +00:00
[llvm-objdump] - Print LMAs when dumping section headers.
When --section-headers is used, GNU objdump prints both LMA and VMA for sections. llvm-objdump does not do that what makes it's output be slightly inconsistent. Patch teaches llvm-objdump to print LMA/VMA for ELF file formats. The behavior for other formats remains unchanged. Differential revision: https://reviews.llvm.org/D57146 llvm-svn: 352366
This commit is contained in:
parent
e49f9fd308
commit
a09a70b235
@ -5,7 +5,7 @@
|
||||
# it anyway.
|
||||
|
||||
# CHECK: Sections:
|
||||
# CHECK: Idx Name Size Address Type
|
||||
# CHECK: Idx Name Size VMA Type
|
||||
# CHECK: 3 .rdata 00000004 0000000000000000 DATA
|
||||
# CHECK: 4 .CRT$XCU 00000008 0000000000000000 DATA
|
||||
# CHECK: SYMBOL TABLE:
|
||||
|
@ -2,5 +2,5 @@
|
||||
; RUN: | FileCheck %s
|
||||
|
||||
; CHECK: Sections:
|
||||
; CHECK: Idx Name Size Address Type
|
||||
; CHECK: Idx Name Size VMA Type
|
||||
; CHECK-NOT: {{.}}
|
||||
|
@ -5,7 +5,7 @@
|
||||
; results in a way that we don't emulate.
|
||||
|
||||
; CHECK: Sections:
|
||||
; CHECK: Idx Name Size Address Type
|
||||
; CHECK: Idx Name Size VMA Type
|
||||
; CHECK: 0 00000000 0000000000000000
|
||||
; CHECK: 1 .text 00000026 0000000000000000 TEXT
|
||||
; CHECK: 2 .rodata.str1.1 0000000d 0000000000000026 DATA
|
||||
|
@ -1,7 +1,7 @@
|
||||
RUN: llvm-objdump -macho -h %p/Inputs/hello.obj.macho-x86_64 | FileCheck %s
|
||||
|
||||
CHECK: Sections:
|
||||
CHECK: Idx Name Size Address Type
|
||||
CHECK: Idx Name Size VMA Type
|
||||
CHECK: 0 __text 0000003b 0000000000000000 TEXT
|
||||
CHECK: 1 __cstring 0000000d 000000000000003b DATA
|
||||
CHECK: 2 __compact_unwind 00000020 0000000000000048 DATA
|
||||
|
48
test/tools/llvm-objdump/X86/phdrs-lma.test
Normal file
48
test/tools/llvm-objdump/X86/phdrs-lma.test
Normal file
@ -0,0 +1,48 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
|
||||
## Check we print both VMA and LMA correctly when dumping section headers.
|
||||
# RUN: llvm-objdump --section-headers %t | FileCheck %s
|
||||
|
||||
# CHECK: Sections:
|
||||
# CHECK-NEXT: Idx Name Size VMA LMA Type
|
||||
# CHECK-NEXT: 0 00000000 0000000000000000 0000000000000000
|
||||
# CHECK-NEXT: 1 .text 00000004 0000000000001000 0000000000002000 TEXT
|
||||
# CHECK-NEXT: 2 .init 00000004 0000000000001010 0000000000001010 TEXT
|
||||
# CHECK-NEXT: 3 .data 00000004 0000000000002000 0000000000003000 DATA
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Content: "00000000"
|
||||
Address: 0x00001000
|
||||
- Name: .init
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Content: "00000000"
|
||||
Address: 0x00001010
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
Content: "00000000"
|
||||
Address: 0x00002000
|
||||
ProgramHeaders:
|
||||
- Type: PT_LOAD
|
||||
Flags: [ PF_X, PF_R ]
|
||||
VAddr: 0x00001000
|
||||
PAddr: 0x00002000
|
||||
Sections:
|
||||
- Section: .text
|
||||
- Section: .init
|
||||
- Type: PT_LOAD
|
||||
Flags: [ PF_R ]
|
||||
VAddr: 0x00002000
|
||||
PAddr: 0x00003000
|
||||
Sections:
|
||||
- Section: .data
|
60
test/tools/llvm-objdump/X86/phdrs-lma2.test
Normal file
60
test/tools/llvm-objdump/X86/phdrs-lma2.test
Normal file
@ -0,0 +1,60 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
|
||||
## If there are no sections with different LMA to VMA,
|
||||
## we do not display LMA column.
|
||||
# RUN: llvm-objdump --section-headers %t | FileCheck %s
|
||||
|
||||
# CHECK: Sections:
|
||||
# CHECK-NEXT: Idx Name Size VMA Type
|
||||
# CHECK-NEXT: 0 00000000 0000000000000000
|
||||
# CHECK-NEXT: 1 .text 00000004 0000000000001000 TEXT
|
||||
# CHECK-NEXT: 2 .init 00000004 0000000000001010 TEXT
|
||||
# CHECK-NEXT: 3 .data 00000004 0000000000002000 DATA
|
||||
|
||||
## Check we can trigger displaying the LMA column with --show-lma.
|
||||
# RUN: llvm-objdump --section-headers --show-lma %t |\
|
||||
# RUN: FileCheck %s --check-prefix=LMA
|
||||
|
||||
# LMA: Sections:
|
||||
# LMA-NEXT: Idx Name Size VMA LMA Type
|
||||
# LMA-NEXT: 0 00000000 0000000000000000 0000000000000000
|
||||
# LMA-NEXT: 1 .text 00000004 0000000000001000 0000000000001000 TEXT
|
||||
# LMA-NEXT: 2 .init 00000004 0000000000001010 0000000000001010 TEXT
|
||||
# LMA-NEXT: 3 .data 00000004 0000000000002000 0000000000002000 DATA
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Content: "00000000"
|
||||
Address: 0x00001000
|
||||
- Name: .init
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Content: "00000000"
|
||||
Address: 0x00001010
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC ]
|
||||
Content: "00000000"
|
||||
Address: 0x00002000
|
||||
ProgramHeaders:
|
||||
- Type: PT_LOAD
|
||||
Flags: [ PF_X, PF_R ]
|
||||
VAddr: 0x00001000
|
||||
PAddr: 0x00001000
|
||||
Sections:
|
||||
- Section: .text
|
||||
- Section: .init
|
||||
- Type: PT_LOAD
|
||||
Flags: [ PF_R ]
|
||||
VAddr: 0x00002000
|
||||
PAddr: 0x00002000
|
||||
Sections:
|
||||
- Section: .data
|
@ -1,7 +1,7 @@
|
||||
# RUN: llvm-objdump -h %p/Inputs/trivial.obj.wasm | FileCheck %s
|
||||
|
||||
# CHECK: Sections:
|
||||
# CHECK-NEXT: Idx Name Size Address Type
|
||||
# CHECK-NEXT: Idx Name Size VMA Type
|
||||
# CHECK-NEXT: 0 TYPE 00000011 0000000000000000
|
||||
# CHECK-NEXT: 1 IMPORT 0000005d 0000000000000000
|
||||
# CHECK-NEXT: 2 FUNCTION 00000003 0000000000000000
|
||||
|
@ -132,6 +132,35 @@ llvm::getELFRelocationValueString(const ELFObjectFileBase *Obj,
|
||||
return getRelocationValueString(ELF64BE, Rel, Result);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static uint64_t getSectionLMA(const ELFFile<ELFT> *Obj,
|
||||
const object::ELFSectionRef &Sec) {
|
||||
auto PhdrRangeOrErr = Obj->program_headers();
|
||||
if (!PhdrRangeOrErr)
|
||||
report_fatal_error(errorToErrorCode(PhdrRangeOrErr.takeError()).message());
|
||||
|
||||
// Search for a PT_LOAD segment containing the requested section. Use this
|
||||
// segment's p_addr to calculate the section's LMA.
|
||||
for (const typename ELFFile<ELFT>::Elf_Phdr &Phdr : *PhdrRangeOrErr)
|
||||
if ((Phdr.p_type == ELF::PT_LOAD) && (Phdr.p_vaddr <= Sec.getAddress()) &&
|
||||
(Phdr.p_vaddr + Phdr.p_memsz > Sec.getAddress()))
|
||||
return Sec.getAddress() - Phdr.p_vaddr + Phdr.p_paddr;
|
||||
|
||||
// Return section's VMA if it isn't in a PT_LOAD segment.
|
||||
return Sec.getAddress();
|
||||
}
|
||||
|
||||
uint64_t llvm::getELFSectionLMA(const object::ELFSectionRef &Sec) {
|
||||
if (const auto *ELFObj = dyn_cast<ELF32LEObjectFile>(Sec.getObject()))
|
||||
return getSectionLMA(ELFObj->getELFFile(), Sec);
|
||||
else if (const auto *ELFObj = dyn_cast<ELF32BEObjectFile>(Sec.getObject()))
|
||||
return getSectionLMA(ELFObj->getELFFile(), Sec);
|
||||
else if (const auto *ELFObj = dyn_cast<ELF64LEObjectFile>(Sec.getObject()))
|
||||
return getSectionLMA(ELFObj->getELFFile(), Sec);
|
||||
const auto *ELFObj = cast<ELF64BEObjectFile>(Sec.getObject());
|
||||
return getSectionLMA(ELFObj->getELFFile(), Sec);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void printDynamicSection(const ELFFile<ELFT> *Elf, StringRef Filename) {
|
||||
auto ProgramHeaderOrError = Elf->program_headers();
|
||||
|
@ -185,6 +185,10 @@ static cl::alias SectionHeadersShorter("h",
|
||||
cl::NotHidden,
|
||||
cl::aliasopt(SectionHeaders));
|
||||
|
||||
static cl::opt<bool>
|
||||
ShowLMA("show-lma",
|
||||
cl::desc("Display LMA column when dumping ELF section headers"));
|
||||
|
||||
cl::list<std::string>
|
||||
llvm::FilterSections("section", cl::desc("Operate on the specified sections only. "
|
||||
"With -macho dump segment,section"));
|
||||
@ -1517,25 +1521,48 @@ void llvm::printDynamicRelocations(const ObjectFile *Obj) {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if we need to show LMA column when dumping section headers. We
|
||||
// show it only when the platform is ELF and either we have at least one section
|
||||
// whose VMA and LMA are different and/or when --show-lma flag is used.
|
||||
static bool shouldDisplayLMA(const ObjectFile *Obj) {
|
||||
if (!Obj->isELF())
|
||||
return false;
|
||||
for (const SectionRef &S : ToolSectionFilter(*Obj))
|
||||
if (S.getAddress() != getELFSectionLMA(S))
|
||||
return true;
|
||||
return ShowLMA;
|
||||
}
|
||||
|
||||
void llvm::printSectionHeaders(const ObjectFile *Obj) {
|
||||
outs() << "Sections:\n"
|
||||
"Idx Name Size Address Type\n";
|
||||
bool HasLMAColumn = shouldDisplayLMA(Obj);
|
||||
if (HasLMAColumn)
|
||||
outs() << "Sections:\n"
|
||||
"Idx Name Size VMA LMA "
|
||||
"Type\n";
|
||||
else
|
||||
outs() << "Sections:\n"
|
||||
"Idx Name Size VMA Type\n";
|
||||
|
||||
for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
|
||||
StringRef Name;
|
||||
error(Section.getName(Name));
|
||||
uint64_t Address = Section.getAddress();
|
||||
if (shouldAdjustVA(Section))
|
||||
Address += AdjustVMA;
|
||||
|
||||
uint64_t VMA = Section.getAddress();
|
||||
uint64_t Size = Section.getSize();
|
||||
bool Text = Section.isText();
|
||||
bool Data = Section.isData();
|
||||
bool BSS = Section.isBSS();
|
||||
std::string Type = (std::string(Text ? "TEXT " : "") +
|
||||
(Data ? "DATA " : "") + (BSS ? "BSS" : ""));
|
||||
outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n",
|
||||
(unsigned)Section.getIndex(), Name.str().c_str(), Size,
|
||||
Address, Type.c_str());
|
||||
|
||||
if (HasLMAColumn)
|
||||
outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %016" PRIx64
|
||||
" %s\n",
|
||||
(unsigned)Section.getIndex(), Name.str().c_str(), Size,
|
||||
VMA, getELFSectionLMA(Section), Type.c_str());
|
||||
else
|
||||
outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n",
|
||||
(unsigned)Section.getIndex(), Name.str().c_str(), Size,
|
||||
VMA, Type.c_str());
|
||||
}
|
||||
outs() << "\n";
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace object {
|
||||
class COFFObjectFile;
|
||||
class COFFImportFile;
|
||||
class ELFObjectFileBase;
|
||||
class ELFSectionRef;
|
||||
class MachOObjectFile;
|
||||
class MachOUniversalBinary;
|
||||
class ObjectFile;
|
||||
@ -137,6 +138,8 @@ getMachORelocationValueString(const object::MachOObjectFile *Obj,
|
||||
const object::RelocationRef &RelRef,
|
||||
llvm::SmallVectorImpl<char> &Result);
|
||||
|
||||
uint64_t getELFSectionLMA(const object::ELFSectionRef& Sec);
|
||||
|
||||
void error(std::error_code ec);
|
||||
bool isRelocAddressLess(object::RelocationRef A, object::RelocationRef B);
|
||||
void parseInputMachO(StringRef Filename);
|
||||
|
Loading…
x
Reference in New Issue
Block a user