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 {
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) {
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()
# 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:
# CHECK-NEXT: _bar_tlv
# CHECK-NEXT: _foo_tlv
+# DYSYMTAB: nindirectsyms 9
+
#--- libfoo.s
.globl _foo, _foo_fn, _bar, _bar_fn