[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