Skip to content

Commit

Permalink
[lld-macho] Make it possible to re-export .tbd files
Browse files Browse the repository at this point in the history
Two things needed fixing for that to work:

1. getName() no longer returns null for DylibFiles constructed from TAPIs
2. markSubLibrary() now accepts .tbd as a possible extension

Differential Revision: https://reviews.llvm.org/D86180
  • Loading branch information
int3 committed Aug 27, 2020
1 parent 3e7a86e commit 6336c04
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 8 deletions.
7 changes: 5 additions & 2 deletions lld/MachO/Driver.cpp
Expand Up @@ -379,12 +379,15 @@ static void parseOrderFile(StringRef path) {
}

// We expect sub-library names of the form "libfoo", which will match a dylib
// with a path of .*/libfoo.dylib.
// with a path of .*/libfoo.{dylib, tbd}.
// XXX ld64 seems to ignore the extension entirely when matching sub-libraries;
// I'm not sure what the use case for that is.
static bool markSubLibrary(StringRef searchName) {
for (InputFile *file : inputFiles) {
if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
StringRef filename = path::filename(dylibFile->getName());
if (filename.consume_front(searchName) && filename == ".dylib") {
if (filename.consume_front(searchName) &&
(filename == ".dylib" || filename == ".tbd")) {
dylibFile->reexport = true;
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion lld/MachO/InputFiles.cpp
Expand Up @@ -397,7 +397,7 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella)
}

DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella)
: InputFile(DylibKind, MemoryBufferRef()) {
: InputFile(DylibKind, interface) {
if (umbrella == nullptr)
umbrella = this;

Expand Down
16 changes: 11 additions & 5 deletions lld/MachO/InputFiles.h
Expand Up @@ -12,6 +12,7 @@
#include "MachOStructs.h"

#include "lld/Common/LLVM.h"
#include "lld/Common/Memory.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Object/Archive.h"
Expand Down Expand Up @@ -45,15 +46,19 @@ class InputFile {

virtual ~InputFile() = default;
Kind kind() const { return fileKind; }
StringRef getName() const { return mb.getBufferIdentifier(); }
StringRef getName() const { return name; }

MemoryBufferRef mb;
std::vector<Symbol *> symbols;
ArrayRef<llvm::MachO::section_64> sectionHeaders;
std::vector<SubsectionMap> subsections;

protected:
InputFile(Kind kind, MemoryBufferRef mb) : mb(mb), fileKind(kind) {}
InputFile(Kind kind, MemoryBufferRef mb)
: mb(mb), fileKind(kind), name(mb.getBufferIdentifier()) {}

InputFile(Kind kind, const llvm::MachO::InterfaceFile &interface)
: fileKind(kind), name(saver.save(interface.getPath())) {}

void parseSections(ArrayRef<llvm::MachO::section_64>);

Expand All @@ -64,6 +69,7 @@ class InputFile {

private:
const Kind fileKind;
const StringRef name;
};

// .o file
Expand All @@ -84,9 +90,6 @@ class OpaqueFile : public InputFile {
// .dylib file
class DylibFile : public InputFile {
public:
explicit DylibFile(const llvm::MachO::InterfaceFile &interface,
DylibFile *umbrella = nullptr);

// Mach-O dylibs can re-export other dylibs as sub-libraries, meaning that the
// symbols in those sub-libraries will be available under the umbrella
// library's namespace. Those sub-libraries can also have their own
Expand All @@ -96,6 +99,9 @@ class DylibFile : public InputFile {
// (through an -lfoo flag), then `umbrella` should be a nullptr.
explicit DylibFile(MemoryBufferRef mb, DylibFile *umbrella = nullptr);

explicit DylibFile(const llvm::MachO::InterfaceFile &interface,
DylibFile *umbrella = nullptr);

static bool classof(const InputFile *f) { return f->kind() == DylibKind; }

StringRef dylibName;
Expand Down
10 changes: 10 additions & 0 deletions lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libc++.tbd
@@ -0,0 +1,10 @@
--- !tapi-tbd-v3
archs: [ i386, x86_64 ]
uuids: [ 'i386: 00000000-0000-0000-0000-000000000000', 'x86_64: 00000000-0000-0000-0000-0
0000000001' ]
platform: macosx
install-name: '/usr/lib/libc++.dylib'
current-version: 1281
exports:
- archs: [ i386, x86_64 ]
...
12 changes: 12 additions & 0 deletions lld/test/MachO/reexport-stub.s
@@ -0,0 +1,12 @@
# REQUIRES: x86
# RUN: mkdir -p %t

## This test verifies that a non-TBD dylib can re-export a TBD library.

# RUN: echo "" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/reexporter.o
# RUN: lld -flavor darwinnew -dylib -syslibroot %S/Inputs/MacOSX.sdk -lc++ -sub_library libc++ \
# RUN: %t/reexporter.o -o %t/libreexporter.dylib
# RUN: llvm-objdump --macho --all-headers %t/libreexporter.dylib | FileCheck %s --check-prefix=DYLIB-HEADERS
# DYLIB-HEADERS: cmd LC_REEXPORT_DYLIB
# DYLIB-HEADERS-NOT: Load command
# DYLIB-HEADERS: name /usr/lib/libc++.dylib

0 comments on commit 6336c04

Please sign in to comment.