diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -872,7 +872,7 @@ uint32_t IndirectSymtabSection::getNumSymbols() const { return in.got->getEntries().size() + in.tlvPointers->getEntries().size() + - in.stubs->getEntries().size(); + 2 * in.stubs->getEntries().size(); } bool IndirectSymtabSection::isNeeded() const { @@ -886,9 +886,9 @@ off += in.got->getEntries().size(); in.tlvPointers->reserved1 = off; off += in.tlvPointers->getEntries().size(); - // There is a 1:1 correspondence between stubs and LazyPointerSection - // entries, so they can share the same sub-array in the table. - in.stubs->reserved1 = in.lazyPointers->reserved1 = off; + in.stubs->reserved1 = off; + off += in.stubs->getEntries().size(); + in.lazyPointers->reserved1 = off; } static uint32_t indirectValue(const Symbol *sym) { @@ -910,6 +910,15 @@ write32le(buf + off * sizeof(uint32_t), indirectValue(sym)); ++off; } + // There is a 1:1 correspondence between stubs and LazyPointerSection + // entries. But giving __stubs and __la_symbol_ptr the same reserved1 + // (the offset into the indirect symbol table) so that they both refer + // to the same range of offsets confuses `strip`, so write the stubs + // symbol table offsets a second time. + for (const Symbol *sym : in.stubs->getEntries()) { + write32le(buf + off * sizeof(uint32_t), indirectValue(sym)); + ++off; + } } StringTableSection::StringTableSection() diff --git a/lld/test/MachO/indirect-symtab.s b/lld/test/MachO/indirect-symtab.s --- a/lld/test/MachO/indirect-symtab.s +++ b/lld/test/MachO/indirect-symtab.s @@ -5,6 +5,7 @@ # RUN: %lld -dylib %t/libfoo.o -o %t/libfoo.dylib -lSystem # RUN: %lld %t/test.o %t/libfoo.dylib -o %t/test -lSystem # RUN: llvm-objdump --macho -d --no-show-raw-insn --indirect-symbols %t/test | FileCheck %s +# RUN: llvm-otool -l %t/test | FileCheck --check-prefix=DYSYMTAB %s # CHECK: (__TEXT,__text) section # CHECK-NEXT: _main: @@ -34,6 +35,8 @@ # CHECK-NEXT: _bar_tlv # CHECK-NEXT: _foo_tlv +# DYSYMTAB: nindirectsyms 9 + #--- libfoo.s .globl _foo, _foo_fn, _bar, _bar_fn