diff --git a/lld/Common/Args.cpp b/lld/Common/Args.cpp --- a/lld/Common/Args.cpp +++ b/lld/Common/Args.cpp @@ -26,14 +26,14 @@ return CodeGenOpt::Default; } -int64_t lld::args::getInteger(opt::InputArgList &args, unsigned key, - int64_t Default) { +static int64_t getInteger(opt::InputArgList &args, unsigned key, + int64_t Default, unsigned base) { auto *a = args.getLastArg(key); if (!a) return Default; int64_t v; - if (to_integer(a->getValue(), v, 10)) + if (to_integer(a->getValue(), v, base)) return v; StringRef spelling = args.getArgString(a->getIndex()); @@ -41,6 +41,16 @@ return 0; } +int64_t lld::args::getInteger(opt::InputArgList &args, unsigned key, + int64_t Default) { + return ::getInteger(args, key, Default, 10); +} + +int64_t lld::args::getHex(opt::InputArgList &args, unsigned key, + int64_t Default) { + return ::getInteger(args, key, Default, 16); +} + std::vector lld::args::getStrings(opt::InputArgList &args, int id) { std::vector v; for (auto *arg : args.filtered(id)) diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -25,6 +25,7 @@ struct Configuration { Symbol *entry; bool hasReexports = false; + uint32_t headerPad; llvm::StringRef installName; llvm::StringRef outputFile; llvm::MachO::Architecture arch; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -396,6 +396,7 @@ config->outputFile = args.getLastArgValue(OPT_o, "a.out"); config->installName = args.getLastArgValue(OPT_install_name, config->outputFile); + config->headerPad = args::getHex(args, OPT_headerpad, 32); getLibrarySearchPaths(config->librarySearchPaths, args); getFrameworkSearchPaths(config->frameworkSearchPaths, args); config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE; @@ -450,6 +451,7 @@ case OPT_e: case OPT_F: case OPT_L: + case OPT_headerpad: case OPT_install_name: case OPT_Z: case OPT_arch: diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -693,7 +693,6 @@ def headerpad : Separate<["-"], "headerpad">, MetaVarName<"">, HelpText<"Allocate hex extra space for future expansion of the load commands via install_name_tool">, - Flags<[HelpHidden]>, 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">, diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -47,7 +47,7 @@ } uint64_t MachHeaderSection::getSize() const { - return sizeof(MachO::mach_header_64) + sizeOfCmds; + return sizeof(MachO::mach_header_64) + sizeOfCmds + config->headerPad; } void MachHeaderSection::writeTo(uint8_t *buf) const { diff --git a/lld/include/lld/Common/Args.h b/lld/include/lld/Common/Args.h --- a/lld/include/lld/Common/Args.h +++ b/lld/include/lld/Common/Args.h @@ -28,6 +28,8 @@ int64_t getInteger(llvm::opt::InputArgList &args, unsigned key, int64_t Default); +int64_t getHex(llvm::opt::InputArgList &args, unsigned key, int64_t Default); + std::vector getStrings(llvm::opt::InputArgList &args, int id); uint64_t getZOptionValue(llvm::opt::InputArgList &args, int id, StringRef key, diff --git a/lld/test/MachO/headerpad.s b/lld/test/MachO/headerpad.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/headerpad.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 + +## NOTE: Here we check that the first non-header section -- __text -- appears +## *exactly* `-headerpad` bytes from the end of the header. ld64 actually +## starts laying out the non-header sections in the __TEXT segment from the end +## of the (page-aligned) segment rather than the front, so its binaries +## typically have more than `-headerpad` bytes of actual padding. `-headerpad` +## 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 -headerpad 0 +# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=PAD0 +# PAD0: magic cputype cpusubtype caps filetype ncmds sizeofcmds +# PAD0-NEXT: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 8 [[#%u, CMDSIZE:]] {{.*}} +# PAD0: sectname __text +# PAD0-NEXT: segname __TEXT +# PAD0-NEXT: addr +# PAD0-NEXT: size +# PAD0-NEXT: offset [[#%u, CMDSIZE + 32]] + +# RUN: lld -flavor darwinnew -o %t %t.o -headerpad 11 +# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=PAD11 +# PAD11: magic cputype cpusubtype caps filetype ncmds sizeofcmds +# PAD11-NEXT: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 8 [[#%u, CMDSIZE:]] {{.*}} +# PAD11: sectname __text +# PAD11-NEXT: segname __TEXT +# PAD11-NEXT: addr +# PAD11-NEXT: size +# PAD11-NEXT: offset [[#%u, CMDSIZE + 32 + 0x11]] + +.globl _main +_main: + ret diff --git a/lld/test/MachO/local-got.s b/lld/test/MachO/local-got.s --- a/lld/test/MachO/local-got.s +++ b/lld/test/MachO/local-got.s @@ -12,12 +12,12 @@ ## address offset and the contents at that address very similarly, so am using ## --match-full-lines to make sure we match on the right thing. # CHECK: Contents of section __cstring: -# CHECK-NEXT: 1000003cc {{.*}} +# CHECK-NEXT: 1000003ec {{.*}} ## 1st 8 bytes refer to the start of __cstring + 0xe, 2nd 8 bytes refer to the ## start of __cstring # CHECK: Contents of section __got: -# CHECK-NEXT: [[#%X,ADDR:]] da030000 01000000 cc030000 01000000 {{.*}} +# CHECK-NEXT: [[#%X,ADDR:]] fa030000 01000000 ec030000 01000000 {{.*}} # CHECK-NEXT: [[#ADDR + 16]] 00000000 00000000 {{.*}} ## Check that a non-locally-defined symbol is still bound at the correct offset: diff --git a/lld/test/MachO/relocations.s b/lld/test/MachO/relocations.s --- a/lld/test/MachO/relocations.s +++ b/lld/test/MachO/relocations.s @@ -21,7 +21,7 @@ # RUN: llvm-objdump --section=__const --full-contents -d %t | FileCheck %s --check-prefix=NONPCREL # NONPCREL: Contents of section __const: -# NONPCREL-NEXT: 100001000 b0030000 01000000 b0030000 01000000 +# NONPCREL-NEXT: 100001000 d0030000 01000000 d0030000 01000000 .section __TEXT,__text .globl _main, _f