[lld/mac] Implement -umbrella

I think this is an old way for doing what is done with
-reexport_library these days, but it's e.g. still used in libunwind's
build (the opensource.apple.com one, not the llvm one).

Differential Revision: https://reviews.llvm.org/D105448
This commit is contained in:
Nico Weber 2021-07-05 14:40:52 -04:00
parent 718c32175b
commit db64306d99
5 changed files with 53 additions and 3 deletions

View File

@ -126,6 +126,7 @@ struct Configuration {
llvm::StringRef outputFile;
llvm::StringRef ltoObjPath;
llvm::StringRef thinLTOJobs;
llvm::StringRef umbrella;
uint32_t ltoo = 2;
bool deadStripDylibs = false;
bool demangle = false;

View File

@ -1121,6 +1121,11 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
addFile(arg->getValue(), /*forceLoadArchive=*/false, /*isExplicit=*/false,
/*isBundleLoader=*/true);
}
if (const Arg *arg = args.getLastArg(OPT_umbrella)) {
if (config->outputType != MH_DYLIB)
warn("-umbrella used, but not creating dylib");
config->umbrella = arg->getValue();
}
config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto);
config->ltoNewPassManager =
args.hasFlag(OPT_no_lto_legacy_pass_manager, OPT_lto_legacy_pass_manager,

View File

@ -780,9 +780,8 @@ def client_name : Separate<["-"], "client_name">,
Flags<[HelpHidden]>,
Group<grp_rare>;
def umbrella : Separate<["-"], "umbrella">,
MetaVarName<"<<name>>">,
HelpText<"Re-export this dylib through the umbrella framework <name>a">,
Flags<[HelpHidden]>,
MetaVarName<"<name>">,
HelpText<"Re-export this dylib through the umbrella framework <name>">,
Group<grp_rare>;
def headerpad : Separate<["-"], "headerpad">,
MetaVarName<"<size>">,

View File

@ -128,6 +128,31 @@ public:
ExportSection *exportSection;
};
class LCSubFramework final : public LoadCommand {
public:
LCSubFramework(StringRef umbrella) : umbrella(umbrella) {}
uint32_t getSize() const override {
return alignTo(sizeof(sub_framework_command) + umbrella.size() + 1,
target->wordSize);
}
void writeTo(uint8_t *buf) const override {
auto *c = reinterpret_cast<sub_framework_command *>(buf);
buf += sizeof(sub_framework_command);
c->cmd = LC_SUB_FRAMEWORK;
c->cmdsize = getSize();
c->umbrella = sizeof(sub_framework_command);
memcpy(buf, umbrella.data(), umbrella.size());
buf[umbrella.size()] = '\0';
}
private:
const StringRef umbrella;
};
class LCFunctionStarts final : public LoadCommand {
public:
explicit LCFunctionStarts(FunctionStartsSection *functionStartsSection)
@ -665,6 +690,8 @@ template <class LP> void Writer::createLoadCommands() {
in.header->addLoadCommand(make<LCSymtab>(symtabSection, stringTableSection));
in.header->addLoadCommand(
make<LCDysymtab>(symtabSection, indirectSymtabSection));
if (!config->umbrella.empty())
in.header->addLoadCommand(make<LCSubFramework>(config->umbrella));
if (functionStartsSection)
in.header->addLoadCommand(make<LCFunctionStarts>(functionStartsSection));
if (dataInCodeSection)

18
lld/test/MachO/umbrella.s Normal file
View File

@ -0,0 +1,18 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t.o %s
# RUN: %lld -dylib -o %t.dylib -umbrella umbrella.dylib %t.o
# RUN: llvm-otool -lv %t.dylib | FileCheck %s
# RUN: %no_fatal_warnings_lld -bundle -o %t.so -umbrella umbrella.dylib %t.o \
# RUN: 2>&1 | FileCheck --check-prefix=WARN %s
# WARN: warning: -umbrella used, but not creating dylib
# RUN: llvm-otool -lv %t.so | FileCheck %s
# CHECK: cmd LC_SUB_FRAMEWORK
# CHECK-NEXT: cmdsize 32
# CHECK-NEXT: umbrella umbrella.dylib (offset 12)
.globl __Z3foo
__Z3foo:
ret