forked from OSchip/llvm-project
[lld-macho] Implement -force_load
It's similar to lld-ELF's `-whole-archive`, but applied to individual archives instead of to a series of them. Reviewed By: #lld-macho, smeenai Differential Revision: https://reviews.llvm.org/D85550
This commit is contained in:
parent
180ad756ec
commit
437e6bd286
|
@ -40,8 +40,9 @@
|
|||
|
||||
using namespace llvm;
|
||||
using namespace llvm::MachO;
|
||||
using namespace llvm::sys;
|
||||
using namespace llvm::object;
|
||||
using namespace llvm::opt;
|
||||
using namespace llvm::sys;
|
||||
using namespace lld;
|
||||
using namespace lld::macho;
|
||||
|
||||
|
@ -253,6 +254,35 @@ static void addFileList(StringRef path) {
|
|||
addFile(path);
|
||||
}
|
||||
|
||||
// Returns slices of MB by parsing MB as an archive file.
|
||||
// Each slice consists of a member file in the archive.
|
||||
static std::vector<MemoryBufferRef> getArchiveMembers(MemoryBufferRef mb) {
|
||||
std::unique_ptr<Archive> file =
|
||||
CHECK(Archive::create(mb),
|
||||
mb.getBufferIdentifier() + ": failed to parse archive");
|
||||
|
||||
std::vector<MemoryBufferRef> v;
|
||||
Error err = Error::success();
|
||||
for (const Archive::Child &c : file->children(err)) {
|
||||
MemoryBufferRef mbref =
|
||||
CHECK(c.getMemoryBufferRef(),
|
||||
mb.getBufferIdentifier() +
|
||||
": could not get the buffer for a child of the archive");
|
||||
v.push_back(mbref);
|
||||
}
|
||||
if (err)
|
||||
fatal(mb.getBufferIdentifier() +
|
||||
": Archive::children failed: " + toString(std::move(err)));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static void forceLoadArchive(StringRef path) {
|
||||
if (Optional<MemoryBufferRef> buffer = readFile(path))
|
||||
for (MemoryBufferRef member : getArchiveMembers(*buffer))
|
||||
inputFiles.push_back(make<ObjFile>(member));
|
||||
}
|
||||
|
||||
static std::array<StringRef, 6> archNames{"arm", "arm64", "i386",
|
||||
"x86_64", "ppc", "ppc64"};
|
||||
static bool isArchString(StringRef s) {
|
||||
|
@ -508,6 +538,9 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
|
|||
case OPT_filelist:
|
||||
addFileList(arg->getValue());
|
||||
break;
|
||||
case OPT_force_load:
|
||||
forceLoadArchive(arg->getValue());
|
||||
break;
|
||||
case OPT_l: {
|
||||
StringRef name = arg->getValue();
|
||||
if (Optional<std::string> path = findLibrary(name)) {
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: mkdir -p %t
|
||||
# RUN: echo ".section __TEXT,archive; .globl _foo; .weak_definition _foo; _foo:" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/archive-foo.o
|
||||
# RUN: rm -f %t/foo.a
|
||||
# RUN: llvm-ar rcs %t/foo.a %t/archive-foo.o
|
||||
# RUN: echo ".section __TEXT,obj; .globl _foo; .weak_definition _foo; _foo:" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/foo.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/test.o
|
||||
|
||||
# RUN: lld -flavor darwinnew -force_load %t/foo.a %t/foo.o %t/test.o -o %t/test-force-load-first
|
||||
# FORCE-LOAD-FIRST: __TEXT,archive _foo
|
||||
# RUN: llvm-objdump --syms %t/test-force-load-first | FileCheck %s --check-prefix=FORCE-LOAD-FIRST
|
||||
|
||||
# RUN: lld -flavor darwinnew %t/foo.o -force_load %t/foo.a %t/test.o -o %t/test-force-load-second
|
||||
# RUN: llvm-objdump --syms %t/test-force-load-second | FileCheck %s --check-prefix=FORCE-LOAD-SECOND
|
||||
# FORCE-LOAD-SECOND: __TEXT,obj _foo
|
||||
|
||||
.globl _main
|
||||
_main:
|
||||
ret
|
|
@ -4,6 +4,7 @@
|
|||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
||||
|
||||
# RUN: not lld -flavor darwinnew %t.o %t.a -o /dev/null 2>&1 | FileCheck -DFILE=%t.a %s
|
||||
# RUN: not lld -flavor darwinnew %t.o -force_load %t.a -o /dev/null 2>&1 | FileCheck -DFILE=%t.a %s
|
||||
# CHECK: error: [[FILE]]: failed to parse archive: truncated or malformed archive (remaining size of archive too small for next archive member header at offset 8)
|
||||
|
||||
.global _main
|
||||
|
|
Loading…
Reference in New Issue