summaryrefslogtreecommitdiff
path: root/lld/ELF/InputFiles.cpp
diff options
context:
space:
mode:
authorMing-Yi Lai <ming-yi.lai@mediatek.com>2025-06-06 10:32:17 +0800
committerGitHub <noreply@github.com>2025-06-06 10:32:17 +0800
commit1728405b13781f2e2696ed2679c9d05101116fa2 (patch)
tree71acb4eb82ac9c1a3e717387d71a256ce2672496 /lld/ELF/InputFiles.cpp
parent0a1fdbe4df326a237e775c81de37aa9ddbb714e0 (diff)
[LLD][ELF][RISCV][Zicfilp] Handle .note.gnu.property sections for Zicfilp/Zicfiss features (#127193)
+ When all relocatable files contain a `.note.gnu.property` section (with `NT_GNU_PROPERTY_TYPE_0` notes) which contains a `GNU_PROPERTY_RISCV_FEATURE_1_AND` property in which the `GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED`/`GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG`/`GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SS` bit is set: + The output file will contain a `.note.gnu.property` section with the bit set + A `PT_GNU_PROPERTY` program header is created to encompass the `.note.gnu.property` section + If `-z zicfilp-unlabeled-report=[warning|error]`/`-z zicfilp-func-sig-report=[warning|error]`/`-z zicfiss-report=[warning|error]` is specified, the linker will report a warning or error for any relocatable file lacking the feature bit RISC-V Zicfilp/Zicfiss features indicate their adoptions as bits in the `.note.gnu.property` section of ELF files. This patch enables LLD to process the information correctly by parsing, checking and merging the bits from all input ELF files and writing the merged result to the output ELF file. These feature bits are encoded as a mask in each input ELF files and intended to be "and"-ed together to check that all input files support a particular feature. For RISC-V Zicfilp features, there are 2 conflicting bits allocated: `GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED` and `GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG`. They represent the adoption of the forward edge protection of control-flow integrity with the "unlabeled" or "func-sig" policy. Since these 2 policies conflicts with each other, these 2 bits also conflict with each other. This patch adds the `-z zicfilp-unlabeled-report=[none|warning|error]` and `-z zicfilp-func-sig-report=[none|warning|error]` commandline options to make LLD report files that do not have the expected bits toggled on. For RISC-V Zicfiss feature, there's only one bit allocated: `GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS`. This bit indicates that the ELF file supports Zicfiss-based shadow stack. This patch adds the `-z zicfiss-report=[none|warning|error]` commandline option to make LLD report files that do not have the expected bit toggled on. The adoption of the `.note.gnu.property` section for RISC-V targets can be found in the psABI PR <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/417> (`CFI_LP_UNLABELED` and `CFI_SS`) and PR <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/434> (`CFI_LP_FUNC_SIG`).
Diffstat (limited to 'lld/ELF/InputFiles.cpp')
-rw-r--r--lld/ELF/InputFiles.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 12a77736aba7..44e77bf57183 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -968,7 +968,7 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
}
// Read the following info from the .note.gnu.property section and write it to
// the corresponding fields in `ObjFile`:
-// - Feature flags (32 bits) representing x86 or AArch64 features for
+// - Feature flags (32 bits) representing x86, AArch64 or RISC-V features for
// hardware-assisted call flow control;
// - AArch64 PAuth ABI core info (16 bytes).
template <class ELFT>
@@ -977,6 +977,22 @@ static void readGnuProperty(Ctx &ctx, const InputSection &sec,
using Elf_Nhdr = typename ELFT::Nhdr;
using Elf_Note = typename ELFT::Note;
+ uint32_t featureAndType;
+ switch (ctx.arg.emachine) {
+ case EM_386:
+ case EM_X86_64:
+ featureAndType = GNU_PROPERTY_X86_FEATURE_1_AND;
+ break;
+ case EM_AARCH64:
+ featureAndType = GNU_PROPERTY_AARCH64_FEATURE_1_AND;
+ break;
+ case EM_RISCV:
+ featureAndType = GNU_PROPERTY_RISCV_FEATURE_1_AND;
+ break;
+ default:
+ return;
+ }
+
ArrayRef<uint8_t> data = sec.content();
auto err = [&](const uint8_t *place) -> ELFSyncStream {
auto diag = Err(ctx);
@@ -997,10 +1013,6 @@ static void readGnuProperty(Ctx &ctx, const InputSection &sec,
continue;
}
- uint32_t featureAndType = ctx.arg.emachine == EM_AARCH64
- ? GNU_PROPERTY_AARCH64_FEATURE_1_AND
- : GNU_PROPERTY_X86_FEATURE_1_AND;
-
// Read a body of a NOTE record, which consists of type-length-value fields.
ArrayRef<uint8_t> desc = note.getDesc(sec.addralign);
const uint8_t *base = sec.content().data();
@@ -1064,9 +1076,9 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
}
// Object files that use processor features such as Intel Control-Flow
- // Enforcement (CET) or AArch64 Branch Target Identification BTI, use a
- // .note.gnu.property section containing a bitfield of feature bits like the
- // GNU_PROPERTY_X86_FEATURE_1_IBT flag. Read a bitmap containing the flag.
+ // Enforcement (CET), AArch64 Branch Target Identification BTI or RISC-V
+ // Zicfilp/Zicfiss extensions, use a .note.gnu.property section containing
+ // a bitfield of feature bits like the GNU_PROPERTY_X86_FEATURE_1_IBT flag.
//
// Since we merge bitmaps from multiple object files to create a new
// .note.gnu.property containing a single AND'ed bitmap, we discard an input