Main: libc/include/setjmp.h: Implement setjmp/longjmp

This commit is contained in:
Alex Kotov 2022-06-14 17:59:08 +03:00
parent 423d3c4902
commit 57a459bb7f
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
10 changed files with 137 additions and 2 deletions

View File

@ -1,8 +1,12 @@
MIT License
Copyright (c) 2014-2019 Marco Paland
Copyright (c) 2020-2022 Alex Kotov
Copyright (c) 2011 Nicholas J. Kain
Copyright (c) 2011-2015 Rich Felker
Copyright (c) 2014-2019 Marco Paland
Copyright (c) 2022 Alexander Monakov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights

View File

@ -1,3 +1,5 @@
# The code was taken from Marco Paland's printf.
# Copyright (c) 2014-2019 Marco Paland <info@paland.com>
# TODO: add remaining tests from

View File

@ -12,3 +12,17 @@ libc_la_SOURCES = \
src/ctype.c \
src/stdlib.c \
src/string.c
if ASM_I386
libc_la_SOURCES += \
src/asm/i386/longjmp.S \
src/asm/i386/setjmp.S
endif
if ASM_X86_64
libc_la_SOURCES += \
src/asm/x86_64/longjmp.S \
src/asm/x86_64/setjmp.S
endif
# TODO: implement setjmp/longjmp for riscv64

View File

@ -5,9 +5,19 @@
extern "C" {
#endif
typedef int jmp_buf;
// TODO: define in architecture-specific header
typedef unsigned long __jmp_buf[sizeof(long) == 8 ? 8 : 6];
typedef struct __jmp_buf_tag {
__jmp_buf __jb;
unsigned long __fl;
unsigned long __ss[128 / sizeof(long)];
} jmp_buf[1];
__attribute__((returns_twice))
int setjmp(jmp_buf env);
__attribute__((noreturn))
void longjmp(jmp_buf env, int val);
#ifdef __cplusplus

View File

@ -0,0 +1,24 @@
/**
* The code was taken from musl libc.
*
* Copyright (c) 2011 Rich Felker
* Copyright (c) 2022 Alexander Monakov
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
.global longjmp
.type longjmp, @function
longjmp:
mov 4(%esp) , %edx
mov 8(%esp) , %eax
cmp $1 , %eax
adc $0 , %al
mov (%edx) , %ebx
mov 4(%edx) , %esi
mov 8(%edx) , %edi
mov 12(%edx) , %ebp
mov 16(%edx) , %esp
jmp *20(%edx)

View File

@ -0,0 +1,24 @@
/**
* The code was taken from musl libc.
*
* Copyright (c) 2011-2015 Rich Felker
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
.global setjmp
.type setjmp, @function
setjmp:
mov 4(%esp) , %eax
mov %ebx , (%eax)
mov %esi , 4(%eax)
mov %edi , 8(%eax)
mov %ebp , 12(%eax)
lea 4(%esp) , %ecx
mov %ecx , 16(%eax)
mov (%esp) , %ecx
mov %ecx , 20(%eax)
xor %eax , %eax
ret

View File

@ -0,0 +1,26 @@
/**
* The code was taken from musl libc.
*
* Copyright (c) 2011 Nicholas J. Kain
* Copyright (c) 2011-2012 Rich Felker
* Copyright (c) 2022 Alexander Monakov
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
.global longjmp
.type longjmp, @function
longjmp:
xor %eax , %eax
cmp $1 , %esi /* CF = val ? 0 : 1 */
adc %esi , %eax /* eax = val + !val */
mov (%rdi) , %rbx /* rdi is the jmp_buf, restore regs from it */
mov 8(%rdi) , %rbp
mov 16(%rdi) , %r12
mov 24(%rdi) , %r13
mov 32(%rdi) , %r14
mov 40(%rdi) , %r15
mov 48(%rdi) , %rsp
jmp *56(%rdi) /* goto saved address without altering rsp */

View File

@ -0,0 +1,27 @@
/**
* The code was taken from musl libc.
*
* Copyright (c) 2011 Nicholas J. Kain
* Copyright (c) 2011-2012 Rich Felker
* Copyright (c) 2022 Alexander Monakov
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
.global setjmp
.type setjmp, @function
setjmp:
mov %rbx , (%rdi) /* rdi is jmp_buf, move registers onto it */
mov %rbp , 8(%rdi)
mov %r12 , 16(%rdi)
mov %r13 , 24(%rdi)
mov %r14 , 32(%rdi)
mov %r15 , 40(%rdi)
lea 8(%rsp) , %rdx /* this is our rsp WITHOUT current ret addr */
mov %rdx , 48(%rdi)
mov (%rsp) , %rdx /* save return addr ptr for new rip */
mov %rdx , 56(%rdi)
xor %eax , %eax /* always return 0 */
ret

View File

@ -1,4 +1,6 @@
/**
* The code was taken from Marco Paland's printf.
*
* Copyright (c) 2014-2019 Marco Paland <info@paland.com>
*
* Tiny [v]fprintf, sfprintf and [v]snprintf implementation, optimized for speed

View File

@ -1,4 +1,6 @@
/**
* The code was taken from Marco Paland's printf.
*
* Copyright (c) 2014-2019 Marco Paland <info@paland.com>
*/