diff --git a/llvm/test/tools/llvm-objdump/X86/Inputs/sort-test.yaml b/llvm/test/tools/llvm-objdump/X86/Inputs/sort-test.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/Inputs/sort-test.yaml @@ -0,0 +1,81 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 + Content: 554889E58B0425A80000005DC30F1F00 + - Name: .anothertext + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000000010 + AddressAlign: 0x0000000000000010 + Content: 554889E54883EC20488D0425A8000000C745FC00000000488945F0488B45F08B08894DECE8C7FFFFFF8B4DEC01C189C84883C4205D746573742073747200C3 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x0000000000000050 + AddressAlign: 0x0000000000000008 + Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C00000090FFFFFF0D00000000410E108602430D06000000000000001C0000003C00000080FFFFFF3F00000000410E108602430D0600000000000000 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x00000000000000A8 + AddressAlign: 0x0000000000000004 + Content: '01000000' + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 5562756E747520636C616E672076657273696F6E20332E352D317562756E74753120287472756E6B2920286261736564206F6E204C4C564D20332E352900 +Symbols: + - Type: STT_SECTION + Section: .text + - Type: STT_SECTION + Section: .anothertext + Value: 0x0000000000000010 + - Type: STT_SECTION + Section: .eh_frame + Value: 0x0000000000000050 + - Type: STT_SECTION + Section: .data + Value: 0x00000000000000A8 + - Type: STT_SECTION + Section: .comment + - Name: /tmp/a.c + Type: STT_FILE + - Type: STT_FILE + - Name: somedata + Type: STT_OBJECT + Section: .anothertext + Value: 0x0000000000000045 + Binding: STB_GLOBAL + - Name: main + Type: STT_FUNC + Section: .anothertext + Value: 0x0000000000000010 + Size: 0x000000000000003F + Binding: STB_GLOBAL + - Name: foo + Type: STT_FUNC + Section: .text + Size: 0x0000000000000004 + Binding: STB_GLOBAL + - Name: bar + Type: STT_FUNC + Section: .text + Value: 0x0000000000000004 + Size: 0x000000000000000A + Binding: STB_GLOBAL + - Name: a + Type: STT_OBJECT + Section: .data + Value: 0x00000000000000A8 + Size: 0x0000000000000004 + Binding: STB_GLOBAL +... diff --git a/llvm/test/tools/llvm-objdump/X86/disassemble-sorted.test b/llvm/test/tools/llvm-objdump/X86/disassemble-sorted.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objdump/X86/disassemble-sorted.test @@ -0,0 +1,16 @@ +## show that --sort does something + +# RUN: yaml2obj -o %t.out %p/Inputs/sort-test.yaml +# RUN: llvm-objdump -d %t.out --sort \ +# RUN: | FileCheck %s --check-prefix=CHECK-SORTED +# RUN: llvm-objdump -d %t.out \ +# RUN: | FileCheck %s --check-prefix=CHECK-UNSORTED + +# CHECK-SORTED: bar: +# CHECK-SORTED: foo: +# CHECK-SORTED: main: +# CHECK-UNSORTED: foo: +# CHECK-UNSORTED: bar: +# CHECK-UNSORTED: main: + + diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -295,6 +295,9 @@ cl::desc("Display LMA column when dumping ELF section headers"), cl::cat(ObjdumpCat)); +static cl::opt Sort("sort", cl::desc("Sort Symbols when Disassembling"), + cl::cat(ObjdumpCat)); + static cl::opt PrintSource( "source", cl::desc( @@ -489,6 +492,12 @@ return A.getOffset() < B.getOffset(); } +// Sort strings, keeping track of the original order with the second entry. +bool SymbolNameOrder(std::tuple A, + std::tuple B) { + return std::get<0>(A) < std::get<0>(B); +} + static Error getRelocationValueString(const RelocationRef &Rel, SmallVectorImpl &Result) { const ObjectFile *Obj = Rel.getObject(); @@ -1177,7 +1186,7 @@ continue; } - // Don't ask a Mach-O STAB symbol for its section unless you know that + // Don't ask a Mach-O STAB symbol for its section unless you know that // STAB symbol's section field refers to a valid section index. Otherwise // the symbol may error trying to load a section that does not exist. if (MachO) { @@ -1315,8 +1324,20 @@ std::vector Rels = RelocMap[Section]; std::vector::const_iterator RelCur = Rels.begin(); std::vector::const_iterator RelEnd = Rels.end(); - // Disassemble symbol by symbol. + + // name, index + typedef std::vector> SortedSectionSymbolsTy; + SortedSectionSymbolsTy sortedSymbols; + sortedSymbols.reserve(Symbols.size()); for (unsigned SI = 0, SE = Symbols.size(); SI != SE; ++SI) { + sortedSymbols.emplace_back(Symbols[SI].Name, SI); + } + if (Sort) + llvm::stable_sort(sortedSymbols, SymbolNameOrder); + + // Disassemble symbol by symbol. + for (unsigned SJ = 0, SE = sortedSymbols.size(); SJ != SE; ++SJ) { + unsigned SI = std::get<1>(sortedSymbols[SJ]); std::string SymbolName = Symbols[SI].Name.str(); if (Demangle) SymbolName = demangle(SymbolName); @@ -1863,7 +1884,7 @@ ArchiveName, ArchitectureName); uint32_t Flags = Symbol.getFlags(); - // Don't ask a Mach-O STAB symbol for its section unless you know that + // Don't ask a Mach-O STAB symbol for its section unless you know that // STAB symbol's section field refers to a valid section index. Otherwise // the symbol may error trying to load a section that does not exist. bool isSTAB = false;