[llvm] [Object][ELF] Support extended header for Object Parser in ELF (PR #162288)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 7 07:06:50 PDT 2025
https://github.com/aokblast created https://github.com/llvm/llvm-project/pull/162288
In ELF file, there is a possible extended header for those phnum, shnum, and shstrndx larger than the maximum of 16 bits. This extended header use section 0 to record these fields in 32 bits. For most of the ELF writers like lld, we already have the mechanism to synthesis this special section 0. However, the parser part don't have such infra and therefore we add it.
Also, we modify some test cases. For those expected-error test cases, their error emission get early. For those expected-correct test cases, we modify the output since we support more than 65535 sections now.
>From fe09ac6992fb8f7cc522162c4a5ffd54b8b066c5 Mon Sep 17 00:00:00 2001
From: ShengYi Hung <aokblast at FreeBSD.org>
Date: Tue, 7 Oct 2025 21:46:52 +0800
Subject: [PATCH] [Object][ELF] Support extended header for Object Parser in
ELF
In ELF file, there is a possible extended header for those phnum, shnum,
and shstrndx larger than the maximum of 16 bits. This extended header
use section 0 to record these fields in 32 bits. For most of the ELF
writers like lld, we already have the mechanism to synthesis this
special section 0. However, the parser part don't have such infra and
therefore we add it.
Also, we modify some test cases. For those expected-error test cases,
their error emission get early. For those expected-correct test cases,
we modify the output since we support more than 65535 sections now.
---
llvm/include/llvm/Object/ELF.h | 53 ++++++--
llvm/include/llvm/Object/ELFTypes.h | 5 +
llvm/test/Object/invalid.test | 4 +-
.../tools/llvm-objcopy/ELF/many-sections.test | 2 +-
.../tools/llvm-readobj/ELF/file-headers.test | 123 +++++++++---------
llvm/tools/llvm-readobj/ELFDumper.cpp | 32 +++--
6 files changed, 133 insertions(+), 86 deletions(-)
diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h
index 59f63eb6b5bb6..4374924371d1c 100644
--- a/llvm/include/llvm/Object/ELF.h
+++ b/llvm/include/llvm/Object/ELF.h
@@ -278,9 +278,17 @@ class ELFFile {
std::vector<Elf_Shdr> FakeSections;
SmallString<0> FakeSectionStrings;
+ // Handle extended header in section 0
+ Elf_Word e_phnum;
+ Elf_Word e_shnum;
+ Elf_Word e_shstrndx;
+
ELFFile(StringRef Object);
public:
+ const Elf_Word getPhNum() const { return e_phnum; }
+ const Elf_Word getShNum() const { return e_shnum; }
+ const Elf_Word getShStrNdx() const { return e_shstrndx; }
const Elf_Ehdr &getHeader() const {
return *reinterpret_cast<const Elf_Ehdr *>(base());
}
@@ -379,22 +387,21 @@ class ELFFile {
/// Iterate over program header table.
Expected<Elf_Phdr_Range> program_headers() const {
- if (getHeader().e_phnum && getHeader().e_phentsize != sizeof(Elf_Phdr))
+ if (e_phnum && getHeader().e_phentsize != sizeof(Elf_Phdr))
return createError("invalid e_phentsize: " +
Twine(getHeader().e_phentsize));
- uint64_t HeadersSize =
- (uint64_t)getHeader().e_phnum * getHeader().e_phentsize;
+ uint64_t HeadersSize = (uint64_t)e_phnum * getHeader().e_phentsize;
uint64_t PhOff = getHeader().e_phoff;
if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())
return createError("program headers are longer than binary of size " +
Twine(getBufSize()) + ": e_phoff = 0x" +
Twine::utohexstr(getHeader().e_phoff) +
- ", e_phnum = " + Twine(getHeader().e_phnum) +
+ ", e_phnum = " + Twine(e_phnum) +
", e_phentsize = " + Twine(getHeader().e_phentsize));
auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);
- return ArrayRef(Begin, Begin + getHeader().e_phnum);
+ return ArrayRef(Begin, Begin + e_phnum);
}
/// Get an iterator over notes in a program header.
@@ -772,7 +779,7 @@ template <class ELFT>
Expected<StringRef>
ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
WarningHandler WarnHandler) const {
- uint32_t Index = getHeader().e_shstrndx;
+ uint32_t Index = e_shstrndx;
if (Index == ELF::SHN_XINDEX) {
// If the section name string table section index is greater than
// or equal to SHN_LORESERVE, then the actual index of the section name
@@ -889,7 +896,12 @@ Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
return 0;
}
-template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
+template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {
+ auto Header = getHeader();
+ e_phnum = Header.e_phnum;
+ e_shnum = Header.e_shnum;
+ e_shstrndx = Header.e_shstrndx;
+}
template <class ELFT>
Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
@@ -897,7 +909,29 @@ Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
return createError("invalid buffer: the size (" + Twine(Object.size()) +
") is smaller than an ELF header (" +
Twine(sizeof(Elf_Ehdr)) + ")");
- return ELFFile(Object);
+ ELFFile Result(Object);
+
+ //
+ // sections() parse the total number of sections by considering the
+ // extended headers
+ //
+ if (Result.getHeader().HasHeaderExtension()) {
+ auto TableOrErr = Result.sections();
+ if (!TableOrErr)
+ return TableOrErr.takeError();
+ if ((*TableOrErr).size() == 0)
+ return Result;
+ auto SecOrErr = object::getSection<ELFT>(*TableOrErr, 0);
+ if (!SecOrErr)
+ return SecOrErr.takeError();
+ if (Result.e_phnum == 0xFFFF)
+ Result.e_phnum = (*SecOrErr)->sh_info;
+ if (Result.e_shnum == ELF::SHN_UNDEF)
+ Result.e_shnum = (*SecOrErr)->sh_size;
+ if (Result.e_shstrndx == ELF::SHN_XINDEX)
+ Result.e_shstrndx = (*SecOrErr)->sh_link;
+ }
+ return Result;
}
/// Used by llvm-objdump -d (which needs sections for disassembly) to
@@ -940,7 +974,6 @@ Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
if (getHeader().e_shentsize != sizeof(Elf_Shdr))
return createError("invalid e_shentsize in ELF header: " +
Twine(getHeader().e_shentsize));
-
const uint64_t FileSize = Buf.size();
if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||
SectionTableOffset + (uintX_t)sizeof(Elf_Shdr) < SectionTableOffset)
@@ -956,7 +989,7 @@ Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
const Elf_Shdr *First =
reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
- uintX_t NumSections = getHeader().e_shnum;
+ uintX_t NumSections = e_shnum;
if (NumSections == 0)
NumSections = First->sh_size;
diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h
index 5a26e2fc31458..232f6be9b4c49 100644
--- a/llvm/include/llvm/Object/ELFTypes.h
+++ b/llvm/include/llvm/Object/ELFTypes.h
@@ -529,6 +529,11 @@ struct Elf_Ehdr_Impl {
unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
+ bool HasHeaderExtension() const {
+ return (e_phnum == 0xFFFF || e_shnum == ELF::SHN_UNDEF ||
+ ELF::SHN_XINDEX == e_phnum) &&
+ e_shoff != 0;
+ }
};
template <endianness Endianness>
diff --git a/llvm/test/Object/invalid.test b/llvm/test/Object/invalid.test
index 58ec3cbeadd19..2bf23b45cdbb8 100644
--- a/llvm/test/Object/invalid.test
+++ b/llvm/test/Object/invalid.test
@@ -556,7 +556,7 @@ Sections:
# RUN: yaml2obj --docnum=25 %s -o %t25
# RUN: not llvm-readobj -h %t25 2>&1 | FileCheck -DFILE=%t25 --check-prefix=INVALID-SEC-NUM1 %s
-# INVALID-SEC-NUM1: error: '[[FILE]]': unable to continue dumping, the file is corrupt: invalid section header table offset (e_shoff = 0x58) or invalid number of sections specified in the first section header's sh_size field (0x3ffffffffffffff)
+# INVALID-SEC-NUM1: error: '[[FILE]]': invalid section header table offset (e_shoff = 0x58) or invalid number of sections specified in the first section header's sh_size field (0x3ffffffffffffff)
--- !ELF
FileHeader:
@@ -575,7 +575,7 @@ Sections:
# RUN: yaml2obj --docnum=26 %s -o %t26
# RUN: not llvm-readobj -h %t26 2>&1 | FileCheck -DFILE=%t26 --check-prefix=INVALID-SEC-NUM2 %s
-# INVALID-SEC-NUM2: error: '[[FILE]]': unable to continue dumping, the file is corrupt: invalid number of sections specified in the NULL section's sh_size field (288230376151711744)
+# INVALID-SEC-NUM2: error: '[[FILE]]': invalid number of sections specified in the NULL section's sh_size field (288230376151711744)
--- !ELF
FileHeader:
diff --git a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
index 6622db237026f..8b49454f98578 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
@@ -6,7 +6,7 @@ RUN: llvm-readobj --file-headers --sections --symbols %t2 | FileCheck %s
RUN: llvm-readelf --symbols %t2 | FileCheck --check-prefix=SYMS %s
## The ELF header should have e_shnum == 0 and e_shstrndx == SHN_XINDEX.
-# CHECK: SectionHeaderCount: 0
+# CHECK: SectionHeaderCount: 0 (65540)
# CHECK-NEXT: StringTableSectionIndex: 65535
## The first section header should store the real section header count and
diff --git a/llvm/test/tools/llvm-readobj/ELF/file-headers.test b/llvm/test/tools/llvm-readobj/ELF/file-headers.test
index 97ab9f092b228..d2fbed1b75656 100644
--- a/llvm/test/tools/llvm-readobj/ELF/file-headers.test
+++ b/llvm/test/tools/llvm-readobj/ELF/file-headers.test
@@ -143,64 +143,67 @@ FileHeader:
# RUN: yaml2obj %s --docnum=4 -o %t.invalid1
# RUN: not llvm-readobj --file-headers %t.invalid1 2>&1 \
# RUN: | FileCheck %s --implicit-check-not=warning: -DFILE=%t.invalid1 \
-# RUN: -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-LLVM
+# RUN: -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-LLVM-TC1
# RUN: not llvm-readelf --file-headers %t.invalid1 2>&1 \
# RUN: | FileCheck %s --implicit-check-not=warning: -DFILE=%t.invalid1 \
-# RUN: -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-GNU
-
-# INVALID-LLVM: File: [[FILE]]
-# INVALID-LLVM-NEXT: Format: elf64-unknown
-# INVALID-LLVM-NEXT: Arch: unknown
-# INVALID-LLVM-NEXT: AddressSize: 64bit
-# INVALID-LLVM-NEXT: LoadName: <Not found>
-# INVALID-LLVM-NEXT: ElfHeader {
-# INVALID-LLVM-NEXT: Ident {
-# INVALID-LLVM-NEXT: Magic: (7F 45 4C 46)
-# INVALID-LLVM-NEXT: Class: 64-bit (0x2)
-# INVALID-LLVM-NEXT: DataEncoding: LittleEndian (0x1)
-# INVALID-LLVM-NEXT: FileVersion: 1
-# INVALID-LLVM-NEXT: OS/ABI: SystemV (0x0)
-# INVALID-LLVM-NEXT: ABIVersion: 0
-# INVALID-LLVM-NEXT: Unused: (00 00 00 00 00 00 00)
-# INVALID-LLVM-NEXT: }
-# INVALID-LLVM-NEXT: Type: Relocatable (0x1)
-# INVALID-LLVM-NEXT: Machine: EM_NONE (0x0)
-# INVALID-LLVM-NEXT: Version: 1
-# INVALID-LLVM-NEXT: Entry: 0x0
-# INVALID-LLVM-NEXT: ProgramHeaderOffset: 0x0
-# INVALID-LLVM-NEXT: SectionHeaderOffset: 0x1000
-# INVALID-LLVM-NEXT: Flags [ (0x0)
-# INVALID-LLVM-NEXT: ]
-# INVALID-LLVM-NEXT: HeaderSize: 64
-# INVALID-LLVM-NEXT: ProgramHeaderEntrySize: 0
-# INVALID-LLVM-NEXT: ProgramHeaderCount: 0
-# INVALID-LLVM-NEXT: SectionHeaderEntrySize: 64
-# INVALID-LLVM-NEXT: SectionHeaderCount: [[SECHDRCOUNT]]
-# INVALID-LLVM-NEXT: StringTableSectionIndex: [[SECHDRSTRTABINDEX]]
-# INVALID-LLVM-NEXT: }
-# INVALID-LLVM-NEXT: error: '[[FILE]]': unable to continue dumping, the file is corrupt: section header table goes past the end of the file: e_shoff = 0x1000
-
-# INVALID-GNU: ELF Header:
-# INVALID-GNU-NEXT: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
-# INVALID-GNU-NEXT: Class: ELF64
-# INVALID-GNU-NEXT: Data: 2's complement, little endian
-# INVALID-GNU-NEXT: Version: 1 (current)
-# INVALID-GNU-NEXT: OS/ABI: UNIX - System V
-# INVALID-GNU-NEXT: ABI Version: 0
-# INVALID-GNU-NEXT: Type: REL (Relocatable file)
-# INVALID-GNU-NEXT: Machine: None
-# INVALID-GNU-NEXT: Version: 0x1
-# INVALID-GNU-NEXT: Entry point address: 0x0
-# INVALID-GNU-NEXT: Start of program headers: 0 (bytes into file)
-# INVALID-GNU-NEXT: Start of section headers: 4096 (bytes into file)
-# INVALID-GNU-NEXT: Flags: 0x0
-# INVALID-GNU-NEXT: Size of this header: 64 (bytes)
-# INVALID-GNU-NEXT: Size of program headers: 0 (bytes)
-# INVALID-GNU-NEXT: Number of program headers: 0
-# INVALID-GNU-NEXT: Size of section headers: 64 (bytes)
-# INVALID-GNU-NEXT: Number of section headers: [[SECHDRCOUNT]]
-# INVALID-GNU-NEXT: Section header string table index: [[SECHDRSTRTABINDEX]]
-# INVALID-GNU-NEXT: error: '[[FILE]]': unable to continue dumping, the file is corrupt: section header table goes past the end of the file: e_shoff = 0x1000
+# RUN: -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-GNU-TC1
+
+# INVALID-LLVM-TC1: File: [[FILE]]
+# INVALID-LLVM-TC1-NEXT: Format: elf64-unknown
+# INVALID-LLVM-TC1-NEXT: Arch: unknown
+# INVALID-LLVM-TC1-NEXT: AddressSize: 64bit
+# INVALID-LLVM-TC1-NEXT: LoadName: <Not found>
+# INVALID-LLVM-TC1-NEXT: ElfHeader {
+# INVALID-LLVM-TC1-NEXT: Ident {
+# INVALID-LLVM-TC1-NEXT: Magic: (7F 45 4C 46)
+# INVALID-LLVM-TC1-NEXT: Class: 64-bit (0x2)
+# INVALID-LLVM-TC1-NEXT: DataEncoding: LittleEndian (0x1)
+# INVALID-LLVM-TC1-NEXT: FileVersion: 1
+# INVALID-LLVM-TC1-NEXT: OS/ABI: SystemV (0x0)
+# INVALID-LLVM-TC1-NEXT: ABIVersion: 0
+# INVALID-LLVM-TC1-NEXT: Unused: (00 00 00 00 00 00 00)
+# INVALID-LLVM-TC1-NEXT: }
+# INVALID-LLVM-TC1-NEXT: Type: Relocatable (0x1)
+# INVALID-LLVM-TC1-NEXT: Machine: EM_NONE (0x0)
+# INVALID-LLVM-TC1-NEXT: Version: 1
+# INVALID-LLVM-TC1-NEXT: Entry: 0x0
+# INVALID-LLVM-TC1-NEXT: ProgramHeaderOffset: 0x0
+# INVALID-LLVM-TC1-NEXT: SectionHeaderOffset: 0x1000
+# INVALID-LLVM-TC1-NEXT: Flags [ (0x0)
+# INVALID-LLVM-TC1-NEXT: ]
+# INVALID-LLVM-TC1-NEXT: HeaderSize: 64
+# INVALID-LLVM-TC1-NEXT: ProgramHeaderEntrySize: 0
+# INVALID-LLVM-TC1-NEXT: ProgramHeaderCount: 0
+# INVALID-LLVM-TC1-NEXT: SectionHeaderEntrySize: 64
+# INVALID-LLVM-TC1-NEXT: SectionHeaderCount: [[SECHDRCOUNT]]
+# INVALID-LLVM-TC1-NEXT: StringTableSectionIndex: [[SECHDRSTRTABINDEX]]
+# INVALID-LLVM-TC1-NEXT: }
+# INVALID-LLVM-TC1-NEXT: error: '[[FILE]]': unable to continue dumping, the file is corrupt: section header table goes past the end of the file: e_shoff = 0x1000
+
+# INVALID-GNU-TC1: ELF Header:
+# INVALID-GNU-TC1-NEXT: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
+# INVALID-GNU-TC1-NEXT: Class: ELF64
+# INVALID-GNU-TC1-NEXT: Data: 2's complement, little endian
+# INVALID-GNU-TC1-NEXT: Version: 1 (current)
+# INVALID-GNU-TC1-NEXT: OS/ABI: UNIX - System V
+# INVALID-GNU-TC1-NEXT: ABI Version: 0
+# INVALID-GNU-TC1-NEXT: Type: REL (Relocatable file)
+# INVALID-GNU-TC1-NEXT: Machine: None
+# INVALID-GNU-TC1-NEXT: Version: 0x1
+# INVALID-GNU-TC1-NEXT: Entry point address: 0x0
+# INVALID-GNU-TC1-NEXT: Start of program headers: 0 (bytes into file)
+# INVALID-GNU-TC1-NEXT: Start of section headers: 4096 (bytes into file)
+# INVALID-GNU-TC1-NEXT: Flags: 0x0
+# INVALID-GNU-TC1-NEXT: Size of this header: 64 (bytes)
+# INVALID-GNU-TC1-NEXT: Size of program headers: 0 (bytes)
+# INVALID-GNU-TC1-NEXT: Number of program headers: 0
+# INVALID-GNU-TC1-NEXT: Size of section headers: 64 (bytes)
+# INVALID-GNU-TC1-NEXT: Number of section headers: [[SECHDRCOUNT]]
+# INVALID-GNU-TC1-NEXT: Section header string table index: [[SECHDRSTRTABINDEX]]
+# INVALID-GNU-TC1-NEXT: error: '[[FILE]]': unable to continue dumping, the file is corrupt: section header table goes past the end of the file: e_shoff = 0x1000
+
+# INVALID-LLVM-TC2: error: '[[FILE]]': section header table goes past the end of the file: e_shoff = 0x1000
+# INVALID-GNU-TC2: error: '[[FILE]]': section header table goes past the end of the file: e_shoff = 0x1000
--- !ELF
FileHeader:
@@ -222,14 +225,14 @@ Sections:
## Check we don't dump anything except the file header when the section header table can't be read.
# RUN: not llvm-readobj -a %t.invalid1 2>&1 \
-# RUN: | FileCheck %s -DFILE=%t.invalid1 -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-LLVM
+# RUN: | FileCheck %s -DFILE=%t.invalid1 -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-LLVM-TC1
# RUN: not llvm-readelf -a %t.invalid1 2>&1 \
-# RUN: | FileCheck %s -DFILE=%t.invalid1 -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-GNU
+# RUN: | FileCheck %s -DFILE=%t.invalid1 -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-GNU-TC1
## Check what we print when e_shnum == 0, e_shstrndx == SHN_XINDEX and the section header table can't be read.
# RUN: yaml2obj %s -DSHNUM=0 -DSHSTRNDX=0xffff --docnum=4 -o %t.invalid2
# RUN: not llvm-readobj --file-headers %t.invalid2 2>&1 \
-# RUN: | FileCheck %s -DFILE=%t.invalid2 -DSECHDRCOUNT="<?>" -DSECHDRSTRTABINDEX="<?>" --check-prefix=INVALID-LLVM
+# RUN: | FileCheck %s -DFILE=%t.invalid2 -DSECHDRCOUNT="<?>" -DSECHDRSTRTABINDEX="<?>" --check-prefix=INVALID-LLVM-TC2
# RUN: not llvm-readelf --file-headers %t.invalid2 2>&1 \
-# RUN: | FileCheck %s -DFILE=%t.invalid2 -DSECHDRCOUNT="<?>" -DSECHDRSTRTABINDEX="<?>" --check-prefix=INVALID-GNU
+# RUN: | FileCheck %s -DFILE=%t.invalid2 -DSECHDRCOUNT="<?>" -DSECHDRSTRTABINDEX="<?>" --check-prefix=INVALID-GNU-TC2
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index ab93316907cc6..1cfa138d7a7ea 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -3575,9 +3575,16 @@ static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
template <class ELFT>
static std::string getSectionHeadersNumString(const ELFFile<ELFT> &Obj,
StringRef FileName) {
- const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();
- if (ElfHeader.e_shnum != 0)
- return to_string(ElfHeader.e_shnum);
+ if (Obj.getHeader().e_shnum != 0) {
+ std::string Result;
+ if (Obj.getHeader().e_shnum != Obj.getShNum())
+ raw_string_ostream(Result)
+ << format("%x (%x)", static_cast<int>(Obj.getHeader().e_shnum),
+ static_cast<int>(Obj.getShNum()));
+ else
+ raw_string_ostream(Result) << Obj.getHeader().e_shnum;
+ return Result;
+ }
Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
if (!ArrOrErr) {
@@ -3595,9 +3602,10 @@ static std::string getSectionHeadersNumString(const ELFFile<ELFT> &Obj,
template <class ELFT>
static std::string getSectionHeaderTableIndexString(const ELFFile<ELFT> &Obj,
StringRef FileName) {
- const typename ELFT::Ehdr &ElfHeader = Obj.getHeader();
- if (ElfHeader.e_shstrndx != SHN_XINDEX)
- return to_string(ElfHeader.e_shstrndx);
+ auto strndx = Obj.getHeader().e_shstrndx;
+
+ if (strndx != SHN_XINDEX)
+ return to_string(strndx);
Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
if (!ArrOrErr) {
@@ -3609,8 +3617,7 @@ static std::string getSectionHeaderTableIndexString(const ELFFile<ELFT> &Obj,
if (ArrOrErr->empty())
return "65535 (corrupt: out of range)";
- return to_string(ElfHeader.e_shstrndx) + " (" +
- to_string((*ArrOrErr)[0].sh_link) + ")";
+ return to_string(strndx) + " (" + to_string(Obj.getShStrNdx()) + ")";
}
static const EnumEntry<unsigned> *getObjectFileEnumEntry(unsigned Type) {
@@ -3765,7 +3772,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() {
printFields(OS, "Size of this header:", Str);
Str = to_string(e.e_phentsize) + " (bytes)";
printFields(OS, "Size of program headers:", Str);
- Str = to_string(e.e_phnum);
+ Str = to_string(this->Obj.getPhNum());
printFields(OS, "Number of program headers:", Str);
Str = to_string(e.e_shentsize) + " (bytes)";
printFields(OS, "Size of section headers:", Str);
@@ -4778,8 +4785,7 @@ void GNUELFDumper<ELFT>::printProgramHeaders(
return;
if (PrintProgramHeaders) {
- const Elf_Ehdr &Header = this->Obj.getHeader();
- if (Header.e_phnum == 0) {
+ if (this->Obj.getPhNum() == 0) {
OS << "\nThere are no program headers in this file.\n";
} else {
printProgramHeaders();
@@ -4798,7 +4804,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printProgramHeaders() {
OS << "\nElf file type is "
<< enumToString(Header.e_type, ArrayRef(ElfObjectFileType)) << "\n"
<< "Entry point " << format_hex(Header.e_entry, 3) << "\n"
- << "There are " << Header.e_phnum << " program headers,"
+ << "There are " << this->Obj.getPhNum() << " program headers,"
<< " starting at offset " << Header.e_phoff << "\n\n"
<< "Program Headers:\n";
if (ELFT::Is64Bits)
@@ -7470,7 +7476,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() {
W.printFlags("Flags", E.e_flags);
W.printNumber("HeaderSize", E.e_ehsize);
W.printNumber("ProgramHeaderEntrySize", E.e_phentsize);
- W.printNumber("ProgramHeaderCount", E.e_phnum);
+ W.printNumber("ProgramHeaderCount", this->Obj.getPhNum());
W.printNumber("SectionHeaderEntrySize", E.e_shentsize);
W.printString("SectionHeaderCount",
getSectionHeadersNumString(this->Obj, this->FileName));
More information about the llvm-commits
mailing list