[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
This commit is contained in:
Fangrui Song 2024-01-21 18:15:57 -08:00
parent 2e30e31e1e
commit 665f913e45
3 changed files with 8 additions and 59 deletions

View File

@ -553,65 +553,14 @@ static uint8_t getZStartStopVisibility(opt::InputArgList &args) {
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 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
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 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
}
readConfigs(args);
checkZOptions(args);
// The behavior of -v or --version is a bit strange, but this is
// needed for compatibility with GNU linkers.

View File

@ -11,7 +11,7 @@ _start:
# 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 [

View File

@ -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