aboutsummaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2020-12-02 18:59:00 -0500
committerNico Weber <thakis@chromium.org>2020-12-03 08:35:12 -0500
commit3422f3cc6e5c8b4657297b5b7b898e5bfb60bbf5 (patch)
tree86b22368a545ad72970690fc56164fb7c4489153 /lld
parent[compiler-rt] Fix building the aarch64 out-of-line atomics assembly for non-E... (diff)
downloadllvm-project-3422f3cc6e5c8b4657297b5b7b898e5bfb60bbf5.tar.gz
llvm-project-3422f3cc6e5c8b4657297b5b7b898e5bfb60bbf5.tar.bz2
llvm-project-3422f3cc6e5c8b4657297b5b7b898e5bfb60bbf5.zip
Reland "[mac/lld] Implement -why_load".
The problem was that `sym` became replaced in the call to make<ObjFile> and referring to it afer that read memory that now stored a different kind of symbol (a Defined instead of a LazySymbol). Since this happens only once per archive, just copy the symbol to the stack before make<ObjFile> and read the copy instead. Originally reviewed at https://reviews.llvm.org/D92496
Diffstat (limited to 'lld')
-rw-r--r--lld/MachO/Config.h1
-rw-r--r--lld/MachO/Driver.cpp4
-rw-r--r--lld/MachO/Driver.h3
-rw-r--r--lld/MachO/DriverUtils.cpp8
-rw-r--r--lld/MachO/InputFiles.cpp9
-rw-r--r--lld/MachO/Options.td3
-rw-r--r--lld/test/MachO/why-load.s83
7 files changed, 109 insertions, 2 deletions
diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h
index 82c017063d44..bc22680db58f 100644
--- a/lld/MachO/Config.h
+++ b/lld/MachO/Config.h
@@ -38,6 +38,7 @@ struct Configuration {
bool staticLink = false;
bool isPic = false;
bool headerPadMaxInstallNames = false;
+ bool printWhyLoad = false;
bool searchDylibsFirst = false;
bool saveTemps = false;
uint32_t headerPad;
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 426101f4f9e1..9822ecdd9f2a 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -275,6 +275,8 @@ static InputFile *addFile(StringRef path, bool forceLoadArchive) {
for (const ArchiveMember &member : getArchiveMembers(*buffer)) {
inputFiles.push_back(
make<ObjFile>(member.mbref, member.modTime, path));
+ printWhyLoad((forceLoadArchive ? "-force_load" : "-all_load"),
+ inputFiles.back());
}
}
} else if (config->forceLoadObjC) {
@@ -291,6 +293,7 @@ static InputFile *addFile(StringRef path, bool forceLoadArchive) {
if (hasObjCSection(member.mbref)) {
inputFiles.push_back(
make<ObjFile>(member.mbref, member.modTime, path));
+ printWhyLoad("-ObjC", inputFiles.back());
}
}
}
@@ -637,6 +640,7 @@ bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32);
config->headerPadMaxInstallNames =
args.hasArg(OPT_headerpad_max_install_names);
+ config->printWhyLoad = args.hasArg(OPT_why_load);
config->outputType = getOutputType(args);
config->runtimePaths = args::getStrings(args, OPT_rpath);
config->allLoad = args.hasArg(OPT_all_load);
diff --git a/lld/MachO/Driver.h b/lld/MachO/Driver.h
index d5625fd3873e..db7c54c59966 100644
--- a/lld/MachO/Driver.h
+++ b/lld/MachO/Driver.h
@@ -19,6 +19,7 @@ namespace lld {
namespace macho {
class DylibFile;
+class InputFile;
class MachOOptTable : public llvm::opt::OptTable {
public:
@@ -45,6 +46,8 @@ llvm::Optional<DylibFile *> makeDylibFromTAPI(llvm::MemoryBufferRef mbref,
uint32_t getModTime(llvm::StringRef path);
+void printWhyLoad(StringRef reason, const InputFile *);
+
} // namespace macho
} // namespace lld
diff --git a/lld/MachO/DriverUtils.cpp b/lld/MachO/DriverUtils.cpp
index 77f76b522d7e..9c09ff682286 100644
--- a/lld/MachO/DriverUtils.cpp
+++ b/lld/MachO/DriverUtils.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "Driver.h"
+#include "Config.h"
#include "InputFiles.h"
#include "lld/Common/Args.h"
@@ -185,3 +186,10 @@ uint32_t macho::getModTime(StringRef path) {
warn("failed to get modification time of " + path);
return 0;
}
+
+void macho::printWhyLoad(StringRef reason, const InputFile *f) {
+ if (!config->printWhyLoad)
+ return;
+ lld::outs() << reason << " forced load of " << toString(f)
+ << '\n';
+}
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 4fd9873bcbd3..7d601c120017 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -619,8 +619,17 @@ void ArchiveFile::fetch(const object::Archive::Symbol &sym) {
"for the member defining symbol " +
toMachOString(sym)));
+ // `sym` is owned by a LazySym, which will be replace<>() by make<ObjFile>
+ // and become invalid after that call. Copy it to the stack so we can refer
+ // to it later.
+ const object::Archive::Symbol sym_copy = sym;
+
auto file = make<ObjFile>(mb, modTime, getName());
+ // ld64 doesn't demangle sym here even with -demangle. Match that, so
+ // intentionally no call to toMachOString() here.
+ printWhyLoad(sym_copy.getName(), file);
+
symbols.insert(symbols.end(), file->symbols.begin(), file->symbols.end());
subsections.insert(subsections.end(), file->subsections.begin(),
file->subsections.end());
diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td
index 399928e8d9ae..5b38fc650e9f 100644
--- a/lld/MachO/Options.td
+++ b/lld/MachO/Options.td
@@ -426,8 +426,7 @@ def commons : Separate<["-"], "commons">,
def grp_introspect : OptionGroup<"introspect">, HelpText<"INTROSPECTING THE LINKER">;
def why_load : Flag<["-"], "why_load">,
- HelpText<"Log the symbol that compels loading of each object file from a static library">,
- Flags<[HelpHidden]>,
+ HelpText<"Log why each object file is loaded from a static library">,
Group<grp_introspect>;
def whyload : Flag<["-"], "whyload">,
Alias<why_load>,
diff --git a/lld/test/MachO/why-load.s b/lld/test/MachO/why-load.s
new file mode 100644
index 000000000000..e2d5c95c8846
--- /dev/null
+++ b/lld/test/MachO/why-load.s
@@ -0,0 +1,83 @@
+# REQUIRES: x86
+# RUN: rm -rf %t
+# RUN: split-file %s %t
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t/objc.o %t/objc.s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t/foo.o %t/foo.s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t/bar.o %t/bar.s
+# RUN: llvm-ar csr %t/lib.a %t/objc.o %t/foo.o %t/bar.o
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t/main.o %t/main.s
+
+# The first line checks that we never demangle symbols in -why_load output.
+# RUN: %lld %t/main.o %t/lib.a -o /dev/null -why_load -demangle | \
+# RUN: FileCheck %s --check-prefix=WHY
+# RUN: %lld %t/main.o -force_load %t/lib.a -o /dev/null -why_load | \
+# RUN: FileCheck %s --check-prefix=WHYFORCE
+# RUN: %lld %t/main.o %t/lib.a -o /dev/null -all_load -why_load | \
+# RUN: FileCheck %s --check-prefix=WHYALL
+# RUN: %lld %t/main.o -force_load %t/lib.a -o /dev/null -all_load -why_load | \
+# RUN: FileCheck %s --check-prefix=WHYALLFORCE
+
+# RUN: %lld %t/main.o %t/lib.a -o /dev/null -ObjC -why_load | \
+# RUN: FileCheck %s --check-prefix=WHYOBJC
+# RUN: %lld %t/main.o -force_load %t/lib.a -o /dev/null -ObjC -why_load | \
+# RUN: FileCheck %s --check-prefix=WHYOBJCFORCE
+# RUN: %lld %t/main.o %t/lib.a -o /dev/null -ObjC -all_load -why_load | \
+# RUN: FileCheck %s --check-prefix=WHYOBJCALL
+# RUN: %lld %t/main.o -force_load %t/lib.a -o /dev/null -ObjC -all_load -why_load | \
+# RUN: FileCheck %s --check-prefix=WHYOBJCALLFORCE
+
+# WHY-DAG: _bar forced load of lib.a(bar.o)
+# WHY-DAG: __Z3foo forced load of lib.a(foo.o)
+# WHY-NOT: {{.*}} forced load of lib.a(objc.o)
+
+# WHYFORCE-DAG: -force_load forced load of lib.a(bar.o)
+# WHYFORCE-DAG: -force_load forced load of lib.a(foo.o)
+# WHYFORCE-DAG: -force_load forced load of lib.a(objc.o)
+
+# WHYALL-DAG: -all_load forced load of lib.a(bar.o)
+# WHYALL-DAG: -all_load forced load of lib.a(foo.o)
+# WHYALL-DAG: -all_load forced load of lib.a(objc.o)
+
+# WHYALLFORCE-DAG: -force_load forced load of lib.a(bar.o)
+# WHYALLFORCE-DAG: -force_load forced load of lib.a(foo.o)
+# WHYALLFORCE-DAG: -force_load forced load of lib.a(objc.o)
+
+# WHYOBJC-DAG: _bar forced load of lib.a(bar.o)
+# WHYOBJC-DAG: __Z3foo forced load of lib.a(foo.o)
+# WHYOBJC-DAG: -ObjC forced load of lib.a(objc.o)
+
+# WHYOBJCFORCE-DAG: -force_load forced load of lib.a(bar.o)
+# WHYOBJCFORCE-DAG: -force_load forced load of lib.a(foo.o)
+# WHYOBJCFORCE-DAG: -force_load forced load of lib.a(objc.o)
+
+# WHYOBJCALL-DAG: -all_load forced load of lib.a(bar.o)
+# WHYOBJCALL-DAG: -all_load forced load of lib.a(foo.o)
+# WHYOBJCALL-DAG: -all_load forced load of lib.a(objc.o)
+
+# WHYOBJCALLFORCE-DAG: -force_load forced load of lib.a(bar.o)
+# WHYOBJCALLFORCE-DAG: -force_load forced load of lib.a(foo.o)
+# WHYOBJCALLFORCE-DAG: -force_load forced load of lib.a(objc.o)
+
+#--- objc.s
+.section __DATA,__objc_catlist
+.quad 0x1234
+
+#--- foo.s
+.globl __Z3foo
+__Z3foo:
+ ret
+
+#--- bar.s
+.globl _bar
+_bar:
+ callq __Z3foo
+ ret
+
+#--- main.s
+.globl _main
+_main:
+ callq _bar
+ callq __Z3foo
+ ret