Skip to content

Conversation

delcypher
Copy link

@delcypher delcypher commented Oct 17, 2025

This patch implements a "soft trap mode" for -fbounds-safety where
hard traps are replaced with calls to a runtime function. It is assumed
the runtime function can return so code is generated so that execution
can proceed past the "soft trap" (i.e. as if the bounds check passed
even though it didn't). It is expected implementations of the runtime
function log the issue in some way.

The motivation behind this is to provide a smoother path to adopting
-fbounds-safety in existing codebases. Using soft trap mode with an
appropriate runtime allows:

  • Improved stability of the program because bounds safety violations
    are no longer fatal because execution continues.
  • The ability to collect all the soft traps that occurred to get an
    overview of how many issues there are.

Note this patch does not implement the actual runtime itself. This will
be done in a separate patch.

This patch introduces the -fbounds-safety-soft-traps= driver and CC1
flag. This allows enabling the soft trap compilation mode. It currently
has two different modes which offer different trade-offs.

  • call_with_str - This generates calls that pass a constant C string
    describing the reason for trapping. This greatly simplifies logging
    but at the cost of increasing code size because a global string needs
    to be emitted for every "trap reason".
  • call_with_code - This generates calls that pass an integer constant
    to identify the reason for trapping. This produces better codesize
    than call_with_str but the reason for trapping is much less
    descriptive. Currently the integer constant is hard coded to zero
    because we don't currently have a good stable integer representation
    of trap reasons. This will be fixed in rdar://162824128.

We may want to add a third soft_trap_instruction option one day that
emits a special trap instruction that uses its immediate to identify
itself as a trap that should be treated as soft by program host (e.g.
the kernel). Implementing that is out-of-scope for this patch because
we'd need a new LLVM IR intrinsic and backend support.

This patch also introduces a new -fbounds-safety-soft-trap-function=
CC1 flag. It is not intended users use this flag. This flag is for Clang
driver to communicate to CC1 what the function name should be. Currently
the driver doesn't pass anything so CC1 picks these function names:

  • __bounds_safety_soft_trap_s for call_with_str
  • __bounds_safety_soft_trap_c for call_with_code

As implementations of Bounds Safety soft trap runtimes are brought up
the driver logic will need add support for them. We will likely need
a new driver flag to control which implementation to use (if any).

Note this implementation deliberately doesn't re-use -ftrap-function
and -ftrap-function-returns so that these features can be used
independently. In particular it allows using -fbounds-safety in soft
trap mode with trapping UBSan in any mode.

Note this implementation continues to deliberately use "trap reasons".
This is the compiler feature where artificial inline frames are added to
debug info on traps to describe the reason for trapping. This means the
string representation for reason from trapping is still available in the
call_with_code case provided debug information is available. This can
be seen the in the LLDB tests added. This does mean that technically
there is some redundancy here (trap reasons passed as arguments and in
the debug info) but this is intentional because it means in the
call_with_str case without debug info can still do a good job of
logging problems.

rdar://158088757

@delcypher delcypher self-assigned this Oct 17, 2025
@delcypher delcypher added the clang:bounds-safety Issue relating to the experimental -fbounds-safety feature in Clang label Oct 17, 2025
@delcypher
Copy link
Author

@swift-ci test llvm

@delcypher delcypher force-pushed the dev/dliew-158088757 branch 2 times, most recently from 191903a to 8f8cd43 Compare October 17, 2025 19:57
@delcypher
Copy link
Author

@swift-ci test llvm

This patch implements a "soft trap mode" for `-fbounds-safety` where hard traps are replaced with calls to a runtime function. It is assumed the runtime function can return so code is generated so that execution can proceed past the "soft trap" (i.e. as if the bounds check passed even though it didn't). It is expected implementations of the runtime function log the issue in some way. The motivation behind this is to provide a smoother path to adopting `-fbounds-safety` in existing codebases. Using soft trap mode with an appropriate runtime allows: * Improved stability of the program because bounds safety violations are no longer fatal because execution continues. * The ability to collect all the soft traps that occurred to get an overview of how many issues there are. Note this patch does not implement the actual runtime itself. This will be done in a separate patch. This patch introduces the `-fbounds-safety-soft-traps=` driver and CC1 flag. This allows enabling the soft trap compilation mode. It currently has two different modes which offer different trade-offs. * `call_with_str` - This generates calls that pass a constant C string describing the reason for trapping. This greatly simplifies logging but at the cost of increasing code size because a global string needs to be emitted for every "trap reason". * `call_with_code` - This generates calls that pass an integer constant to identify the reason for trapping. This produces better codesize than `call_with_str` but the reason for trapping is much less descriptive. Currently the integer constant is hard coded to zero because we don't currently have a good stable integer representation of trap reasons. This will be fixed in rdar://162824128. We may want to add a third `soft_trap_instruction` option one day that emits a special trap instruction that uses its immediate to identify itself as a trap that should be treated as soft by program host (e.g. the kernel). Implementing that is out-of-scope for this patch because we'd need a new LLVM IR intrinsic and backend support. This patch also introduces a new `-fbounds-safety-soft-trap-function=` CC1 flag. It is not intended users use this flag. This flag is for Clang driver to communicate to CC1 what the function name should be. Currently the driver doesn't pass anything so CC1 picks these function names: * `__bounds_safety_soft_trap_s` for `call_with_str` * `__bounds_safety_soft_trap_c` for `call_with_code` As implementations of Bounds Safety soft trap runtimes are brought up the driver logic will need add support for them. We will likely need a new driver flag to control which implementation to use (if any). The soft trap function names and API are defined in a new header (`bounds_safety_soft_traps.h`) that ships with the compiler. Having the interface defined in header provides several advantages: * Runtime implementations can include the header to check they conform to the current interface which might evolve over time. * It provides an explicit interface that runtime implementers can implement. In contrast `-ftrap-function` has an implicit interface that basically can't be evolved without causing a silent ABI break. Note this implementation deliberately doesn't re-use `-ftrap-function` and `-ftrap-function-returns` so that these features can be used independently. In particular it allows using `-fbounds-safety` in soft trap mode with trapping UBSan in any mode (see test cases). Note this implementation continues to deliberately use "trap reasons". This is the compiler feature where artificial inline frames are added to debug info on traps to describe the reason for trapping. This means the string representation for reason from trapping is still available in the `call_with_code` case provided debug information is available. This can be seen the in the LLDB tests added. This does mean that technically there is some redundancy here (trap reasons passed as arguments and in the debug info) but this is intentional because it means in the `call_with_str` case without debug info can still do a good job of logging problems. rdar://158088757
@delcypher delcypher force-pushed the dev/dliew-158088757 branch from 8f8cd43 to 92a1a26 Compare October 17, 2025 22:00
@delcypher
Copy link
Author

@swift-ci test llvm

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

Labels

clang:bounds-safety Issue relating to the experimental -fbounds-safety feature in Clang

1 participant