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.

impl

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).

impl

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. Which stores register states.

Misc

TODO: investigate on add_entrypoint_object cmake

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