Index: include/lld/ReaderWriter/MachOLinkingContext.h =================================================================== --- include/lld/ReaderWriter/MachOLinkingContext.h +++ include/lld/ReaderWriter/MachOLinkingContext.h @@ -143,6 +143,9 @@ uint64_t baseAddress() const { return _baseAddress; } void setBaseAddress(uint64_t baseAddress) { _baseAddress = baseAddress; } + uint64_t headerPad() const { return _headerPad; } + void setHeaderPad(uint64_t headerPad) { _headerPad = headerPad; } + bool padHeaderPaths() const { return _padHeaderPaths; } void setPadHeaderPaths(bool padHeaderPaths) { _padHeaderPaths = padHeaderPaths; @@ -399,6 +402,9 @@ uint64_t _pageSize; uint64_t _baseAddress; uint64_t _stackSize; + // Note, _headerPad is 32 as that leaves enough space for code signing to be + // done after linking. + uint64_t _headerPad; uint32_t _compatibilityVersion; uint32_t _currentVersion; StringRef _installName; Index: lib/Driver/DarwinLdDriver.cpp =================================================================== --- lib/Driver/DarwinLdDriver.cpp +++ lib/Driver/DarwinLdDriver.cpp @@ -735,6 +735,17 @@ ctx.setStackSize(stackSizeVal); } + // Handle headerpad + if (llvm::opt::Arg *headerPad = parsedArgs.getLastArg(OPT_headerpad)) { + uint64_t headerPadVal; + if (parseNumberBase16(headerPad->getValue(), headerPadVal)) { + diagnostics << "error: headerpad expects a hex number\n"; + return false; + } + + ctx.setHeaderPad(headerPadVal); + } + // Handle -headerpad_max_install_names if (parsedArgs.getLastArg(OPT_headerpad_max_install_names)) ctx.setPadHeaderPaths(true); Index: lib/Driver/DarwinLdOptions.td =================================================================== --- lib/Driver/DarwinLdOptions.td +++ lib/Driver/DarwinLdOptions.td @@ -195,6 +195,8 @@ HelpText<"Add path to the runpath search path list for image being created">; def headerpad_max_install_names : Flag<["-"], "headerpad_max_install_names">, HelpText<"Pads paths up to MAXPATHLEN for use with install_name_tool">; +def headerpad : Separate<["-"], "headerpad">, + HelpText<"Pads the header by the given (hex) number of bytes (default=32b)">; def t : Flag<["-"], "t">, HelpText<"Print the names of the input files as ld processes them">; Index: lib/ReaderWriter/MachO/MachOLinkingContext.cpp =================================================================== --- lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -143,8 +143,8 @@ : _outputMachOType(MH_EXECUTE), _outputMachOTypeStatic(false), _doNothing(false), _pie(false), _arch(arch_unknown), _os(OS::macOSX), _osMinVersion(0), _pageZeroSize(0), _pageSize(4096), _baseAddress(0), - _stackSize(0), _compatibilityVersion(0), _currentVersion(0), - _flatNamespace(false), _padHeaderPaths(false), + _stackSize(0), _headerPad(32), _compatibilityVersion(0), + _currentVersion(0), _flatNamespace(false), _padHeaderPaths(false), _undefinedMode(UndefinedMode::error), _deadStrippableDylib(false), _printAtoms(false), _testingFileUsage(false), _keepPrivateExterns(false), _demangle(false), _archHandler(nullptr), Index: lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp =================================================================== --- lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp +++ lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp @@ -274,7 +274,8 @@ _swap(!MachOLinkingContext::isHostEndian(file.arch)), _bigEndianArch(MachOLinkingContext::isBigEndian(file.arch)), _padHeaderPaths(ctx.padHeaderPaths()), - _seg1addr(INT64_MAX) { + _seg1addr(INT64_MAX), + _headerPad(ctx.headerPad()) { _startOfLoadCommands = _is64 ? sizeof(mach_header_64) : sizeof(mach_header); const size_t segCommandBaseSize = (_is64 ? sizeof(segment_command_64) : sizeof(segment_command)); @@ -455,7 +456,6 @@ } void MachOFileLayout::padHeader() { - _headerPad = 0; if (!_padHeaderPaths) return; @@ -463,7 +463,7 @@ // pad the header with enough space for each path to grow to MAXPATHLEN. // FIXME!: We need to get the max path in a reliable way. const unsigned maxpathlen = 1024; - size_t padding = 0; + uint32_t padding = 0; for (const DependentDylib &dep : _file.dependentDylibs) { size_t size = pointerAlign(dep.path.size()+1); if (size < maxpathlen) @@ -477,7 +477,7 @@ padding += maxpathlen - size; } - _headerPad = padding; + _headerPad = std::max(padding, _headerPad); } static bool overlaps(const Segment &s1, const Segment &s2) {