[lld] 4220843 - [lld][Macho] Include dead-stripped symbols in mapfile

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 28 10:57:18 PST 2022


Author: Roger Kim
Date: 2022-01-28T10:51:27-08:00
New Revision: 422084332a783e9a496160908235ed71b1af9364

URL: https://github.com/llvm/llvm-project/commit/422084332a783e9a496160908235ed71b1af9364
DIFF: https://github.com/llvm/llvm-project/commit/422084332a783e9a496160908235ed71b1af9364.diff

LOG: [lld][Macho] Include dead-stripped symbols in mapfile

ld64 outputs dead stripped symbols when using the -dead-strip flag. This change mimics that behavior for lld.

ld64's -dead_strip flag outputs:
```
$ ld -map map basics.o -o out -dead_strip -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -lSystem
$ cat map
# Path: out
# Arch: x86_64
# Object files:
[  0] linker synthesized
[  1] basics.o
# Sections:
# Address       Size            Segment Section
0x100003F97     0x00000021      __TEXT  __text
0x100003FB8     0x00000048      __TEXT  __unwind_info
0x100004000     0x00000008      __DATA_CONST    __got
0x100008000     0x00000010      __DATA  __ref_section
0x100008010     0x00000001      __DATA  __common
# Symbols:
# Address       Size            File  Name
0x100003F97     0x00000006      [  1] _ref_local
0x100003F9D     0x00000001      [  1] _ref_private_extern
0x100003F9E     0x0000000C      [  1] _main
0x100003FAA     0x00000006      [  1] _no_dead_strip_globl
0x100003FB0     0x00000001      [  1] _ref_from_no_dead_strip_globl
0x100003FB1     0x00000006      [  1] _no_dead_strip_local
0x100003FB7     0x00000001      [  1] _ref_from_no_dead_strip_local
0x100003FB8     0x00000048      [  0] compact unwind info
0x100004000     0x00000008      [  0] non-lazy-pointer-to-local: _ref_com
0x100008000     0x00000008      [  1] _ref_data
0x100008008     0x00000008      [  1] l_ref_data
0x100008010     0x00000001      [  1] _ref_com

# Dead Stripped Symbols:
#               Size            File  Name
<<dead>>        0x00000006      [  1] _unref_extern
<<dead>>        0x00000001      [  1] _unref_local
<<dead>>        0x00000007      [  1] _unref_private_extern
<<dead>>        0x00000001      [  1] _ref_private_extern_u
<<dead>>        0x00000008      [  1] _unref_data
<<dead>>        0x00000008      [  1] l_unref_data
<<dead>>        0x00000001      [  1] _unref_com
```

Reviewed By: int3, #lld-macho, thevinster

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

Added: 
    

Modified: 
    lld/MachO/MapFile.cpp
    lld/test/MachO/dead-strip.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/MapFile.cpp b/lld/MachO/MapFile.cpp
index 93abea2ed08b2..8f9381ff0d792 100644
--- a/lld/MachO/MapFile.cpp
+++ b/lld/MachO/MapFile.cpp
@@ -40,18 +40,32 @@ using namespace llvm::sys;
 using namespace lld;
 using namespace lld::macho;
 
-// Returns a list of all symbols that we want to print out.
-static std::vector<Defined *> getSymbols() {
-  std::vector<Defined *> v;
+using Symbols = std::vector<Defined *>;
+// Returns a pair where the left element is a container of all live Symbols and
+// the right element is a container of all dead symbols.
+static std::pair<Symbols, Symbols> getSymbols() {
+  Symbols liveSymbols, deadSymbols;
   for (InputFile *file : inputFiles)
     if (isa<ObjFile>(file))
       for (Symbol *sym : file->symbols)
         if (auto *d = dyn_cast_or_null<Defined>(sym))
-          if (d->isLive() && d->isec && d->getFile() == file) {
-            assert(!shouldOmitFromOutput(d->isec));
-            v.push_back(d);
+          if (d->isec && d->getFile() == file) {
+            if (d->isLive()) {
+              assert(!shouldOmitFromOutput(d->isec));
+              liveSymbols.push_back(d);
+            } else {
+              deadSymbols.push_back(d);
+            }
           }
-  return v;
+  parallelSort(liveSymbols.begin(), liveSymbols.end(),
+               [](Defined *a, Defined *b) {
+                 return a->getVA() != b->getVA() ? a->getVA() < b->getVA()
+                                                 : a->getName() < b->getName();
+               });
+  parallelSort(
+      deadSymbols.begin(), deadSymbols.end(),
+      [](Defined *a, Defined *b) { return a->getName() < b->getName(); });
+  return {std::move(liveSymbols), std::move(deadSymbols)};
 }
 
 // Construct a map from symbols to their stringified representations.
@@ -104,14 +118,6 @@ void macho::writeMapFile() {
     }
   }
 
-  // Collect symbol info that we want to print out.
-  std::vector<Defined *> syms = getSymbols();
-  parallelSort(syms.begin(), syms.end(), [](Defined *a, Defined *b) {
-    return a->getVA() != b->getVA() ? a->getVA() < b->getVA()
-                                    : a->getName() < b->getName();
-  });
-  DenseMap<Symbol *, std::string> symStr = getSymbolStrings(syms);
-
   // Dump table of sections
   os << "# Sections:\n";
   os << "# Address\tSize    \tSegment\tSection\n";
@@ -125,12 +131,29 @@ void macho::writeMapFile() {
     }
 
   // Dump table of symbols
+  Symbols liveSymbols, deadSymbols;
+  std::tie(liveSymbols, deadSymbols) = getSymbols();
+
+  DenseMap<Symbol *, std::string> liveSymbolStrings =
+      getSymbolStrings(liveSymbols);
   os << "# Symbols:\n";
   os << "# Address\t    File  Name\n";
-  for (Symbol *sym : syms) {
+  for (Symbol *sym : liveSymbols) {
+    assert(sym->isLive());
     os << format("0x%08llX\t[%3u] %s\n", sym->getVA(),
-                 readerToFileOrdinal[sym->getFile()], symStr[sym].c_str());
+                 readerToFileOrdinal[sym->getFile()],
+                 liveSymbolStrings[sym].c_str());
   }
 
-  // TODO: when we implement -dead_strip, we should dump dead stripped symbols
+  if (config->deadStrip) {
+    DenseMap<Symbol *, std::string> deadSymbolStrings =
+        getSymbolStrings(deadSymbols);
+    os << "# Dead Stripped Symbols:\n";
+    os << "# Address\t    File  Name\n";
+    for (Symbol *sym : deadSymbols) {
+      assert(!sym->isLive());
+      os << format("<<dead>>\t[%3u] %s\n", readerToFileOrdinal[sym->getFile()],
+                   deadSymbolStrings[sym].c_str());
+    }
+  }
 }

diff  --git a/lld/test/MachO/dead-strip.s b/lld/test/MachO/dead-strip.s
index 01272a11fea49..00cc5ee7bba51 100644
--- a/lld/test/MachO/dead-strip.s
+++ b/lld/test/MachO/dead-strip.s
@@ -7,7 +7,6 @@
 
 ## Check that .private_extern symbols are marked as local in the symbol table
 ## and aren't in the export trie.
-## Dead-stripped symbols should also not be in a map file output.
 # RUN: %lld -lSystem -dead_strip -map %t/map -u _ref_private_extern_u \
 # RUN:     %t/basics.o -o %t/basics
 # RUN: llvm-objdump --syms --section-headers %t/basics | \
@@ -16,7 +15,6 @@
 # RUN:     --exports-trie --indirect-symbols %t/basics | \
 # RUN:     FileCheck --check-prefix=EXECDATA --implicit-check-not _unref %s
 # RUN: llvm-otool -l %t/basics | grep -q 'segname __PAGEZERO'
-# RUN: FileCheck --check-prefix=MAP --implicit-check-not _unref %s < %t/map
 # EXEC-LABEL: Sections:
 # EXEC-LABEL: Name
 # EXEC-NEXT:  __text
@@ -44,7 +42,33 @@
 # EXECDATA-DAG:   _ref_com
 # EXECDATA-DAG:   _no_dead_strip_globl
 # EXECDATA-DAG:   __mh_execute_header
+
+## Check that dead stripped symbols get listed properly.
+# RUN: FileCheck --check-prefix=MAP %s < %t/map
+
 # MAP: _main
+# MAP-LABEL: Dead Stripped Symbols
+# MAP: <<dead>> [ 1] _unref_com
+# MAP: <<dead>> [ 1] _unref_data
+# MAP: <<dead>> [ 1] _unref_extern
+# MAP: <<dead>> [ 1] _unref_local
+# MAP: <<dead>> [ 1] _unref_private_extern
+# MAP: <<dead>> [ 1] l_unref_data
+
+## Run dead stripping on code without any dead symbols.
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
+# RUN:     %t/no-dead-symbols.s -o %t/no-dead-symbols.o
+# RUN: %lld -lSystem -dead_strip -map %t/no-dead-symbols-map \
+# RUN:     %t/no-dead-symbols.o -o %t/no-dead-symbols
+## Mark the end of the file with a string.
+# RUN: FileCheck --check-prefix=NODEADSYMBOLS %s < %t/no-dead-symbols-map
+
+# NODEADSYMBOLS-LABEL: # Symbols:
+# NODEADSYMBOLS-NEXT: # Address File Name
+# NODEADSYMBOLS-NEXT: _main
+# NODEADSYMBOLS-LABEL: # Dead Stripped Symbols:
+# NODEADSYMBOLS-NEXT: # Address File Name
+# NODEADSYMBOLS-EMPTY:
 
 # RUN: %lld -dylib -dead_strip -u _ref_private_extern_u %t/basics.o -o %t/basics.dylib
 # RUN: llvm-objdump --syms %t/basics.dylib | \
@@ -879,6 +903,12 @@ _main:
 
 .subsections_via_symbols
 
+#--- no-dead-symbols.s
+.text
+.globl _main
+_main:
+  retq
+
 #--- literals.s
 .cstring
 _unref_foo:


        


More information about the llvm-commits mailing list