When used with :option:`--sections`, display symbols for each section shown.
This option has no effect for GNU style output.
-.. option:: --sort-symbols=<sort_key[,sort_key]>
-
- Specify the keys to sort symbols before displaying symtab.
- Valid values for sort_key are ``name`` and ``type``.
.. option:: --stackmap
Display contents of the stackmap section.
+++ /dev/null
-## Verify that llvm-readobj can dump files with stabs symbols in a sorted order.
-
-# RUN: yaml2obj --docnum=1 %s -o %t
-
-# RUN: not llvm-readobj --syms --sort-symbols=foo %t 2>&1 | FileCheck %s --check-prefix ERR-KEY
-# RUN: not llvm-readobj --syms --sort-symbols=,, %t 2>&1 | FileCheck %s --check-prefix ERR-KEY-EMPT
-
-# RUN: llvm-readobj --syms --sort-symbols=type,name %t | FileCheck %s --check-prefix TYPE-NAME
-# RUN: llvm-readobj --syms --sort-symbols=name,type %t | FileCheck %s --check-prefix NAME-TYPE
-# RUN: llvm-readobj --syms --sort-symbols=type %t | FileCheck %s --check-prefix TYPE-ONLY
-
-# TYPE-NAME: Name: _a (19)
-# TYPE-NAME-NEXT: Type: Section (0xE)
-# TYPE-NAME: Name: _d (10)
-# TYPE-NAME-NEXT: Type: Section (0xE)
-# TYPE-NAME: Name: _f (7)
-# TYPE-NAME-NEXT: Type: SymDebugTable (0x2E)
-# TYPE-NAME: Name: _z (1)
-# TYPE-NAME-NEXT: Type: SymDebugTable (0x2E)
-# TYPE-NAME: Name: _c (13)
-# TYPE-NAME-NEXT: Type: SymDebugTable (0x64)
-# TYPE-NAME: Name: _g (4)
-# TYPE-NAME-NEXT: Type: SymDebugTable (0x64)
-# TYPE-NAME: Name: _b (16)
-# TYPE-NAME-NEXT: Type: SymDebugTable (0x66)
-# TYPE-NAME: Name: _d2 (22)
-# TYPE-NAME-NEXT: Type: SymDebugTable (0x66)
-
-# NAME-TYPE: Name: _a (19)
-# NAME-TYPE-NEXT: Type: Section (0xE)
-# NAME-TYPE: Name: _b (16)
-# NAME-TYPE-NEXT: Type: SymDebugTable (0x66)
-# NAME-TYPE: Name: _c (13)
-# NAME-TYPE-NEXT: Type: SymDebugTable (0x64)
-# NAME-TYPE: Name: _d (10)
-# NAME-TYPE-NEXT: Type: Section (0xE)
-# NAME-TYPE: Name: _d2 (22)
-# NAME-TYPE-NEXT: Type: SymDebugTable (0x66)
-# NAME-TYPE: Name: _f (7)
-# NAME-TYPE-NEXT: Type: SymDebugTable (0x2E)
-# NAME-TYPE: Name: _g (4)
-# NAME-TYPE-NEXT: Type: SymDebugTable (0x64)
-# NAME-TYPE: Name: _z (1)
-# NAME-TYPE-NEXT: Type: SymDebugTable (0x2E)
-
-# TYPE-ONLY: Name: _d (10)
-# TYPE-ONLY-NEXT: Type: Section (0xE)
-# TYPE-ONLY: Name: _a (19)
-# TYPE-ONLY-NEXT: Type: Section (0xE)
-# TYPE-ONLY: Name: _f (7)
-# TYPE-ONLY-NEXT: Type: SymDebugTable (0x2E)
-# TYPE-ONLY: Name: _z (1)
-# TYPE-ONLY-NEXT: Type: SymDebugTable (0x2E)
-# TYPE-ONLY: Name: _g (4)
-# TYPE-ONLY-NEXT: Type: SymDebugTable (0x64)
-# TYPE-ONLY: Name: _c (13)
-# TYPE-ONLY-NEXT: Type: SymDebugTable (0x64)
-# TYPE-ONLY: Name: _d2 (22)
-# TYPE-ONLY-NEXT: Type: SymDebugTable (0x66)
-# TYPE-ONLY: Name: _b (16)
-# TYPE-ONLY-NEXT: Type: SymDebugTable (0x66)
-
---- !mach-o
-FileHeader:
- magic: 0xFEEDFACF
- cputype: 0x1000007
- cpusubtype: 0x3
- filetype: 0x1
- ncmds: 3
- sizeofcmds: 496
- flags: 0x2000
- reserved: 0x0
-LoadCommands:
- - cmd: LC_SEGMENT_64
- cmdsize: 392
- segname: ''
- vmaddr: 0
- vmsize: 32
- fileoff: 528
- filesize: 28
- maxprot: 7
- initprot: 7
- nsects: 4
- flags: 0
- Sections:
- - sectname: __text
- segname: __TEXT
- addr: 0x0
- size: 9
- offset: 0x210
- align: 0
- reloff: 0x230
- nreloc: 1
- flags: 0x80000000
- reserved1: 0x0
- reserved2: 0x0
- reserved3: 0x0
- content: '000000000000000000'
- relocations:
- - address: 0x0
- symbolnum: 7
- pcrel: false
- length: 3
- extern: true
- type: 0
- scattered: false
- value: 0
- - sectname: more_data
- segname: __DATA
- addr: 0x9
- size: 8
- offset: 0x219
- align: 0
- reloff: 0x0
- nreloc: 0
- flags: 0x0
- reserved1: 0x0
- reserved2: 0x0
- reserved3: 0x0
- content: 7B00000000000000
- - sectname: __data
- segname: __DATA
- addr: 0x11
- size: 11
- offset: 0x221
- align: 0
- reloff: 0x0
- nreloc: 0
- flags: 0x0
- reserved1: 0x0
- reserved2: 0x0
- reserved3: 0x0
- content: 7B00000000000000000000
- - sectname: __common
- segname: __DATA
- addr: 0x1C
- size: 4
- offset: 0x0
- align: 2
- reloff: 0x0
- nreloc: 0
- flags: 0x1
- reserved1: 0x0
- reserved2: 0x0
- reserved3: 0x0
- - cmd: LC_SYMTAB
- cmdsize: 24
- symoff: 568
- nsyms: 8
- stroff: 696
- strsize: 32
- - cmd: LC_DYSYMTAB
- cmdsize: 80
- ilocalsym: 0
- nlocalsym: 7
- iextdefsym: 7
- nextdefsym: 0
- iundefsym: 7
- nundefsym: 1
- tocoff: 0
- ntoc: 0
- modtaboff: 0
- nmodtab: 0
- extrefsymoff: 0
- nextrefsyms: 0
- indirectsymoff: 0
- nindirectsyms: 0
- extreloff: 0
- nextrel: 0
- locreloff: 0
- nlocrel: 0
-LinkEditData:
- NameList:
- - n_strx: 4
- n_type: 0x64
- n_sect: 1
- n_desc: 0
- n_value: 0
- - n_strx: 10
- n_type: 0xE
- n_sect: 1
- n_desc: 0
- n_value: 8
- - n_strx: 22
- n_type: 0x66
- n_sect: 1
- n_desc: 0
- n_value: 8
- - n_strx: 16
- n_type: 0x66
- n_sect: 2
- n_desc: 0
- n_value: 9
- - n_strx: 19
- n_type: 0xE
- n_sect: 3
- n_desc: 0
- n_value: 17
- - n_strx: 13
- n_type: 0x64
- n_sect: 4
- n_desc: 0
- n_value: 28
- - n_strx: 7
- n_type: 0x2E
- n_sect: 3
- n_desc: 0
- n_value: 25
- - n_strx: 1
- n_type: 0x2E
- n_sect: 0
- n_desc: 0
- n_value: 0
- StringTable:
- - ''
- - _z
- - _g
- - _f
- - _d
- - _c
- - _b
- - _a
- - _d2
- - ''
- - ''
- - ''
- - ''
- - ''
- - ''
-...
+++ /dev/null
-## Test that we print a warning for ELF, WASM, and COFF but still dump the contents for all.
-
-# RUN: yaml2obj --docnum=1 %s -o %t_macho
-# RUN: yaml2obj --docnum=2 %s -o %t_coff
-# RUN: yaml2obj --docnum=3 %s -o %t_elf
-# RUN: yaml2obj --docnum=4 %s -o %t_wasm
-# RUN: yaml2obj --docnum=5 %s -o %t_xcoff
-
-# RUN: llvm-readobj --syms --sort-symbols=type,name \
-# RUN: %t_coff %t_elf %t_wasm %t_xcoff %t_macho 2>&1 | FileCheck %s \
-# RUN: -DMSG="--sort-symbols is not supported yet for this format"
-
-# CHECK: warning: '{{.+}}_coff': [[MSG]]
-# CHECK: Format: COFF-ARM
-# CHECK: warning: '{{.+}}_elf': [[MSG]]
-# CHECK: Format: elf64-unknown
-# CHECK: warning: '{{.+}}_wasm': [[MSG]]
-# CHECK: Format: WASM
-# CHECK: warning: '{{.+}}_xcoff': [[MSG]]
-# CHECK: Format: aixcoff-rs6000
-# CHECK-NOT: warning '{{.+}}_macho': [[MSG]]
-# CHECK: Format: Mach-O 64-bit x86-64
-
---- !mach-o
-FileHeader:
- magic: 0xFEEDFACF
- cputype: 0x1000007
- cpusubtype: 0x3
- filetype: 0x1
- ncmds: 0
- sizeofcmds: 0
- flags: 0x2000
- reserved: 0x0
-...
---- !COFF
-header:
- Machine: IMAGE_FILE_MACHINE_ARMNT
- Characteristics: [ ]
-sections:
-symbols:
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_EXEC
-Sections:
- - Name: .gnu.version
- Type: SHT_GNU_versym
-...
---- !WASM
-FileHeader:
- Version: 0x00000001
-Sections:
- - Type: DATA
- Segments:
- - SectionOffset: 6
- InitFlags: 0
- Offset:
- Opcode: GLOBAL_GET
- Index: 1
- Content: '64'
-...
---- !XCOFF
-FileHeader:
- MagicNumber: 0x01DF
- CreationTime: 1
- EntriesInSymbolTable: 1
-...
#include "ObjDumper.h"
#include "StackMapPrinter.h"
#include "llvm-readobj.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Object/MachO.h"
void printNeededLibraries() override;
- bool canCompareSymbols() const override { return true; }
- bool compareSymbolsByName(object::SymbolRef LHS,
- object::SymbolRef RHS) const override;
- bool compareSymbolsByType(object::SymbolRef LHS,
- object::SymbolRef RHS) const override;
// MachO-specific.
void printMachODataInCode() override;
void printMachOVersionMin() override;
template<class MachHeader>
void printFileHeaders(const MachHeader &Header);
- StringRef getSymbolName(const SymbolRef &Symbol) const;
- uint8_t getSymbolType(const SymbolRef &Symbol) const;
+ StringRef getSymbolName(const SymbolRef &Symbol);
- void printSymbols(Optional<SymbolComparator> SymComp) override;
- void printDynamicSymbols(Optional<SymbolComparator> SymComp) override;
- void printSymbol(const SymbolRef &Symbol, ScopedPrinter &W);
+ void printSymbols() override;
+ void printDynamicSymbols() override;
void printSymbol(const SymbolRef &Symbol);
void printRelocation(const RelocationRef &Reloc);
}
}
-StringRef MachODumper::getSymbolName(const SymbolRef &Symbol) const {
+StringRef MachODumper::getSymbolName(const SymbolRef &Symbol) {
Expected<StringRef> SymbolNameOrErr = Symbol.getName();
if (!SymbolNameOrErr) {
reportError(SymbolNameOrErr.takeError(), Obj->getFileName());
return *SymbolNameOrErr;
}
-uint8_t MachODumper::getSymbolType(const SymbolRef &Symbol) const {
- return Obj->getSymbol64TableEntry(Symbol.getRawDataRefImpl()).n_type;
-}
-
-bool MachODumper::compareSymbolsByName(SymbolRef LHS, SymbolRef RHS) const {
- return getSymbolName(LHS).str().compare(getSymbolName(RHS).str()) < 0;
-}
-
-bool MachODumper::compareSymbolsByType(SymbolRef LHS, SymbolRef RHS) const {
- return getSymbolType(LHS) < getSymbolType(RHS);
-}
+void MachODumper::printSymbols() {
+ ListScope Group(W, "Symbols");
-void MachODumper::printSymbols(Optional<SymbolComparator> SymComp) {
- if (SymComp) {
- auto SymbolRange = Obj->symbols();
- std::vector<SymbolRef> SortedSymbols(SymbolRange.begin(),
- SymbolRange.end());
- llvm::stable_sort(SortedSymbols, *SymComp);
- for (SymbolRef Symbol : SortedSymbols)
- printSymbol(Symbol);
- } else {
- for (const SymbolRef &Symbol : Obj->symbols()) {
- printSymbol(Symbol);
- }
+ for (const SymbolRef &Symbol : Obj->symbols()) {
+ printSymbol(Symbol);
}
}
-void MachODumper::printDynamicSymbols(Optional<SymbolComparator> SymComp) {
+void MachODumper::printDynamicSymbols() {
ListScope Group(W, "DynamicSymbols");
}
void MachODumper::printSymbol(const SymbolRef &Symbol) {
- printSymbol(Symbol, W);
-}
-
-void MachODumper::printSymbol(const SymbolRef &Symbol, ScopedPrinter &W) {
StringRef SymbolName = getSymbolName(Symbol);
MachOSymbol MOSymbol;
#include <memory>
#include <system_error>
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/STLFunctionalExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
class ObjectFile;
class XCOFFObjectFile;
class ELFObjectFileBase;
-} // namespace object
+}
namespace codeview {
class GlobalTypeTableBuilder;
class MergingTypeTableBuilder;
class ScopedPrinter;
-// Comparator to compare symbols.
-// Usage: the caller registers predicates (i.e., how to compare the symbols) by
-// calling addPredicate(). The order in which predicates are registered is also
-// their priority.
-class SymbolComparator {
-public:
- using CompPredicate =
- function_ref<bool(object::SymbolRef, object::SymbolRef)>;
-
- // Each Obj format has a slightly different way of retrieving a symbol's info
- // So we defer the predicate's impl to each format.
- void addPredicate(CompPredicate Pred) { Predicates.push_back(Pred); }
-
- bool operator()(object::SymbolRef LHS, object::SymbolRef RHS) {
- for (CompPredicate Pred : Predicates) {
- if (Pred(LHS, RHS))
- return true;
- if (Pred(RHS, LHS))
- return false;
- }
- return false;
- }
-
-private:
- SmallVector<CompPredicate, 2> Predicates;
-};
-
class ObjDumper {
public:
ObjDumper(ScopedPrinter &Writer, StringRef ObjName);
virtual void printSectionHeaders() = 0;
virtual void printRelocations() = 0;
virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) {
- printSymbols(PrintSymbols, PrintDynamicSymbols, llvm::None);
- }
- virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols,
- llvm::Optional<SymbolComparator> SymComp) {
if (PrintSymbols)
- printSymbols(SymComp);
+ printSymbols();
if (PrintDynamicSymbols)
- printDynamicSymbols(SymComp);
+ printDynamicSymbols();
}
virtual void printProgramHeaders(bool PrintProgramHeaders,
cl::boolOrDefault PrintSectionMapping) {
virtual void printUnwindInfo() = 0;
- // Symbol comparison functions.
- virtual bool canCompareSymbols() const { return false; }
- virtual bool compareSymbolsByName(object::SymbolRef LHS,
- object::SymbolRef RHS) const {
- return true;
- }
- virtual bool compareSymbolsByType(object::SymbolRef LHS,
- object::SymbolRef RHS) const {
- return true;
- }
-
// Only implemented for ELF at this time.
virtual void printDependentLibs() {}
virtual void printDynamicRelocations() { }
ScopedPrinter &W;
private:
- virtual void printSymbols() { printSymbols(llvm::None); }
- virtual void printSymbols(llvm::Optional<SymbolComparator> Comp) {}
- virtual void printDynamicSymbols() { printDynamicSymbols(llvm::None); }
- virtual void printDynamicSymbols(llvm::Optional<SymbolComparator> Comp) {}
+ virtual void printSymbols() {}
+ virtual void printDynamicSymbols() {}
virtual void printProgramHeaders() {}
virtual void printSectionMapping() {}
def section_mapping_EQ_false : FF<"section-mapping=false", "Don't display the section to segment mapping">, Flags<[HelpHidden]>;
def section_relocations : FF<"section-relocations", "Display relocations for each section shown. This option has no effect for GNU style output">;
def section_symbols : FF<"section-symbols", "Display symbols for each section shown. This option has no effect for GNU style output">;
-defm sort_symbols : Eq<"sort-symbols", "Specify the keys to sort the symbols before displaying symtab">;
def stack_sizes : FF<"stack-sizes", "Display contents of all stack sizes sections. This option has no effect for GNU style output">;
def stackmap : FF<"stackmap", "Display contents of stackmap section">;
defm string_dump : Eq<"string-dump", "Display the specified section(s) as a list of strings">, MetaVarName<"<name or index>">;
#include "llvm-readobj.h"
#include "ObjDumper.h"
#include "WindowsResourceDumper.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
#include "llvm/MC/TargetRegistry.h"
};
enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols };
-
-enum SortSymbolKeyTy {
- NAME = 0,
- TYPE = 1,
- UNKNOWN = 100,
- // TODO: add ADDRESS, SIZE as needed.
-};
-
} // namespace
namespace opts {
static bool Symbols;
static bool UnwindInfo;
static cl::boolOrDefault SectionMapping;
-static SmallVector<SortSymbolKeyTy> SortKeys;
// ELF specific options.
static bool DynamicTable;
opts::ProgramHeaders = Args.hasArg(OPT_program_headers);
opts::RawRelr = Args.hasArg(OPT_raw_relr);
opts::SectionGroups = Args.hasArg(OPT_section_groups);
- if (Arg *A = Args.getLastArg(OPT_sort_symbols_EQ)) {
- std::string SortKeysString = A->getValue();
- for (StringRef KeyStr : llvm::split(A->getValue(), ",")) {
- SortSymbolKeyTy KeyType = StringSwitch<SortSymbolKeyTy>(KeyStr)
- .Case("name", SortSymbolKeyTy::NAME)
- .Case("type", SortSymbolKeyTy::TYPE)
- .Default(SortSymbolKeyTy::UNKNOWN);
- if (KeyType == SortSymbolKeyTy::UNKNOWN)
- error("--sort-symbols value should be 'name' or 'type', but was '" +
- Twine(KeyStr) + "'");
- opts::SortKeys.push_back(KeyType);
- }
- }
opts::VersionInfo = Args.hasArg(OPT_version_info);
// Mach-O specific options.
toString(std::move(ContentErr));
ObjDumper *Dumper;
- Optional<SymbolComparator> SymComp;
Expected<std::unique_ptr<ObjDumper>> DumperOrErr = createDumper(Obj, Writer);
if (!DumperOrErr)
reportError(DumperOrErr.takeError(), FileStr);
Dumper = (*DumperOrErr).get();
- if (!opts::SortKeys.empty()) {
- if (Dumper->canCompareSymbols()) {
- SymComp = SymbolComparator();
- for (SortSymbolKeyTy Key : opts::SortKeys) {
- switch (Key) {
- case NAME:
- SymComp->addPredicate([Dumper](SymbolRef LHS, SymbolRef RHS) {
- return Dumper->compareSymbolsByName(LHS, RHS);
- });
- break;
- case TYPE:
- SymComp->addPredicate([Dumper](SymbolRef LHS, SymbolRef RHS) {
- return Dumper->compareSymbolsByType(LHS, RHS);
- });
- break;
- case UNKNOWN:
- llvm_unreachable("Unsupported sort key");
- }
- }
-
- } else {
- reportWarning(createStringError(
- errc::invalid_argument,
- "--sort-symbols is not supported yet for this format"),
- FileStr);
- }
- }
Dumper->printFileSummary(FileStr, Obj, opts::InputFilenames, A);
if (opts::FileHeaders)
if (opts::UnwindInfo)
Dumper->printUnwindInfo();
if (opts::Symbols || opts::DynamicSymbols)
- Dumper->printSymbols(opts::Symbols, opts::DynamicSymbols, SymComp);
+ Dumper->printSymbols(opts::Symbols, opts::DynamicSymbols);
if (!opts::StringDump.empty())
Dumper->printSectionsAsString(Obj, opts::StringDump);
if (!opts::HexDump.empty())
#ifndef LLVM_TOOLS_LLVM_READOBJ_LLVM_READOBJ_H
#define LLVM_TOOLS_LLVM_READOBJ_LLVM_READOBJ_H
-#include "ObjDumper.h"
-
-#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/Error.h"
#include <string>
namespace llvm {