Skip to content

Commit

Permalink
lld: initial pass at supporting TBD
Browse files Browse the repository at this point in the history
Add support to lld to use Text Based API stubs for linking.  This is
support is incomplete not filtering out platforms.  It also does not
account for architecture specific API handling and potentially does not
correctly handle trees of re-exports with inlined libraries being
treated as direct children of the top level library.
  • Loading branch information
compnerd committed Jun 9, 2020
1 parent 48c28d5 commit 6fe27b5
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 4 deletions.
15 changes: 13 additions & 2 deletions lld/MachO/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,20 @@ opt::InputArgList MachOOptTable::parse(ArrayRef<const char *> argv) {
}

static Optional<std::string> findLibrary(StringRef name) {
std::string stub = (llvm::Twine("lib") + name + ".tbd").str();
std::string shared = (llvm::Twine("lib") + name + ".dylib").str();
std::string archive = (llvm::Twine("lib") + name + ".a").str();
llvm::SmallString<260> location;

for (StringRef dir : config->searchPaths) {
for (StringRef library : {shared, archive}) {
for (StringRef library : {stub, shared, archive}) {
location = dir;
llvm::sys::path::append(location, library);
if (fs::exists(location))
return location.str().str();
}
}
return None;
return {};
}

static TargetInfo *createTargetInfo(opt::InputArgList &args) {
Expand Down Expand Up @@ -135,6 +136,16 @@ static void addFile(StringRef path) {
case file_magic::macho_dynamically_linked_shared_lib:
inputFiles.push_back(make<DylibFile>(mbref));
break;
case file_magic::tapi_file: {
llvm::Expected<std::unique_ptr<llvm::MachO::InterfaceFile>> result =
TextAPIReader::get(mbref);
if (!result)
return;

std::unique_ptr<llvm::MachO::InterfaceFile> interface{std::move(*result)};
inputFiles.push_back(make<DylibFile>(std::move(interface)));
break;
}
default:
error(path + ": unhandled file type");
}
Expand Down
19 changes: 19 additions & 0 deletions lld/MachO/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,25 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella)
}
}

DylibFile::DylibFile(std::shared_ptr<llvm::MachO::InterfaceFile> interface,
DylibFile *umbrella)
: InputFile(DylibKind, MemoryBufferRef()) {
if (umbrella == nullptr)
umbrella = this;

dylibName = saver.save(interface->getInstallName());
// TODO(compnerd) filter out symbols based on the target platform
for (const auto symbol : interface->symbols())
if (symbol->getArchitectures().has(config->arch))
symbols.push_back(
symtab->addDylib(saver.save(symbol->getName()), umbrella));
// TODO(compnerd) properly represent the hierarchy of the documents as it is
// in theory possible to have re-exported dylibs from re-exported dylibs which
// should be parent'ed to the child.
for (auto document : interface->documents())
reexported.push_back(make<DylibFile>(document, umbrella));
}

DylibFile::DylibFile() : InputFile(DylibKind, MemoryBufferRef()) {}

DylibFile *DylibFile::createLibSystemMock() {
Expand Down
6 changes: 6 additions & 0 deletions lld/MachO/InputFiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Object/Archive.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/TextAPI/MachO/InterfaceFile.h"
#include "llvm/TextAPI/MachO/TextAPIReader.h"

#include <map>
#include <vector>
Expand Down Expand Up @@ -73,6 +75,9 @@ class ObjFile : public InputFile {
// .dylib file
class DylibFile : public InputFile {
public:
explicit DylibFile(std::shared_ptr<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 @@ -81,6 +86,7 @@ class DylibFile : public InputFile {
// to the root. On the other hand, if a dylib is being directly loaded
// (through an -lfoo flag), then `umbrella` should be a nullptr.
explicit DylibFile(MemoryBufferRef mb, DylibFile *umbrella = nullptr);

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

// Do not use this constructor!! This is meant only for createLibSystemMock(),
Expand Down
4 changes: 2 additions & 2 deletions lld/MachO/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ class LCLoadDylinker : public LoadCommand {
void Writer::scanRelocations() {
for (InputSection *isec : inputSections) {
for (Reloc &r : isec->relocs) {
if (auto *s = r.target.dyn_cast<Symbol *>()) {
if (auto *s = r.target.dyn_cast<lld::macho::Symbol *>()) {
if (isa<Undefined>(s))
error("undefined symbol " + s->getName() + ", referenced from " +
sys::path::filename(isec->file->getName()));
Expand Down Expand Up @@ -329,7 +329,7 @@ static DenseMap<const InputSection *, size_t> buildInputSectionPriorities() {
// TODO: Make sure this handles weak symbols correctly.
for (InputFile *file : inputFiles)
if (isa<ObjFile>(file) || isa<ArchiveFile>(file))
for (Symbol *sym : file->symbols)
for (lld::macho::Symbol *sym : file->symbols)
if (auto *d = dyn_cast<Defined>(sym))
addSym(*d);

Expand Down
42 changes: 42 additions & 0 deletions lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libSystem.tbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--- !tapi-tbd-v3
archs: [ x86_64 ]
uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000000' ]
platform: macosx
install-name: '/usr/lib/libSystem.B.dylib'
current-version: 0001.001.1
exports:
- archs: [ 'x86_64' ]
re-exports: [ '/usr/lib/system/libdyld.dylib',
'/usr/lib/system/libsystem_c.dylib',
'/usr/lib/system/libsystem_m.dylib' ]
--- !tapi-tbd-v3
archs: [ x86_64 ]
uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000001' ]
platform: macosx
install-name: '/usr/lib/libdyld.dylib'
current-version: 0001.001.1
parent-umbrella: System
exports:
- archs: [ 'x86_64' ]
symbols: [ dyld_stub_binder ]
--- !tapi-tbd-v3
archs: [ x86_64 ]
uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000002' ]
platform: macosx
install-name: '/usr/lib/libsystem_c.dylib'
current-version: 0001.001.1
parent-umbrella: System
exports:
- archs: [ 'x86_64' ]
symbols: [ ]
--- !tapi-tbd-v3
archs: [ x86_64 ]
uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000003' ]
platform: macosx
install-name: '/usr/lib/libsystem_m.dylib'
current-version: 0001.001.1
parent-umbrella: System
exports:
- archs: [ 'x86_64' ]
symbols: [ ___nan ]
...
23 changes: 23 additions & 0 deletions lld/test/MachO/Inputs/iPhoneSimulator.sdk/usr/lib/libSystem.tbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--- !tapi-tbd-v3
archs: [ i386, x86_64 ]
uuids: [ 'i386: 00000000-0000-0000-0000-000000000000', 'x86_64: 00000000-0000-0000-0000-000000000001' ]
platform: ios
install-name: '/usr/lib/libSystem.B.dylib'
current-version: 1281
exports:
- archs: [ i386, x86_64 ]
re-exports: [ '/usr/lib/system/libcache.dylib' ]
symbols: [ __crashreporter_info__ ]
--- !tapi-tbd-v3
archs: [ i386, x86_64 ]
uuids: [ 'i386: 00000000-0000-0000-0000-000000000002', 'x86_64: 00000000-0000-0000-0000-000000000003' ]
platform: ios
install-name: '/usr/lib/libcache.dylib'
current-version: 83
parent-umbrella: System
exports:
- archs: [ i386 ]
symbols: [ __cache_handle_memory_pressure_event ]
- archs: [ i386, x86_64 ]
symbols: [ _cache_create, _cache_destroy, _cache_get ]
...
15 changes: 15 additions & 0 deletions lld/test/MachO/invalid/stub-link.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# REQUIRES: x86

# RUN: mkdir -p %t
#
# RUN: llvm-mc -filetype obj -triple x86_64-apple-ios %s -o %t/test.o
# RUN: not lld -flavor darwinnew -o %t/test -Z -L%S/../Inputs/iPhoneSimulator.sdk/usr/lib -lSystem %t/test.o 2>&1 | FileCheck %s

# CHECK: error: undefined symbol __cache_handle_memory_pressure_event

.section __TEXT,__text
.global _main

_main:
movq __cache_handle_memory_pressure_event@GOTPCREL(%rip), %rax
ret
21 changes: 21 additions & 0 deletions lld/test/MachO/stub-link.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# REQUIRES: x86

# RUN: mkdir -p %t
#
# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %s -o %t/test.o
# RUN: lld -flavor darwinnew -o %t/test -Z -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem %t/test.o
#
# RUN: llvm-objdump --bind --no-show-raw-insn -d -r %t/test | FileCheck %s

# CHECK: Disassembly of section __TEXT,__text:
# CHECK: movq {{.*}} # [[ADDR:[0-9a-f]+]]

# CHECK: Bind table:
# CHECK: __DATA_CONST __got 0x[[ADDR]] pointer 0 libSystem ___nan

.section __TEXT,__text
.global _main

_main:
movq ___nan@GOTPCREL(%rip), %rax
ret

0 comments on commit 6fe27b5

Please sign in to comment.