Skip to content

Conversation

@kito-cheng
Copy link
Collaborator

We introduce .note.gnu.property section to store infomations that linker or runtime system may use, and we define two bit for landing pad and shadow stack.

Those two bit will checked by loader - and use that info to enable the landing pad checking and/or shadow stack feature.

@kito-cheng
Copy link
Collaborator Author

cc @ved-rivos

@rui314
Copy link
Collaborator

rui314 commented Jan 5, 2024

My concern about this proposal is that, with the 32-bit bitmap, we can't have more than 32 extensions. That might be OK for x86-64 that is controlled only by Intel and AMD, but it is likely that we would have way more extensions than x86-64 for RISC-V. I'm not sure even 64 bits is enough. Maybe we should avoid the bitmap completely?

@kito-cheng
Copy link
Collaborator Author

@rui314
GNU property is kind of key-value structure, key is 32 bit integer, and we have 536,870,912 can use for the key per the definition of GNU_PROPERTY_LOPROC and GNU_PROPERTY_HIPROC.

/* Processor-specific semantics, lo */
#define GNU_PROPERTY_LOPROC                     0xc0000000
/* Processor-specific semantics, hi */
#define GNU_PROPERTY_HIPROC                     0xdfffffff

So we have 536,870,912 * 32 rather than only 32-bit bitmap :)

@rui314
Copy link
Collaborator

rui314 commented Jan 5, 2024

@kito-cheng Ah, you are right. Even though I've implemented the feature to the linker, I forgot the actual on-file format. Thank you for pointing that out!

@MaskRay
Copy link
Collaborator

MaskRay commented Jan 8, 2024

Thanks for the proposal. On Arm/x86, if all relocatable files contain .note.gnu.property (which contains NT_GNU_PROPERTY_TYPE_0 notes) with the GNU_PROPERTY_X86_FEATURE_1_IBT bit set, the linker will mark the output as compatible with the feature. Assembly files often lack .note.gnu.property, making the CFI features difficult to deploy...

That said, this is most viable proposal. Defining GNU program property looks good for x86/Arm parity.

You may want to mention that n_type is NT_GNU_PROPERTY_TYPE_0.

Add property for CFI extension

"property" is a heavily overloaded term. Consider "program property" or just use .note.gnu.property to be more specific.

@sorear
Copy link
Collaborator

sorear commented Feb 18, 2024

@kito-cheng Isn't the usefulness of this degraded by the fact that we only allocate 1 32-bit property instead of the ~ 3 * 32768 allocated on x86? When we start to use the next bitmap, an old linker won't be able to propagate it, and so on.

kito-cheng added a commit that referenced this pull request Feb 26, 2024
We introduce .note.gnu.property section to store infomations that linker
or runtime system may use, and we define 4 program property classes to
specifying the merge semantics, it's used for forward compatibility in linker
implementations, allowing linker can correctly handle program property types
even if they are not recognized.

We don't define any program property within this PR, it would be
separate PR like #417
@kito-cheng kito-cheng mentioned this pull request Feb 26, 2024
@kito-cheng
Copy link
Collaborator Author

Split base program property part into #428

kito-cheng added a commit that referenced this pull request Feb 26, 2024
We introduce .note.gnu.property section to store infomations that linker
or runtime system may use, and we define 4 program property classes to
specifying the merge semantics, it's used for forward compatibility in linker
implementations, allowing linker can correctly handle program property types
even if they are not recognized.

We don't define any program property within this PR, it would be
separate PR like #417
@kito-cheng kito-cheng changed the base branch from master to prog-prop February 26, 2024 09:56
@kito-cheng
Copy link
Collaborator Author

ChangeLog:

  • Based on Add program property #428
  • Rename GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP to GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE
  • Rename GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS to GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS
  • Explicitly specify the labeling scheme in GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE, label will always set to 1.

@kito-cheng kito-cheng changed the title Add program property for CFI extension Add program property and PLT for CFI extension Feb 26, 2024
@kito-cheng
Copy link
Collaborator Author

Changes:

  • Explicitly specify the labeling scheme in GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE, label will always set to 0.
  • Add simple landing pad PLT.
  • Add DT_RISCV_SIMPLE_LP_PLT to mark this object use simple landing pad PLT.

mylai-mtk added a commit to llvm/llvm-project that referenced this pull request Jun 6, 2025
…filp/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
<riscv-non-isa/riscv-elf-psabi-doc#417>
(`CFI_LP_UNLABELED` and `CFI_SS`) and PR
<riscv-non-isa/riscv-elf-psabi-doc#434>
(`CFI_LP_FUNC_SIG`).
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Jun 6, 2025
…ons 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
<riscv-non-isa/riscv-elf-psabi-doc#417>
(`CFI_LP_UNLABELED` and `CFI_SS`) and PR
<riscv-non-isa/riscv-elf-psabi-doc#434>
(`CFI_LP_FUNC_SIG`).
@kito-cheng
Copy link
Collaborator Author

ping, any further comment for this?

@kito-cheng
Copy link
Collaborator Author

Update on binutils part: Nelson is approved, but waiting glibc patch send out before merge.

saagarjha pushed a commit to ahjragaas/binutils-gdb that referenced this pull request Jun 24, 2025
…V_FEATURE_1_CFI_LP_UNLABELED

This patch adds two new GNU properties for RISC-V:
GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS and GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED.

We only add readelf and define the properties in this patch.

Ref: riscv-non-isa/riscv-elf-psabi-doc#417
saagarjha pushed a commit to ahjragaas/binutils-gdb that referenced this pull request Jun 24, 2025
This patch adds support for generating unlabeled landing pad PLT entries
for the RISC-V architecture. Unlabeled landing pad will place a LPAD
instruction at the PLT entry and PLT header, also PLT header will have
few changes due to the offset is different from the original one.

Ref: riscv-non-isa/riscv-elf-psabi-doc#417
lgaver2 pushed a commit to fpetrot/riscv-binutils that referenced this pull request Jun 30, 2025
…V_FEATURE_1_CFI_LP_UNLABELED

This patch adds two new GNU properties for RISC-V:
GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS and GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED.

We only add readelf and define the properties in this patch.

Ref: riscv-non-isa/riscv-elf-psabi-doc#417
lgaver2 pushed a commit to fpetrot/riscv-binutils that referenced this pull request Jun 30, 2025
This patch adds support for generating unlabeled landing pad PLT entries
for the RISC-V architecture. Unlabeled landing pad will place a LPAD
instruction at the PLT entry and PLT header, also PLT header will have
few changes due to the offset is different from the original one.

Ref: riscv-non-isa/riscv-elf-psabi-doc#417
Define two bit for landing pad and shadow stack, and we plan to defined
third bit `GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_COMPLEX` for complex
labeling scheme.
Changes:
- Rename `GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_SIMPLE` to `GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED`
- Fix wrong offset in the first PLT stubs for the simple landing pad PLT.
- Use sw guarded call in PLT entry and PLT header.
- Also remove `lpad 0` in the entry of PLT header.
- Forbid lazy binding at psABI spec level.

This change could unify the PLT entry and PLT header with function
signature based PLT.
Comment on lines -743 to +765
sub t1, t1, t3 # shifted .got.plt offset + hdr size + 12
sub t1, t1, t3 # shifted .got.plt offset + hdr size + 12

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extraneous space.

function pointer from the GOT. On the first call to a function, the
entry redirects to the first PLT entry which calls `_dl_runtime_resolve`
and fills in the GOT entry for subsequent calls to the function:
And occupies two 16 byte entries for the unlabeled landing pad PLT style:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we don't need to distinguish between unlabeled and func-sig landing pad PLT styles anymore.

executable sections are built to be compatible with the landing pad mechanism
provided by the Zicfilp extension in the unlabeled scheme: Executables and
shared libraries with this bit set are required to generate PLTs in the
unlabeled landing pad PLT style, and all of the labels of lpad instructions are

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unlabeled

Comment on lines +1562 to +1566
* Static linkers when generating PLT entries.

* Other executables and shared libraries via calls through PLT entries or
function pointers.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we force LD_BIND_NOW with LPAD PLTs, I guess these won't count as "indirect branches" anymore? Perhaps this two items should be replaced as a note that explains their exemption from this list.

each bit indicating a feature that the object file is compatible with. The
linker should perform a bitwise AND operation when merging different objects.

The value of `GNU_PROPERTY_RISCV_FEATURE_1_AND` is defined in <<rv-prog-prop-type>>.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link does not make sense to me here. We are here in the section that defines the values in the lines below.

|===
| Bit | Bit Name
| 0 | GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
| 1 | GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS
Copy link

@xypron xypron Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need a bit for unlabeled landing pads?
I would have expected a bit for "have landing pads" and a property for the labeling scheme which may be unlabeled or labeled according to a specific algorithm.

Copy link

@xypron xypron Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For easy migration of distros we will probably need at least:

  • no landing pads
  • landing pads are unlabeled, callers do not set x7
  • landing pads are unlabeled, but callers set x7 according to labeling scheme
  • both landing pads and callers abide to labeling scheme

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants