diff options
-rw-r--r-- | lld/ELF/MapFile.cpp | 53 | ||||
-rw-r--r-- | lld/ELF/MapFile.h | 3 | ||||
-rw-r--r-- | lld/ELF/Options.td | 3 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 3 | ||||
-rw-r--r-- | lld/docs/ReleaseNotes.rst | 2 | ||||
-rw-r--r-- | lld/docs/ld.lld.1 | 4 | ||||
-rw-r--r-- | lld/test/ELF/cref.s | 17 |
7 files changed, 54 insertions, 31 deletions
diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index 7b8db00..0673580 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 1b8c016..df54898 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 3bb358c4..f9f9f54 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 423f989..07c5e23 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 9024599..a2456fc 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 3bb3eb2..0422231 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 3098920..662a2ce 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 |