diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -694,6 +694,11 @@ } void SymtabSection::finalizeContents() { + auto addSymbol = [&](std::vector &symbols, Symbol *sym) { + uint32_t strx = stringTableSection.addString(sym->getName()); + symbols.push_back({sym, strx}); + }; + // Local symbols aren't in the SymbolTable, so we walk the list of object // files to gather them. for (InputFile *file : inputFiles) { @@ -702,10 +707,8 @@ // TODO: when we implement -dead_strip, we should filter out symbols // that belong to dead sections. if (auto *defined = dyn_cast(sym)) { - if (!defined->isExternal()) { - uint32_t strx = stringTableSection.addString(sym->getName()); - localSymbols.push_back({sym, strx}); - } + if (!defined->isExternal()) + addSymbol(localSymbols, sym); } } } @@ -713,19 +716,16 @@ // __dyld_private is a local symbol too. It's linker-created and doesn't // exist in any object file. - if (Defined* dyldPrivate = in.stubHelper->dyldPrivate) { - uint32_t strx = stringTableSection.addString(dyldPrivate->getName()); - localSymbols.push_back({dyldPrivate, strx}); - } + if (Defined* dyldPrivate = in.stubHelper->dyldPrivate) + addSymbol(localSymbols, dyldPrivate); for (Symbol *sym : symtab->getSymbols()) { - uint32_t strx = stringTableSection.addString(sym->getName()); if (auto *defined = dyn_cast(sym)) { assert(defined->isExternal()); - externalSymbols.push_back({sym, strx}); + addSymbol(externalSymbols, sym); } else if (auto *dysym = dyn_cast(sym)) { if (dysym->isReferenced()) - undefinedSymbols.push_back({sym, strx}); + addSymbol(undefinedSymbols, sym); } } diff --git a/lld/test/MachO/symtab.s b/lld/test/MachO/symtab.s --- a/lld/test/MachO/symtab.s +++ b/lld/test/MachO/symtab.s @@ -86,17 +86,19 @@ # CHECK-NEXT: iundefsym: 5 # CHECK-NEXT: nundefsym: 2 -## Verify that the first entry in the StringTable is a space. +## Verify that the first entry in the StringTable is a space, and that +## unreferenced symbols aren't emitted. # RUN: obj2yaml %t/test | FileCheck %s --check-prefix=YAML # YAML: StringTable: # YAML-NEXT: ' ' +# YAML-NOT: _unreferenced #--- libfoo.s .globl _dynamic _dynamic: #--- test.s -.globl _main, _external, _external_weak +.globl _main, _external, _external_weak, _unreferenced .data _external: