mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-26 07:16:39 +00:00
[llvm-readobj] - Implement --dependent-libraries flag.
There is no way to dump SHT_LLVM_DEPENDENT_LIBRARIES sections currently. This patch implements this. The section is described here: https://llvm.org/docs/Extensions.html#sht-llvm-dependent-libraries-section-dependent-libraries Differential revision: https://reviews.llvm.org/D70665
This commit is contained in:
parent
765a5a757e
commit
41cf18166c
@ -152,6 +152,10 @@ The following options are implemented only for the ELF file format.
|
||||
|
||||
Display demangled symbol names in the output.
|
||||
|
||||
.. option:: --dependent-libraries
|
||||
|
||||
Display the dependent libraries section.
|
||||
|
||||
.. option:: --dyn-relocations
|
||||
|
||||
Display the dynamic relocation entries.
|
||||
|
74
test/tools/llvm-readobj/elf-dependent-libraries.test
Normal file
74
test/tools/llvm-readobj/elf-dependent-libraries.test
Normal file
@ -0,0 +1,74 @@
|
||||
## Check that we can use the --dependent-libraries 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 --dependent-libraries %t1 2>&1 | FileCheck %s -DFILE=%t
|
||||
|
||||
# CHECK: DependentLibs [
|
||||
# CHECK-NEXT: foo
|
||||
# CHECK-NEXT: bar
|
||||
# CHECK-NEXT: 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 --dependent-libraries %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-NEXT: abc
|
||||
# MIX-EMPTY:
|
||||
# MIX-NEXT: warning: '[[FILE]]': SHT_LLVM_DEPENDENT_LIBRARIES section at index 4 is broken: section [index 4] has a sh_offset (0xffff0000) + sh_size (0x4) that is greater than the file size (0x2c0)
|
||||
# MIX-NEXT: bar
|
||||
# MIX-NEXT: xxx
|
||||
# MIX-NEXT: ]
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
## Case 1: test we report a warning for a non-null-terminated section.
|
||||
- Name: .deplibs.nonul
|
||||
Type: SHT_LLVM_DEPENDENT_LIBRARIES
|
||||
Content: "666f6f" ## 'f', 'o', 'o'
|
||||
## Case 2: test we can dump an entry from a valid section that has a single entry.
|
||||
- Name: .deplibs.single
|
||||
Type: SHT_LLVM_DEPENDENT_LIBRARIES
|
||||
Libraries: [ abc ]
|
||||
## Case 3: test we do not display warnings for an empty section.
|
||||
- Name: .deplibs.empty
|
||||
Type: SHT_LLVM_DEPENDENT_LIBRARIES
|
||||
Content: ""
|
||||
## Case 4: test we report a warning when the section offset is invalid.
|
||||
- Name: .deplibs.broken.shoffset
|
||||
Type: SHT_LLVM_DEPENDENT_LIBRARIES
|
||||
Libraries: [ yyy ]
|
||||
ShOffset: 0xffff0000
|
||||
## Case 5: test we can dump all entries from a valid section that has more than one entry.
|
||||
- Name: .deplibs.multiple
|
||||
Type: SHT_LLVM_DEPENDENT_LIBRARIES
|
||||
Libraries: [ bar, xxx ]
|
||||
|
||||
## llvm-readelf doesn't support --dependent-libraries yet.
|
||||
# RUN: llvm-readelf --dependent-libraries %t1 2>&1 | FileCheck %s --check-prefix=READELF
|
||||
|
||||
# READELF: printDependentLibs not implemented!
|
@ -193,6 +193,7 @@ public:
|
||||
void printFileHeaders() override;
|
||||
void printSectionHeaders() override;
|
||||
void printRelocations() override;
|
||||
void printDependentLibs() override;
|
||||
void printDynamicRelocations() override;
|
||||
void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override;
|
||||
void printHashSymbols() override;
|
||||
@ -617,6 +618,7 @@ public:
|
||||
virtual void printSymbols(const ELFFile<ELFT> *Obj, bool PrintSymbols,
|
||||
bool PrintDynamicSymbols) = 0;
|
||||
virtual void printHashSymbols(const ELFFile<ELFT> *Obj) {}
|
||||
virtual void printDependentLibs(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printDynamic(const ELFFile<ELFT> *Obj) {}
|
||||
virtual void printDynamicRelocations(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printSymtabMessage(const ELFFile<ELFT> *Obj, StringRef Name,
|
||||
@ -687,6 +689,7 @@ public:
|
||||
void printSymbols(const ELFO *Obj, bool PrintSymbols,
|
||||
bool PrintDynamicSymbols) override;
|
||||
void printHashSymbols(const ELFO *Obj) override;
|
||||
void printDependentLibs(const ELFFile<ELFT> *Obj) override;
|
||||
void printDynamic(const ELFFile<ELFT> *Obj) override;
|
||||
void printDynamicRelocations(const ELFO *Obj) override;
|
||||
void printSymtabMessage(const ELFO *Obj, StringRef Name, size_t Offset,
|
||||
@ -807,6 +810,7 @@ public:
|
||||
void printSectionHeaders(const ELFO *Obj) override;
|
||||
void printSymbols(const ELFO *Obj, bool PrintSymbols,
|
||||
bool PrintDynamicSymbols) override;
|
||||
void printDependentLibs(const ELFFile<ELFT> *Obj) override;
|
||||
void printDynamic(const ELFFile<ELFT> *Obj) override;
|
||||
void printDynamicRelocations(const ELFO *Obj) override;
|
||||
void printProgramHeaders(const ELFO *Obj, bool PrintProgramHeaders,
|
||||
@ -2054,6 +2058,10 @@ template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
|
||||
SymbolVersionNeedSection);
|
||||
}
|
||||
|
||||
template <class ELFT> void ELFDumper<ELFT>::printDependentLibs() {
|
||||
ELFDumperStyle->printDependentLibs(ObjF->getELFFile());
|
||||
}
|
||||
|
||||
template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
|
||||
ELFDumperStyle->printDynamicRelocations(ObjF->getELFFile());
|
||||
}
|
||||
@ -4873,6 +4881,11 @@ void GNUStyle<ELFT>::printELFLinkerOptions(const ELFFile<ELFT> *Obj) {
|
||||
OS << "printELFLinkerOptions not implemented!\n";
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void GNUStyle<ELFT>::printDependentLibs(const ELFFile<ELFT> *Obj) {
|
||||
OS << "printDependentLibs not implemented!\n";
|
||||
}
|
||||
|
||||
// Used for printing section names in places where possible errors can be
|
||||
// ignored.
|
||||
static StringRef getSectionName(const SectionRef &Sec) {
|
||||
@ -6143,6 +6156,42 @@ void LLVMStyle<ELFT>::printELFLinkerOptions(const ELFFile<ELFT> *Obj) {
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LLVMStyle<ELFT>::printDependentLibs(const ELFFile<ELFT> *Obj) {
|
||||
ListScope L(W, "DependentLibs");
|
||||
|
||||
auto Warn = [this](unsigned SecNdx, StringRef Msg) {
|
||||
this->reportUniqueWarning(
|
||||
createError("SHT_LLVM_DEPENDENT_LIBRARIES section at index " +
|
||||
Twine(SecNdx) + " is broken: " + Msg));
|
||||
};
|
||||
|
||||
unsigned I = -1;
|
||||
for (const Elf_Shdr &Shdr : unwrapOrError(this->FileName, Obj->sections())) {
|
||||
++I;
|
||||
if (Shdr.sh_type != ELF::SHT_LLVM_DEPENDENT_LIBRARIES)
|
||||
continue;
|
||||
|
||||
Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj->getSectionContents(&Shdr);
|
||||
if (!ContentsOrErr) {
|
||||
Warn(I, toString(ContentsOrErr.takeError()));
|
||||
continue;
|
||||
}
|
||||
|
||||
ArrayRef<uint8_t> 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);
|
||||
W.printString(Lib);
|
||||
I += Lib.size() + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LLVMStyle<ELFT>::printStackSizes(const ELFObjectFile<ELFT> *Obj) {
|
||||
ListScope L(W, "StackSizes");
|
||||
|
@ -53,6 +53,7 @@ public:
|
||||
virtual void printUnwindInfo() = 0;
|
||||
|
||||
// Only implemented for ELF at this time.
|
||||
virtual void printDependentLibs() {}
|
||||
virtual void printDynamicRelocations() { }
|
||||
virtual void printDynamicTable() { }
|
||||
virtual void printNeededLibraries() { }
|
||||
|
@ -58,6 +58,11 @@ namespace opts {
|
||||
"--section-groups and --elf-hash-histogram."));
|
||||
cl::alias AllShort("a", cl::desc("Alias for --all"), cl::aliasopt(All));
|
||||
|
||||
// --dependent-libraries
|
||||
cl::opt<bool>
|
||||
DependentLibraries("dependent-libraries",
|
||||
cl::desc("Display the dependent libraries section"));
|
||||
|
||||
// --headers -e
|
||||
cl::opt<bool>
|
||||
Headers("headers",
|
||||
@ -489,6 +494,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer,
|
||||
if (opts::VersionInfo)
|
||||
Dumper->printVersionInfo();
|
||||
if (Obj->isELF()) {
|
||||
if (opts::DependentLibraries)
|
||||
Dumper->printDependentLibs();
|
||||
if (opts::ELFLinkerOptions)
|
||||
Dumper->printELFLinkerOptions();
|
||||
if (opts::ArchSpecificInfo)
|
||||
|
Loading…
x
Reference in New Issue
Block a user