diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h index 60c20a3f79f92f..c9c41a4e0ef3d4 100644 --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -81,6 +81,7 @@ struct Configuration { bool searchDylibsFirst = false; bool saveTemps = false; bool adhocCodesign = false; + bool emitFunctionStarts = false; bool timeTraceEnabled = false; uint32_t headerPad; uint32_t dylibCompatibilityVersion = 0; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 35f3ddf8b2a779..86ae732fdc7684 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -905,6 +905,7 @@ bool macho::link(ArrayRef argsArr, bool canExitEarly, config->forceLoadObjC = args.hasArg(OPT_ObjC); config->demangle = args.hasArg(OPT_demangle); config->implicitDylibs = !args.hasArg(OPT_no_implicit_dylibs); + config->emitFunctionStarts = !args.hasArg(OPT_no_function_starts); if (const Arg *arg = args.getLastArg(OPT_install_name)) { if (config->outputType != MH_DYLIB) diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index cdb8a467614592..c6e61219f34571 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -866,8 +866,7 @@ def interposable_list : Separate<["-"], "interposable_list">, Flags<[HelpHidden]>, Group; def no_function_starts : Flag<["-"], "no_function_starts">, - HelpText<"Do not creates a compressed table of function start addresses">, - Flags<[HelpHidden]>, + HelpText<"Do not create a table of function start addresses">, Group; def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">, HelpText<"Do not merge Objective-C categories into their classes">, diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h index 92869476390a8b..8674e5455afd09 100644 --- a/lld/MachO/SyntheticSections.h +++ b/lld/MachO/SyntheticSections.h @@ -488,7 +488,6 @@ struct InStruct { WeakBindingSection *weakBinding = nullptr; LazyBindingSection *lazyBinding = nullptr; ExportSection *exports = nullptr; - FunctionStartsSection *functionStarts = nullptr; GotSection *got = nullptr; TlvPointerSection *tlvPointers = nullptr; LazyPointerSection *lazyPointers = nullptr; diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp index 9a28ade965fb49..38a6627b63e934 100644 --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -70,6 +70,8 @@ class Writer { IndirectSymtabSection *indirectSymtabSection = nullptr; CodeSignatureSection *codeSignatureSection = nullptr; UnwindInfoSection *unwindInfoSection = nullptr; + FunctionStartsSection *functionStartsSection = nullptr; + LCUuid *uuidCommand = nullptr; OutputSegment *linkEditSegment = nullptr; }; @@ -122,8 +124,8 @@ class LCDyldInfo : public LoadCommand { class LCFunctionStarts : public LoadCommand { public: - explicit LCFunctionStarts(FunctionStartsSection *functionStarts) - : functionStarts(functionStarts) {} + explicit LCFunctionStarts(FunctionStartsSection *functionStartsSection) + : functionStartsSection(functionStartsSection) {} uint32_t getSize() const override { return sizeof(linkedit_data_command); } @@ -131,12 +133,12 @@ class LCFunctionStarts : public LoadCommand { auto *c = reinterpret_cast(buf); c->cmd = LC_FUNCTION_STARTS; c->cmdsize = getSize(); - c->dataoff = functionStarts->fileOff; - c->datasize = functionStarts->getFileSize(); + c->dataoff = functionStartsSection->fileOff; + c->datasize = functionStartsSection->getFileSize(); } private: - FunctionStartsSection *functionStarts; + FunctionStartsSection *functionStartsSection; }; class LCDysymtab : public LoadCommand { @@ -563,7 +565,8 @@ void Writer::createLoadCommands() { in.header->addLoadCommand(make(symtabSection, stringTableSection)); in.header->addLoadCommand( make(symtabSection, indirectSymtabSection)); - in.header->addLoadCommand(make(in.functionStarts)); + if (functionStartsSection) + in.header->addLoadCommand(make(functionStartsSection)); for (StringRef path : config->runtimePaths) in.header->addLoadCommand(make(path)); @@ -791,6 +794,8 @@ void Writer::createOutputSections() { indirectSymtabSection = make(); if (config->adhocCodesign) codeSignatureSection = make(); + if (config->emitFunctionStarts) + functionStartsSection = make(); switch (config->outputType) { case MH_EXECUTE: @@ -863,10 +868,12 @@ void Writer::finalizeLinkEditSegment() { in.weakBinding->finalizeContents(); in.lazyBinding->finalizeContents(); in.exports->finalizeContents(); - in.functionStarts->finalizeContents(); symtabSection->finalizeContents(); indirectSymtabSection->finalizeContents(); + if (functionStartsSection) + functionStartsSection->finalizeContents(); + // Now that __LINKEDIT is filled out, do a proper calculation of its // addresses and offsets. assignAddresses(linkEditSegment); @@ -962,7 +969,6 @@ void macho::createSyntheticSections() { in.weakBinding = make(); in.lazyBinding = make(); in.exports = make(); - in.functionStarts = make(); in.got = make(); in.tlvPointers = make(); in.lazyPointers = make(); diff --git a/lld/test/MachO/function-starts.s b/lld/test/MachO/function-starts.s index ce2d4299cbdd7f..d5168c630b6176 100644 --- a/lld/test/MachO/function-starts.s +++ b/lld/test/MachO/function-starts.s @@ -1,33 +1,40 @@ # REQUIRES: x86 -# RUN: split-file %s %t - -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/basic.s -o %t.basic.o -# RUN: %lld %t.basic.o -o %t.basic -# RUN: llvm-objdump --syms %t.basic > %t.objdump -# RUN: llvm-objdump --macho --function-starts %t.basic >> %t.objdump -# RUN: FileCheck %s --check-prefix=BASIC < %t.objdump - -# BASIC: SYMBOL TABLE: -# BASIC-NEXT: [[#%x,MAIN:]] g F __TEXT,__text _main -# BASIC-NEXT: [[#%x,F1:]] g F __TEXT,__text _f1 -# BASIC-NEXT: [[#%x,F2:]] g F __TEXT,__text _f2 -# BASIC: [[#MAIN]] -# BASIC: [[#F1]] -# BASIC: [[#F2]] - -# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/alias.s -o %t.alias.o -# RUN: %lld %t.alias.o -o %t.alias -# RUN: llvm-objdump --syms %t.alias > %t.objdump -# RUN: llvm-objdump --macho --function-starts %t.alias >> %t.objdump -# RUN: FileCheck %s --check-prefix=ALIAS < %t.objdump - -# ALIAS: SYMBOL TABLE: -# ALIAS-NEXT: [[#%x,F2:]] l F __TEXT,__text _f2 -# ALIAS-NEXT: [[#%x,MAIN:]] g F __TEXT,__text _main -# ALIAS-NEXT: [[#%x,F1:]] g F __TEXT,__text _f1 -# ALIAS: [[#MAIN]] -# ALIAS: [[#F1]] +# RUN: rm -rf %t; split-file %s %t + +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/basic.s -o %t/basic.o +# RUN: %lld %t/basic.o -o %t/basic +# RUN: llvm-objdump --syms %t/basic > %t/objdump +# RUN: llvm-objdump --macho --function-starts %t/basic >> %t/objdump +# RUN: FileCheck %s --check-prefix=BASIC < %t/objdump + +# BASIC-LABEL: SYMBOL TABLE: +# BASIC-NEXT: [[#%x,MAIN:]] g F __TEXT,__text _main +# BASIC-NEXT: [[#%x,F1:]] g F __TEXT,__text _f1 +# BASIC-NEXT: [[#%x,F2:]] g F __TEXT,__text _f2 +# BASIC-LABEL: basic: +# BASIC: [[#MAIN]] +# BASIC: [[#F1]] +# BASIC: [[#F2]] + +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/alias.s -o %t/alias.o +# RUN: %lld %t/alias.o -o %t/alias +# RUN: llvm-objdump --syms %t/alias > %t/objdump +# RUN: llvm-objdump --macho --function-starts %t/alias >> %t/objdump +# RUN: FileCheck %s --check-prefix=ALIAS < %t/objdump + +# ALIAS-LABEL: SYMBOL TABLE: +# ALIAS-NEXT: [[#%x,F2:]] l F __TEXT,__text _f2 +# ALIAS-NEXT: [[#%x,MAIN:]] g F __TEXT,__text _main +# ALIAS-NEXT: [[#%x,F1:]] g F __TEXT,__text _f1 +# ALIAS-LABEL: alias: +# ALIAS: [[#MAIN]] +# ALIAS: [[#F1]] + +# RUN: %lld %t/basic.o -no_function_starts -o %t/basic-no-function-starts +# RUN: llvm-objdump --macho --function-starts %t/basic-no-function-starts | FileCheck %s --check-prefix=NO-FUNCTION-STARTS +# NO-FUNCTION-STARTS: basic-no-function-starts: +# NO-FUNCTION-STARTS-EMPTY: #--- basic.s .section __TEXT,__text,regular,pure_instructions