Skip to content

Commit

Permalink
[llvm-readelf] Make llvm-readelf more compatible with GNU readelf.
Browse files Browse the repository at this point in the history
Summary:
This change adds a bunch of options that GNU readelf supports. There is one breaking change when invoked as `llvm-readobj`, and three breaking changes when invoked as `llvm-readelf`:
 - Add --all (implies --file-header, --program-headers, etc.)
 - [Breaking] -a is --all instead of --arm-attributes
 - Add --file-header as an alias for --file-headers
 - Replace --sections with --sections-headers, keeping --sections as an alias for it
 - Add --relocs as an alias for --relocations
 - Add --dynamic as an alias for --dynamic-table
 - Add --segments as an alias for --program-headers
 - Add --section-groups as an alias for --elf-section-groups
 - Add --dyn-syms as an alias for --dyn-symbols
 - Add --syms as an alias for --symbols
 - Add --histogram as an alias for --elf-hash-histogram
 - [Breaking] When invoked as `llvm-readelf`, -s is --symbols instead of --sections
 - [Breaking] When invoked as `llvm-readelf`, -t is no longer an alias for --symbols

Reviewers: MaskRay, phosek, mcgrathr, jhenderson

Reviewed By: MaskRay, jhenderson

Subscribers: sbc100, aheejin, edd, jhenderson, silvas, echristo, compnerd, kristina, javed.absar, kristof.beyls, llvm-commits, Bigcheese

Differential Revision: https://reviews.llvm.org/D54124

llvm-svn: 346685
  • Loading branch information
rupprecht committed Nov 12, 2018
1 parent ec3c085 commit dbf552c
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 94 deletions.
6 changes: 3 additions & 3 deletions llvm/test/MC/ARM/elf-execute-only-section.ll
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
; RUN: llc < %s -mtriple=thumbv8m.base-eabi -mattr=+execute-only -filetype=obj %s -o - | \
; RUN: llvm-readelf -s | FileCheck %s
; RUN: llvm-readelf -S | FileCheck %s
; RUN: llc < %s -mtriple=thumbv8m.main-eabi -mattr=+execute-only -filetype=obj %s -o - | \
; RUN: llvm-readelf -s | FileCheck %s
; RUN: llvm-readelf -S | FileCheck %s
; RUN: llc < %s -mtriple=thumbv7m-eabi -mattr=+execute-only -filetype=obj %s -o - | \
; RUN: llvm-readelf -s | FileCheck %s
; RUN: llvm-readelf -S | FileCheck %s

; CHECK-NOT: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AX[^p]}}
; CHECK: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AXp}}
Expand Down
15 changes: 15 additions & 0 deletions llvm/test/tools/llvm-readobj/all.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
RUN: llvm-readobj -a %p/Inputs/trivial.obj.elf-i386 \
RUN: | FileCheck %s -check-prefix ALL
RUN: llvm-readobj --all %p/Inputs/trivial.obj.elf-i386 \
RUN: | FileCheck %s -check-prefix ALL

ALL: Format: ELF32-i386
ALL: Arch: i386
ALL: AddressSize: 32bit
ALL: LoadName:
ALL: ElfHeader {
ALL: Sections [
ALL: Relocations [
ALL: Symbols [
ALL: ProgramHeaders [
ALL: Notes [
49 changes: 49 additions & 0 deletions llvm/test/tools/llvm-readobj/readelf-s-alias.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# In llvm-readobj, -s is an alias for --sections.
RUN: llvm-readobj -s %p/Inputs/trivial.obj.elf-i386 \
RUN: | FileCheck %s -check-prefix SEC
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.elf-i386 \
RUN: | FileCheck %s -check-prefix SEC

# In llvm-readelf, -s is an alias for --symbols.
RUN: llvm-readelf -s %p/Inputs/trivial.obj.elf-i386 \
RUN: | FileCheck %s -check-prefix SYM
RUN: llvm-readelf --symbols %p/Inputs/trivial.obj.elf-i386 \
RUN: | FileCheck %s -check-prefix SYM

SEC: Sections [
SEC-NEXT: Section {
SEC-NEXT: Index: 0
SEC-NEXT: Name: (0)
SEC-NEXT: Type: SHT_NULL (0x0)
SEC-NEXT: Flags [ (0x0)
SEC-NEXT: ]
SEC-NEXT: Address: 0x0
SEC-NEXT: Offset: 0x0
SEC-NEXT: Size: 0
SEC-NEXT: Link: 0
SEC-NEXT: Info: 0
SEC-NEXT: AddressAlignment: 0
SEC-NEXT: EntrySize: 0
SEC-NEXT: }
SEC-NEXT: Section {
SEC-NEXT: Index: 1
SEC-NEXT: Name: .text (5)
SEC-NEXT: Type: SHT_PROGBITS (0x1)
SEC-NEXT: Flags [ (0x6)
SEC-NEXT: SHF_ALLOC (0x2)
SEC-NEXT: SHF_EXECINSTR (0x4)
SEC-NEXT: ]
SEC-NEXT: Address: 0x0
SEC-NEXT: Offset: 0x40
SEC-NEXT: Size: 42
SEC-NEXT: Link: 0
SEC-NEXT: Info: 0
SEC-NEXT: AddressAlignment: 16
SEC-NEXT: EntrySize: 0
SEC-NEXT: }

SYM: Symbol table '.symtab' contains {{.*}} entries:
SYM-NEXT: Num: Value Size Type Bind Vis Ndx Name
SYM-NEXT: 0: {{.*}} NOTYPE {{.*}} UND
SYM-NEXT: 1: {{.*}} FILE {{.*}} trivial.ll
SYM-NEXT: 2: {{.*}} OBJECT {{.*}} .L.str
25 changes: 16 additions & 9 deletions llvm/test/tools/llvm-readobj/sections.test
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
RUN: llvm-readobj -s %p/Inputs/trivial.obj.coff-i386 \
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.coff-i386 \
RUN: | FileCheck %s -check-prefix COFF
RUN: llvm-readobj -s %p/Inputs/trivial.obj.elf-i386 \
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.elf-i386 \
RUN: | FileCheck %s -check-prefix ELF
RUN: llvm-readobj -s %p/Inputs/trivial.obj.elf-mipsel \
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.elf-mipsel \
RUN: | FileCheck %s -check-prefix ELF-MIPSEL
RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-i386 \
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.macho-i386 \
RUN: | FileCheck %s -check-prefix MACHO-I386
RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-x86-64 \
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.macho-x86-64 \
RUN: | FileCheck %s -check-prefix MACHO-X86-64
RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc \
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.macho-ppc \
RUN: | FileCheck %s -check-prefix MACHO-PPC
RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc64 \
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.macho-ppc64 \
RUN: | FileCheck %s -check-prefix MACHO-PPC64
RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-arm \
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.macho-arm \
RUN: | FileCheck %s -check-prefix MACHO-ARM
RUN: llvm-readobj -s %p/Inputs/trivial.obj.wasm \
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.wasm \
RUN: | FileCheck %s -check-prefix WASM

# Check flag aliases produce identical output.
RUN: llvm-readobj --sections %p/Inputs/trivial.obj.elf-i386 > %t.sections
RUN: llvm-readobj -S %p/Inputs/trivial.obj.elf-i386 > %t.uppers
RUN: cmp %t.sections %t.uppers
RUN: llvm-readobj -s %p/Inputs/trivial.obj.elf-i386 > %t.lowers
RUN: cmp %t.sections %t.lowers

COFF: Sections [
COFF-NEXT: Section {
COFF-NEXT: Number: 1
Expand Down
15 changes: 12 additions & 3 deletions llvm/test/tools/llvm-readobj/symbols.test
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
RUN: llvm-readobj -t %p/Inputs/trivial.obj.coff-i386 \
RUN: llvm-readobj --symbols %p/Inputs/trivial.obj.coff-i386 \
RUN: | FileCheck %s -check-prefix COFF
RUN: llvm-readobj -t %p/Inputs/trivial.obj.elf-i386 \
RUN: llvm-readobj --symbols %p/Inputs/trivial.obj.elf-i386 \
RUN: | FileCheck %s -check-prefix ELF
RUN: llvm-readobj -t %p/Inputs/trivial.obj.wasm \
RUN: llvm-readobj --symbols %p/Inputs/trivial.obj.wasm \
RUN: | FileCheck %s -check-prefix WASM

# Check flag aliases produce identical output.
RUN: llvm-readobj --symbols %p/Inputs/trivial.obj.elf-i386 > %t.symbols
RUN: llvm-readobj --syms %p/Inputs/trivial.obj.elf-i386 > %t.syms
RUN: cmp %t.symbols %t.syms
RUN: llvm-readobj -t %p/Inputs/trivial.obj.elf-i386 > %t.t
RUN: cmp %t.symbols %t.t
RUN: llvm-readelf -s -elf-output-style LLVM %p/Inputs/trivial.obj.elf-i386 > %t.lowers
RUN: cmp %t.symbols %t.lowers

COFF: Symbols [
COFF-NEXT: Symbol {
COFF-NEXT: Name: @comp.id
Expand Down
6 changes: 3 additions & 3 deletions llvm/tools/llvm-readobj/COFFDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class COFFDumper : public ObjDumper {
: ObjDumper(Writer), Obj(Obj), Writer(Writer), Types(100) {}

void printFileHeaders() override;
void printSections() override;
void printSectionHeaders() override;
void printRelocations() override;
void printSymbols() override;
void printDynamicSymbols() override;
Expand Down Expand Up @@ -959,7 +959,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
StringMap<StringRef> FunctionLineTables;

ListScope D(W, "CodeViewDebugInfo");
// Print the section to allow correlation with printSections.
// Print the section to allow correlation with printSectionHeaders.
W.printNumber("Section", SectionName, Obj->getSectionID(Section));

uint32_t Magic;
Expand Down Expand Up @@ -1279,7 +1279,7 @@ void COFFDumper::printCodeViewTypeSection(StringRef SectionName,
W.flush();
}

void COFFDumper::printSections() {
void COFFDumper::printSectionHeaders() {
ListScope SectionsD(W, "Sections");
int SectionNumber = 0;
for (const SectionRef &Sec : Obj->sections()) {
Expand Down
19 changes: 10 additions & 9 deletions llvm/tools/llvm-readobj/ELFDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class ELFDumper : public ObjDumper {
ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer);

void printFileHeaders() override;
void printSections() override;
void printSectionHeaders() override;
void printRelocations() override;
void printDynamicRelocations() override;
void printSymbols() override;
Expand Down Expand Up @@ -324,7 +324,7 @@ template <typename ELFT> class DumpStyle {
virtual void printFileHeaders(const ELFFile<ELFT> *Obj) = 0;
virtual void printGroupSections(const ELFFile<ELFT> *Obj) = 0;
virtual void printRelocations(const ELFFile<ELFT> *Obj) = 0;
virtual void printSections(const ELFFile<ELFT> *Obj) = 0;
virtual void printSectionHeaders(const ELFFile<ELFT> *Obj) = 0;
virtual void printSymbols(const ELFFile<ELFT> *Obj) = 0;
virtual void printDynamicSymbols(const ELFFile<ELFT> *Obj) = 0;
virtual void printDynamicRelocations(const ELFFile<ELFT> *Obj) = 0;
Expand Down Expand Up @@ -359,7 +359,7 @@ template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
void printFileHeaders(const ELFO *Obj) override;
void printGroupSections(const ELFFile<ELFT> *Obj) override;
void printRelocations(const ELFO *Obj) override;
void printSections(const ELFO *Obj) override;
void printSectionHeaders(const ELFO *Obj) override;
void printSymbols(const ELFO *Obj) override;
void printDynamicSymbols(const ELFO *Obj) override;
void printDynamicRelocations(const ELFO *Obj) override;
Expand Down Expand Up @@ -452,7 +452,7 @@ template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
void printGroupSections(const ELFFile<ELFT> *Obj) override;
void printRelocations(const ELFO *Obj) override;
void printRelocations(const Elf_Shdr *Sec, const ELFO *Obj);
void printSections(const ELFO *Obj) override;
void printSectionHeaders(const ELFO *Obj) override;
void printSymbols(const ELFO *Obj) override;
void printDynamicSymbols(const ELFO *Obj) override;
void printDynamicRelocations(const ELFO *Obj) override;
Expand Down Expand Up @@ -1592,9 +1592,8 @@ void ELFDumper<ELFT>::printFileHeaders() {
ELFDumperStyle->printFileHeaders(Obj);
}

template<class ELFT>
void ELFDumper<ELFT>::printSections() {
ELFDumperStyle->printSections(Obj);
template <class ELFT> void ELFDumper<ELFT>::printSectionHeaders() {
ELFDumperStyle->printSectionHeaders(Obj);
}

template<class ELFT>
Expand Down Expand Up @@ -2920,7 +2919,8 @@ std::string getSectionTypeString(unsigned Arch, unsigned Type) {
return "";
}

template <class ELFT> void GNUStyle<ELFT>::printSections(const ELFO *Obj) {
template <class ELFT>
void GNUStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
size_t SectionIndex = 0;
std::string Number, Type, Size, Address, Offset, Flags, Link, Info, EntrySize,
Alignment;
Expand Down Expand Up @@ -4213,7 +4213,8 @@ void LLVMStyle<ELFT>::printRelocation(const ELFO *Obj, Elf_Rela Rel,
}
}

template <class ELFT> void LLVMStyle<ELFT>::printSections(const ELFO *Obj) {
template <class ELFT>
void LLVMStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
ListScope SectionsD(W, "Sections");

int SectionIndex = -1;
Expand Down
10 changes: 4 additions & 6 deletions llvm/tools/llvm-readobj/MachODumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class MachODumper : public ObjDumper {
: ObjDumper(Writer), Obj(Obj) {}

void printFileHeaders() override;
void printSections() override;
void printSectionHeaders() override;
void printRelocations() override;
void printSymbols() override;
void printDynamicSymbols() override;
Expand All @@ -59,7 +59,7 @@ class MachODumper : public ObjDumper {

void printRelocation(const MachOObjectFile *Obj, const RelocationRef &Reloc);

void printSections(const MachOObjectFile *Obj);
void printSectionHeaders(const MachOObjectFile *Obj);

const MachOObjectFile *Obj;
};
Expand Down Expand Up @@ -428,11 +428,9 @@ void MachODumper::printFileHeaders(const MachHeader &Header) {
W.printFlags("Flags", Header.flags, makeArrayRef(MachOHeaderFlags));
}

void MachODumper::printSections() {
return printSections(Obj);
}
void MachODumper::printSectionHeaders() { return printSectionHeaders(Obj); }

void MachODumper::printSections(const MachOObjectFile *Obj) {
void MachODumper::printSectionHeaders(const MachOObjectFile *Obj) {
ListScope Group(W, "Sections");

int SectionIndex = -1;
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/llvm-readobj/ObjDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ObjDumper {
virtual ~ObjDumper();

virtual void printFileHeaders() = 0;
virtual void printSections() = 0;
virtual void printSectionHeaders() = 0;
virtual void printRelocations() = 0;
virtual void printSymbols() = 0;
virtual void printDynamicSymbols() = 0;
Expand Down
4 changes: 2 additions & 2 deletions llvm/tools/llvm-readobj/WasmDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class WasmDumper : public ObjDumper {
: ObjDumper(Writer), Obj(Obj) {}

void printFileHeaders() override;
void printSections() override;
void printSectionHeaders() override;
void printRelocations() override;
void printSymbols() override;
void printDynamicSymbols() override { llvm_unreachable("unimplemented"); }
Expand Down Expand Up @@ -148,7 +148,7 @@ void WasmDumper::printSymbols() {
printSymbol(Symbol);
}

void WasmDumper::printSections() {
void WasmDumper::printSectionHeaders() {
ListScope Group(W, "Sections");
for (const SectionRef &Section : Obj->sections()) {
const WasmSection &WasmSec = Obj->getWasmSection(Section);
Expand Down
Loading

0 comments on commit dbf552c

Please sign in to comment.