[lld-macho] Make it possible to re-export .tbd files

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
This commit is contained in:
Jez Ng 2020-08-18 15:46:21 -07:00
parent 3e7a86e366
commit 6336c042f6
5 changed files with 39 additions and 8 deletions

View File

@ -379,12 +379,15 @@ static void parseOrderFile(StringRef path) {
} }
// We expect sub-library names of the form "libfoo", which will match a dylib // 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) { static bool markSubLibrary(StringRef searchName) {
for (InputFile *file : inputFiles) { for (InputFile *file : inputFiles) {
if (auto *dylibFile = dyn_cast<DylibFile>(file)) { if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
StringRef filename = path::filename(dylibFile->getName()); 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; dylibFile->reexport = true;
return true; return true;
} }

View File

@ -397,7 +397,7 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella)
} }
DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella) DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella)
: InputFile(DylibKind, MemoryBufferRef()) { : InputFile(DylibKind, interface) {
if (umbrella == nullptr) if (umbrella == nullptr)
umbrella = this; umbrella = this;

View File

@ -12,6 +12,7 @@
#include "MachOStructs.h" #include "MachOStructs.h"
#include "lld/Common/LLVM.h" #include "lld/Common/LLVM.h"
#include "lld/Common/Memory.h"
#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DenseSet.h"
#include "llvm/BinaryFormat/MachO.h" #include "llvm/BinaryFormat/MachO.h"
#include "llvm/Object/Archive.h" #include "llvm/Object/Archive.h"
@ -45,7 +46,7 @@ public:
virtual ~InputFile() = default; virtual ~InputFile() = default;
Kind kind() const { return fileKind; } Kind kind() const { return fileKind; }
StringRef getName() const { return mb.getBufferIdentifier(); } StringRef getName() const { return name; }
MemoryBufferRef mb; MemoryBufferRef mb;
std::vector<Symbol *> symbols; std::vector<Symbol *> symbols;
@ -53,7 +54,11 @@ public:
std::vector<SubsectionMap> subsections; std::vector<SubsectionMap> subsections;
protected: 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>); void parseSections(ArrayRef<llvm::MachO::section_64>);
@ -64,6 +69,7 @@ protected:
private: private:
const Kind fileKind; const Kind fileKind;
const StringRef name;
}; };
// .o file // .o file
@ -84,9 +90,6 @@ public:
// .dylib file // .dylib file
class DylibFile : public InputFile { class DylibFile : public InputFile {
public: 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 // 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 // symbols in those sub-libraries will be available under the umbrella
// library's namespace. Those sub-libraries can also have their own // library's namespace. Those sub-libraries can also have their own
@ -96,6 +99,9 @@ public:
// (through an -lfoo flag), then `umbrella` should be a nullptr. // (through an -lfoo flag), then `umbrella` should be a nullptr.
explicit DylibFile(MemoryBufferRef mb, DylibFile *umbrella = 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; } static bool classof(const InputFile *f) { return f->kind() == DylibKind; }
StringRef dylibName; StringRef dylibName;

View File

@ -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 ]
...

View File

@ -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