Index: ELF/CallGraphSort.cpp =================================================================== --- ELF/CallGraphSort.cpp +++ ELF/CallGraphSort.cpp @@ -226,6 +226,27 @@ for (int SecIndex : C.Sections) OrderMap[Sections[SecIndex]] = CurOrder++; + if (!Config->PrintSymbolOrder.empty()) { + std::error_code EC; + raw_fd_ostream OS(Config->PrintSymbolOrder, EC, sys::fs::F_None); + if (EC) { + error("cannot open " + Config->PrintSymbolOrder + ": " + EC.message()); + return OrderMap; + } + + // Print the symbols ordered by C3, in the order of increasing CurOrder + // Instead of sorting all the OrderMap, just repeat the loops above. + for (const Cluster &C : Clusters) + for (int SecIndex : C.Sections) + // Search all the symbols in the file of the section + // and find out a Defined symbol with name that is within the section. + for (Symbol *Sym: Sections[SecIndex]->File->getSymbols()) + if (!Sym->isSection()) // Filter out section-type symbols here. + if (auto *D = dyn_cast(Sym)) + if (Sections[SecIndex] == D->Section) + OS << Sym->getName() << "\n"; + } + return OrderMap; } Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -101,6 +101,7 @@ llvm::StringRef OptRemarksFilename; llvm::StringRef OptRemarksPasses; llvm::StringRef ProgName; + llvm::StringRef PrintSymbolOrder; llvm::StringRef SoName; llvm::StringRef Sysroot; llvm::StringRef ThinLTOCacheDir; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -836,6 +836,8 @@ Args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false); Config->PrintGcSections = Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false); + Config->PrintSymbolOrder = + Args.getLastArgValue(OPT_print_symbol_order); Config->Rpath = getRpath(Args); Config->Relocatable = Args.hasArg(OPT_relocatable); Config->SaveTemps = Args.hasArg(OPT_save_temps); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -274,6 +274,9 @@ "List identical folded sections", "Do not list identical folded sections (default)">; +defm print_symbol_order: Eq<"print-symbol-order", + "Print a symbol order specified by --call-graph-ordering-file into the speficied file">; + def pop_state: F<"pop-state">, HelpText<"Undo the effect of -push-state">; Index: test/ELF/cgprofile-print.s =================================================================== --- test/ELF/cgprofile-print.s +++ test/ELF/cgprofile-print.s @@ -0,0 +1,37 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "A B 5" > %t.call_graph +# RUN: echo "B C 50" >> %t.call_graph +# RUN: echo "C D 40" >> %t.call_graph +# RUN: echo "D B 10" >> %t.call_graph +# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2 --print-symbol-order=%t3 +# RUN: FileCheck %s --input-file %t3 + +# CHECK: B +# CHECK-NEXT: C +# CHECK-NEXT: D +# CHECK-NEXT: A + +.section .text.A,"ax",@progbits +.globl A +A: + nop + +.section .text.B,"ax",@progbits +.globl B +B: + nop + +.section .text.C,"ax",@progbits +.globl C +C: + nop + +.section .text.D,"ax",@progbits +.globl D +D: + nop + + + Index: test/ELF/cgprofile-reproduce.s =================================================================== --- test/ELF/cgprofile-reproduce.s +++ test/ELF/cgprofile-reproduce.s @@ -0,0 +1,42 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "A B 5" > %t.call_graph +# RUN: echo "B C 50" >> %t.call_graph +# RUN: echo "C D 40" >> %t.call_graph +# RUN: echo "D B 10" >> %t.call_graph +# RUN: ld.lld -e A %t --call-graph-ordering-file %t.call_graph -o %t2 --print-symbol-order=%t3 +# RUN: ld.lld -e A %t --symbol-ordering-file %t3 -o %t2 +# RUN: llvm-readobj -symbols %t2 | FileCheck %s + +# CHECK: Name: A +# CHECK-NEXT: Value: 0x201003 +# CHECK: Name: B +# CHECK-NEXT: Value: 0x201000 +# CHECK: Name: C +# CHECK-NEXT: Value: 0x201001 +# CHECK: Name: D +# CHECK-NEXT: Value: 0x201002 + +.section .text.A,"ax",@progbits +.globl A +A: + nop + +.section .text.B,"ax",@progbits +.globl B +B: + nop + +.section .text.C,"ax",@progbits +.globl C +C: + nop + +.section .text.D,"ax",@progbits +.globl D +D: + nop + + +