Index: llvm/test/tools/llvm-readobj/elf-dependent-libraries.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-readobj/elf-dependent-libraries.test @@ -0,0 +1,65 @@ +## Check that we can use the --elf-dependent-libs option +## to dump SHT_LLVM_DEPENDENT_LIBRARIES sections. + +## Check how we dump a file that has a single valid SHT_LLVM_DEPENDENT_LIBRARIES +## section with multiple entries. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: llvm-readobj --elf-dependent-libs %t1 2>&1 | FileCheck %s -DFILE=%t + +# CHECK: DependentLibs [ +# CHECK-NEXT: Entries: [foo, bar, foo] +# CHECK-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .deplibs + Type: SHT_LLVM_DEPENDENT_LIBRARIES + Libraries: [ foo, bar, foo ] + +## Now, check how we dump a mix of valid, empty and invalid SHT_LLVM_DEPENDENT_LIBRARIES sections. + +# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: llvm-readobj --elf-dependent-libs %t2 2>&1 | FileCheck %s --check-prefix=MIX -DFILE=%t2 + +# MIX: DependentLibs [ +# MIX-EMPTY: +# MIX-NEXT: warning: '[[FILE]]': SHT_LLVM_DEPENDENT_LIBRARIES section at index 1 is broken: the content is not null-terminated +# MIX-EMPTY: +# MIX-NEXT: warning: '[[FILE]]': SHT_LLVM_DEPENDENT_LIBRARIES section at index 5 is broken: section [index 5] has a sh_offset (0xffff0000) + sh_size (0x4) that cannot be represented +# MIX-NEXT: Entries: [abc, bar, xxx] +# MIX-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .deplibs.nonul + Type: SHT_LLVM_DEPENDENT_LIBRARIES + Content: "666f6f" ## 'f', 'o', 'o' + - Name: .deplibs.single + Type: SHT_LLVM_DEPENDENT_LIBRARIES + Libraries: [ abc ] + - Name: .deplibs.empty + Type: SHT_LLVM_DEPENDENT_LIBRARIES + Content: "" + - Name: .deplibs.multiple + Type: SHT_LLVM_DEPENDENT_LIBRARIES + Libraries: [ bar, xxx ] + - Name: .deplibs.broken.shoffset + Type: SHT_LLVM_DEPENDENT_LIBRARIES + Libraries: [ yyy ] + ShOffset: 0xffff0000 + +## llvm-readelf doesn't support --elf-dependent-libs yet. +# RUN: llvm-readelf --elf-dependent-libs %t1 2>&1 | FileCheck %s --check-prefix=READELF + +# READELF: printELFDependentLibs not implemented! Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -185,6 +185,8 @@ void printNotes() override; void printELFLinkerOptions() override; + void printELFDependentLibs() override; + void printStackSizes() override; const object::ELFObjectFile *getElfObject() const { return ObjF; }; @@ -414,6 +416,7 @@ virtual void printAddrsig(const ELFFile *Obj) = 0; virtual void printNotes(const ELFFile *Obj) = 0; virtual void printELFLinkerOptions(const ELFFile *Obj) = 0; + virtual void printELFDependentLibs(const ELFFile *Obj) = 0; virtual void printStackSizes(const ELFObjectFile *Obj) = 0; void printNonRelocatableStackSizes(const ELFObjectFile *Obj, std::function PrintHeader); @@ -480,6 +483,7 @@ void printAddrsig(const ELFFile *Obj) override; void printNotes(const ELFFile *Obj) override; void printELFLinkerOptions(const ELFFile *Obj) override; + void printELFDependentLibs(const ELFFile *Obj) override; void printStackSizes(const ELFObjectFile *Obj) override; void printStackSizeEntry(uint64_t Size, StringRef FuncName) override; void printMipsGOT(const MipsGOTParser &Parser) override; @@ -595,6 +599,7 @@ void printAddrsig(const ELFFile *Obj) override; void printNotes(const ELFFile *Obj) override; void printELFLinkerOptions(const ELFFile *Obj) override; + void printELFDependentLibs(const ELFFile *Obj) override; void printStackSizes(const ELFObjectFile *Obj) override; void printStackSizeEntry(uint64_t Size, StringRef FuncName) override; void printMipsGOT(const MipsGOTParser &Parser) override; @@ -1919,6 +1924,10 @@ ELFDumperStyle->printELFLinkerOptions(ObjF->getELFFile()); } +template void ELFDumper::printELFDependentLibs() { + ELFDumperStyle->printELFDependentLibs(ObjF->getELFFile()); +} + template void ELFDumper::printStackSizes() { ELFDumperStyle->printStackSizes(ObjF); } @@ -4741,6 +4750,11 @@ OS << "printELFLinkerOptions not implemented!\n"; } +template +void GNUStyle::printELFDependentLibs(const ELFFile *Obj) { + OS << "printELFDependentLibs not implemented!\n"; +} + // Used for printing section names in places where possible errors can be // ignored. static StringRef getSectionName(const SectionRef &Sec) { @@ -6051,6 +6065,45 @@ } } +template +void LLVMStyle::printELFDependentLibs(const ELFFile *Obj) { + ListScope L(W, "DependentLibs"); + + auto Warn = [this](unsigned SecNdx, StringRef Msg) { + reportWarning(createError("SHT_LLVM_DEPENDENT_LIBRARIES section at index " + + Twine(SecNdx) + " is broken: " + Msg), + this->FileName); + }; + + unsigned I = -1; + std::vector Ret; + for (const Elf_Shdr &Shdr : unwrapOrError(this->FileName, Obj->sections())) { + ++I; + if (Shdr.sh_type != ELF::SHT_LLVM_DEPENDENT_LIBRARIES) + continue; + + Expected> ContentsOrErr = Obj->getSectionContents(&Shdr); + if (!ContentsOrErr) { + Warn(I, toString(ContentsOrErr.takeError())); + continue; + } + + ArrayRef Contents = *ContentsOrErr; + if (!Contents.empty() && Contents.back() != 0) { + Warn(I, "the content is not null-terminated"); + continue; + } + + for (const uint8_t *I = Contents.begin(), *E = Contents.end(); I < E;) { + StringRef Lib((const char *)I); + Ret.push_back(Lib); + I += Lib.size() + 1; + } + } + + W.printList("Entries", Ret); +} + template void LLVMStyle::printStackSizes(const ELFObjectFile *Obj) { ListScope L(W, "StackSizes"); Index: llvm/tools/llvm-readobj/ObjDumper.h =================================================================== --- llvm/tools/llvm-readobj/ObjDumper.h +++ llvm/tools/llvm-readobj/ObjDumper.h @@ -68,6 +68,7 @@ virtual void printAddrsig() {} virtual void printNotes() {} virtual void printELFLinkerOptions() {} + virtual void printELFDependentLibs() {} virtual void printStackSizes() {} virtual void printArchSpecificInfo() { } Index: llvm/tools/llvm-readobj/llvm-readobj.cpp =================================================================== --- llvm/tools/llvm-readobj/llvm-readobj.cpp +++ llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -274,6 +274,11 @@ ELFLinkerOptions("elf-linker-options", cl::desc("Display the ELF .linker-options section")); + // --elf-dependent-libs + cl::opt + ELFDependentLibs("elf-dependent-libs", + cl::desc("Display the dependent libraries section")); + // --macho-data-in-code cl::opt MachODataInCode("macho-data-in-code", @@ -491,6 +496,8 @@ if (Obj->isELF()) { if (opts::ELFLinkerOptions) Dumper->printELFLinkerOptions(); + if (opts::ELFDependentLibs) + Dumper->printELFDependentLibs(); if (opts::ArchSpecificInfo) Dumper->printArchSpecificInfo(); if (opts::SectionGroups)