[libc-commits] [libc] [libc][arm] implement a basic setjmp/longjmp (PR #93220)

Simon Tatham via libc-commits libc-commits at lists.llvm.org
Tue May 28 03:15:44 PDT 2024


================
@@ -0,0 +1,68 @@
+
+//===-- Implementation of longjmp -----------------------------------------===//
+//
+// 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/longjmp.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+#if defined(__thumb__) && __ARM_ARCH_ISA_THUMB == 1
+
+[[gnu::naked, gnu::target("thumb")]]
+LLVM_LIBC_FUNCTION(void, longjmp, (__jmp_buf * buf, int val)) {
+  asm(R"(
+      # Reload r4, r5, r6, r7.
+      ldmia r0!, {r4, r5, r6, r7}
+
+      # Reload r8, r9, r10. They cannot appear in register lists so load them
+      # into the lower registers, then move them into place.
+      ldmia r0!, {r1, r2, r3}
+      mov r8, r1
+      mov r9, r2
+      mov r10, r3
+
+      # Reload r11, sp, lr. They cannot appear in register lists so load them
+      # into the lower registers, then move them into place.
+      ldmia r0!, {r1, r2, r3}
+      mov r11, r1
+      mov sp, r2
+      mov lr, r3
+
+      # return val ?: 1;
+      movs r0, r1
----------------
statham-arm wrote:

This use of r1 ought to be accessing the value passed in to `longjmp` as a parameter. But that's not what's in r1 right now. The previous two `ldmia` both clobbered it. At the point of this instruction, the value in r1 is whatever value the jmp_buf had saved for r11.

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


More information about the libc-commits mailing list