[llvm] ea9cf2d - [llvm-readobj][MachO] Add option to sort the symbol table before dumping (MachO only, for now).
Vy Nguyen via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 31 06:16:08 PDT 2022
Author: Vy Nguyen
Date: 2022-03-31T09:13:31-04:00
New Revision: ea9cf2dc96c765773ee574a9189d529175a57751
URL: https://github.com/llvm/llvm-project/commit/ea9cf2dc96c765773ee574a9189d529175a57751
DIFF: https://github.com/llvm/llvm-project/commit/ea9cf2dc96c765773ee574a9189d529175a57751.diff
LOG: [llvm-readobj][MachO] Add option to sort the symbol table before dumping (MachO only, for now).
This would help making tests less brittle as the order will be fixed.
(see also PR/53026)
Differential Revision: https://reviews.llvm.org/D116787
Added:
llvm/test/tools/llvm-readobj/MachO/stabs-sorted.yaml
llvm/test/tools/llvm-readobj/sort-symbols.test
Modified:
llvm/docs/CommandGuide/llvm-readobj.rst
llvm/tools/llvm-readobj/MachODumper.cpp
llvm/tools/llvm-readobj/ObjDumper.h
llvm/tools/llvm-readobj/Opts.td
llvm/tools/llvm-readobj/llvm-readobj.cpp
llvm/tools/llvm-readobj/llvm-readobj.h
Removed:
################################################################################
diff --git a/llvm/docs/CommandGuide/llvm-readobj.rst b/llvm/docs/CommandGuide/llvm-readobj.rst
index ef2ea3eb0e587..b33e722403468 100644
--- a/llvm/docs/CommandGuide/llvm-readobj.rst
+++ b/llvm/docs/CommandGuide/llvm-readobj.rst
@@ -106,6 +106,10 @@ file formats.
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.
diff --git a/llvm/test/tools/llvm-readobj/MachO/stabs-sorted.yaml b/llvm/test/tools/llvm-readobj/MachO/stabs-sorted.yaml
new file mode 100644
index 0000000000000..496fadb1681fc
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/MachO/stabs-sorted.yaml
@@ -0,0 +1,230 @@
+## 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
+ - ''
+ - ''
+ - ''
+ - ''
+ - ''
+ - ''
+...
diff --git a/llvm/test/tools/llvm-readobj/sort-symbols.test b/llvm/test/tools/llvm-readobj/sort-symbols.test
new file mode 100644
index 0000000000000..0d01c9b5d85cb
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/sort-symbols.test
@@ -0,0 +1,68 @@
+## 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
+...
diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp
index 599b0355917e9..5d474021cba82 100644
--- a/llvm/tools/llvm-readobj/MachODumper.cpp
+++ b/llvm/tools/llvm-readobj/MachODumper.cpp
@@ -13,6 +13,7 @@
#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"
@@ -39,6 +40,11 @@ class MachODumper : public ObjDumper {
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;
@@ -51,10 +57,12 @@ class MachODumper : public ObjDumper {
template<class MachHeader>
void printFileHeaders(const MachHeader &Header);
- StringRef getSymbolName(const SymbolRef &Symbol);
+ StringRef getSymbolName(const SymbolRef &Symbol) const;
+ uint8_t getSymbolType(const SymbolRef &Symbol) const;
- void printSymbols() override;
- void printDynamicSymbols() override;
+ void printSymbols(Optional<SymbolComparator> SymComp) override;
+ void printDynamicSymbols(Optional<SymbolComparator> SymComp) override;
+ void printSymbol(const SymbolRef &Symbol, ScopedPrinter &W);
void printSymbol(const SymbolRef &Symbol);
void printRelocation(const RelocationRef &Reloc);
@@ -602,7 +610,7 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj,
}
}
-StringRef MachODumper::getSymbolName(const SymbolRef &Symbol) {
+StringRef MachODumper::getSymbolName(const SymbolRef &Symbol) const {
Expected<StringRef> SymbolNameOrErr = Symbol.getName();
if (!SymbolNameOrErr) {
reportError(SymbolNameOrErr.takeError(), Obj->getFileName());
@@ -610,19 +618,42 @@ StringRef MachODumper::getSymbolName(const SymbolRef &Symbol) {
return *SymbolNameOrErr;
}
-void MachODumper::printSymbols() {
- ListScope Group(W, "Symbols");
+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);
+}
- for (const SymbolRef &Symbol : Obj->symbols()) {
- printSymbol(Symbol);
+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);
+ }
}
}
-void MachODumper::printDynamicSymbols() {
+void MachODumper::printDynamicSymbols(Optional<SymbolComparator> SymComp) {
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;
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index a09a243d381ec..46750c099dbac 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -12,6 +12,10 @@
#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"
@@ -25,7 +29,7 @@ class COFFImportFile;
class ObjectFile;
class XCOFFObjectFile;
class ELFObjectFileBase;
-}
+} // namespace object
namespace codeview {
class GlobalTypeTableBuilder;
class MergingTypeTableBuilder;
@@ -33,6 +37,33 @@ 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
diff erent 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);
@@ -47,10 +78,14 @@ class ObjDumper {
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();
+ printSymbols(SymComp);
if (PrintDynamicSymbols)
- printDynamicSymbols();
+ printDynamicSymbols(SymComp);
}
virtual void printProgramHeaders(bool PrintProgramHeaders,
cl::boolOrDefault PrintSectionMapping) {
@@ -62,6 +97,17 @@ class ObjDumper {
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() { }
@@ -132,8 +178,10 @@ class ObjDumper {
ScopedPrinter &W;
private:
- virtual void printSymbols() {}
- virtual void printDynamicSymbols() {}
+ 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 printProgramHeaders() {}
virtual void printSectionMapping() {}
diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index 528c7f64e2234..4687fc71245f8 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -37,6 +37,7 @@ def section_mapping : FF<"section-mapping", "Display the section to segment mapp
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>">;
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 543b0de82cdf6..e1ebbeb41f28b 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -21,6 +21,7 @@
#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"
@@ -83,6 +84,14 @@ class ReadobjOptTable : public opt::OptTable {
};
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 {
@@ -113,6 +122,7 @@ static bool StringTable;
static bool Symbols;
static bool UnwindInfo;
static cl::boolOrDefault SectionMapping;
+static SmallVector<SortSymbolKeyTy> SortKeys;
// ELF specific options.
static bool DynamicTable;
@@ -253,6 +263,19 @@ static void parseOptions(const opt::InputArgList &Args) {
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.
@@ -334,11 +357,39 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
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)
@@ -374,7 +425,7 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
if (opts::UnwindInfo)
Dumper->printUnwindInfo();
if (opts::Symbols || opts::DynamicSymbols)
- Dumper->printSymbols(opts::Symbols, opts::DynamicSymbols);
+ Dumper->printSymbols(opts::Symbols, opts::DynamicSymbols, SymComp);
if (!opts::StringDump.empty())
Dumper->printSectionsAsString(Obj, opts::StringDump);
if (!opts::HexDump.empty())
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.h b/llvm/tools/llvm-readobj/llvm-readobj.h
index 0ea695d1673d1..989cd0aba6c01 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.h
+++ b/llvm/tools/llvm-readobj/llvm-readobj.h
@@ -9,10 +9,13 @@
#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/ErrorOr.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorOr.h"
#include <string>
namespace llvm {
More information about the llvm-commits
mailing list