Skip to content

Instantly share code, notes, and snippets.

@orion160
Last active September 1, 2024 18:16
Show Gist options
  • Select an option

  • Save orion160/4049fe811aae0e333c630cd13a7d8ed5 to your computer and use it in GitHub Desktop.

Select an option

Save orion160/4049fe811aae0e333c630cd13a7d8ed5 to your computer and use it in GitHub Desktop.
LLVM libc AArch64 setjmp/longjmp

LLVM libc AArch64 setjmp/longjmp

commit

AArch64 extensions

PAC

Pointer Authentication

BTI

Branch Target Identification

MTE

Memory Tagging Extension

Procedura call

AAPCS64 -> ARM Architecture Procedure Call Standard for 64-bit

libc functions

These routines can be used for error handling recovery, and are included in <setjmp.h>

setjmp

Saves the current execution context into a variable of type jmp_buf. It returns 0 on the first call, and a value different from zero if program control is restored with longjmp.

longjmp

Loads the execution context env saved by a previous call to setjmp. If the function that called setjmp has exited, the behavior is undefined (in other words, only long jumps up the call stack are allowed).

Example

GODBOLT

#include <math.h>
#include <setjmp.h>
#include <stdio.h>

typedef enum { DIV_BY_ZERO = 1 } division_exceptions;

jmp_buf divide_exception_h;

float divide(float x, float y) {
  if (y < 1e-6) {
    longjmp(divide_exception_h, DIV_BY_ZERO);
  }

  return x / y;
}

int main(int argc, char **argv) {
  switch (setjmp(divide_exception_h)) {
  case 0:
    float a = 1.0f;
    float b = 2.0f;
    float r = divide(a, b);
    printf("%f = %f / %f\n", r, a, b);
    break;
  case DIV_BY_ZERO:
    printf("Cannot divide by zero...\n");
    break;
  }

  switch (setjmp(divide_exception_h)) {
  case 0:
    float a = 1.0f;
    float b = 0.0f;
    float r = divide(a, b);
    printf("%f = %f / %f\n", r, a, b);
    break;
  case DIV_BY_ZERO:
    printf("Cannot divide by zero...\n");
    break;
  }

  return 0;
}

Implementation

Special care is taken with X18 register which is reserved as a platform register.

jmp_buf is defined at src.

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