mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 15:41:46 +00:00
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
This commit is contained in:
parent
d3fef7a7c2
commit
3422f3cc6e
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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';
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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>,
|
||||
|
83
lld/test/MachO/why-load.s
Normal file
83
lld/test/MachO/why-load.s
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user