[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