[llvm-readelf] Print more information for RELR

llvm-readelf/llvm-readobj print RELR as REL relocations with a fixed
type (e.g. `R_*_RELATIVE`). GNU readelf printed only addresses and have
recently switched to a more descritive style that includes a symbolic
address column (symbolized using .symtab/.strtab) (milestone: binutils
2.43).

This patch implements the new GNU style, which seems superior to the
current REL style and essentially obsoletes LLVM-specific --raw-relr
(`printRelrReloc`).

Pull Request: https://github.com/llvm/llvm-project/pull/89162
This commit is contained in:
Fangrui Song 2024-04-19 09:21:57 -07:00 committed by GitHub
parent 854cc89866
commit d86079f93c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 239 additions and 88 deletions

View File

@ -328,31 +328,31 @@
// RELR64-NEXT: 0000000000030510 0000000200000101 R_AARCH64_ABS64 0000000000000000 zed2 + 0
// RELR64-EMPTY:
// RELR64-NEXT: Relocation section '.relr.dyn' at offset {{.*}} contains 24 entries:
// RELR64-NEXT: Offset Info Type Symbol's Value Symbol's Name
// RELR64-NEXT: 0000000000030490 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030498 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304a0 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304a8 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304b0 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304b8 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304c0 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304c8 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304d8 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304e0 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304e8 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304f0 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 00000000000304f8 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030500 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030508 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030520 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030528 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030530 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030538 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030540 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030548 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030550 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030558 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: 0000000000030560 0000000000000403 R_AARCH64_RELATIVE
// RELR64-NEXT: Symbolic Address
// RELR64-NEXT: $d.0{{$}}
// RELR64-NEXT: $d.0 + 0x8
// RELR64-NEXT: $d.0 + 0x10
// RELR64-NEXT: $d.0 + 0x18
// RELR64-NEXT: $d.0 + 0x20
// RELR64-NEXT: $d.0 + 0x28
// RELR64-NEXT: $d.0 + 0x30
// RELR64-NEXT: $d.0 + 0x38
// RELR64-NEXT: $d.0 + 0x48
// RELR64-NEXT: $d.0 + 0x50
// RELR64-NEXT: $d.0 + 0x58
// RELR64-NEXT: $d.0 + 0x60
// RELR64-NEXT: $d.0 + 0x68
// RELR64-NEXT: $d.0 + 0x70
// RELR64-NEXT: $d.0 + 0x78
// RELR64-NEXT: $d.0 + 0x90
// RELR64-NEXT: $d.0 + 0x98
// RELR64-NEXT: $d.0 + 0xa0
// RELR64-NEXT: $d.0 + 0xa8
// RELR64-NEXT: $d.0 + 0xb0
// RELR64-NEXT: $d.0 + 0xb8
// RELR64-NEXT: $d.0 + 0xc0
// RELR64-NEXT: $d.0 + 0xc8
// RELR64-NEXT: $d.0 + 0xd0
// RELR64-EMPTY:
// RELR64-NEXT: Hex dump of section '.data':
// RELR64-NEXT: 0x00030490 90040300 00000000 91040300 00000000 .

View File

@ -29,9 +29,9 @@
// CHECK-EMPTY:
// CHECK: Relocation section '.relr.dyn'
// CHECK-NEXT: Offset
// PART0-NEXT: 000000000000[[DATA_SEGMENT]]378 {{.*}} R_X86_64_RELATIVE
// PART1-NEXT: 000000000000[[DATA_SEGMENT]]340 {{.*}} R_X86_64_RELATIVE
// CHECK-NEXT: Address Symbolic Address
// PART0-NEXT: 000000000000[[DATA_SEGMENT]]378 p0{{$}}
// PART1-NEXT: 000000000000[[DATA_SEGMENT]]340 p1{{$}}
// CHECK-EMPTY:
.section .llvm_sympart,"",@llvm_sympart

View File

@ -47,29 +47,39 @@
# RAW-GNU1-NEXT: 00000000000f0501
# RAW-GNU1-NEXT: 000a700550400009
# RUN: llvm-readelf --relocations %t1 | FileCheck --check-prefix=GNU1 %s
# GNU1: Relocation section '.relr.dyn' at offset 0x40 contains 21 entries:
# GNU1: 0000000000010d60 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000010d68 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000010da0 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020000 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020040 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020050 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020080 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020088 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020090 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020098 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020210 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 00000000000202a8 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 00000000000202d8 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 00000000000202e8 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 00000000000202f8 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020308 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020358 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020360 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020368 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020380 0000000000000008 R_X86_64_RELATIVE
# GNU1-NEXT: 0000000000020390 0000000000000008 R_X86_64_RELATIVE
# RUN: llvm-readelf --relocations %t1 | FileCheck --check-prefix=GNU1 --match-full-lines --strict-whitespace %s
# GNU1:Relocation section '.relr.dyn' at offset 0x40 contains 21 entries:
# GNU1-NEXT:Index: Entry Address Symbolic Address
# GNU1-NEXT:0000: 0000000000010d60 0000000000010d60
# GNU1-NEXT:0001: 0000000000000103 0000000000010d68
# GNU1-NEXT: 0000000000010da0 base + 0x30
# GNU1-NEXT:0002: 0000000000020000 0000000000020000 foo
# GNU1-NEXT:0003: 00000000000f0501 0000000000020040 foo + 0x40
# GNU1-NEXT: 0000000000020050 foo + 0x50
# GNU1-NEXT: 0000000000020080 foo + 0x80
# GNU1-NEXT: 0000000000020088 foo + 0x88
# GNU1-NEXT: 0000000000020090 foo + 0x90
# GNU1-NEXT: 0000000000020098 foo + 0x98
# GNU1-NEXT:0004: 000a700550400009 0000000000020210 bar + 0x10
# GNU1-NEXT: 00000000000202a8 bar + 0xa8
# GNU1-NEXT: 00000000000202d8 bar + 0xd8
# GNU1-NEXT: 00000000000202e8 bar + 0xe8
# GNU1-NEXT: 00000000000202f8 bar + 0xf8
# GNU1-NEXT: 0000000000020308 bar + 0x108
# GNU1-NEXT: 0000000000020358 bar + 0x158
# GNU1-NEXT: 0000000000020360 bar + 0x160
# GNU1-NEXT: 0000000000020368 bar + 0x168
# GNU1-NEXT: 0000000000020380 bar + 0x180
# GNU1-NEXT: 0000000000020390 bar + 0x190
# GNU1-NOT:{{.}}
## The addresses are not symbolized in the absence of .symtab.
# RUN: llvm-objcopy --strip-all %t1 %t1.stripped
# RUN: llvm-readelf --relocations %t1.stripped | FileCheck --check-prefix=GNU1S --match-full-lines --strict-whitespace %s
# GNU1S:Relocation section '.relr.dyn' at offset 0x40 contains 21 entries:
# GNU1S-NEXT:Index: Entry Address Symbolic Address
# GNU1S-NEXT:0000: 0000000000010d60 0000000000010d60
# GNU1S-NEXT:0001: 0000000000000103 0000000000010d68
--- !ELF
FileHeader:
@ -83,6 +93,18 @@ Sections:
Flags: [ SHF_ALLOC ]
Entries: [ 0x0000000000010D60, 0x0000000000000103, 0x0000000000020000,
0x00000000000F0501, 0x000A700550400009 ]
Symbols:
- Name: bar
Value: 0x20200
Section: .relr.dyn
- Name: foo
Value: 0x20000
Section: .relr.dyn
- Name: base
Value: 0x10d70
Section: .relr.dyn
- Name: ignored
Value: 0x20210
# RUN: yaml2obj --docnum=2 %s -o %t2
# RUN: llvm-readobj --relocations --raw-relr %t2 | \
@ -124,22 +146,24 @@ Sections:
# RAW-GNU2-NEXT: 000f0501
# RAW-GNU2-NEXT: 50400009
# RUN: llvm-readelf --relocations %t2 | FileCheck --check-prefix=GNU2 %s
# GNU2: Relocation section '.relr.dyn' at offset 0x34 contains 14 entries:
# GNU2: 00010d60 00000008 R_386_RELATIVE
# GNU2-NEXT: 00010d64 00000008 R_386_RELATIVE
# GNU2-NEXT: 00010d80 00000008 R_386_RELATIVE
# GNU2-NEXT: 00020000 00000008 R_386_RELATIVE
# GNU2-NEXT: 00020020 00000008 R_386_RELATIVE
# GNU2-NEXT: 00020028 00000008 R_386_RELATIVE
# GNU2-NEXT: 00020040 00000008 R_386_RELATIVE
# GNU2-NEXT: 00020044 00000008 R_386_RELATIVE
# GNU2-NEXT: 00020048 00000008 R_386_RELATIVE
# GNU2-NEXT: 0002004c 00000008 R_386_RELATIVE
# GNU2-NEXT: 00020088 00000008 R_386_RELATIVE
# GNU2-NEXT: 000200d4 00000008 R_386_RELATIVE
# GNU2-NEXT: 000200ec 00000008 R_386_RELATIVE
# GNU2-NEXT: 000200f4 00000008 R_386_RELATIVE
# RUN: llvm-readelf --relocations %t2 | FileCheck --check-prefix=GNU2 --match-full-lines --strict-whitespace %s
# GNU2:Relocation section '.relr.dyn' at offset 0x34 contains 14 entries:
# GNU2-NEXT:Index: Entry Address Symbolic Address
# GNU2-NEXT:0000: 00010d60 00010d60 .relr.dyn
# GNU2-NEXT:0001: 00000103 00010d64 .relr.dyn + 0x4
# GNU2-NEXT: 00010d80 .relr.dyn + 0x20
# GNU2-NEXT:0002: 00020000 00020000 .relr.dyn + 0xf2a0
# GNU2-NEXT:0003: 000f0501 00020020 .relr.dyn + 0xf2c0
# GNU2-NEXT: 00020028 .relr.dyn + 0xf2c8
# GNU2-NEXT: 00020040 .relr.dyn + 0xf2e0
# GNU2-NEXT: 00020044 .relr.dyn + 0xf2e4
# GNU2-NEXT: 00020048 .relr.dyn + 0xf2e8
# GNU2-NEXT: 0002004c .relr.dyn + 0xf2ec
# GNU2-NEXT:0004: 50400009 00020088 .relr.dyn + 0xf328
# GNU2-NEXT: 000200d4 .relr.dyn + 0xf374
# GNU2-NEXT: 000200ec .relr.dyn + 0xf38c
# GNU2-NEXT: 000200f4 .relr.dyn + 0xf394
# GNU2-NOT:{{.}}
--- !ELF
FileHeader:
@ -156,6 +180,11 @@ Sections:
EntSize: [[ENTSIZE=<none>]]
ShType: [[SHTYPE=<none>]]
Link: [[LINK=<none>]]
Symbols:
- Name: .relr.dyn
Type: STT_SECTION
Value: 0x10D60
Section: .relr.dyn
## Check we report a warning when we are unable to dump relocations
## for a SHT_RELR/SHT_ANDROID_RELR/SHT_AARCH64_AUTH_RELR section.
@ -175,7 +204,6 @@ Sections:
# BROKEN-GNU: warning: '[[FILE]]': unable to get the number of relocations in [[SECNAME]] section with index 1: section [index 1] has invalid sh_entsize: expected 4, but got 1
# BROKEN-GNU: Relocation section '.relr.dyn' at offset 0x34 contains <?> entries:
# BROKEN-GNU-NEXT: Offset Info Type Sym. Value Symbol's Name
# BROKEN-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from [[SECNAME]] section with index 1: section [index 1] has invalid sh_entsize: expected 4, but got 1
## Case B: check the case when relocations can't be read from an SHT_ANDROID_RELR section.
@ -218,3 +246,36 @@ Sections:
# RUN: FileCheck -DFILE=%t2.has.link --check-prefix=RAW-LLVM2 %s
# RUN: llvm-readelf --relocations --raw-relr %t2.has.link 2>&1 | \
# RUN: FileCheck -DFILE=%t2.has.link --check-prefix=RAW-GNU2 %s
## .symtab is invalid. Check we report a warning and print entries without symbolization.
# RUN: yaml2obj --docnum=3 -DENTSIZE=1 %s -o %t3.err1
# RUN: llvm-readelf -r %t3.err1 2>&1 | FileCheck -DFILE=%t3.err1 --check-prefixes=GNU3,GNU3-ERR1 --match-full-lines %s
# RUN: yaml2obj --docnum=3 -DLINK=0xff %s -o %t3.err2
# RUN: llvm-readelf -r %t3.err2 2>&1 | FileCheck -DFILE=%t3.err2 --check-prefixes=GNU3,GNU3-ERR2 --match-full-lines %s
# GNU3:Index: Entry Address Symbolic Address
# GNU3-ERR1-NEXT:{{.*}}warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 2] has invalid sh_entsize: expected 24, but got 1
# GNU3-ERR2-NEXT:{{.*}}warning: '[[FILE]]': unable to get the string table for the SHT_SYMTAB section: invalid section index: 255
# GNU3-NEXT:0000: 0000000000010d60 0000000000010d60
# GNU3-NEXT:0001: 0000000000000103 0000000000010d68
# GNU3-NEXT: 0000000000010da0
# GNU3-NOT:{{.}}
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .relr.dyn
Type: SHT_RELR
Flags: [ SHF_ALLOC ]
Entries: [ 0x0000000000010D60, 0x0000000000000103 ]
- Name: .symtab
Type: SHT_SYMTAB
Link: [[LINK=.strtab]]
EntSize: [[ENTSIZE=0x18]]
Symbols:
- Name: bar
Value: 0x10D60

View File

@ -411,6 +411,7 @@ protected:
std::string getStaticSymbolName(uint32_t Index) const;
StringRef getDynamicString(uint64_t Value) const;
std::pair<Elf_Sym_Range, std::optional<StringRef>> getSymtabAndStrtab() const;
void printSymbolsHelper(bool IsDynamic, bool ExtraSymInfo) const;
std::string getDynamicEntry(uint64_t Type, uint64_t Value) const;
@ -512,6 +513,28 @@ ELFDumper<ELFT>::getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,
return *VersionsOrErr;
}
template <class ELFT>
std::pair<typename ELFDumper<ELFT>::Elf_Sym_Range, std::optional<StringRef>>
ELFDumper<ELFT>::getSymtabAndStrtab() const {
assert(DotSymtabSec);
Elf_Sym_Range Syms(nullptr, nullptr);
std::optional<StringRef> StrTable;
if (Expected<StringRef> StrTableOrErr =
Obj.getStringTableForSymtab(*DotSymtabSec))
StrTable = *StrTableOrErr;
else
reportUniqueWarning(
"unable to get the string table for the SHT_SYMTAB section: " +
toString(StrTableOrErr.takeError()));
if (Expected<Elf_Sym_Range> SymsOrErr = Obj.symbols(DotSymtabSec))
Syms = *SymsOrErr;
else
reportUniqueWarning("unable to read symbols from the SHT_SYMTAB section: " +
toString(SymsOrErr.takeError()));
return {Syms, StrTable};
}
template <class ELFT>
void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic,
bool ExtraSymInfo) const {
@ -525,20 +548,7 @@ void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic,
Syms = dynamic_symbols();
Entries = Syms.size();
} else if (DotSymtabSec) {
if (Expected<StringRef> StrTableOrErr =
Obj.getStringTableForSymtab(*DotSymtabSec))
StrTable = *StrTableOrErr;
else
reportUniqueWarning(
"unable to get the string table for the SHT_SYMTAB section: " +
toString(StrTableOrErr.takeError()));
if (Expected<Elf_Sym_Range> SymsOrErr = Obj.symbols(DotSymtabSec))
Syms = *SymsOrErr;
else
reportUniqueWarning(
"unable to read symbols from the SHT_SYMTAB section: " +
toString(SymsOrErr.takeError()));
std::tie(Syms, StrTable) = getSymtabAndStrtab();
Entries = DotSymtabSec->getEntityCount();
}
if (Syms.empty())
@ -658,6 +668,7 @@ private:
void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex,
DataRegion<Elf_Word> ShndxTable, StringRef StrTable,
uint32_t Bucket);
void printRelr(const Elf_Shdr &Sec);
void printRelrReloc(const Elf_Relr &R) override;
void printRelRelaReloc(const Relocation<ELFT> &R,
const RelSymbol<ELFT> &RelSym) override;
@ -3882,6 +3893,12 @@ static bool isRelocationSec(const typename ELFT::Shdr &Sec,
}
template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
auto PrintAsRelr = [&](const Elf_Shdr &Sec) {
return !opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR ||
Sec.sh_type == ELF::SHT_ANDROID_RELR ||
(this->Obj.getHeader().e_machine == EM_AARCH64 &&
Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR));
};
auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected<size_t> {
// Android's packed relocation section needs to be unpacked first
// to get the actual number of entries.
@ -3894,10 +3911,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
return RelasOrErr->size();
}
if (!opts::RawRelr &&
(Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_ANDROID_RELR ||
(this->Obj.getHeader().e_machine == EM_AARCH64 &&
Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR))) {
if (PrintAsRelr(Sec)) {
Expected<Elf_Relr_Range> RelrsOrErr = this->Obj.relrs(Sec);
if (!RelrsOrErr)
return RelrsOrErr.takeError();
@ -3926,13 +3940,89 @@ template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
OS << "\nRelocation section '" << Name << "' at offset 0x"
<< utohexstr(Offset, /*LowerCase=*/true) << " contains " << EntriesNum
<< " entries:\n";
printRelocHeaderFields<ELFT>(OS, Sec.sh_type, this->Obj.getHeader());
this->printRelocationsHelper(Sec);
if (PrintAsRelr(Sec)) {
printRelr(Sec);
} else {
printRelocHeaderFields<ELFT>(OS, Sec.sh_type, this->Obj.getHeader());
this->printRelocationsHelper(Sec);
}
}
if (!HasRelocSections)
OS << "\nThere are no relocations in this file.\n";
}
template <class ELFT> void GNUELFDumper<ELFT>::printRelr(const Elf_Shdr &Sec) {
Expected<Elf_Relr_Range> RangeOrErr = this->Obj.relrs(Sec);
if (!RangeOrErr) {
this->reportUniqueWarning("unable to read relocations from " +
this->describe(Sec) + ": " +
toString(RangeOrErr.takeError()));
return;
}
if (ELFT::Is64Bits)
OS << "Index: Entry Address Symbolic Address\n";
else
OS << "Index: Entry Address Symbolic Address\n";
// If .symtab is available, collect its defined symbols and sort them by
// st_value.
SmallVector<std::pair<uint64_t, std::string>, 0> Syms;
if (this->DotSymtabSec) {
Elf_Sym_Range Symtab;
std::optional<StringRef> Strtab;
std::tie(Symtab, Strtab) = this->getSymtabAndStrtab();
if (Symtab.size() && Strtab) {
for (auto [I, Sym] : enumerate(Symtab)) {
if (!Sym.st_shndx)
continue;
Syms.emplace_back(Sym.st_value,
this->getFullSymbolName(Sym, I, ArrayRef<Elf_Word>(),
*Strtab, false));
}
}
}
llvm::stable_sort(Syms);
typename ELFT::uint Base = 0;
size_t I = 0;
auto Print = [&](uint64_t Where) {
OS << format_hex_no_prefix(Where, ELFT::Is64Bits ? 16 : 8);
for (; I < Syms.size() && Syms[I].first <= Where; ++I)
;
// Try symbolizing the address. Find the nearest symbol before or at the
// address and print the symbol and the address difference.
if (I) {
OS << " " << Syms[I - 1].second;
if (Syms[I - 1].first < Where)
OS << " + 0x" << Twine::utohexstr(Where - Syms[I - 1].first);
}
OS << '\n';
};
for (auto [Index, R] : enumerate(*RangeOrErr)) {
typename ELFT::uint Entry = R;
OS << formatv("{0:4}: ", Index)
<< format_hex_no_prefix(Entry, ELFT::Is64Bits ? 16 : 8) << ' ';
if ((Entry & 1) == 0) {
Print(Entry);
Base = Entry + sizeof(typename ELFT::uint);
} else {
bool First = true;
for (auto Where = Base; Entry >>= 1;
Where += sizeof(typename ELFT::uint)) {
if (Entry & 1) {
if (First)
First = false;
else
OS.indent(ELFT::Is64Bits ? 24 : 16);
Print(Where);
}
}
Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(typename ELFT::uint);
}
}
}
// Print the offset of a particular section from anyone of the ranges:
// [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].
// If 'Type' does not fall within any of those ranges, then a string is