[libc-commits] [libc] [libc][setjmp] fix setjmp test (PR #87837)

James Y Knight via libc-commits libc-commits at lists.llvm.org
Mon Apr 8 16:26:44 PDT 2024


jyknight wrote:

Implementing the set of functions I mentioned in the discourse-thread as pure-asm is required for correctness -- that can either be via a "naked" function or in a separate asm file. There is really no other way to guarantee the proper behavior, vs just "happens to work today".

> More so opening the door for out of line asm is something we'd like to avoid as then it can be used in future arguments for "here's memcpy in out of line asm; look, you use out of line asm here and here and here so I should be able to use it, too."

I don't think that needs to be a concern. Document _why_ this small number of functions must be implemented fully in asm (that it's not about performance!), and that solves that problem.

> I've implemented setjmp here using a naked fn attr just to get a feel for it

That is a definite improvement. Using a naked function could be theoretically correct. However, this correctness applies ONLY if your code has a single asm statement. That significantly limits the usefulness of being in a C file.

Compared to a standalone-asm file, a naked function has other downsides:
1. There is a risk of a developer inadvertently putting non-asm code into the function, thus breaking the correctness (e.g. the `__builtin_return_address` call in the draft PR, or a theoretical call to a proposed `__builtin_stack_address`, or something else)
2. Compilers often fail to implement the attribute correctly, because it's such a rarely-used feature. GCC only supports it on a subset of platforms.

The primary advantage I see of using inline-asm is the ability to use offsetof to get the offsets of jmp_buf members. If you instead write the function in a pure asm file, you'll need to get the applicable type-offsets into asm-usable `#define` statements. But, IMO that's not a huge problem (for these specific functions), because they are so extremely platform-specific already. It's not a big lift to write such offset defines manually, and then assert correspondence (that the `#define` values match the actual struct offsets) via static_assert on the C side.

...actually, I now note that even the `offsetof` constant operands of the inline-asm is something [GCC's docs](https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/x86-Function-Attributes.html#index-naked-function-attribute_002c-x86) explicitly say you cannot validly do in a naked function. I'm not sure if there's a good reason for that or not. But maybe that eliminates that advantage, too...

https://github.com/llvm/llvm-project/pull/87837


More information about the libc-commits mailing list