[lld] r327565 - Implement --cref.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 14 13:29:45 PDT 2018


Author: ruiu
Date: Wed Mar 14 13:29:45 2018
New Revision: 327565

URL: http://llvm.org/viewvc/llvm-project?rev=327565&view=rev
Log:
Implement --cref.

This is an option to print out a table of symbols and filenames.
The output format of this option is the same as GNU, so that it can be
processed by the same scripts as before after migrating from GNU to lld.

This option is mildly useful; we can live without it. But it is pretty
convenient sometimes, and it can be implemented in 50 lines of code, so
I think lld should support this option.

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

Added:
    lld/trunk/test/ELF/cref.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/MapFile.cpp
    lld/trunk/ELF/MapFile.h
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/silent-ignore.test

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=327565&r1=327564&r2=327565&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Mar 14 13:29:45 2018
@@ -113,6 +113,7 @@ struct Configuration {
   bool BsymbolicFunctions;
   bool CheckSections;
   bool CompressDebugSections;
+  bool Cref;
   bool DefineCommon;
   bool Demangle = true;
   bool DisableVerify;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=327565&r1=327564&r2=327565&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Mar 14 13:29:45 2018
@@ -618,6 +618,7 @@ void LinkerDriver::readConfigs(opt::Inpu
       Args.hasFlag(OPT_check_sections, OPT_no_check_sections, true);
   Config->Chroot = Args.getLastArgValue(OPT_chroot);
   Config->CompressDebugSections = getCompressDebugSections(Args);
+  Config->Cref = Args.hasFlag(OPT_cref, OPT_no_cref, false);
   Config->DefineCommon = Args.hasFlag(OPT_define_common, OPT_no_define_common,
                                       !Args.hasArg(OPT_relocatable));
   Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);

Modified: lld/trunk/ELF/MapFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MapFile.cpp?rev=327565&r1=327564&r2=327565&view=diff
==============================================================================
--- lld/trunk/ELF/MapFile.cpp (original)
+++ lld/trunk/ELF/MapFile.cpp Wed Mar 14 13:29:45 2018
@@ -28,6 +28,8 @@
 #include "SyntheticSections.h"
 #include "lld/Common/Strings.h"
 #include "lld/Common/Threads.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
@@ -146,3 +148,50 @@ void elf::writeMapFile() {
     }
   }
 }
+
+static void print(StringRef A, StringRef B) {
+  outs() << left_justify(A, 49) << " " << B << "\n";
+}
+
+// Output a cross reference table to stdout. This is for --cref.
+//
+// For each global symbol, we print out a file that defines the symbol
+// followed by files that uses that symbol. Here is an example.
+//
+//     strlen     /lib/x86_64-linux-gnu/libc.so.6
+//                tools/lld/tools/lld/CMakeFiles/lld.dir/lld.cpp.o
+//                lib/libLLVMSupport.a(PrettyStackTrace.cpp.o)
+//
+// In this case, strlen is defined by libc.so.6 and used by other two
+// files.
+void elf::writeCrossReferenceTable() {
+  if (!Config->Cref)
+    return;
+
+  // Collect symbols and files.
+  MapVector<Symbol *, SetVector<InputFile *>> Map;
+  for (InputFile *File : ObjectFiles) {
+    for (Symbol *Sym : File->getSymbols()) {
+      if (isa<SharedSymbol>(Sym))
+        Map[Sym].insert(File);
+      if (auto *D = dyn_cast<Defined>(Sym))
+        if (!D->isLocal() && (!D->Section || D->Section->Live))
+          Map[D].insert(File);
+    }
+  }
+
+  // Print out a header.
+  outs() << "Cross Reference Table\n\n";
+  print("Symbol", "File");
+
+  // Print out a table.
+  for (auto KV : Map) {
+    Symbol *Sym = KV.first;
+    SetVector<InputFile *> &Files = KV.second;
+
+    print(toString(*Sym), toString(Sym->File));
+    for (InputFile *File : Files)
+      if (File != Sym->File)
+        print("", toString(File));
+  }
+}

Modified: lld/trunk/ELF/MapFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MapFile.h?rev=327565&r1=327564&r2=327565&view=diff
==============================================================================
--- lld/trunk/ELF/MapFile.h (original)
+++ lld/trunk/ELF/MapFile.h Wed Mar 14 13:29:45 2018
@@ -13,6 +13,7 @@
 namespace lld {
 namespace elf {
 void writeMapFile();
+void writeCrossReferenceTable();
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=327565&r1=327564&r2=327565&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Wed Mar 14 13:29:45 2018
@@ -75,6 +75,10 @@ def color_diagnostics: F<"color-diagnost
 def color_diagnostics_eq: J<"color-diagnostics=">,
   HelpText<"Use colors in diagnostics">;
 
+defm cref: B<"cref",
+    "Output cross reference table",
+    "Do not output cross reference table">;
+
 defm define_common: B<"define-common",
     "Assign space to common symbols",
     "Do not assign space to common symbols">;
@@ -420,7 +424,6 @@ defm plugin: Eq<"plugin">;
 
 // Options listed below are silently ignored for now for compatibility.
 def allow_shlib_undefined: F<"allow-shlib-undefined">;
-def cref: F<"cref">;
 def detect_odr_violations: F<"detect-odr-violations">;
 def g: Flag<["-"], "g">;
 def long_plt: F<"long-plt">;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=327565&r1=327564&r2=327565&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Mar 14 13:29:45 2018
@@ -475,8 +475,9 @@ template <class ELFT> void Writer<ELFT>:
   if (errorCount())
     return;
 
-  // Handle -Map option.
+  // Handle -Map and -cref options.
   writeMapFile();
+  writeCrossReferenceTable();
   if (errorCount())
     return;
 

Added: lld/trunk/test/ELF/cref.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/cref.s?rev=327565&view=auto
==============================================================================
--- lld/trunk/test/ELF/cref.s (added)
+++ lld/trunk/test/ELF/cref.s Wed Mar 14 13:29:45 2018
@@ -0,0 +1,26 @@
+// REQUIRES: x86
+
+// RUN: echo '.global foo; foo:' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t1.o
+// RUN: echo '.global foo, bar; bar:' | llvm-mc -filetype=obj -triple=x86_64-pc-linux - -o %t2.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t3.o
+// RUN: ld.lld -shared -o %t1.so %t1.o -gc-sections
+// RUN: ld.lld -o /dev/null %t1.so %t2.o %t3.o -cref | FileCheck -strict-whitespace %s
+
+//      CHECK: Symbol                                            File
+// CHECK-NEXT: bar                                               {{.*}}2.o
+// CHECK-NEXT:                                                   {{.*}}3.o
+// CHECK-NEXT: foo                                               {{.*}}1.so
+// CHECK-NEXT:                                                   {{.*}}2.o
+// CHECK-NEXT:                                                   {{.*}}3.o
+// CHECK-NEXT: _start                                            {{.*}}3.o
+// CHECK-NEXT: baz                                               {{.*}}3.o
+
+.global _start, foo, bar, baz
+_start:
+  call foo
+  call bar
+localsym:
+baz:
+
+.section .text.a,"ax", at progbits
+discarded:

Modified: lld/trunk/test/ELF/silent-ignore.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/silent-ignore.test?rev=327565&r1=327564&r2=327565&view=diff
==============================================================================
--- lld/trunk/test/ELF/silent-ignore.test (original)
+++ lld/trunk/test/ELF/silent-ignore.test Wed Mar 14 13:29:45 2018
@@ -1,6 +1,5 @@
 RUN: ld.lld --version \
 RUN:   -allow-shlib-undefined \
-RUN:   -cref \
 RUN:   -g \
 RUN:   -no-add-needed \
 RUN:   -no-allow-shlib-undefined \




More information about the llvm-commits mailing list