Skip to content

[ELF] Introduce ReportPolicy to handle -z *-report options. NFC #130715

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions lld/ELF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ enum LtoKind : uint8_t {UnifiedThin, UnifiedRegular, Default};
// For -z gcs=
enum class GcsPolicy { Implicit, Never, Always };

// For some options that resemble -z bti-report={none,warning,error}
enum class ReportPolicy { None, Warning, Error };

struct SymbolVersion {
llvm::StringRef name;
bool isExternCpp;
Expand Down Expand Up @@ -225,11 +228,11 @@ struct Config {
llvm::StringRef whyExtract;
llvm::StringRef cmseInputLib;
llvm::StringRef cmseOutputLib;
StringRef zBtiReport = "none";
StringRef zCetReport = "none";
StringRef zPauthReport = "none";
StringRef zGcsReport = "none";
StringRef zExecuteOnlyReport = "none";
ReportPolicy zBtiReport = ReportPolicy::None;
ReportPolicy zCetReport = ReportPolicy::None;
ReportPolicy zPauthReport = ReportPolicy::None;
ReportPolicy zGcsReport = ReportPolicy::None;
ReportPolicy zExecuteOnlyReport = ReportPolicy::None;
bool ltoBBAddrMap;
llvm::StringRef ltoBasicBlockSections;
std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
Expand Down Expand Up @@ -748,6 +751,14 @@ ELFSyncStream InternalErr(Ctx &ctx, const uint8_t *buf);

#define CHECK2(E, S) lld::check2((E), [&] { return toStr(ctx, S); })

inline DiagLevel toDiagLevel(ReportPolicy policy) {
if (policy == ReportPolicy::Error)
return DiagLevel::Err;
else if (policy == ReportPolicy::Warning)
return DiagLevel::Warn;
return DiagLevel::None;
}

} // namespace lld::elf

#endif
40 changes: 18 additions & 22 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,18 +396,18 @@ static void checkOptions(Ctx &ctx) {
ErrAlways(ctx) << "-z pac-plt only supported on AArch64";
if (ctx.arg.zForceBti)
ErrAlways(ctx) << "-z force-bti only supported on AArch64";
if (ctx.arg.zBtiReport != "none")
if (ctx.arg.zBtiReport != ReportPolicy::None)
ErrAlways(ctx) << "-z bti-report only supported on AArch64";
if (ctx.arg.zPauthReport != "none")
if (ctx.arg.zPauthReport != ReportPolicy::None)
ErrAlways(ctx) << "-z pauth-report only supported on AArch64";
if (ctx.arg.zGcsReport != "none")
if (ctx.arg.zGcsReport != ReportPolicy::None)
ErrAlways(ctx) << "-z gcs-report only supported on AArch64";
if (ctx.arg.zGcs != GcsPolicy::Implicit)
ErrAlways(ctx) << "-z gcs only supported on AArch64";
}

if (ctx.arg.emachine != EM_AARCH64 && ctx.arg.emachine != EM_ARM &&
ctx.arg.zExecuteOnlyReport != "none")
ctx.arg.zExecuteOnlyReport != ReportPolicy::None)
ErrAlways(ctx)
<< "-z execute-only-report only supported on AArch64 and ARM";

Expand All @@ -423,7 +423,7 @@ static void checkOptions(Ctx &ctx) {
ErrAlways(ctx) << "--relax-gp is only supported on RISC-V targets";

if (ctx.arg.emachine != EM_386 && ctx.arg.emachine != EM_X86_64 &&
ctx.arg.zCetReport != "none")
ctx.arg.zCetReport != ReportPolicy::None)
ErrAlways(ctx) << "-z cet-report only supported on X86 and X86_64";

if (ctx.arg.pie && ctx.arg.shared)
Expand Down Expand Up @@ -1272,11 +1272,6 @@ static void parseClangOption(Ctx &ctx, StringRef opt, const Twine &msg) {
ErrAlways(ctx) << msg << ": " << StringRef(err).trim();
}

// Checks the parameter of the bti-report and cet-report options.
static bool isValidReportString(StringRef arg) {
return arg == "none" || arg == "warning" || arg == "error";
}

// Process a remap pattern 'from-glob=to-file'.
static bool remapInputs(Ctx &ctx, StringRef line, const Twine &location) {
SmallVector<StringRef, 0> fields;
Expand Down Expand Up @@ -1638,12 +1633,17 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
if (option.first != reportArg.first)
continue;
arg->claim();
if (!isValidReportString(option.second)) {
if (option.second == "none")
*reportArg.second = ReportPolicy::None;
else if (option.second == "warning")
*reportArg.second = ReportPolicy::Warning;
else if (option.second == "error")
*reportArg.second = ReportPolicy::Error;
else {
ErrAlways(ctx) << "unknown -z " << reportArg.first
<< "= value: " << option.second;
continue;
}
*reportArg.second = option.second;
}
}

Expand Down Expand Up @@ -2820,17 +2820,13 @@ static void readSecurityNotes(Ctx &ctx) {
bool hasValidPauthAbiCoreInfo = llvm::any_of(
ctx.aarch64PauthAbiCoreInfo, [](uint8_t c) { return c != 0; });

auto report = [&](StringRef config) -> ELFSyncStream {
if (config == "error")
return {ctx, DiagLevel::Err};
else if (config == "warning")
return {ctx, DiagLevel::Warn};
return {ctx, DiagLevel::None};
auto report = [&](ReportPolicy policy) -> ELFSyncStream {
return {ctx, toDiagLevel(policy)};
};
auto reportUnless = [&](StringRef config, bool cond) -> ELFSyncStream {
auto reportUnless = [&](ReportPolicy policy, bool cond) -> ELFSyncStream {
if (cond)
return {ctx, DiagLevel::None};
return report(config);
return {ctx, toDiagLevel(policy)};
};
for (ELFFileBase *f : ctx.objectFiles) {
uint32_t features = f->andFeatures;
Expand Down Expand Up @@ -2860,13 +2856,13 @@ static void readSecurityNotes(Ctx &ctx) {

if (ctx.arg.zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
if (ctx.arg.zBtiReport == "none")
if (ctx.arg.zBtiReport == ReportPolicy::None)
Warn(ctx) << f
<< ": -z force-bti: file does not have "
"GNU_PROPERTY_AARCH64_FEATURE_1_BTI property";
} else if (ctx.arg.zForceIbt &&
!(features & GNU_PROPERTY_X86_FEATURE_1_IBT)) {
if (ctx.arg.zCetReport == "none")
if (ctx.arg.zCetReport == ReportPolicy::None)
Warn(ctx) << f
<< ": -z force-ibt: file does not have "
"GNU_PROPERTY_X86_FEATURE_1_IBT property";
Expand Down
8 changes: 2 additions & 6 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2181,17 +2181,13 @@ template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
// Check which input sections of RX output sections don't have the
// SHF_AARCH64_PURECODE or SHF_ARM_PURECODE flag set.
template <class ELFT> void Writer<ELFT>::checkExecuteOnlyReport() {
if (ctx.arg.zExecuteOnlyReport == "none")
if (ctx.arg.zExecuteOnlyReport == ReportPolicy::None)
return;

auto reportUnless = [&](bool cond) -> ELFSyncStream {
if (cond)
return {ctx, DiagLevel::None};
if (ctx.arg.zExecuteOnlyReport == "error")
return {ctx, DiagLevel::Err};
if (ctx.arg.zExecuteOnlyReport == "warning")
return {ctx, DiagLevel::Warn};
return {ctx, DiagLevel::None};
return {ctx, toDiagLevel(ctx.arg.zExecuteOnlyReport)};
};

uint64_t purecodeFlag =
Expand Down