diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -36,6 +36,7 @@ bool allLoad = false; bool forceLoadObjC = false; bool staticLink = false; + bool headerPadMaxInstallNames = false; uint32_t headerPad; llvm::StringRef installName; llvm::StringRef outputFile; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -524,6 +524,8 @@ config->installName = args.getLastArgValue(OPT_install_name, config->outputFile); config->headerPad = args::getHex(args, OPT_headerpad, /*Default=*/32); + config->headerPadMaxInstallNames = + args.hasArg(OPT_headerpad_max_install_names); config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE; config->runtimePaths = args::getStrings(args, OPT_rpath); config->allLoad = args.hasArg(OPT_all_load); @@ -601,6 +603,7 @@ case OPT_L: case OPT_ObjC: case OPT_headerpad: + case OPT_headerpad_max_install_names: case OPT_install_name: case OPT_rpath: case OPT_sub_library: diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -687,11 +687,10 @@ Group; def headerpad : Separate<["-"], "headerpad">, MetaVarName<"">, - HelpText<"Allocate hex extra space for future expansion of the load commands via install_name_tool">, + HelpText<"Allocate hex extra space for future expansion of the load commands via install_name_tool (default is 0x20)">, Group; def headerpad_max_install_names : Flag<["-"], "headerpad_max_install_names">, HelpText<"Allocate extra space so all load-command paths can expand to MAXPATHLEN via install_name_tool">, - Flags<[HelpHidden]>, Group; def bind_at_load : Flag<["-"], "bind_at_load">, HelpText<"Tell dyld to bind all symbols at load time, rather than lazily">, diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -354,18 +354,24 @@ seg->index = segIndex++; } - uint64_t dylibOrdinal = 1; + uint64_t dylibCount = 0; for (InputFile *file : inputFiles) { if (auto *dylibFile = dyn_cast(file)) { in.header->addLoadCommand( make(LC_LOAD_DYLIB, dylibFile->dylibName)); - dylibFile->ordinal = dylibOrdinal++; + dylibFile->ordinal = ++dylibCount; if (dylibFile->reexport) in.header->addLoadCommand( make(LC_REEXPORT_DYLIB, dylibFile->dylibName)); } } + if (config->headerPadMaxInstallNames) { + size_t installNamesPadSize = + (dylibCount + ((config->outputType == MH_DYLIB) ? 1 : 0)) * 1024; + if (config->headerPad < installNamesPadSize) + config->headerPad = installNamesPadSize; + } } static size_t getSymbolPriority(const SymbolPriorityEntry &entry, diff --git a/lld/test/MachO/headerpad.s b/lld/test/MachO/headerpad.s --- a/lld/test/MachO/headerpad.s +++ b/lld/test/MachO/headerpad.s @@ -8,6 +8,17 @@ ## just enforces a lower bound. We should consider implementing the same ## alignment behavior. +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o +# RUN: lld -flavor darwinnew -o %t %t.o +# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=PADN +# PADN: magic cputype cpusubtype caps filetype ncmds sizeofcmds flags +# PADN-NEXT: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 9 [[#%u, CMDSIZE:]] {{.*}} +# PADN: sectname __text +# PADN-NEXT: segname __TEXT +# PADN-NEXT: addr +# PADN-NEXT: size +# PADN-NEXT: offset [[#%u, CMDSIZE + 0x20 + 0x20]] + # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o # RUN: lld -flavor darwinnew -o %t %t.o -headerpad 0 # RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=PAD0 @@ -17,7 +28,7 @@ # PAD0-NEXT: segname __TEXT # PAD0-NEXT: addr # PAD0-NEXT: size -# PAD0-NEXT: offset [[#%u, CMDSIZE + 32]] +# PAD0-NEXT: offset [[#%u, CMDSIZE + 0x20 + 0]] # RUN: lld -flavor darwinnew -o %t %t.o -headerpad 11 # RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=PAD11 @@ -27,7 +38,27 @@ # PAD11-NEXT: segname __TEXT # PAD11-NEXT: addr # PAD11-NEXT: size -# PAD11-NEXT: offset [[#%u, CMDSIZE + 32 + 0x11]] +# PAD11-NEXT: offset [[#%u, CMDSIZE + 0x20 + 0x11]] + +# RUN: lld -flavor darwinnew -o %t %t.o -headerpad_max_install_names +# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=PADMAX0 +# PADMAX0: magic cputype cpusubtype caps filetype ncmds sizeofcmds flags +# PADMAX0-NEXT: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 9 [[#%u, CMDSIZE:]] {{.*}} +# PADMAX0: sectname __text +# PADMAX0-NEXT: segname __TEXT +# PADMAX0-NEXT: addr +# PADMAX0-NEXT: size +# PADMAX0-NEXT: offset [[#%u, CMDSIZE + 0x20 + 0x20]] + +# RUN: lld -flavor darwinnew -o %t %t.o -headerpad_max_install_names -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem +# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=PADMAX1 +# PADMAX1: magic cputype cpusubtype caps filetype ncmds sizeofcmds flags +# PADMAX1-NEXT: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 10 [[#%u, CMDSIZE:]] {{.*}} +# PADMAX1: sectname __text +# PADMAX1-NEXT: segname __TEXT +# PADMAX1-NEXT: addr +# PADMAX1-NEXT: size +# PADMAX1-NEXT: offset [[#%u, CMDSIZE + 0x20 + 0x400]] .globl _main _main: