Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[libc] remarks about using extended asm in GCC naked function and on aarch64 #137055

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
SchrodingerZhu opened this issue Apr 23, 2025 · 3 comments
Labels

Comments

@SchrodingerZhu
Copy link
Contributor

SchrodingerZhu commented Apr 23, 2025

In LLVM libc, we use [[gnu::naked]] to implement setjmp/longjmp.

Inside the function body, we used extended asm so that we can get the offset to the jmpbuf fields.

However, GCC says explicitly that:

This attribute allows the compiler to construct the requisite function declaration, while allowing the body of the function to be assembly code. The specified function will not have prologue/epilogue sequences generated by the compiler. Only basic asm statements can safely be included in naked functions (see Basic Asm — Assembler Instructions Without Operands). While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.

The naked attribute is actually a target-specific one that is not supported on aarch64 by GCC, but we used it regardlessly.

@llvmbot llvmbot added the libc label Apr 23, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 23, 2025

@llvm/issue-subscribers-libc

Author: Schrodinger ZHU Yifan (SchrodingerZhu)

@SchrodingerZhu
Copy link
Contributor Author

BTW, I do not know clang's assumption on this. Will this attribute be always available on all uarchs? Does clang permit extended asm with constant operands?

@SchrodingerZhu
Copy link
Contributor Author

The team report that this is a known problem. Since we are using extended operand syntax for passing in some constants, there should not be anything too wrong about current approach.

Regarding the aarch64 problem, GCC is not doing anything affect the correctness of code.

Using extended asm combined with constant operands should have well-defined behavior even in a naked function. We expect compilers to behave properly in this case rather than mark it as unsupported.

@SchrodingerZhu SchrodingerZhu changed the title [libc] using extended asm in GCC naked function is undefined behavior [libc] remarks about using extended asm in GCC naked function and on aarch64 Apr 23, 2025
SchrodingerZhu added a commit that referenced this issue Apr 29, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of #136072
See also #137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/setjmp/sigsetjmp.h"
#include "hdr/offsetof_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
#include "src/setjmp/sigsetjmp_epilogue.h"

namespace LIBC_NAMESPACE_DECL {
[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
  asm(R"(
      cbz w1, %c[setjmp]
      str x30, [x0, %c[retaddr]]
      str x19, [x0, %c[extra]]
      mov x19, x0
      bl %c[setjmp]
      mov w1, w0
      mov x0, x19
      ldr x30, [x0, %c[retaddr]]
      ldr x19, [x0, %c[extra]]
      b %c[epilogue])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
      [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
      [epilogue] "i"(sigsetjmp_epilogue)
      : "x0", "x1", "x19", "x30");
}
} // namespace LIBC_NAMESPACE_DECL
```
SchrodingerZhu added a commit that referenced this issue May 1, 2025
We use naked functions to avoid compiler-generated prologue and
epilogue.

Despite GCC documentation listing this as an unsupported case for
extended asm, the generated code is not wrong as we only pass in
constant operands to extended asm.

See #137055 for related
remarks.

---------

Co-authored-by: Copilot <[email protected]>
TheBlindArchitect pushed a commit to XSLabs/integration that referenced this issue May 2, 2025
…mplementation (#137066)

We use naked functions to avoid compiler-generated prologue and
epilogue.

Despite GCC documentation listing this as an unsupported case for
extended asm, the generated code is not wrong as we only pass in
constant operands to extended asm.

See llvm/llvm-project#137055 for related
remarks.

---------

Co-authored-by: Copilot <[email protected]>
GitOrigin-RevId: 034ab7b5ceaa520bca94008add70a7231365e505
Original-Revision: de20cee59ac52f8df30345e4263901af0ed08412
Change-Id: I1f160470692989c4ad77bc9b0de2f019f1db50eb
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this issue May 6, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/setjmp/sigsetjmp.h"
#include "hdr/offsetof_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
#include "src/setjmp/sigsetjmp_epilogue.h"

namespace LIBC_NAMESPACE_DECL {
[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
  asm(R"(
      cbz w1, %c[setjmp]
      str x30, [x0, %c[retaddr]]
      str x19, [x0, %c[extra]]
      mov x19, x0
      bl %c[setjmp]
      mov w1, w0
      mov x0, x19
      ldr x30, [x0, %c[retaddr]]
      ldr x19, [x0, %c[extra]]
      b %c[epilogue])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
      [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
      [epilogue] "i"(sigsetjmp_epilogue)
      : "x0", "x1", "x19", "x30");
}
} // namespace LIBC_NAMESPACE_DECL
```
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this issue May 6, 2025
We use naked functions to avoid compiler-generated prologue and
epilogue.

Despite GCC documentation listing this as an unsupported case for
extended asm, the generated code is not wrong as we only pass in
constant operands to extended asm.

See llvm#137055 for related
remarks.

---------

Co-authored-by: Copilot <[email protected]>
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this issue May 6, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/setjmp/sigsetjmp.h"
#include "hdr/offsetof_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
#include "src/setjmp/sigsetjmp_epilogue.h"

namespace LIBC_NAMESPACE_DECL {
[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
  asm(R"(
      cbz w1, %c[setjmp]
      str x30, [x0, %c[retaddr]]
      str x19, [x0, %c[extra]]
      mov x19, x0
      bl %c[setjmp]
      mov w1, w0
      mov x0, x19
      ldr x30, [x0, %c[retaddr]]
      ldr x19, [x0, %c[extra]]
      b %c[epilogue])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
      [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
      [epilogue] "i"(sigsetjmp_epilogue)
      : "x0", "x1", "x19", "x30");
}
} // namespace LIBC_NAMESPACE_DECL
```
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this issue May 6, 2025
We use naked functions to avoid compiler-generated prologue and
epilogue.

Despite GCC documentation listing this as an unsupported case for
extended asm, the generated code is not wrong as we only pass in
constant operands to extended asm.

See llvm#137055 for related
remarks.

---------

Co-authored-by: Copilot <[email protected]>
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this issue May 6, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/setjmp/sigsetjmp.h"
#include "hdr/offsetof_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
#include "src/setjmp/sigsetjmp_epilogue.h"

namespace LIBC_NAMESPACE_DECL {
[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
  asm(R"(
      cbz w1, %c[setjmp]
      str x30, [x0, %c[retaddr]]
      str x19, [x0, %c[extra]]
      mov x19, x0
      bl %c[setjmp]
      mov w1, w0
      mov x0, x19
      ldr x30, [x0, %c[retaddr]]
      ldr x19, [x0, %c[extra]]
      b %c[epilogue])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
      [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
      [epilogue] "i"(sigsetjmp_epilogue)
      : "x0", "x1", "x19", "x30");
}
} // namespace LIBC_NAMESPACE_DECL
```
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this issue May 6, 2025
We use naked functions to avoid compiler-generated prologue and
epilogue.

Despite GCC documentation listing this as an unsupported case for
extended asm, the generated code is not wrong as we only pass in
constant operands to extended asm.

See llvm#137055 for related
remarks.

---------

Co-authored-by: Copilot <[email protected]>
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this issue May 6, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm/llvm-project#136072
See also llvm/llvm-project#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/setjmp/sigsetjmp.h"
#include "hdr/offsetof_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
#include "src/setjmp/sigsetjmp_epilogue.h"

namespace LIBC_NAMESPACE_DECL {
[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
  asm(R"(
      cbz w1, %c[setjmp]
      str x30, [x0, %c[retaddr]]
      str x19, [x0, %c[extra]]
      mov x19, x0
      bl %c[setjmp]
      mov w1, w0
      mov x0, x19
      ldr x30, [x0, %c[retaddr]]
      ldr x19, [x0, %c[extra]]
      b %c[epilogue])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
      [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
      [epilogue] "i"(sigsetjmp_epilogue)
      : "x0", "x1", "x19", "x30");
}
} // namespace LIBC_NAMESPACE_DECL
```
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this issue May 6, 2025
…066)

We use naked functions to avoid compiler-generated prologue and
epilogue.

Despite GCC documentation listing this as an unsupported case for
extended asm, the generated code is not wrong as we only pass in
constant operands to extended asm.

See llvm/llvm-project#137055 for related
remarks.

---------

Co-authored-by: Copilot <[email protected]>
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this issue May 7, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/setjmp/sigsetjmp.h"
#include "hdr/offsetof_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
#include "src/setjmp/sigsetjmp_epilogue.h"

namespace LIBC_NAMESPACE_DECL {
[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
  asm(R"(
      cbz w1, %c[setjmp]
      str x30, [x0, %c[retaddr]]
      str x19, [x0, %c[extra]]
      mov x19, x0
      bl %c[setjmp]
      mov w1, w0
      mov x0, x19
      ldr x30, [x0, %c[retaddr]]
      ldr x19, [x0, %c[extra]]
      b %c[epilogue])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
      [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
      [epilogue] "i"(sigsetjmp_epilogue)
      : "x0", "x1", "x19", "x30");
}
} // namespace LIBC_NAMESPACE_DECL
```
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this issue May 7, 2025
We use naked functions to avoid compiler-generated prologue and
epilogue.

Despite GCC documentation listing this as an unsupported case for
extended asm, the generated code is not wrong as we only pass in
constant operands to extended asm.

See llvm#137055 for related
remarks.

---------

Co-authored-by: Copilot <[email protected]>
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this issue May 9, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/setjmp/sigsetjmp.h"
#include "hdr/offsetof_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
#include "src/setjmp/sigsetjmp_epilogue.h"

namespace LIBC_NAMESPACE_DECL {
[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
  asm(R"(
      cbz w1, %c[setjmp]
      str x30, [x0, %c[retaddr]]
      str x19, [x0, %c[extra]]
      mov x19, x0
      bl %c[setjmp]
      mov w1, w0
      mov x0, x19
      ldr x30, [x0, %c[retaddr]]
      ldr x19, [x0, %c[extra]]
      b %c[epilogue])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
      [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
      [epilogue] "i"(sigsetjmp_epilogue)
      : "x0", "x1", "x19", "x30");
}
} // namespace LIBC_NAMESPACE_DECL
```
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this issue May 9, 2025
We use naked functions to avoid compiler-generated prologue and
epilogue.

Despite GCC documentation listing this as an unsupported case for
extended asm, the generated code is not wrong as we only pass in
constant operands to extended asm.

See llvm#137055 for related
remarks.

---------

Co-authored-by: Copilot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants