// in previous block for why this means we must copy `file` here.
newFile = file;
if (newFile->exportingFile)
- newFile->parseLoadCommands(mbref, umbrella);
+ newFile->parseLoadCommands(mbref);
}
return newFile;
}
for (InterfaceFile &child :
make_pointee_range(currentTopLevelTapi->documents())) {
assert(child.documents().empty());
- if (path == child.getInstallName())
- return make<DylibFile>(child, umbrella);
+ if (path == child.getInstallName()) {
+ auto file = make<DylibFile>(child, umbrella);
+ file->parseReexports(child);
+ return file;
+ }
}
}
assert(!isBundleLoader || !umbrella);
if (umbrella == nullptr)
umbrella = this;
+ this->umbrella = umbrella;
auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
auto *hdr = reinterpret_cast<const mach_header *>(mb.getBufferStart());
return;
// Initialize symbols.
- exportingFile = isImplicitlyLinked(dylibName) ? this : umbrella;
+ exportingFile = isImplicitlyLinked(dylibName) ? this : this->umbrella;
if (const load_command *cmd = findCommand(hdr, LC_DYLD_INFO_ONLY)) {
auto *c = reinterpret_cast<const dyld_info_command *>(cmd);
parseTrie(buf + c->export_off, c->export_size,
}
}
-void DylibFile::parseLoadCommands(MemoryBufferRef mb, DylibFile *umbrella) {
+void DylibFile::parseLoadCommands(MemoryBufferRef mb) {
auto *hdr = reinterpret_cast<const mach_header *>(mb.getBufferStart());
const uint8_t *p = reinterpret_cast<const uint8_t *>(mb.getBufferStart()) +
target->headerSize;
if (umbrella == nullptr)
umbrella = this;
+ this->umbrella = umbrella;
dylibName = saver.save(interface.getInstallName());
compatibilityVersion = interface.getCompatibilityVersion().rawValue();
}
}
-void DylibFile::parseReexports(const llvm::MachO::InterfaceFile &interface) {
+void DylibFile::parseReexports(const InterfaceFile &interface) {
const InterfaceFile *topLevel =
interface.getParent() == nullptr ? &interface : interface.getParent();
for (InterfaceFileRef intfRef : interface.reexportedLibraries()) {
// the root dylib to ensure symbols in the child library are correctly bound
// to the root. On the other hand, if a dylib is being directly loaded
// (through an -lfoo flag), then `umbrella` should be a nullptr.
- void parseLoadCommands(MemoryBufferRef mb, DylibFile *umbrella);
+ void parseLoadCommands(MemoryBufferRef mb);
void parseReexports(const llvm::MachO::InterfaceFile &interface);
static bool classof(const InputFile *f) { return f->kind() == DylibKind; }
StringRef dylibName;
DylibFile *exportingFile = nullptr;
+ DylibFile *umbrella;
uint32_t compatibilityVersion = 0;
uint32_t currentVersion = 0;
int64_t ordinal = 0; // Ordinal numbering starts from 1, so 0 is a sentinel
# REQUIRES: x86
-# RUN: mkdir -p %t
-#
-# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %s -o %t/test.o
+# RUN: split-file %s %t --no-leading-lines
-# RUN: %lld -o %t/test -lSystem -lc++ -framework CoreFoundation %t/test.o
+# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %t/test.s -o %t/test.o
+
+# RUN: %lld -o %t/test -lSystem -lc++ -framework CoreFoundation %t/libNested.tbd %t/test.o
# RUN: llvm-objdump --bind --no-show-raw-insn -d -r %t/test | FileCheck %s
## libReexportSystem.tbd tests that we can reference symbols from a dylib,
## re-exported by a top-level tapi document, which itself is re-exported by
## another top-level tapi document.
-# RUN: %lld -o %t/with-reexport %S/Inputs/libReexportSystem.tbd -lc++ -framework CoreFoundation %t/test.o
+# RUN: %lld -o %t/with-reexport %S/Inputs/libReexportSystem.tbd -lc++ -framework CoreFoundation %t/libNested.tbd %t/test.o
# RUN: llvm-objdump --bind --no-show-raw-insn -d -r %t/with-reexport | FileCheck %s
# CHECK: Disassembly of section __TEXT,__text:
# CHECK-DAG: __DATA __data {{.*}} pointer 0 CoreFoundation _OBJC_IVAR_$_NSConstantArray._count
# CHECK-DAG: __DATA __data {{.*}} pointer 0 CoreFoundation _OBJC_EHTYPE_$_NSException
# CHECK-DAG: __DATA __data {{.*}} pointer 0 libc++abi ___gxx_personality_v0
+# CHECK-DAG: __DATA __data {{.*}} pointer 0 libNested3 _deeply_nested
# RUN: llvm-objdump --macho --all-headers %t/test | \
# RUN: FileCheck --check-prefix=LOAD %s
# LOAD-REEXPORT-NEXT: current version 1.0.0
# LOAD-REEXPORT-NEXT: compatibility version
+#--- test.s
.section __TEXT,__text
.global _main
.quad _OBJC_METACLASS_$_NSObject
.quad _OBJC_IVAR_$_NSConstantArray._count
.quad _OBJC_EHTYPE_$_NSException
+ .quad _deeply_nested
## This symbol is defined in libc++abi.tbd, but we are linking test.o against
## libc++.tbd (which re-exports libc++abi). Linking against this symbol verifies
## that .tbd file re-exports can refer not just to TAPI documents within the
## same .tbd file, but to other on-disk files as well.
.quad ___gxx_personality_v0
+
+## This tests that we can locate a symbol re-exported by a child of a TAPI
+## document.
+#--- libNested.tbd
+--- !tapi-tbd-v3
+archs: [ x86_64 ]
+uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000000' ]
+platform: macosx
+install-name: '/usr/lib/libNested.dylib'
+exports:
+ - archs: [ x86_64 ]
+ re-exports: [ '/usr/lib/libNested2.dylib' ]
+--- !tapi-tbd-v3
+archs: [ x86_64 ]
+uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000001' ]
+platform: macosx
+install-name: '/usr/lib/libNested2.dylib'
+exports:
+ - archs: [ x86_64 ]
+ re-exports: [ '/usr/lib/libNested3.dylib' ]
+--- !tapi-tbd-v3
+archs: [ x86_64 ]
+uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000002' ]
+platform: macosx
+install-name: '/usr/lib/libNested3.dylib'
+exports:
+ - archs: [ x86_64 ]
+ symbols: [ _deeply_nested ]
+...