- enable retpoline by default - enable PIE by default. - arm64 and riscv64 can now do --execute-only by default - enable --exec-only as default on AMD64 - Make --execute-only the default on powerpc64. - Permit the --exec-only option on i386 also. - make --execute-only the default on powerpc - default sparc64 ld.lld to --execute-only - switch mips64 ld.lld to execute-only - Implement support for PT_OPENBSD_NOBTCFI in lld(1). This can be set using the -z nobtcfi option. Index: lld/ELF/Driver.cpp --- lld/ELF/Driver.cpp.orig +++ lld/ELF/Driver.cpp @@ -358,8 +358,19 @@ static void checkOptions() { } if (config->executeOnly) { - if (config->emachine != EM_AARCH64) - error("-execute-only is only supported on AArch64 targets"); + switch (config->emachine) { + case EM_386: + case EM_AARCH64: + case EM_MIPS: + case EM_PPC: + case EM_PPC64: + case EM_RISCV: + case EM_SPARCV9: + case EM_X86_64: + break; + default: + error("-execute-only is not supported on this target"); + } if (config->singleRoRx && !script->hasSectionsCommand) error("-execute-only and -no-rosegment cannot be used together"); @@ -451,10 +462,12 @@ static bool isKnownZFlag(StringRef s) { s == "initfirst" || s == "interpose" || s == "keep-text-section-prefix" || s == "lazy" || s == "muldefs" || s == "separate-code" || s == "separate-loadable-segments" || - s == "start-stop-gc" || s == "nocombreloc" || s == "nocopyreloc" || + s == "start-stop-gc" || s == "nobtcfi" || + s == "nocombreloc" || s == "nocopyreloc" || s == "nodefaultlib" || s == "nodelete" || s == "nodlopen" || s == "noexecstack" || s == "nognustack" || s == "nokeep-text-section-prefix" || s == "norelro" || + s == "noretpolineplt" || s == "noseparate-code" || s == "nostart-stop-gc" || s == "notext" || s == "now" || s == "origin" || s == "pac-plt" || s == "rel" || s == "rela" || s == "relro" || s == "retpolineplt" || @@ -1045,8 +1058,6 @@ static void readConfigs(opt::InputArgList &args) { errorHandler().errorHandlingScript = args.getLastArgValue(OPT_error_handling_script); - config->executeOnly = - args.hasFlag(OPT_execute_only, OPT_no_execute_only, false); config->exportDynamic = args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false); config->filterList = args::getStrings(args, OPT_filter); @@ -1064,7 +1075,8 @@ static void readConfigs(opt::InputArgList &args) { config->ignoreDataAddressEquality = args.hasArg(OPT_ignore_data_address_equality); config->ignoreFunctionAddressEquality = - args.hasArg(OPT_ignore_function_address_equality); + args.hasFlag(OPT_ignore_function_address_equality, + OPT_no_ignore_function_address_equality, true); config->init = args.getLastArgValue(OPT_init, "_init"); config->ltoAAPipeline = args.getLastArgValue(OPT_lto_aa_pipeline); config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate); @@ -1118,7 +1130,12 @@ static void readConfigs(opt::InputArgList &args) { config->optimize = args::getInteger(args, OPT_O, 1); config->orphanHandling = getOrphanHandling(args); config->outputFile = args.getLastArgValue(OPT_o); +#ifdef __OpenBSD__ + config->pie = args.hasFlag(OPT_pie, OPT_no_pie, + !args.hasArg(OPT_shared) && !args.hasArg(OPT_relocatable)); +#else config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false); +#endif config->printIcfSections = args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false); config->printGcSections = @@ -1181,6 +1198,7 @@ static void readConfigs(opt::InputArgList &args) { config->zInterpose = hasZOption(args, "interpose"); config->zKeepTextSectionPrefix = getZFlag( args, "keep-text-section-prefix", "nokeep-text-section-prefix", false); + config->zNoBtCfi = hasZOption(args, "nobtcfi"); config->zNodefaultlib = hasZOption(args, "nodefaultlib"); config->zNodelete = hasZOption(args, "nodelete"); config->zNodlopen = hasZOption(args, "nodlopen"); @@ -1188,7 +1206,11 @@ static void readConfigs(opt::InputArgList &args) { config->zOrigin = hasZOption(args, "origin"); config->zPacPlt = hasZOption(args, "pac-plt"); config->zRelro = getZFlag(args, "relro", "norelro", true); - config->zRetpolineplt = hasZOption(args, "retpolineplt"); +#ifndef __OpenBSD__ + config->zRetpolineplt = getZFlag(args, "retpolineplt", "noretpolineplt", false); +#else + config->zRetpolineplt = getZFlag(args, "retpolineplt", "noretpolineplt", true); +#endif config->zRodynamic = hasZOption(args, "rodynamic"); config->zSeparate = getZSeparate(args); config->zShstk = hasZOption(args, "shstk"); @@ -1459,6 +1481,23 @@ static void setConfigs(opt::InputArgList &args) { args.hasFlag(OPT_toc_optimize, OPT_no_toc_optimize, m == EM_PPC64); config->pcRelOptimize = args.hasFlag(OPT_pcrel_optimize, OPT_no_pcrel_optimize, m == EM_PPC64); + + config->executeOnly = false; +#ifdef __OpenBSD__ + switch (m) { + case EM_AARCH64: + case EM_MIPS: + case EM_PPC: + case EM_PPC64: + case EM_RISCV: + case EM_SPARCV9: + case EM_X86_64: + config->executeOnly = true; + break; + } +#endif + config->executeOnly = + args.hasFlag(OPT_execute_only, OPT_no_execute_only, config->executeOnly); } // Returns a value of "-format" option. @@ -1596,7 +1635,7 @@ void LinkerDriver::inferMachineType() { } // Parse -z max-page-size=. The default value is defined by -// each target. +// each target. Is set to 1 if given nmagic or omagic. static uint64_t getMaxPageSize(opt::InputArgList &args) { uint64_t val = args::getZOptionValue(args, OPT_z, "max-page-size", target->defaultMaxPageSize); @@ -1611,7 +1650,7 @@ static uint64_t getMaxPageSize(opt::InputArgList &args } // Parse -z common-page-size=. The default value is defined by -// each target. +// each target. Is set to 1 if given nmagic or omagic. static uint64_t getCommonPageSize(opt::InputArgList &args) { uint64_t val = args::getZOptionValue(args, OPT_z, "common-page-size", target->defaultCommonPageSize); @@ -1628,6 +1667,16 @@ static uint64_t getCommonPageSize(opt::InputArgList &a return val; } +// Parse -z max-page-size=. The default value is defined by +// each target. +static uint64_t getRealMaxPageSize(opt::InputArgList &args) { + uint64_t val = args::getZOptionValue(args, OPT_z, "max-page-size", + target->defaultMaxPageSize); + if (!isPowerOf2_64(val)) + error("max-page-size: value isn't a power of 2"); + return val; +} + // Parses -image-base option. static Optional getImageBase(opt::InputArgList &args) { // Because we are using "Config->maxPageSize" here, this function has to be @@ -2414,6 +2463,11 @@ template void LinkerDriver::link(opt::Inp // optimizations such as DATA_SEGMENT_ALIGN in linker scripts. LLD's use of it // is limited to writing trap instructions on the last executable segment. config->commonPageSize = getCommonPageSize(args); + // textAlignPageSize is the alignment page size to use when aligning PT_LOAD + // sections. This is the same as maxPageSize except under -omagic, where data + // sections are non-aligned (maxPageSize set to 1) but text sections are aligned + // to the target page size. + config->textAlignPageSize = config->omagic ? getRealMaxPageSize(args) : config->maxPageSize; config->imageBase = getImageBase(args);