Skip to content

Conversation

@resistor
Copy link
Collaborator

  • [MC] Rework .chericap to support expressions that can fold to sym+const
  • [MC] Add general FK_Cap_ fixup kinds rather than duplicating per target*
  • [MC] Support folding capability offset label difference between fragments
  • [CodeGen] Use non-preemptible symbol for BlockAddress global constants
  • [clang][RISCV] Return ISAInfo from getArchFeatures rather than recomputing
  • [clangd][test] Account for downstream coroutines hack in isKeywords test
  • tests: prefer __has_feature(capabilities) to defined(CHERI)
  • libunwind: prefer __has_feature(capabilities) to defined(CHERI)
  • libcxx: prefer __has_feature(capabilities) to defined(CHERI)
  • Add __has_feature(cheri)
  • Use __has_feature(cheri) in tests
  • Introduce CHERI_HYBRID macro
  • Make CHERI a synonym for CHERI_PURE_CAPABILITY
  • [Sema] Expose diagnoseAmbiguousProvenance for other uses
  • [Sema][CodeGen] Support _builtin_overflow with __intcap
  • Add missing underscore in __has_feature

jrtc27 and others added 16 commits November 12, 2025 13:49
Currently we require the expression to be sym+const, where the constant
is a known parse-time constant. However, that prevents the use of symbol
difference expressions for the constant, something which LLVM does
itself emit and so cannot round-trip through assembly.

Rework the implementation to look more like nromal data directives. At
parse time, any expression can be used, which will then get folded as
normal, giving an error later if it could not be folded into a
relocatable expression. This also requires taking care to preserve the
provenance within such expressions.
…ents

In LLVM 15, these expressions would first try and fold the RHS, which
would succeed, and use that as a constant offset for the symbol. In LLVM
17, RISC-V no longer folds label difference expressions within a section
that has instructions due to relaxation, so the RHS remains unfolded,
but cross-term folding will cancel the same symbol if it appears on both
sides with different signs.

Ideally we'd have SET/ADD/SUB-like capability relocations to support
relaxation, but for now just force the RHS folding to happen again for
capability relocations.

Note that when RVC is enabled branches trigger the same code paths as
linker relaxation, even with -mno-relax.
Just as with landing pads, which are basically a special form of
BlockAddress, we should not use preemptible symbols here.
This is intended to replace __has_feature(capabilities) which is almost
certainly too generic to upstream.  We'll support them side by side for
the long term in our tree, but projects should generally migrate to
__has_feature(cheri) as their need for older compilers passes.
Migrate tests that aren't explicitly about __has_feature(capabilities)
to __has_feature(cheri).
This is meant to replace expressions like:
    __has_feature(capabilities) && !defined(__CHERI_PURE_CAPABILITY__)
or (currently(
    __CHERI__ && !defined(__CHERI_PURE_CAPABILITY__)
WARNING: This is a breaking change for hybrid + standard C/C++ code.

Rationale: We strongly encourage all CHERI consumers to use a
pure-capability ABI whenever possible. Therefore it should be the
easiest thing to type and less preferred options should be longer. The
existing macros date to the earliest compiler support which barely
supported capability types. Before broad adoption of CHERI we should
make the macros be sensible. We're past Stuart Feldman's too many users
of make to change the tabs threshold (12), but few codebases will be
effected, the required changes are simple can be safely performed
without automatic review, and we shouldn't have to live with this aspect
of history forever.

Backwards compatible code transition:

For purecap + standard C/C++ code (no hybrid):
  No change required.

For hybrid + standard C/C++ (with or without purecap):
  defined(__CHERI__) -> __has_feature(capabilities)
or
  defined(__CHERI__) -> defined(__CHERI__) || defined(__CHERI_HYBRID__)

Once the need for compatability with old compilers is passed, further
simplication is possible.

For purecap + standard C/C++ code:
  __CHERI_PURE_CAPABILITY__ -> __CHERI__

For hybrid + standard C/C++ code:
  __has_feature(capabilities) && !defined(__CHERI_PURE_CAPABILITY__) ->
      defined(__CHERI_HYBRID__)
This will be reused for __builtin_<op>_overflow, which gets checked in
SemaChecking.cpp instead and so can't currently use this.
Morello LLVM has downstream support for this, but it's both incomplete
(see https://git.morello-project.org/morello/llvm-project/-/issues/80)
and incorrect with regards to provenance (in that it takes a naive
type-based approach rather than considering the cheri_no_provenance
attribute, meaning it differs from the binary operators in provenance
semantics). This is a from-scratch implementation that aims to not have
the same shortcomings.

Fixes CTSRD-CHERI#720
@resistor resistor merged commit 4dc095a into CHERIoT-Platform:cheriot Nov 12, 2025
14 checks passed
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.

3 participants