forked from OSchip/llvm-project
lld: initial pass at supporting TBD
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.
This commit is contained in:
parent
48c28d58c6
commit
6fe27b5fed
|
@ -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) {
|
||||
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>
|
||||
|
@ -73,6 +75,9 @@ public:
|
|||
// .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
|
||||
|
@ -81,6 +86,7 @@ public:
|
|||
// 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(),
|
||||
|
|
|
@ -251,7 +251,7 @@ private:
|
|||
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()));
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 ]
|
||||
...
|
|
@ -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 ]
|
||||
...
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue