diff --git a/lld/test/ELF/pack-dyn-relocs.s b/lld/test/ELF/pack-dyn-relocs.s index dd5d366ae23448..e267147759d4d4 100644 --- a/lld/test/ELF/pack-dyn-relocs.s +++ b/lld/test/ELF/pack-dyn-relocs.s @@ -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 . diff --git a/lld/test/ELF/partition-pack-dyn-relocs.s b/lld/test/ELF/partition-pack-dyn-relocs.s index 3727bcc21614d8..8127110e348c55 100644 --- a/lld/test/ELF/partition-pack-dyn-relocs.s +++ b/lld/test/ELF/partition-pack-dyn-relocs.s @@ -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 diff --git a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test index 91b148ebb6e3c8..9b59f991c051e2 100644 --- a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test +++ b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test @@ -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=]] ShType: [[SHTYPE=]] Link: [[LINK=]] +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 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 1108672003fc76..f145653ac743c5 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -411,6 +411,7 @@ template class ELFDumper : public ObjDumper { std::string getStaticSymbolName(uint32_t Index) const; StringRef getDynamicString(uint64_t Value) const; + std::pair> getSymtabAndStrtab() const; void printSymbolsHelper(bool IsDynamic, bool ExtraSymInfo) const; std::string getDynamicEntry(uint64_t Type, uint64_t Value) const; @@ -512,6 +513,28 @@ ELFDumper::getVersionTable(const Elf_Shdr &Sec, ArrayRef *SymTab, return *VersionsOrErr; } +template +std::pair::Elf_Sym_Range, std::optional> +ELFDumper::getSymtabAndStrtab() const { + assert(DotSymtabSec); + Elf_Sym_Range Syms(nullptr, nullptr); + std::optional StrTable; + if (Expected StrTableOrErr = + Obj.getStringTableForSymtab(*DotSymtabSec)) + StrTable = *StrTableOrErr; + else + reportUniqueWarning( + "unable to get the string table for the SHT_SYMTAB section: " + + toString(StrTableOrErr.takeError())); + + if (Expected SymsOrErr = Obj.symbols(DotSymtabSec)) + Syms = *SymsOrErr; + else + reportUniqueWarning("unable to read symbols from the SHT_SYMTAB section: " + + toString(SymsOrErr.takeError())); + return {Syms, StrTable}; +} + template void ELFDumper::printSymbolsHelper(bool IsDynamic, bool ExtraSymInfo) const { @@ -525,20 +548,7 @@ void ELFDumper::printSymbolsHelper(bool IsDynamic, Syms = dynamic_symbols(); Entries = Syms.size(); } else if (DotSymtabSec) { - if (Expected StrTableOrErr = - Obj.getStringTableForSymtab(*DotSymtabSec)) - StrTable = *StrTableOrErr; - else - reportUniqueWarning( - "unable to get the string table for the SHT_SYMTAB section: " + - toString(StrTableOrErr.takeError())); - - if (Expected 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 @@ template class GNUELFDumper : public ELFDumper { void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex, DataRegion ShndxTable, StringRef StrTable, uint32_t Bucket); + void printRelr(const Elf_Shdr &Sec); void printRelrReloc(const Elf_Relr &R) override; void printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) override; @@ -3882,6 +3893,12 @@ static bool isRelocationSec(const typename ELFT::Shdr &Sec, } template void GNUELFDumper::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 { // Android's packed relocation section needs to be unpacked first // to get the actual number of entries. @@ -3894,10 +3911,7 @@ template void GNUELFDumper::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 RelrsOrErr = this->Obj.relrs(Sec); if (!RelrsOrErr) return RelrsOrErr.takeError(); @@ -3926,13 +3940,89 @@ template void GNUELFDumper::printRelocations() { OS << "\nRelocation section '" << Name << "' at offset 0x" << utohexstr(Offset, /*LowerCase=*/true) << " contains " << EntriesNum << " entries:\n"; - printRelocHeaderFields(OS, Sec.sh_type, this->Obj.getHeader()); - this->printRelocationsHelper(Sec); + + if (PrintAsRelr(Sec)) { + printRelr(Sec); + } else { + printRelocHeaderFields(OS, Sec.sh_type, this->Obj.getHeader()); + this->printRelocationsHelper(Sec); + } } if (!HasRelocSections) OS << "\nThere are no relocations in this file.\n"; } +template void GNUELFDumper::printRelr(const Elf_Shdr &Sec) { + Expected 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, 0> Syms; + if (this->DotSymtabSec) { + Elf_Sym_Range Symtab; + std::optional 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(), + *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