[lld] c17547d - Revert "Implement -bundle_loader"
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 19 17:40:31 PST 2021
Author: Vitaly Buka
Date: 2021-02-19T17:40:07-08:00
New Revision: c17547df44fcbe2cd34bd264b6bda7af0208248b
URL: https://github.com/llvm/llvm-project/commit/c17547df44fcbe2cd34bd264b6bda7af0208248b
DIFF: https://github.com/llvm/llvm-project/commit/c17547df44fcbe2cd34bd264b6bda7af0208248b.diff
LOG: Revert "Implement -bundle_loader"
D95913 passes null pointer into memcpy
This reverts commit 1a0afcf518717f61d45a1cdc6ad1a6436ec663b1.
Added:
Modified:
lld/MachO/Driver.cpp
lld/MachO/Driver.h
lld/MachO/DriverUtils.cpp
lld/MachO/InputFiles.cpp
lld/MachO/InputFiles.h
lld/MachO/Options.td
lld/MachO/SyntheticSections.cpp
lld/MachO/Writer.cpp
Removed:
lld/test/MachO/bundle-loader.s
################################################################################
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 375ad03dd163..7c7fd869b9bf 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -261,8 +261,7 @@ static std::vector<ArchiveMember> getArchiveMembers(MemoryBufferRef mb) {
return v;
}
-static InputFile *addFile(StringRef path, bool forceLoadArchive,
- bool isBundleLoader = false) {
+static InputFile *addFile(StringRef path, bool forceLoadArchive) {
Optional<MemoryBufferRef> buffer = readFile(path);
if (!buffer)
return nullptr;
@@ -326,16 +325,6 @@ static InputFile *addFile(StringRef path, bool forceLoadArchive,
case file_magic::bitcode:
newFile = make<BitcodeFile>(mbref);
break;
- case file_magic::macho_executable:
- case file_magic::macho_bundle:
- // We only allow executable and bundle type here if it is used
- // as a bundle loader.
- if (!isBundleLoader)
- error(path + ": unhandled file type");
- if (Optional<DylibFile *> dylibFile =
- loadDylib(mbref, nullptr, isBundleLoader))
- newFile = *dylibFile;
- break;
default:
error(path + ": unhandled file type");
}
@@ -758,11 +747,6 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
config->printEachFile = args.hasArg(OPT_t);
config->printWhyLoad = args.hasArg(OPT_why_load);
config->outputType = getOutputType(args);
- if (const opt::Arg *arg = args.getLastArg(OPT_bundle_loader)) {
- if (config->outputType != MH_BUNDLE)
- error("-bundle_loader can only be used with MachO bundle output");
- addFile(arg->getValue(), false, true);
- }
config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto);
config->ltoNewPassManager =
args.hasFlag(OPT_no_lto_legacy_pass_manager, OPT_lto_legacy_pass_manager,
@@ -812,7 +796,6 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
const auto &opt = arg->getOption();
warnIfDeprecatedOption(opt);
warnIfUnimplementedOption(opt);
-
// TODO: are any of these better handled via filtered() or getLastArg()?
switch (opt.getID()) {
case OPT_INPUT:
diff --git a/lld/MachO/Driver.h b/lld/MachO/Driver.h
index bf7abdda4e01..08491f51261a 100644
--- a/lld/MachO/Driver.h
+++ b/lld/MachO/Driver.h
@@ -44,8 +44,7 @@ std::string createResponseFile(const llvm::opt::InputArgList &args);
llvm::Optional<std::string> resolveDylibPath(llvm::StringRef path);
llvm::Optional<DylibFile *> loadDylib(llvm::MemoryBufferRef mbref,
- DylibFile *umbrella = nullptr,
- bool isBundleLoader = false);
+ DylibFile *umbrella = nullptr);
llvm::Optional<InputFile *> loadArchiveMember(MemoryBufferRef, uint32_t modTime,
StringRef archiveName,
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index 6d9413ea4e57..836b86346ab8 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -176,8 +176,7 @@ Optional<std::string> macho::resolveDylibPath(StringRef path) {
static DenseMap<CachedHashStringRef, DylibFile *> loadedDylibs;
Optional<DylibFile *> macho::loadDylib(MemoryBufferRef mbref,
- DylibFile *umbrella,
- bool isBundleLoader) {
+ DylibFile *umbrella) {
StringRef path = mbref.getBufferIdentifier();
DylibFile *&file = loadedDylibs[CachedHashStringRef(path)];
if (file)
@@ -191,13 +190,11 @@ Optional<DylibFile *> macho::loadDylib(MemoryBufferRef mbref,
": " + toString(result.takeError()));
return {};
}
- file = make<DylibFile>(**result, umbrella, isBundleLoader);
+ file = make<DylibFile>(**result, umbrella);
} else {
assert(magic == file_magic::macho_dynamically_linked_shared_lib ||
- magic == file_magic::macho_dynamically_linked_shared_lib_stub ||
- magic == file_magic::macho_executable ||
- magic == file_magic::macho_bundle);
- file = make<DylibFile>(mbref, umbrella, isBundleLoader);
+ magic == file_magic::macho_dynamically_linked_shared_lib_stub);
+ file = make<DylibFile>(mbref, umbrella);
}
return file;
}
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index c10ae9159a36..41b375575a0d 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -605,11 +605,8 @@ void loadReexport(StringRef path, DylibFile *umbrella) {
inputFiles.insert(*reexport);
}
-DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
- bool isBundleLoader)
- : InputFile(DylibKind, mb), refState(RefState::Unreferenced),
- isBundleLoader(isBundleLoader) {
- assert(!isBundleLoader || !umbrella);
+DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella)
+ : InputFile(DylibKind, mb), refState(RefState::Unreferenced) {
if (umbrella == nullptr)
umbrella = this;
@@ -622,9 +619,7 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
currentVersion = read32le(&c->dylib.current_version);
compatibilityVersion = read32le(&c->dylib.compatibility_version);
dylibName = reinterpret_cast<const char *>(cmd) + read32le(&c->dylib.name);
- } else if (!isBundleLoader) {
- // macho_executable and macho_bundle don't have LC_ID_DYLIB,
- // so it's OK.
+ } else {
error("dylib " + toString(this) + " missing LC_ID_DYLIB load command");
return;
}
@@ -663,12 +658,8 @@ DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella,
}
}
-DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella,
- bool isBundleLoader)
- : InputFile(DylibKind, interface), refState(RefState::Unreferenced),
- isBundleLoader(isBundleLoader) {
- // FIXME: Add test for the missing TBD code path.
-
+DylibFile::DylibFile(const InterfaceFile &interface, DylibFile *umbrella)
+ : InputFile(DylibKind, interface), refState(RefState::Unreferenced) {
if (umbrella == nullptr)
umbrella = this;
diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h
index 10935050584d..ef573145f594 100644
--- a/lld/MachO/InputFiles.h
+++ b/lld/MachO/InputFiles.h
@@ -125,28 +125,20 @@ class DylibFile : public InputFile {
// the root dylib to ensure symbols in the child library are correctly bound
// 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,
- bool isBundleLoader = false);
+ explicit DylibFile(MemoryBufferRef mb, DylibFile *umbrella = nullptr);
explicit DylibFile(const llvm::MachO::InterfaceFile &interface,
- DylibFile *umbrella = nullptr,
- bool isBundleLoader = false);
+ DylibFile *umbrella = nullptr);
static bool classof(const InputFile *f) { return f->kind() == DylibKind; }
StringRef dylibName;
uint32_t compatibilityVersion = 0;
uint32_t currentVersion = 0;
- int64_t ordinal = 0; // Ordinal numbering starts from 1, so 0 is a sentinel
+ uint64_t ordinal = 0; // Ordinal numbering starts from 1, so 0 is a sentinel
RefState refState;
bool reexport = false;
bool forceWeakImport = false;
-
- // An executable can be used as a bundle loader that will load the output
- // file being linked, and that contains symbols referenced, but not
- // implemented in the bundle. When used like this, it is very similar
- // to a Dylib, so we re-used the same class to represent it.
- bool isBundleLoader;
};
// .a file
diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index d07c4a9cc3c7..adff1d10e250 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -396,6 +396,7 @@ def grp_bundle : OptionGroup<"bundle">, HelpText<"CREATING A BUNDLE">;
def bundle_loader : Separate<["-"], "bundle_loader">,
MetaVarName<"<executable>">,
HelpText<"Resolve undefined symbols from <executable>">,
+ Flags<[HelpHidden]>,
Group<grp_bundle>;
def grp_object : OptionGroup<"object">, HelpText<"CREATING AN OBJECT FILE">;
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index b4ef0ccf6f07..ca7f08239d04 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -215,7 +215,7 @@ struct Binding {
OutputSegment *segment = nullptr;
uint64_t offset = 0;
int64_t addend = 0;
- int16_t ordinal = 0;
+ uint8_t ordinal = 0;
};
} // namespace
@@ -262,24 +262,18 @@ static void encodeBinding(const Symbol *sym, const OutputSection *osec,
}
// Non-weak bindings need to have their dylib ordinal encoded as well.
-static void encodeDylibOrdinal(const DylibSymbol *dysym, Binding *lastBinding,
+static void encodeDylibOrdinal(const DylibSymbol *dysym, Binding &lastBinding,
raw_svector_ostream &os) {
using namespace llvm::MachO;
- if (lastBinding == nullptr ||
- lastBinding->ordinal != dysym->getFile()->ordinal) {
- if (dysym->getFile()->ordinal <= 0) {
- os << static_cast<uint8_t>(
- BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
- (dysym->getFile()->ordinal & BIND_IMMEDIATE_MASK));
- } else if (dysym->getFile()->ordinal <= BIND_IMMEDIATE_MASK) {
+ if (lastBinding.ordinal != dysym->getFile()->ordinal) {
+ if (dysym->getFile()->ordinal <= BIND_IMMEDIATE_MASK) {
os << static_cast<uint8_t>(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
dysym->getFile()->ordinal);
} else {
os << static_cast<uint8_t>(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB);
encodeULEB128(dysym->getFile()->ordinal, os);
}
- if (lastBinding != nullptr)
- lastBinding->ordinal = dysym->getFile()->ordinal;
+ lastBinding.ordinal = dysym->getFile()->ordinal;
}
}
@@ -315,7 +309,7 @@ void BindingSection::finalizeContents() {
return a.target.getVA() < b.target.getVA();
});
for (const BindingEntry &b : bindings) {
- encodeDylibOrdinal(b.dysym, &lastBinding, os);
+ encodeDylibOrdinal(b.dysym, lastBinding, os);
if (auto *isec = b.target.section.dyn_cast<const InputSection *>()) {
encodeBinding(b.dysym, isec->parent, isec->outSecOff + b.target.offset,
b.addend, /*isWeakBinding=*/false, lastBinding, os);
@@ -535,7 +529,13 @@ uint32_t LazyBindingSection::encode(const DylibSymbol &sym) {
uint64_t offset = in.lazyPointers->addr - dataSeg->firstSection()->addr +
sym.stubsIndex * WordSize;
encodeULEB128(offset, os);
- encodeDylibOrdinal(&sym, nullptr, os);
+ if (sym.getFile()->ordinal <= MachO::BIND_IMMEDIATE_MASK) {
+ os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
+ sym.getFile()->ordinal);
+ } else {
+ os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB);
+ encodeULEB128(sym.getFile()->ordinal, os);
+ }
uint8_t flags = MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM;
if (sym.isWeakRef())
@@ -796,12 +796,7 @@ void SymtabSection::writeTo(uint8_t *buf) const {
nList->n_desc |= defined->isExternalWeakDef() ? MachO::N_WEAK_DEF : 0;
} else if (auto *dysym = dyn_cast<DylibSymbol>(entry.sym)) {
uint16_t n_desc = nList->n_desc;
- if (dysym->getFile()->isBundleLoader)
- MachO::SET_LIBRARY_ORDINAL(n_desc, MachO::EXECUTABLE_ORDINAL);
- else
- MachO::SET_LIBRARY_ORDINAL(
- n_desc, static_cast<uint8_t>(dysym->getFile()->ordinal));
-
+ MachO::SET_LIBRARY_ORDINAL(n_desc, dysym->getFile()->ordinal);
nList->n_type = MachO::N_EXT;
n_desc |= dysym->isWeakRef() ? MachO::N_WEAK_REF : 0;
nList->n_desc = n_desc;
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 8a30216dc8fc..010ff827f0b8 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -497,13 +497,9 @@ void Writer::createLoadCommands() {
in.header->addLoadCommand(make<LCBuildVersion>(config->platform));
- int64_t dylibOrdinal = 1;
+ uint64_t dylibOrdinal = 1;
for (InputFile *file : inputFiles) {
if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
- if (dylibFile->isBundleLoader)
- dylibFile->ordinal = MachO::BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE;
- else
- dylibFile->ordinal = dylibOrdinal++;
LoadCommandType lcType =
dylibFile->forceWeakImport || dylibFile->refState == RefState::Weak
? LC_LOAD_WEAK_DYLIB
@@ -511,6 +507,7 @@ void Writer::createLoadCommands() {
in.header->addLoadCommand(make<LCDylib>(lcType, dylibFile->dylibName,
dylibFile->compatibilityVersion,
dylibFile->currentVersion));
+ dylibFile->ordinal = dylibOrdinal++;
if (dylibFile->reexport)
in.header->addLoadCommand(
diff --git a/lld/test/MachO/bundle-loader.s b/lld/test/MachO/bundle-loader.s
deleted file mode 100644
index d960b4b01e4c..000000000000
--- a/lld/test/MachO/bundle-loader.s
+++ /dev/null
@@ -1,52 +0,0 @@
-# REQUIRES: x86
-
-# RUN: rm -rf %t; split-file %s %t
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/2.s -o %t/2.o
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/3.s -o %t/3.o
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/main.s -o %t/main.o
-
-# RUN: %lld -lSystem -dylib -install_name %t/my_lib.dylib -o %t/mylib.dylib %t/2.o
-# RUN: %lld %t/2.o %t/main.o -o %t/main
-# RUN: %lld -lSystem -bundle -bundle_loader %t/main -o %t/bundle.bundle %t/3.o %t/mylib.dylib
-# Check bundle.bundle to ensure the `my_func` symbol is from executable
-# RUN: llvm-nm -m %t/bundle.bundle | FileCheck %s --check-prefix BUNDLE
-# BUNDLE: (undefined) external _main (from executable)
-# BUNDLE: (undefined) external my_func (from executable)
-# RUN: llvm-objdump --macho --lazy-bind %t/bundle.bundle | FileCheck %s --check-prefix BUNDLE-OBJ
-# BUNDLE-OBJ: segment section address dylib symbol
-# BUNDLE-OBJ: __DATA __la_symbol_ptr 0x{{.*}} my_fun
-
-
-# RUN: %lld -lSystem -bundle -bundle_loader %t/main -o %t/bundle2.bundle %t/3.o %t/2.o
-# Check bundle2.bundle to ensure that _main is still from executable
-# but my_func is not.
-# RUN: llvm-nm -m %t/bundle2.bundle | FileCheck %s --check-prefix BUNDLE2
-# BUNDLE2: (undefined) external _main (from executable)
-# BUNDLE2: (__TEXT,__text) external my_func
-
-# Test that bundle_loader can only be used with MachO bundle output.
-# RUN: not %lld -lSystem -bundle_loader %t/main -o %t/bundle3.bundle 2>&1 | FileCheck %s --check-prefix ERROR
-# ERROR: -bundle_loader can only be used with MachO bundle output
-
-#--- 2.s
-# my_lib: This contains the exported function
-.globl my_func
-my_func:
- retq
-
-#--- 3.s
-# my_user.s: This is the user/caller of the
-# exported function
-.text
-my_user:
- callq my_func()
- retq
-
-#--- main.s
-# main.s: dummy exec/main loads the exported function.
-# This is basically a way to say `my_user` should get
-# `my_func` from this executable.
-.globl _main
-.text
- _main:
- retq
More information about the llvm-commits
mailing list