$OpenBSD: patch-tools_lld_ELF_Driver_cpp,v 1.16 2021/05/13 23:54:25 jca Exp $

- Enable PIE by default.
- XXX retpoline, EM_SPARCV9, ???

Index: tools/lld/ELF/Driver.cpp
--- tools/lld/ELF/Driver.cpp.orig
+++ tools/lld/ELF/Driver.cpp
@@ -439,7 +439,8 @@ static bool isKnownZFlag(StringRef s) {
          s == "nocombreloc" || s == "nocopyreloc" || s == "nodefaultlib" ||
          s == "nodelete" || s == "nodlopen" || s == "noexecstack" ||
          s == "nognustack" || s == "nokeep-text-section-prefix" ||
-         s == "norelro" || s == "noseparate-code" || s == "notext" ||
+         s == "norelro" || s == "noretpolineplt" ||
+         s == "noseparate-code" || s == "notext" ||
          s == "now" || s == "origin" || s == "pac-plt" || s == "rel" ||
          s == "rela" || s == "relro" || s == "retpolineplt" ||
          s == "rodynamic" || s == "shstk" || s == "text" || s == "undefs" ||
@@ -948,7 +949,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);
@@ -986,7 +988,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 =
@@ -1061,7 +1068,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");
@@ -1421,7 +1432,7 @@ void LinkerDriver::inferMachineType() {
 }
 
 // Parse -z max-page-size=<value>. 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);
@@ -1436,7 +1447,7 @@ static uint64_t getMaxPageSize(opt::InputArgList &args
 }
 
 // Parse -z common-page-size=<value>. 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);
@@ -1453,6 +1464,16 @@ static uint64_t getCommonPageSize(opt::InputArgList &a
   return val;
 }
 
+// Parse -z max-page-size=<value>. 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<uint64_t> getImageBase(opt::InputArgList &args) {
   // Because we are using "Config->maxPageSize" here, this function has to be
@@ -2088,6 +2109,11 @@ template <class ELFT> 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);
 
