[ELF] Reimplement unknown -z options using the isClaimed bit

Maintaining the long list of known -z options
(https://reviews.llvm.org/D48621) turns out to be cumbersome. Go the
D48433 route instead.

max-page-size/common-page-size are claimed when `target` is available.

Inspired by: https://reviews.llvm.org/D48433

GitOrigin-RevId: 665f913e4509e3e4f531aa4a4ebe92ec2ea5c23f
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 157f6ee..b988f43 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -553,65 +553,14 @@
   return ret;
 }
 
-constexpr const char *knownZFlags[] = {
-    "combreloc",
-    "copyreloc",
-    "defs",
-    "execstack",
-    "force-bti",
-    "force-ibt",
-    "global",
-    "hazardplt",
-    "ifunc-noplt",
-    "initfirst",
-    "interpose",
-    "keep-text-section-prefix",
-    "lazy",
-    "muldefs",
-    "nocombreloc",
-    "nocopyreloc",
-    "nodefaultlib",
-    "nodelete",
-    "nodlopen",
-    "noexecstack",
-    "nognustack",
-    "nokeep-text-section-prefix",
-    "nopack-relative-relocs",
-    "norelro",
-    "noseparate-code",
-    "nostart-stop-gc",
-    "notext",
-    "now",
-    "origin",
-    "pac-plt",
-    "pack-relative-relocs",
-    "rel",
-    "rela",
-    "relro",
-    "retpolineplt",
-    "rodynamic",
-    "separate-code",
-    "separate-loadable-segments",
-    "shstk",
-    "start-stop-gc",
-    "text",
-    "undefs",
-    "wxneeded",
-};
-
-static bool isKnownZFlag(StringRef s) {
-  return llvm::is_contained(knownZFlags, s) ||
-         s.starts_with("common-page-size=") || s.starts_with("bti-report=") ||
-         s.starts_with("cet-report=") ||
-         s.starts_with("dead-reloc-in-nonalloc=") ||
-         s.starts_with("max-page-size=") || s.starts_with("stack-size=") ||
-         s.starts_with("start-stop-visibility=");
-}
-
 // Report a warning for an unknown -z option.
 static void checkZOptions(opt::InputArgList &args) {
+  // This function is called before getTarget(), when certain options are not
+  // initialized yet. Claim them here.
+  args::getZOptionValue(args, OPT_z, "max-page-size", 0);
+  args::getZOptionValue(args, OPT_z, "common-page-size", 0);
   for (auto *arg : args.filtered(OPT_z))
-    if (!isKnownZFlag(arg->getValue()))
+    if (!arg->isClaimed())
       warn("unknown -z value: " + StringRef(arg->getValue()));
 }
 
@@ -629,7 +578,6 @@
       args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false) &&
       !args.hasArg(OPT_no_warnings);
   errorHandler().suppressWarnings = args.hasArg(OPT_no_warnings);
-  checkZOptions(args);
 
   // Handle -help
   if (args.hasArg(OPT_help)) {
@@ -672,6 +620,7 @@
   }
 
   readConfigs(args);
+  checkZOptions(args);
 
   // The behavior of -v or --version is a bit strange, but this is
   // needed for compatibility with GNU linkers.
diff --git a/test/ELF/common-page.s b/test/ELF/common-page.s
index a11b699..fd6564c 100644
--- a/test/ELF/common-page.s
+++ b/test/ELF/common-page.s
@@ -11,7 +11,7 @@
 # of 4k. If the last loadable segment is executable then lld aligns the next
 # section using the common page size.
 
-# RUN: ld.lld -z max-page-size=0x10000 -z common-page-size=0x1000 %t -o %t2
+# RUN: ld.lld -z max-page-size=0x10000 -z common-page-size=0x1000 %t -o %t2 2>&1 | count 0
 # RUN: llvm-readobj --sections -l %t2 | FileCheck --check-prefix=CHECK-MAX %s
 
 # CHECK-MAX:      Sections [
diff --git a/test/ELF/driver.test b/test/ELF/driver.test
index cb43998..260be8e 100644
--- a/test/ELF/driver.test
+++ b/test/ELF/driver.test
@@ -65,7 +65,7 @@
 # ERR10-FATAL: error: unknown -z value: foo
 
 # RUN: not ld.lld %t -z max-page-size 2>&1 | FileCheck -check-prefix=ERR11 %s
-# ERR11: unknown -z value: max-page-size
+# ERR11: error: invalid max-page-size:
 
 ## Attempt to use -r and --export-dynamic together
 # RUN: not ld.lld -r -export-dynamic %t -o /dev/null 2>&1 | FileCheck -check-prefix=ERR12 %s