Author: Nico Weber Date: 2020-12-03T08:35:12-05:00 New Revision: 3422f3cc6e5c8b4657297b5b7b898e5bfb60bbf5
URL: https://github.com/llvm/llvm-project/commit/3422f3cc6e5c8b4657297b5b7b898e5bfb60bbf5 DIFF: https://github.com/llvm/llvm-project/commit/3422f3cc6e5c8b4657297b5b7b898e5bfb60bbf5.diff LOG: 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 Added: lld/test/MachO/why-load.s Modified: lld/MachO/Config.h lld/MachO/Driver.cpp lld/MachO/Driver.h lld/MachO/DriverUtils.cpp lld/MachO/InputFiles.cpp lld/MachO/Options.td Removed: ################################################################################ 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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits