[lld] [LLD][ELF][AArch64] Add support for SHF_AARCH64_PURECODE ELF section flag (3/3) (PR #125689)
Csanád Hajdú via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 14 02:31:39 PST 2025
https://github.com/Il-Capitano updated https://github.com/llvm/llvm-project/pull/125689
>From 4328cdb38e6c5adfdecc2e686d68aebfd26d6de4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Tue, 4 Feb 2025 14:55:22 +0100
Subject: [PATCH 1/6] [LLD][ELF][AArch64] Add support for SHF_AARCH64_PURECODE
ELF section flag (3/3)
Add support for the new SHF_AARCH64_PURECODE ELF section flag: https://github.com/ARM-software/abi-aa/pull/304
The general implementation follows the existing one for ARM targets. The
output section only has the `SHF_AARCH64_PURECODE` flag set if all input
sections have it set.
---
lld/ELF/Config.h | 1 +
lld/ELF/Driver.cpp | 67 +++++++++++++++++++++++++++--
lld/ELF/OutputSections.cpp | 10 +++--
lld/ELF/ScriptParser.cpp | 1 +
lld/test/ELF/aarch64-execute-only.s | 33 ++++++++++++++
5 files changed, 105 insertions(+), 7 deletions(-)
create mode 100644 lld/test/ELF/aarch64-execute-only.s
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index f132b11b20c63..b5872b85efd3a 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -229,6 +229,7 @@ struct Config {
StringRef zCetReport = "none";
StringRef zPauthReport = "none";
StringRef zGcsReport = "none";
+ StringRef zExecuteOnlyReport = "none";
bool ltoBBAddrMap;
llvm::StringRef ltoBasicBlockSections;
std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 7d14180a49926..90b6dc0c75036 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -461,6 +461,27 @@ static void checkOptions(Ctx &ctx) {
if (ctx.arg.zRetpolineplt && ctx.arg.zForceIbt)
ErrAlways(ctx) << "-z force-ibt may not be used with -z retpolineplt";
+
+ if (ctx.arg.emachine != EM_AARCH64) {
+ if (ctx.arg.zPacPlt)
+ 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")
+ ErrAlways(ctx) << "-z bti-report only supported on AArch64";
+ if (ctx.arg.zPauthReport != "none")
+ ErrAlways(ctx) << "-z pauth-report only supported on AArch64";
+ if (ctx.arg.zGcsReport != "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.zExecuteOnlyReport != "none")
+ ErrAlways(ctx) << "-z execute-only-report only supported on AArch64";
+ }
+
+ if (ctx.arg.emachine != EM_386 && ctx.arg.emachine != EM_X86_64 &&
+ ctx.arg.zCetReport != "none")
+ ErrAlways(ctx) << "-z cet-report only supported on X86 and X86_64";
}
static const char *getReproduceOption(opt::InputArgList &args) {
@@ -1620,10 +1641,12 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
ErrAlways(ctx) << errPrefix << pat.takeError() << ": " << kv.first;
}
- auto reports = {std::make_pair("bti-report", &ctx.arg.zBtiReport),
- std::make_pair("cet-report", &ctx.arg.zCetReport),
- std::make_pair("gcs-report", &ctx.arg.zGcsReport),
- std::make_pair("pauth-report", &ctx.arg.zPauthReport)};
+ auto reports = {
+ std::make_pair("bti-report", &ctx.arg.zBtiReport),
+ std::make_pair("cet-report", &ctx.arg.zCetReport),
+ std::make_pair("gcs-report", &ctx.arg.zGcsReport),
+ std::make_pair("pauth-report", &ctx.arg.zPauthReport),
+ std::make_pair("execute-only-report", &ctx.arg.zExecuteOnlyReport)};
for (opt::Arg *arg : args.filtered(OPT_z)) {
std::pair<StringRef, StringRef> option =
StringRef(arg->getValue()).split('=');
@@ -2907,6 +2930,40 @@ static void readSecurityNotes(Ctx &ctx) {
ctx.arg.andFeatures &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
}
+static void checkExecuteOnly(Ctx &ctx) {
+ if (ctx.arg.emachine != EM_AARCH64)
+ return;
+
+ auto report = [&](StringRef config) -> ELFSyncStream {
+ if (config == "error")
+ return {ctx, DiagLevel::Err};
+ if (config == "warning")
+ return {ctx, DiagLevel::Warn};
+ return {ctx, DiagLevel::None};
+ };
+ auto reportUnless = [&](StringRef config, bool cond) -> ELFSyncStream {
+ if (cond)
+ return {ctx, DiagLevel::None};
+ return report(config);
+ };
+
+ for (ELFFileBase *file : ctx.objectFiles) {
+ for (InputSectionBase *section : file->getSections()) {
+ // Only check for executable sections.
+ if (!(section && section->flags & SHF_EXECINSTR))
+ continue;
+
+ OutputSection *outputSection = section->getOutputSection();
+ if (outputSection && outputSection->name == ".text") {
+ reportUnless(ctx.arg.zExecuteOnlyReport,
+ section->flags & SHF_AARCH64_PURECODE)
+ << file << ": -z execute-only-report: section " << section->name
+ << " does not have SHF_AARCH64_PURECODE flag set";
+ }
+ }
+ }
+}
+
static void initSectionsAndLocalSyms(ELFFileBase *file, bool ignoreComdats) {
switch (file->ekind) {
case ELF32LEKind:
@@ -3272,6 +3329,8 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
ctx.script->addOrphanSections();
}
+ checkExecuteOnly(ctx);
+
{
llvm::TimeTraceScope timeScope("Merge/finalize input sections");
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index a2da5543d5867..c8dc0e5fe0335 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -42,7 +42,8 @@ using namespace lld::elf;
uint32_t OutputSection::getPhdrFlags() const {
uint32_t ret = 0;
- if (ctx.arg.emachine != EM_ARM || !(flags & SHF_ARM_PURECODE))
+ if ((ctx.arg.emachine != EM_ARM || !(flags & SHF_ARM_PURECODE)) &&
+ (ctx.arg.emachine != EM_AARCH64 || !(flags & SHF_AARCH64_PURECODE)))
ret |= PF_R;
if (flags & SHF_WRITE)
ret |= PF_W;
@@ -161,8 +162,11 @@ void OutputSection::commitSection(InputSection *isec) {
}
isec->parent = this;
- uint64_t andMask =
- ctx.arg.emachine == EM_ARM ? (uint64_t)SHF_ARM_PURECODE : 0;
+ uint64_t andMask = 0;
+ if (ctx.arg.emachine == EM_ARM)
+ andMask |= (uint64_t)SHF_ARM_PURECODE;
+ if (ctx.arg.emachine == EM_AARCH64)
+ andMask |= (uint64_t)SHF_AARCH64_PURECODE;
uint64_t orMask = ~andMask;
uint64_t andFlags = (flags & isec->flags) & andMask;
uint64_t orFlags = (flags | isec->flags) & orMask;
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index a10af9565a1d6..671a5ec4deccb 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1411,6 +1411,7 @@ static std::optional<uint64_t> parseFlag(StringRef tok) {
.Case(CASE_ENT(SHF_COMPRESSED))
.Case(CASE_ENT(SHF_EXCLUDE))
.Case(CASE_ENT(SHF_ARM_PURECODE))
+ .Case(CASE_ENT(SHF_AARCH64_PURECODE))
.Default(std::nullopt);
#undef CASE_ENT
}
diff --git a/lld/test/ELF/aarch64-execute-only.s b/lld/test/ELF/aarch64-execute-only.s
new file mode 100644
index 0000000000000..e67bbf05ff2e2
--- /dev/null
+++ b/lld/test/ELF/aarch64-execute-only.s
@@ -0,0 +1,33 @@
+// REQUIRES: aarch64
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readelf -l %t.so | FileCheck --implicit-check-not=LOAD %s
+
+// RUN: echo ".section .foo,\"ax\"; \
+// RUN: ret" > %t.s
+// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %t.s -o %t2.o
+// RUN: ld.lld %t.o %t2.o -o %t.so -shared
+// RUN: llvm-readelf -l %t.so | FileCheck --check-prefix=DIFF --implicit-check-not=LOAD %s
+
+// CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000245 0x000245 R 0x10000
+// CHECK: LOAD 0x000248 0x0000000000010248 0x0000000000010248 0x{{.*}} 0x{{.*}} R E 0x10000
+// CHECK: LOAD 0x00024c 0x000000000002024c 0x000000000002024c 0x{{.*}} 0x{{.*}} E 0x10000
+// CHECK: LOAD 0x000250 0x0000000000030250 0x0000000000030250 0x000070 0x000db0 RW 0x10000
+
+// CHECK: 01 .dynsym .gnu.hash .hash .dynstr
+// CHECK: 02 .text
+// CHECK: 03 .foo
+// CHECK: 04 .dynamic
+
+// DIFF: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x00020d 0x00020d R 0x10000
+// DIFF: LOAD 0x000210 0x0000000000010210 0x0000000000010210 0x00000c 0x00000c R E 0x10000
+// DIFF: LOAD 0x000220 0x0000000000020220 0x0000000000020220 0x000070 0x000de0 RW 0x10000
+
+// DIFF: 01 .dynsym .gnu.hash .hash .dynstr
+// DIFF: 02 .text .foo
+// DIFF: 03 .dynamic
+
+ ret
+ .section .foo,"axy"
+ ret
>From 60ed7aac3d9053dd0863fcde8005b13318971df9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Tue, 4 Feb 2025 16:46:48 +0100
Subject: [PATCH 2/6] Address some review feedback
---
lld/ELF/Driver.cpp | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 90b6dc0c75036..8a8d06992425a 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2934,22 +2934,18 @@ static void checkExecuteOnly(Ctx &ctx) {
if (ctx.arg.emachine != EM_AARCH64)
return;
- auto report = [&](StringRef config) -> ELFSyncStream {
+ auto reportUnless = [&](StringRef config, bool cond) -> ELFSyncStream {
+ if (cond)
+ return {ctx, DiagLevel::None};
if (config == "error")
return {ctx, DiagLevel::Err};
if (config == "warning")
return {ctx, DiagLevel::Warn};
return {ctx, DiagLevel::None};
};
- auto reportUnless = [&](StringRef config, bool cond) -> ELFSyncStream {
- if (cond)
- return {ctx, DiagLevel::None};
- return report(config);
- };
for (ELFFileBase *file : ctx.objectFiles) {
for (InputSectionBase *section : file->getSections()) {
- // Only check for executable sections.
if (!(section && section->flags & SHF_EXECINSTR))
continue;
>From 537dd6d81ba92afee33f0160284ef47a57074027 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Tue, 4 Feb 2025 17:14:23 +0100
Subject: [PATCH 3/6] Add tests for -z execute-only-report
---
.../ELF/aarch64-execute-only-report-error.s | 17 +++++++++++++++++
lld/test/ELF/aarch64-execute-only-report.s | 16 ++++++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 lld/test/ELF/aarch64-execute-only-report-error.s
create mode 100644 lld/test/ELF/aarch64-execute-only-report.s
diff --git a/lld/test/ELF/aarch64-execute-only-report-error.s b/lld/test/ELF/aarch64-execute-only-report-error.s
new file mode 100644
index 0000000000000..3414e34a3a2cc
--- /dev/null
+++ b/lld/test/ELF/aarch64-execute-only-report-error.s
@@ -0,0 +1,17 @@
+// REQUIRES: x86
+
+// RUN: llvm-mc --triple=x86_64-pc-linux --filetype=obj -o %t.o %s
+// RUN: not ld.lld -z execute-only-report=warning %t.o -o /dev/null 2>&1 \
+// RUN: | FileCheck %s
+// RUN: not ld.lld -z execute-only-report=error %t.o -o /dev/null 2>&1 \
+// RUN: | FileCheck %s
+
+// CHECK: error: -z execute-only-report only supported on AArch64
+//
+// RUN: not ld.lld -z execute-only-report=something %t.o -o /dev/null 2>&1 \
+// RUN: | FileCheck --check-prefix=REPORT_INVALID %s
+// REPORT_INVALID: error: -z execute-only-report= parameter something is not recognized
+
+ .globl _start
+_start:
+ ret
diff --git a/lld/test/ELF/aarch64-execute-only-report.s b/lld/test/ELF/aarch64-execute-only-report.s
new file mode 100644
index 0000000000000..9c120997270ad
--- /dev/null
+++ b/lld/test/ELF/aarch64-execute-only-report.s
@@ -0,0 +1,16 @@
+// REQUIRES: aarch64
+
+// RUN: llvm-mc --triple=aarch64-linux-none --filetype=obj -o %t.o %s
+// RUN: ld.lld -z execute-only-report=none --fatal-warnings %t.o -o /dev/null 2>&1
+// RUN: ld.lld -z execute-only-report=warning %t.o -o /dev/null 2>&1 \
+// RUN: | FileCheck --check-prefix=WARNING %s
+// RUN: not ld.lld -z execute-only-report=error %t.o -o /dev/null 2>&1 \
+// RUN: | FileCheck --check-prefix=ERROR %s
+
+// WARNING: warning: {{.*}}.o: -z execute-only-report: section .text does not have SHF_AARCH64_PURECODE flag set
+// ERROR: error: {{.*}}.o: -z execute-only-report: section .text does not have SHF_AARCH64_PURECODE flag set
+
+ .section .text,"ax"
+ .globl _start
+_start:
+ ret
>From 41472adbbdd435eafb9c9a98658db987fb5a544a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Wed, 5 Feb 2025 10:04:48 +0100
Subject: [PATCH 4/6] Address review feedback from MaskRay
---
lld/ELF/Driver.cpp | 16 ++++++++--------
lld/ELF/OutputSections.cpp | 6 ++++--
lld/test/ELF/aarch64-execute-only-report.s | 4 ++--
3 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 8a8d06992425a..4af9a1dadd546 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1644,9 +1644,9 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) {
auto reports = {
std::make_pair("bti-report", &ctx.arg.zBtiReport),
std::make_pair("cet-report", &ctx.arg.zCetReport),
+ std::make_pair("execute-only-report", &ctx.arg.zExecuteOnlyReport),
std::make_pair("gcs-report", &ctx.arg.zGcsReport),
- std::make_pair("pauth-report", &ctx.arg.zPauthReport),
- std::make_pair("execute-only-report", &ctx.arg.zExecuteOnlyReport)};
+ std::make_pair("pauth-report", &ctx.arg.zPauthReport)};
for (opt::Arg *arg : args.filtered(OPT_z)) {
std::pair<StringRef, StringRef> option =
StringRef(arg->getValue()).split('=');
@@ -2945,15 +2945,15 @@ static void checkExecuteOnly(Ctx &ctx) {
};
for (ELFFileBase *file : ctx.objectFiles) {
- for (InputSectionBase *section : file->getSections()) {
- if (!(section && section->flags & SHF_EXECINSTR))
+ for (InputSectionBase *sec : file->getSections()) {
+ if (!(sec && sec->flags & SHF_EXECINSTR))
continue;
- OutputSection *outputSection = section->getOutputSection();
- if (outputSection && outputSection->name == ".text") {
+ OutputSection *osec = sec->getOutputSection();
+ if (osec && osec->name == ".text") {
reportUnless(ctx.arg.zExecuteOnlyReport,
- section->flags & SHF_AARCH64_PURECODE)
- << file << ": -z execute-only-report: section " << section->name
+ sec->flags & SHF_AARCH64_PURECODE)
+ << "-z execute-only-report: " << sec
<< " does not have SHF_AARCH64_PURECODE flag set";
}
}
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index c8dc0e5fe0335..1020dd9f2569e 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -42,8 +42,10 @@ using namespace lld::elf;
uint32_t OutputSection::getPhdrFlags() const {
uint32_t ret = 0;
- if ((ctx.arg.emachine != EM_ARM || !(flags & SHF_ARM_PURECODE)) &&
- (ctx.arg.emachine != EM_AARCH64 || !(flags & SHF_AARCH64_PURECODE)))
+ bool purecode =
+ (ctx.arg.emachine == EM_ARM && (flags & SHF_ARM_PURECODE)) ||
+ (ctx.arg.emachine == EM_AARCH64 && (flags & SHF_AARCH64_PURECODE));
+ if (!purecode)
ret |= PF_R;
if (flags & SHF_WRITE)
ret |= PF_W;
diff --git a/lld/test/ELF/aarch64-execute-only-report.s b/lld/test/ELF/aarch64-execute-only-report.s
index 9c120997270ad..b385ab4a2935d 100644
--- a/lld/test/ELF/aarch64-execute-only-report.s
+++ b/lld/test/ELF/aarch64-execute-only-report.s
@@ -7,8 +7,8 @@
// RUN: not ld.lld -z execute-only-report=error %t.o -o /dev/null 2>&1 \
// RUN: | FileCheck --check-prefix=ERROR %s
-// WARNING: warning: {{.*}}.o: -z execute-only-report: section .text does not have SHF_AARCH64_PURECODE flag set
-// ERROR: error: {{.*}}.o: -z execute-only-report: section .text does not have SHF_AARCH64_PURECODE flag set
+// WARNING: warning: -z execute-only-report: {{.*}}.o:(.text) does not have SHF_AARCH64_PURECODE flag set
+// ERROR: error: -z execute-only-report: {{.*}}.o:(.text) does not have SHF_AARCH64_PURECODE flag set
.section .text,"ax"
.globl _start
>From d12bc148f72b8887266d9f10754c6f2903169b57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Wed, 5 Feb 2025 10:42:10 +0100
Subject: [PATCH 5/6] Move -z execute-only-report checking into Writer.cpp
---
lld/ELF/Driver.cpp | 32 --------------------------------
lld/ELF/Writer.cpp | 30 ++++++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 4af9a1dadd546..0af4d71b2e095 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2930,36 +2930,6 @@ static void readSecurityNotes(Ctx &ctx) {
ctx.arg.andFeatures &= ~GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
}
-static void checkExecuteOnly(Ctx &ctx) {
- if (ctx.arg.emachine != EM_AARCH64)
- return;
-
- auto reportUnless = [&](StringRef config, bool cond) -> ELFSyncStream {
- if (cond)
- return {ctx, DiagLevel::None};
- if (config == "error")
- return {ctx, DiagLevel::Err};
- if (config == "warning")
- return {ctx, DiagLevel::Warn};
- return {ctx, DiagLevel::None};
- };
-
- for (ELFFileBase *file : ctx.objectFiles) {
- for (InputSectionBase *sec : file->getSections()) {
- if (!(sec && sec->flags & SHF_EXECINSTR))
- continue;
-
- OutputSection *osec = sec->getOutputSection();
- if (osec && osec->name == ".text") {
- reportUnless(ctx.arg.zExecuteOnlyReport,
- sec->flags & SHF_AARCH64_PURECODE)
- << "-z execute-only-report: " << sec
- << " does not have SHF_AARCH64_PURECODE flag set";
- }
- }
- }
-}
-
static void initSectionsAndLocalSyms(ELFFileBase *file, bool ignoreComdats) {
switch (file->ekind) {
case ELF32LEKind:
@@ -3325,8 +3295,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
ctx.script->addOrphanSections();
}
- checkExecuteOnly(ctx);
-
{
llvm::TimeTraceScope timeScope("Merge/finalize input sections");
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 858f92c001158..8e1698af518a4 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -64,6 +64,7 @@ template <class ELFT> class Writer {
void sortOrphanSections();
void finalizeSections();
void checkExecuteOnly();
+ void checkExecuteOnlyReport();
void setReservedSymbolSections();
SmallVector<std::unique_ptr<PhdrEntry>, 0> createPhdrs(Partition &part);
@@ -325,6 +326,7 @@ template <class ELFT> void Writer<ELFT>::run() {
// finalizeSections does that.
finalizeSections();
checkExecuteOnly();
+ checkExecuteOnlyReport();
// If --compressed-debug-sections is specified, compress .debug_* sections.
// Do it right now because it changes the size of output sections.
@@ -2179,6 +2181,34 @@ template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
"data and code";
}
+// Check that all input sections of .text have the SHF_AARCH64_PURECODE section
+// flag set.
+template <class ELFT> void Writer<ELFT>::checkExecuteOnlyReport() {
+ if (ctx.arg.emachine != EM_AARCH64 || ctx.arg.zExecuteOnlyReport == "none")
+ return;
+
+ auto reportUnless = [&](StringRef config, bool cond) -> ELFSyncStream {
+ if (cond)
+ return {ctx, DiagLevel::None};
+ if (config == "error")
+ return {ctx, DiagLevel::Err};
+ if (config == "warning")
+ return {ctx, DiagLevel::Warn};
+ return {ctx, DiagLevel::None};
+ };
+
+ SmallVector<InputSection *, 0> storage;
+ for (OutputSection *osec : ctx.outputSections) {
+ if (osec->name != ".text")
+ continue;
+ for (InputSection *sec : getInputSections(*osec, storage))
+ reportUnless(ctx.arg.zExecuteOnlyReport,
+ sec->flags & SHF_AARCH64_PURECODE)
+ << "-z execute-only-report: " << sec
+ << " does not have SHF_AARCH64_PURECODE flag set";
+ }
+}
+
// The linker is expected to define SECNAME_start and SECNAME_end
// symbols for a few sections. This function defines them.
template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
>From 5d894c7e2a5687ab03361b926d3207e205dbe578 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Fri, 14 Feb 2025 11:29:24 +0100
Subject: [PATCH 6/6] Resolve merge conflicts after rebase
---
lld/ELF/Driver.cpp | 23 ++---------------------
1 file changed, 2 insertions(+), 21 deletions(-)
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 0af4d71b2e095..ad69121643a20 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -404,6 +404,8 @@ static void checkOptions(Ctx &ctx) {
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.zExecuteOnlyReport != "none")
+ ErrAlways(ctx) << "-z execute-only-report only supported on AArch64";
}
if (ctx.arg.emachine != EM_PPC64) {
@@ -461,27 +463,6 @@ static void checkOptions(Ctx &ctx) {
if (ctx.arg.zRetpolineplt && ctx.arg.zForceIbt)
ErrAlways(ctx) << "-z force-ibt may not be used with -z retpolineplt";
-
- if (ctx.arg.emachine != EM_AARCH64) {
- if (ctx.arg.zPacPlt)
- 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")
- ErrAlways(ctx) << "-z bti-report only supported on AArch64";
- if (ctx.arg.zPauthReport != "none")
- ErrAlways(ctx) << "-z pauth-report only supported on AArch64";
- if (ctx.arg.zGcsReport != "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.zExecuteOnlyReport != "none")
- ErrAlways(ctx) << "-z execute-only-report only supported on AArch64";
- }
-
- if (ctx.arg.emachine != EM_386 && ctx.arg.emachine != EM_X86_64 &&
- ctx.arg.zCetReport != "none")
- ErrAlways(ctx) << "-z cet-report only supported on X86 and X86_64";
}
static const char *getReproduceOption(opt::InputArgList &args) {
More information about the llvm-commits
mailing list