diff options
| author | Ming-Yi Lai <ming-yi.lai@mediatek.com> | 2025-06-06 10:32:17 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-06 10:32:17 +0800 |
| commit | 1728405b13781f2e2696ed2679c9d05101116fa2 (patch) | |
| tree | 71acb4eb82ac9c1a3e717387d71a256ce2672496 /lld/ELF/InputFiles.cpp | |
| parent | 0a1fdbe4df326a237e775c81de37aa9ddbb714e0 (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.cpp | 28 |
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 |
