[lld] 1ce51a5 - [ELF] --cref: If -Map is specified, print to the map file

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 29 14:14:58 PST 2021


Author: Fangrui Song
Date: 2021-11-29T14:14:53-08:00
New Revision: 1ce51a5f355ffba72b01e5e688cda7bbba2aa282

URL: https://github.com/llvm/llvm-project/commit/1ce51a5f355ffba72b01e5e688cda7bbba2aa282
DIFF: https://github.com/llvm/llvm-project/commit/1ce51a5f355ffba72b01e5e688cda7bbba2aa282.diff

LOG: [ELF] --cref: If -Map is specified, print to the map file

PR48282: This behavior matches GNU ld and gold.

Reviewed By: markj

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

Added: 
    

Modified: 
    lld/ELF/MapFile.cpp
    lld/ELF/MapFile.h
    lld/ELF/Options.td
    lld/ELF/Writer.cpp
    lld/docs/ReleaseNotes.rst
    lld/docs/ld.lld.1
    lld/test/ELF/cref.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index 7b8db004de95f..06735802f7f14 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -139,20 +139,7 @@ static void printEhFrame(raw_ostream &os, const EhFrameSection *sec) {
   }
 }
 
-void elf::writeMapFile() {
-  if (config->mapFile.empty())
-    return;
-
-  llvm::TimeTraceScope timeScope("Write map file");
-
-  // Open a map file for writing.
-  std::error_code ec;
-  raw_fd_ostream os(config->mapFile, ec, sys::fs::OF_None);
-  if (ec) {
-    error("cannot open " + config->mapFile + ": " + ec.message());
-    return;
-  }
-
+static void writeMapFile(raw_fd_ostream &os) {
   // Collect symbol info that we want to print out.
   std::vector<Defined *> syms = getSymbols();
   SymbolMapTy sectionSyms = getSectionSyms(syms);
@@ -235,10 +222,6 @@ void elf::writeWhyExtract() {
   }
 }
 
-static void print(StringRef a, StringRef b) {
-  lld::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
@@ -250,10 +233,7 @@ static void print(StringRef a, StringRef b) {
 //
 // In this case, strlen is defined by libc.so.6 and used by other two
 // files.
-void elf::writeCrossReferenceTable() {
-  if (!config->cref)
-    return;
-
+static void writeCref(raw_fd_ostream &os) {
   // Collect symbols and files.
   MapVector<Symbol *, SetVector<InputFile *>> map;
   for (InputFile *file : objectFiles) {
@@ -266,8 +246,12 @@ void elf::writeCrossReferenceTable() {
     }
   }
 
-  // Print out a header.
-  lld::outs() << "Cross Reference Table\n\n";
+  auto print = [&](StringRef a, StringRef b) {
+    os << left_justify(a, 49) << ' ' << b << '\n';
+  };
+
+  // Print a blank line and a header. The format matches GNU ld.
+  os << "\nCross Reference Table\n\n";
   print("Symbol", "File");
 
   // Print out a table.
@@ -282,6 +266,27 @@ void elf::writeCrossReferenceTable() {
   }
 }
 
+void elf::writeMapAndCref() {
+  if (config->mapFile.empty() && !config->cref)
+    return;
+
+  llvm::TimeTraceScope timeScope("Write map file");
+
+  // Open a map file for writing.
+  std::error_code ec;
+  StringRef mapFile = config->mapFile.empty() ? "-" : config->mapFile;
+  raw_fd_ostream os(mapFile, ec, sys::fs::OF_None);
+  if (ec) {
+    error("cannot open " + mapFile + ": " + ec.message());
+    return;
+  }
+
+  if (!config->mapFile.empty())
+    writeMapFile(os);
+  if (config->cref)
+    writeCref(os);
+}
+
 void elf::writeArchiveStats() {
   if (config->printArchiveStats.empty())
     return;

diff  --git a/lld/ELF/MapFile.h b/lld/ELF/MapFile.h
index 1b8c0168c0de8..df548988c03b4 100644
--- a/lld/ELF/MapFile.h
+++ b/lld/ELF/MapFile.h
@@ -11,9 +11,8 @@
 
 namespace lld {
 namespace elf {
-void writeMapFile();
+void writeMapAndCref();
 void writeWhyExtract();
-void writeCrossReferenceTable();
 void writeArchiveStats();
 } // namespace elf
 } // namespace lld

diff  --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 3bb358c457d3c..f9f9f54a80d88 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -129,7 +129,8 @@ def color_diagnostics_eq: J<"color-diagnostics=">,
   HelpText<"Use colors in diagnostics (default: auto)">,
   MetaVarName<"[auto,always,never]">;
 
-def cref: FF<"cref">, HelpText<"Output cross reference table">;
+def cref: FF<"cref">,
+  HelpText<"Output cross reference table. If -Map is specified, print to the map file">;
 
 defm define_common: B<"define-common",
     "Assign space to common symbols",

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 423f98976ad17..07c5e23033743 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -565,9 +565,8 @@ template <class ELFT> void Writer<ELFT>::run() {
   // --print-archive-stats=. Dump them before checkSections() because the files
   // may be useful in case checkSections() or openFile() fails, for example, due
   // to an erroneous file size.
-  writeMapFile();
+  writeMapAndCref();
   writeWhyExtract();
-  writeCrossReferenceTable();
   writeArchiveStats();
 
   if (config->checkSections)

diff  --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst
index 90245996b1cf0..a2456fc46689b 100644
--- a/lld/docs/ReleaseNotes.rst
+++ b/lld/docs/ReleaseNotes.rst
@@ -31,6 +31,8 @@ ELF Improvements
 * ``e_entry`` no longer falls back to the address of ``.text`` if the entry symbol does not exist.
   Instead, a value of 0 will be written.
   (`D110014 <https://reviews.llvm.org/D110014>`_)
+* If ``-Map`` is specified, ``--cref`` will be printted to the specified file.
+  (`D114663 <https://reviews.llvm.org/D114663>`_)
 
 Architecture specific changes:
 

diff  --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1
index 3bb3eb2ff3de7..0422231d78b51 100644
--- a/lld/docs/ld.lld.1
+++ b/lld/docs/ld.lld.1
@@ -141,7 +141,9 @@ you can specify
 .Fl O2
 to set the compression level to 6.
 .It Fl -cref
-Output cross reference table.
+Output cross reference table. If
+.Fl Map
+is specified, print to the map file.
 .It Fl -define-common , Fl d
 Assign space to common symbols.
 .It Fl -defsym Ns = Ns Ar symbol Ns = Ns Ar expression

diff  --git a/lld/test/ELF/cref.s b/lld/test/ELF/cref.s
index 30989205874fe..662a2ce339c33 100644
--- a/lld/test/ELF/cref.s
+++ b/lld/test/ELF/cref.s
@@ -9,7 +9,14 @@
 // RUN: ld.lld -shared -o %t1.so %t1.o
 // RUN: ld.lld -o /dev/null %t1.so %t2.o %t3.o %t.a --gc-sections --cref | FileCheck -strict-whitespace %s
 
-//      CHECK: Symbol                                            File
+/// If -Map is specified, print to the map file.
+// RUN: ld.lld -o /dev/null %t1.so %t2.o %t3.o %t.a --gc-sections -Map=%t.map --cref
+// RUN: FileCheck --input-file=%t.map %s --check-prefix=CHECK2
+
+// CHECK:      {{^$}}
+// CHECK-NEXT: Cross Reference Table
+// CHECK-EMPTY:
+// CHECK-NEXT: Symbol                                            File
 // CHECK-NEXT: foo                                               {{.*}}1.so
 // CHECK-NEXT:                                                   {{.*}}2.o
 // CHECK-NEXT:                                                   {{.*}}3.o
@@ -21,6 +28,14 @@
 // CHECK-NEXT:                                                   {{.*}}3.o
 // CHECK-NOT:  discarded
 
+// CHECK2:         VMA              LMA     Size Align Out     In      Symbol
+// CHECK2:      .strtab
+// CHECK2-NEXT:         <internal>:(.strtab)
+
+/// There is a blank line before the "Cross Reference Table" header.
+// CHECK2-EMPTY:
+// CHECK2-NEXT: Cross Reference Table
+
 .global _start, foo, bar, baz, discarded
 _start:
   call foo


        


More information about the llvm-commits mailing list