Implement basic setjmp using musl's awesome existing code
This commit is contained in:
Generated
+9
@@ -283,6 +283,7 @@ dependencies = [
|
||||
"netinet 0.1.0",
|
||||
"platform 0.1.0",
|
||||
"semaphore 0.1.0",
|
||||
"setjmp 0.1.0",
|
||||
"signal 0.1.0",
|
||||
"stdio 0.1.0",
|
||||
"stdlib 0.1.0",
|
||||
@@ -357,6 +358,14 @@ dependencies = [
|
||||
"serde 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "setjmp"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cbindgen 0.5.2",
|
||||
"platform 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal"
|
||||
version = "0.1.0"
|
||||
|
||||
@@ -24,6 +24,7 @@ grp = { path = "src/grp" }
|
||||
locale = { path = "src/locale" }
|
||||
netinet = { path = "src/netinet" }
|
||||
platform = { path = "src/platform" }
|
||||
setjmp = { path = "src/setjmp" }
|
||||
semaphore = { path = "src/semaphore" }
|
||||
signal = { path = "src/signal" }
|
||||
stdio = { path = "src/stdio" }
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef _BITS_SETJMP_H
|
||||
#define _BITS_SETJMP_H
|
||||
|
||||
#ifdef __arch64__
|
||||
typedef unsigned long jmp_buf[22];
|
||||
#endif
|
||||
|
||||
#ifdef __arm__
|
||||
typedef unsigned long long jmp_buf[32];
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
typedef unsigned long jmp_buf[6];
|
||||
#endif
|
||||
|
||||
#ifdef __m68k__
|
||||
typedef unsigned long jmp_buf[39];
|
||||
#endif
|
||||
|
||||
#ifdef __microblaze__
|
||||
typedef unsigned long jmp_buf[18];
|
||||
#endif
|
||||
|
||||
#ifdef __mips__
|
||||
typedef unsigned long long jmp_buf[13];
|
||||
#endif
|
||||
|
||||
#ifdef __mips64__
|
||||
typedef unsigned long long jmp_buf[23];
|
||||
#endif
|
||||
|
||||
#ifdef __mipsn32__
|
||||
typedef unsigned long long jmp_buf[23];
|
||||
#endif
|
||||
|
||||
#ifdef __or1k__
|
||||
typedef unsigned long jmp_buf[13];
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc__
|
||||
typedef unsigned long long jmp_buf[56];
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
typedef uint128_t jmp_buf[32];
|
||||
#endif
|
||||
|
||||
#ifdef __s390x__
|
||||
typedef unsigned long jmp_buf[18];
|
||||
#endif
|
||||
|
||||
#ifdef __sh__
|
||||
typedef unsigned long jmp_buf[15];
|
||||
#endif
|
||||
|
||||
#ifdef __x32__
|
||||
typedef unsigned long long jmp_buf[8];
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
typedef unsigned long jmp_buf[8];
|
||||
#endif
|
||||
|
||||
int setjmp(jmp_buf buf);
|
||||
void longjmp(jmp_buf buf, int value);
|
||||
|
||||
#endif /* _SETJMP_H */
|
||||
@@ -13,6 +13,7 @@ pub extern crate grp;
|
||||
pub extern crate locale;
|
||||
pub extern crate netinet;
|
||||
pub extern crate semaphore;
|
||||
pub extern crate setjmp;
|
||||
pub extern crate stdio;
|
||||
pub extern crate stdlib;
|
||||
pub extern crate string;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "setjmp"
|
||||
version = "0.1.0"
|
||||
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = { path = "../../cbindgen" }
|
||||
|
||||
[dependencies]
|
||||
platform = { path = "../platform" }
|
||||
@@ -0,0 +1,72 @@
|
||||
extern crate cbindgen;
|
||||
|
||||
use std::{env, fs, process::Command};
|
||||
|
||||
fn compile(file: &str, object: &str, output: &str) {
|
||||
let status = Command::new("gcc")
|
||||
.args(&["-c", file, "-o", object])
|
||||
.status()
|
||||
.expect("failed to run gcc to compile assembly");
|
||||
|
||||
if !status.success() {
|
||||
panic!("compilation error");
|
||||
}
|
||||
|
||||
let status = Command::new("ar")
|
||||
.args(&["rcs", output, object])
|
||||
.status()
|
||||
.expect("failed to run ar to convert object to a static library");
|
||||
|
||||
if !status.success() {
|
||||
panic!("error converting object to static library");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rustc-link-lib=static=setjmp");
|
||||
println!("cargo:rustc-link-lib=static=longjmp");
|
||||
|
||||
macro_rules! detect_arch {
|
||||
($($($token:tt);+),+) => {
|
||||
$(
|
||||
detect_arch!(inner $($token);+);
|
||||
)+
|
||||
};
|
||||
(inner $arch:expr) => {
|
||||
detect_arch!(inner $arch; ".s");
|
||||
};
|
||||
(inner $arch:expr; $ext:expr) => {
|
||||
#[cfg(target_arch = $arch)] {
|
||||
compile(concat!("impl/", $arch, "/setjmp", $ext), "impl/bin/setjmp.o", "impl/bin/libsetjmp.a");
|
||||
compile(concat!("impl/", $arch, "/longjmp", $ext), "impl/bin/longjmp.o", "impl/bin/liblongjmp.a");
|
||||
|
||||
let dir = env::current_dir().expect("failed to find current directory");
|
||||
println!("cargo:rustc-link-search=native={}/impl/bin", dir.display());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
detect_arch! {
|
||||
"aarch64",
|
||||
"arm",
|
||||
"i386",
|
||||
"m68k",
|
||||
"microblaze",
|
||||
"mips"; ".S",
|
||||
"mips64"; ".S",
|
||||
"mipsn32"; ".S",
|
||||
"or1k",
|
||||
"powerpc"; ".S",
|
||||
"powerpc64",
|
||||
"s390x",
|
||||
"sh"; ".S",
|
||||
"x32",
|
||||
"x86_64"
|
||||
}
|
||||
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
|
||||
fs::create_dir_all("../../target/include").expect("failed to create include directory");
|
||||
cbindgen::generate(crate_dir)
|
||||
.expect("failed to generate bindings")
|
||||
.write_to_file("../../target/include/setjmp.h");
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
include_guard = "_SETJMP_H"
|
||||
trailer = "#include <bits/setjmp.h>"
|
||||
language = "C"
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
@@ -0,0 +1,6 @@
|
||||
# setjmp implementation
|
||||
|
||||
All this code belongs to [musl libc](https://www.musl-libc.org/).
|
||||
They own it. All rights go to them.
|
||||
Huge thanks to them for doing this tedious per-arch assembly work!
|
||||
We will reuse this awesome effort :)
|
||||
@@ -0,0 +1,24 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,%function
|
||||
.type longjmp,%function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
// IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
|
||||
ldp x19, x20, [x0,#0]
|
||||
ldp x21, x22, [x0,#16]
|
||||
ldp x23, x24, [x0,#32]
|
||||
ldp x25, x26, [x0,#48]
|
||||
ldp x27, x28, [x0,#64]
|
||||
ldp x29, x30, [x0,#80]
|
||||
ldr x2, [x0,#104]
|
||||
mov sp, x2
|
||||
ldp d8 , d9, [x0,#112]
|
||||
ldp d10, d11, [x0,#128]
|
||||
ldp d12, d13, [x0,#144]
|
||||
ldp d14, d15, [x0,#160]
|
||||
|
||||
mov x0, x1
|
||||
cbnz x1, 1f
|
||||
mov x0, #1
|
||||
1: br x30
|
||||
@@ -0,0 +1,24 @@
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
// IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
|
||||
stp x19, x20, [x0,#0]
|
||||
stp x21, x22, [x0,#16]
|
||||
stp x23, x24, [x0,#32]
|
||||
stp x25, x26, [x0,#48]
|
||||
stp x27, x28, [x0,#64]
|
||||
stp x29, x30, [x0,#80]
|
||||
mov x2, sp
|
||||
str x2, [x0,#104]
|
||||
stp d8, d9, [x0,#112]
|
||||
stp d10, d11, [x0,#128]
|
||||
stp d12, d13, [x0,#144]
|
||||
stp d14, d15, [x0,#160]
|
||||
mov x0, #0
|
||||
ret
|
||||
@@ -0,0 +1,43 @@
|
||||
.syntax unified
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,%function
|
||||
.type longjmp,%function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
mov ip,r0
|
||||
movs r0,r1
|
||||
moveq r0,#1
|
||||
ldmia ip!, {v1,v2,v3,v4,v5,v6,sl,fp}
|
||||
ldmia ip!, {r2,lr}
|
||||
mov sp,r2
|
||||
|
||||
adr r1,1f
|
||||
ldr r2,1f
|
||||
ldr r1,[r1,r2]
|
||||
|
||||
tst r1,#0x260
|
||||
beq 3f
|
||||
tst r1,#0x20
|
||||
beq 2f
|
||||
ldc p2, cr4, [ip], #48
|
||||
2: tst r1,#0x40
|
||||
beq 2f
|
||||
.fpu vfp
|
||||
vldmia ip!, {d8-d15}
|
||||
.fpu softvfp
|
||||
.eabi_attribute 10, 0
|
||||
.eabi_attribute 27, 0
|
||||
2: tst r1,#0x200
|
||||
beq 3f
|
||||
ldcl p1, cr10, [ip], #8
|
||||
ldcl p1, cr11, [ip], #8
|
||||
ldcl p1, cr12, [ip], #8
|
||||
ldcl p1, cr13, [ip], #8
|
||||
ldcl p1, cr14, [ip], #8
|
||||
ldcl p1, cr15, [ip], #8
|
||||
3: bx lr
|
||||
|
||||
.hidden __hwcap
|
||||
.align 2
|
||||
1: .word __hwcap-1b
|
||||
@@ -0,0 +1,45 @@
|
||||
.syntax unified
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,%function
|
||||
.type _setjmp,%function
|
||||
.type setjmp,%function
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
mov ip,r0
|
||||
stmia ip!,{v1,v2,v3,v4,v5,v6,sl,fp}
|
||||
mov r2,sp
|
||||
stmia ip!,{r2,lr}
|
||||
mov r0,#0
|
||||
|
||||
adr r1,1f
|
||||
ldr r2,1f
|
||||
ldr r1,[r1,r2]
|
||||
|
||||
tst r1,#0x260
|
||||
beq 3f
|
||||
tst r1,#0x20
|
||||
beq 2f
|
||||
stc p2, cr4, [ip], #48
|
||||
2: tst r1,#0x40
|
||||
beq 2f
|
||||
.fpu vfp
|
||||
vstmia ip!, {d8-d15}
|
||||
.fpu softvfp
|
||||
.eabi_attribute 10, 0
|
||||
.eabi_attribute 27, 0
|
||||
2: tst r1,#0x200
|
||||
beq 3f
|
||||
stcl p1, cr10, [ip], #8
|
||||
stcl p1, cr11, [ip], #8
|
||||
stcl p1, cr12, [ip], #8
|
||||
stcl p1, cr13, [ip], #8
|
||||
stcl p1, cr14, [ip], #8
|
||||
stcl p1, cr15, [ip], #8
|
||||
3: bx lr
|
||||
|
||||
.hidden __hwcap
|
||||
.align 2
|
||||
1: .word __hwcap-1b
|
||||
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -0,0 +1,20 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
mov 4(%esp),%edx
|
||||
mov 8(%esp),%eax
|
||||
test %eax,%eax
|
||||
jnz 1f
|
||||
inc %eax
|
||||
1:
|
||||
mov (%edx),%ebx
|
||||
mov 4(%edx),%esi
|
||||
mov 8(%edx),%edi
|
||||
mov 12(%edx),%ebp
|
||||
mov 16(%edx),%ecx
|
||||
mov %ecx,%esp
|
||||
mov 20(%edx),%ecx
|
||||
jmp *%ecx
|
||||
@@ -0,0 +1,23 @@
|
||||
.global ___setjmp
|
||||
.hidden ___setjmp
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
___setjmp:
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
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
|
||||
@@ -0,0 +1,14 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
movea.l 4(%sp),%a0
|
||||
move.l 8(%sp),%d0
|
||||
bne 1f
|
||||
move.l #1,%d0
|
||||
1: movem.l (%a0),%d2-%d7/%a2-%a7
|
||||
fmovem.x 52(%a0),%fp2-%fp7
|
||||
move.l 48(%a0),(%sp)
|
||||
rts
|
||||
@@ -0,0 +1,18 @@
|
||||
.global ___setjmp
|
||||
.hidden ___setjmp
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
___setjmp:
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
movea.l 4(%sp),%a0
|
||||
movem.l %d2-%d7/%a2-%a7,(%a0)
|
||||
move.l (%sp),48(%a0)
|
||||
fmovem.x %fp2-%fp7,52(%a0)
|
||||
clr.l %d0
|
||||
rts
|
||||
@@ -0,0 +1,29 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
addi r3, r6, 0
|
||||
bnei r3, 1f
|
||||
addi r3, r3, 1
|
||||
1: lwi r1, r5, 0
|
||||
lwi r15, r5, 4
|
||||
lwi r2, r5, 8
|
||||
lwi r13, r5, 12
|
||||
lwi r18, r5, 16
|
||||
lwi r19, r5, 20
|
||||
lwi r20, r5, 24
|
||||
lwi r21, r5, 28
|
||||
lwi r22, r5, 32
|
||||
lwi r23, r5, 36
|
||||
lwi r24, r5, 40
|
||||
lwi r25, r5, 44
|
||||
lwi r26, r5, 48
|
||||
lwi r27, r5, 52
|
||||
lwi r28, r5, 56
|
||||
lwi r29, r5, 60
|
||||
lwi r30, r5, 64
|
||||
lwi r31, r5, 68
|
||||
rtsd r15, 8
|
||||
nop
|
||||
@@ -0,0 +1,32 @@
|
||||
.global ___setjmp
|
||||
.hidden ___setjmp
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
___setjmp:
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
swi r1, r5, 0
|
||||
swi r15, r5, 4
|
||||
swi r2, r5, 8
|
||||
swi r13, r5, 12
|
||||
swi r18, r5, 16
|
||||
swi r19, r5, 20
|
||||
swi r20, r5, 24
|
||||
swi r21, r5, 28
|
||||
swi r22, r5, 32
|
||||
swi r23, r5, 36
|
||||
swi r24, r5, 40
|
||||
swi r25, r5, 44
|
||||
swi r26, r5, 48
|
||||
swi r27, r5, 52
|
||||
swi r28, r5, 56
|
||||
swi r29, r5, 60
|
||||
swi r30, r5, 64
|
||||
swi r31, r5, 68
|
||||
rtsd r15, 8
|
||||
ori r3, r0, 0
|
||||
@@ -0,0 +1,40 @@
|
||||
.set noreorder
|
||||
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
move $2, $5
|
||||
bne $2, $0, 1f
|
||||
nop
|
||||
addu $2, $2, 1
|
||||
1:
|
||||
#ifndef __mips_soft_float
|
||||
lwc1 $20, 56($4)
|
||||
lwc1 $21, 60($4)
|
||||
lwc1 $22, 64($4)
|
||||
lwc1 $23, 68($4)
|
||||
lwc1 $24, 72($4)
|
||||
lwc1 $25, 76($4)
|
||||
lwc1 $26, 80($4)
|
||||
lwc1 $27, 84($4)
|
||||
lwc1 $28, 88($4)
|
||||
lwc1 $29, 92($4)
|
||||
lwc1 $30, 96($4)
|
||||
lwc1 $31, 100($4)
|
||||
#endif
|
||||
lw $ra, 0($4)
|
||||
lw $sp, 4($4)
|
||||
lw $16, 8($4)
|
||||
lw $17, 12($4)
|
||||
lw $18, 16($4)
|
||||
lw $19, 20($4)
|
||||
lw $20, 24($4)
|
||||
lw $21, 28($4)
|
||||
lw $22, 32($4)
|
||||
lw $23, 36($4)
|
||||
lw $30, 40($4)
|
||||
jr $ra
|
||||
lw $28, 44($4)
|
||||
@@ -0,0 +1,39 @@
|
||||
.set noreorder
|
||||
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
sw $ra, 0($4)
|
||||
sw $sp, 4($4)
|
||||
sw $16, 8($4)
|
||||
sw $17, 12($4)
|
||||
sw $18, 16($4)
|
||||
sw $19, 20($4)
|
||||
sw $20, 24($4)
|
||||
sw $21, 28($4)
|
||||
sw $22, 32($4)
|
||||
sw $23, 36($4)
|
||||
sw $30, 40($4)
|
||||
sw $28, 44($4)
|
||||
#ifndef __mips_soft_float
|
||||
swc1 $20, 56($4)
|
||||
swc1 $21, 60($4)
|
||||
swc1 $22, 64($4)
|
||||
swc1 $23, 68($4)
|
||||
swc1 $24, 72($4)
|
||||
swc1 $25, 76($4)
|
||||
swc1 $26, 80($4)
|
||||
swc1 $27, 84($4)
|
||||
swc1 $28, 88($4)
|
||||
swc1 $29, 92($4)
|
||||
swc1 $30, 96($4)
|
||||
swc1 $31, 100($4)
|
||||
#endif
|
||||
jr $ra
|
||||
li $2, 0
|
||||
@@ -0,0 +1,37 @@
|
||||
.set noreorder
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
move $2, $5
|
||||
|
||||
bne $2, $0, 1f
|
||||
nop
|
||||
daddu $2, $2, 1
|
||||
1:
|
||||
#ifndef __mips_soft_float
|
||||
ldc1 $24, 96($4)
|
||||
ldc1 $25, 104($4)
|
||||
ldc1 $26, 112($4)
|
||||
ldc1 $27, 120($4)
|
||||
ldc1 $28, 128($4)
|
||||
ldc1 $29, 136($4)
|
||||
ldc1 $30, 144($4)
|
||||
ldc1 $31, 152($4)
|
||||
#endif
|
||||
ld $ra, 0($4)
|
||||
ld $sp, 8($4)
|
||||
ld $gp, 16($4)
|
||||
ld $16, 24($4)
|
||||
ld $17, 32($4)
|
||||
ld $18, 40($4)
|
||||
ld $19, 48($4)
|
||||
ld $20, 56($4)
|
||||
ld $21, 64($4)
|
||||
ld $22, 72($4)
|
||||
ld $23, 80($4)
|
||||
ld $30, 88($4)
|
||||
jr $ra
|
||||
nop
|
||||
@@ -0,0 +1,34 @@
|
||||
.set noreorder
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
sd $ra, 0($4)
|
||||
sd $sp, 8($4)
|
||||
sd $gp, 16($4)
|
||||
sd $16, 24($4)
|
||||
sd $17, 32($4)
|
||||
sd $18, 40($4)
|
||||
sd $19, 48($4)
|
||||
sd $20, 56($4)
|
||||
sd $21, 64($4)
|
||||
sd $22, 72($4)
|
||||
sd $23, 80($4)
|
||||
sd $30, 88($4)
|
||||
#ifndef __mips_soft_float
|
||||
sdc1 $24, 96($4)
|
||||
sdc1 $25, 104($4)
|
||||
sdc1 $26, 112($4)
|
||||
sdc1 $27, 120($4)
|
||||
sdc1 $28, 128($4)
|
||||
sdc1 $29, 136($4)
|
||||
sdc1 $30, 144($4)
|
||||
sdc1 $31, 152($4)
|
||||
#endif
|
||||
jr $ra
|
||||
li $2, 0
|
||||
@@ -0,0 +1,36 @@
|
||||
.set noreorder
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
move $2, $5
|
||||
bne $2, $0, 1f
|
||||
nop
|
||||
addu $2, $2, 1
|
||||
1:
|
||||
#ifndef __mips_soft_float
|
||||
ldc1 $24, 96($4)
|
||||
ldc1 $25, 104($4)
|
||||
ldc1 $26, 112($4)
|
||||
ldc1 $27, 120($4)
|
||||
ldc1 $28, 128($4)
|
||||
ldc1 $29, 136($4)
|
||||
ldc1 $30, 144($4)
|
||||
ldc1 $31, 152($4)
|
||||
#endif
|
||||
ld $ra, 0($4)
|
||||
ld $sp, 8($4)
|
||||
ld $gp, 16($4)
|
||||
ld $16, 24($4)
|
||||
ld $17, 32($4)
|
||||
ld $18, 40($4)
|
||||
ld $19, 48($4)
|
||||
ld $20, 56($4)
|
||||
ld $21, 64($4)
|
||||
ld $22, 72($4)
|
||||
ld $23, 80($4)
|
||||
ld $30, 88($4)
|
||||
jr $ra
|
||||
nop
|
||||
@@ -0,0 +1,34 @@
|
||||
.set noreorder
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
sd $ra, 0($4)
|
||||
sd $sp, 8($4)
|
||||
sd $gp, 16($4)
|
||||
sd $16, 24($4)
|
||||
sd $17, 32($4)
|
||||
sd $18, 40($4)
|
||||
sd $19, 48($4)
|
||||
sd $20, 56($4)
|
||||
sd $21, 64($4)
|
||||
sd $22, 72($4)
|
||||
sd $23, 80($4)
|
||||
sd $30, 88($4)
|
||||
#ifndef __mips_soft_float
|
||||
sdc1 $24, 96($4)
|
||||
sdc1 $25, 104($4)
|
||||
sdc1 $26, 112($4)
|
||||
sdc1 $27, 120($4)
|
||||
sdc1 $28, 128($4)
|
||||
sdc1 $29, 136($4)
|
||||
sdc1 $30, 144($4)
|
||||
sdc1 $31, 152($4)
|
||||
#endif
|
||||
jr $ra
|
||||
li $2, 0
|
||||
@@ -0,0 +1,25 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
l.sfeqi r4, 0
|
||||
l.bnf 1f
|
||||
l.addi r11, r4,0
|
||||
l.ori r11, r0, 1
|
||||
1: l.lwz r1, 0(r3)
|
||||
l.lwz r2, 4(r3)
|
||||
l.lwz r9, 8(r3)
|
||||
l.lwz r10, 12(r3)
|
||||
l.lwz r14, 16(r3)
|
||||
l.lwz r16, 20(r3)
|
||||
l.lwz r18, 24(r3)
|
||||
l.lwz r20, 28(r3)
|
||||
l.lwz r22, 32(r3)
|
||||
l.lwz r24, 36(r3)
|
||||
l.lwz r26, 40(r3)
|
||||
l.lwz r28, 44(r3)
|
||||
l.lwz r30, 48(r3)
|
||||
l.jr r9
|
||||
l.nop
|
||||
@@ -0,0 +1,27 @@
|
||||
.global ___setjmp
|
||||
.hidden ___setjmp
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
___setjmp:
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
l.sw 0(r3), r1
|
||||
l.sw 4(r3), r2
|
||||
l.sw 8(r3), r9
|
||||
l.sw 12(r3), r10
|
||||
l.sw 16(r3), r14
|
||||
l.sw 20(r3), r16
|
||||
l.sw 24(r3), r18
|
||||
l.sw 28(r3), r20
|
||||
l.sw 32(r3), r22
|
||||
l.sw 36(r3), r24
|
||||
l.sw 40(r3), r26
|
||||
l.sw 44(r3), r28
|
||||
l.sw 48(r3), r30
|
||||
l.jr r9
|
||||
l.ori r11,r0,0
|
||||
@@ -0,0 +1,69 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
/*
|
||||
* void longjmp(jmp_buf env, int val);
|
||||
* put val into return register and restore the env saved in setjmp
|
||||
* if val(r4) is 0, put 1 there.
|
||||
*/
|
||||
/* 0) move old return address into r0 */
|
||||
lwz 0, 0(3)
|
||||
/* 1) put it into link reg */
|
||||
mtlr 0
|
||||
/* 2 ) restore stack ptr */
|
||||
lwz 1, 4(3)
|
||||
/* 3) restore control reg */
|
||||
lwz 0, 8(3)
|
||||
mtcr 0
|
||||
/* 4) restore r14-r31 */
|
||||
lwz 14, 12(3)
|
||||
lwz 15, 16(3)
|
||||
lwz 16, 20(3)
|
||||
lwz 17, 24(3)
|
||||
lwz 18, 28(3)
|
||||
lwz 19, 32(3)
|
||||
lwz 20, 36(3)
|
||||
lwz 21, 40(3)
|
||||
lwz 22, 44(3)
|
||||
lwz 23, 48(3)
|
||||
lwz 24, 52(3)
|
||||
lwz 25, 56(3)
|
||||
lwz 26, 60(3)
|
||||
lwz 27, 64(3)
|
||||
lwz 28, 68(3)
|
||||
lwz 29, 72(3)
|
||||
lwz 30, 76(3)
|
||||
lwz 31, 80(3)
|
||||
#ifndef _SOFT_FLOAT
|
||||
lfd 14,88(3)
|
||||
lfd 15,96(3)
|
||||
lfd 16,104(3)
|
||||
lfd 17,112(3)
|
||||
lfd 18,120(3)
|
||||
lfd 19,128(3)
|
||||
lfd 20,136(3)
|
||||
lfd 21,144(3)
|
||||
lfd 22,152(3)
|
||||
lfd 23,160(3)
|
||||
lfd 24,168(3)
|
||||
lfd 25,176(3)
|
||||
lfd 26,184(3)
|
||||
lfd 27,192(3)
|
||||
lfd 28,200(3)
|
||||
lfd 29,208(3)
|
||||
lfd 30,216(3)
|
||||
lfd 31,224(3)
|
||||
#endif
|
||||
/* 5) put val into return reg r3 */
|
||||
mr 3, 4
|
||||
|
||||
/* 6) check if return value is 0, make it 1 in that case */
|
||||
cmpwi cr7, 4, 0
|
||||
bne cr7, 1f
|
||||
li 3, 1
|
||||
1:
|
||||
blr
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
.global ___setjmp
|
||||
.hidden ___setjmp
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
___setjmp:
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
/* 0) store IP int 0, then into the jmpbuf pointed to by r3 (first arg) */
|
||||
mflr 0
|
||||
stw 0, 0(3)
|
||||
/* 1) store reg1 (SP) */
|
||||
stw 1, 4(3)
|
||||
/* 2) store cr */
|
||||
mfcr 0
|
||||
stw 0, 8(3)
|
||||
/* 3) store r14-31 */
|
||||
stw 14, 12(3)
|
||||
stw 15, 16(3)
|
||||
stw 16, 20(3)
|
||||
stw 17, 24(3)
|
||||
stw 18, 28(3)
|
||||
stw 19, 32(3)
|
||||
stw 20, 36(3)
|
||||
stw 21, 40(3)
|
||||
stw 22, 44(3)
|
||||
stw 23, 48(3)
|
||||
stw 24, 52(3)
|
||||
stw 25, 56(3)
|
||||
stw 26, 60(3)
|
||||
stw 27, 64(3)
|
||||
stw 28, 68(3)
|
||||
stw 29, 72(3)
|
||||
stw 30, 76(3)
|
||||
stw 31, 80(3)
|
||||
#ifndef _SOFT_FLOAT
|
||||
stfd 14,88(3)
|
||||
stfd 15,96(3)
|
||||
stfd 16,104(3)
|
||||
stfd 17,112(3)
|
||||
stfd 18,120(3)
|
||||
stfd 19,128(3)
|
||||
stfd 20,136(3)
|
||||
stfd 21,144(3)
|
||||
stfd 22,152(3)
|
||||
stfd 23,160(3)
|
||||
stfd 24,168(3)
|
||||
stfd 25,176(3)
|
||||
stfd 26,184(3)
|
||||
stfd 27,192(3)
|
||||
stfd 28,200(3)
|
||||
stfd 29,208(3)
|
||||
stfd 30,216(3)
|
||||
stfd 31,224(3)
|
||||
#endif
|
||||
/* 4) set return value to 0 */
|
||||
li 3, 0
|
||||
/* 5) return */
|
||||
blr
|
||||
@@ -0,0 +1,81 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
# 0) move old return address into the link register
|
||||
ld 0, 0*8(3)
|
||||
mtlr 0
|
||||
# 1) restore cr
|
||||
ld 0, 1*8(3)
|
||||
mtcr 0
|
||||
# 2) restore SP
|
||||
ld 1, 2*8(3)
|
||||
# 3) restore TOC into both r2 and the caller's stack.
|
||||
# Which location is required depends on whether setjmp was called
|
||||
# locally or non-locally, but it's always safe to restore to both.
|
||||
ld 2, 3*8(3)
|
||||
std 2, 24(1)
|
||||
# 4) restore r14-r31
|
||||
ld 14, 4*8(3)
|
||||
ld 15, 5*8(3)
|
||||
ld 16, 6*8(3)
|
||||
ld 17, 7*8(3)
|
||||
ld 18, 8*8(3)
|
||||
ld 19, 9*8(3)
|
||||
ld 20, 10*8(3)
|
||||
ld 21, 11*8(3)
|
||||
ld 22, 12*8(3)
|
||||
ld 23, 13*8(3)
|
||||
ld 24, 14*8(3)
|
||||
ld 25, 15*8(3)
|
||||
ld 26, 16*8(3)
|
||||
ld 27, 17*8(3)
|
||||
ld 28, 18*8(3)
|
||||
ld 29, 19*8(3)
|
||||
ld 30, 20*8(3)
|
||||
ld 31, 21*8(3)
|
||||
# 5) restore floating point registers f14-f31
|
||||
lfd 14, 22*8(3)
|
||||
lfd 15, 23*8(3)
|
||||
lfd 16, 24*8(3)
|
||||
lfd 17, 25*8(3)
|
||||
lfd 18, 26*8(3)
|
||||
lfd 19, 27*8(3)
|
||||
lfd 20, 28*8(3)
|
||||
lfd 21, 29*8(3)
|
||||
lfd 22, 30*8(3)
|
||||
lfd 23, 31*8(3)
|
||||
lfd 24, 32*8(3)
|
||||
lfd 25, 33*8(3)
|
||||
lfd 26, 34*8(3)
|
||||
lfd 27, 35*8(3)
|
||||
lfd 28, 36*8(3)
|
||||
lfd 29, 37*8(3)
|
||||
lfd 30, 38*8(3)
|
||||
lfd 31, 39*8(3)
|
||||
|
||||
# 6) restore vector registers v20-v31
|
||||
addi 3, 3, 40*8
|
||||
lvx 20, 0, 3 ; addi 3, 3, 16
|
||||
lvx 21, 0, 3 ; addi 3, 3, 16
|
||||
lvx 22, 0, 3 ; addi 3, 3, 16
|
||||
lvx 23, 0, 3 ; addi 3, 3, 16
|
||||
lvx 24, 0, 3 ; addi 3, 3, 16
|
||||
lvx 25, 0, 3 ; addi 3, 3, 16
|
||||
lvx 26, 0, 3 ; addi 3, 3, 16
|
||||
lvx 27, 0, 3 ; addi 3, 3, 16
|
||||
lvx 28, 0, 3 ; addi 3, 3, 16
|
||||
lvx 29, 0, 3 ; addi 3, 3, 16
|
||||
lvx 30, 0, 3 ; addi 3, 3, 16
|
||||
lvx 31, 0, 3
|
||||
|
||||
# 7) return r4 ? r4 : 1
|
||||
mr 3, 4
|
||||
cmpwi cr7, 4, 0
|
||||
bne cr7, 1f
|
||||
li 3, 1
|
||||
1:
|
||||
blr
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
ld 5, 24(1) # load from the TOC slot in the caller's stack frame
|
||||
b __setjmp_toc
|
||||
|
||||
.localentry __setjmp,.-__setjmp
|
||||
.localentry _setjmp,.-_setjmp
|
||||
.localentry setjmp,.-setjmp
|
||||
mr 5, 2
|
||||
|
||||
.global __setjmp_toc
|
||||
.hidden __setjmp_toc
|
||||
# same as normal setjmp, except TOC pointer to save is provided in r5.
|
||||
# r4 would normally be the 2nd parameter, but we're using r5 to simplify calling from sigsetjmp.
|
||||
# solves the problem of knowing whether to save the TOC pointer from r2 or the caller's stack frame.
|
||||
__setjmp_toc:
|
||||
# 0) store IP into 0, then into the jmpbuf pointed to by r3 (first arg)
|
||||
mflr 0
|
||||
std 0, 0*8(3)
|
||||
# 1) store cr
|
||||
mfcr 0
|
||||
std 0, 1*8(3)
|
||||
# 2) store SP and TOC
|
||||
std 1, 2*8(3)
|
||||
std 5, 3*8(3)
|
||||
# 3) store r14-31
|
||||
std 14, 4*8(3)
|
||||
std 15, 5*8(3)
|
||||
std 16, 6*8(3)
|
||||
std 17, 7*8(3)
|
||||
std 18, 8*8(3)
|
||||
std 19, 9*8(3)
|
||||
std 20, 10*8(3)
|
||||
std 21, 11*8(3)
|
||||
std 22, 12*8(3)
|
||||
std 23, 13*8(3)
|
||||
std 24, 14*8(3)
|
||||
std 25, 15*8(3)
|
||||
std 26, 16*8(3)
|
||||
std 27, 17*8(3)
|
||||
std 28, 18*8(3)
|
||||
std 29, 19*8(3)
|
||||
std 30, 20*8(3)
|
||||
std 31, 21*8(3)
|
||||
# 4) store floating point registers f14-f31
|
||||
stfd 14, 22*8(3)
|
||||
stfd 15, 23*8(3)
|
||||
stfd 16, 24*8(3)
|
||||
stfd 17, 25*8(3)
|
||||
stfd 18, 26*8(3)
|
||||
stfd 19, 27*8(3)
|
||||
stfd 20, 28*8(3)
|
||||
stfd 21, 29*8(3)
|
||||
stfd 22, 30*8(3)
|
||||
stfd 23, 31*8(3)
|
||||
stfd 24, 32*8(3)
|
||||
stfd 25, 33*8(3)
|
||||
stfd 26, 34*8(3)
|
||||
stfd 27, 35*8(3)
|
||||
stfd 28, 36*8(3)
|
||||
stfd 29, 37*8(3)
|
||||
stfd 30, 38*8(3)
|
||||
stfd 31, 39*8(3)
|
||||
|
||||
# 5) store vector registers v20-v31
|
||||
addi 3, 3, 40*8
|
||||
stvx 20, 0, 3 ; addi 3, 3, 16
|
||||
stvx 21, 0, 3 ; addi 3, 3, 16
|
||||
stvx 22, 0, 3 ; addi 3, 3, 16
|
||||
stvx 23, 0, 3 ; addi 3, 3, 16
|
||||
stvx 24, 0, 3 ; addi 3, 3, 16
|
||||
stvx 25, 0, 3 ; addi 3, 3, 16
|
||||
stvx 26, 0, 3 ; addi 3, 3, 16
|
||||
stvx 27, 0, 3 ; addi 3, 3, 16
|
||||
stvx 28, 0, 3 ; addi 3, 3, 16
|
||||
stvx 29, 0, 3 ; addi 3, 3, 16
|
||||
stvx 30, 0, 3 ; addi 3, 3, 16
|
||||
stvx 31, 0, 3
|
||||
|
||||
# 6) return 0
|
||||
li 3, 0
|
||||
blr
|
||||
@@ -0,0 +1,23 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
|
||||
1:
|
||||
lmg %r6, %r15, 0(%r2)
|
||||
|
||||
ld %f8, 10*8(%r2)
|
||||
ld %f9, 11*8(%r2)
|
||||
ld %f10, 12*8(%r2)
|
||||
ld %f11, 13*8(%r2)
|
||||
ld %f12, 14*8(%r2)
|
||||
ld %f13, 15*8(%r2)
|
||||
ld %f14, 16*8(%r2)
|
||||
ld %f15, 17*8(%r2)
|
||||
|
||||
ltgr %r2, %r3
|
||||
bnzr %r14
|
||||
lhi %r2, 1
|
||||
br %r14
|
||||
@@ -0,0 +1,25 @@
|
||||
.global ___setjmp
|
||||
.hidden ___setjmp
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
___setjmp:
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
stmg %r6, %r15, 0(%r2)
|
||||
|
||||
std %f8, 10*8(%r2)
|
||||
std %f9, 11*8(%r2)
|
||||
std %f10, 12*8(%r2)
|
||||
std %f11, 13*8(%r2)
|
||||
std %f12, 14*8(%r2)
|
||||
std %f13, 15*8(%r2)
|
||||
std %f14, 16*8(%r2)
|
||||
std %f15, 17*8(%r2)
|
||||
|
||||
lghi %r2, 0
|
||||
br %r14
|
||||
@@ -0,0 +1,28 @@
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp, @function
|
||||
.type longjmp, @function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
mov.l @r4+, r8
|
||||
mov.l @r4+, r9
|
||||
mov.l @r4+, r10
|
||||
mov.l @r4+, r11
|
||||
mov.l @r4+, r12
|
||||
mov.l @r4+, r13
|
||||
mov.l @r4+, r14
|
||||
mov.l @r4+, r15
|
||||
lds.l @r4+, pr
|
||||
#if __SH_FPU_ANY__ || __SH4__
|
||||
fmov.s @r4+, fr12
|
||||
fmov.s @r4+, fr13
|
||||
fmov.s @r4+, fr14
|
||||
fmov.s @r4+, fr15
|
||||
#endif
|
||||
|
||||
tst r5, r5
|
||||
movt r0
|
||||
add r5, r0
|
||||
|
||||
rts
|
||||
nop
|
||||
@@ -0,0 +1,32 @@
|
||||
.global ___setjmp
|
||||
.hidden ___setjmp
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp, @function
|
||||
.type _setjmp, @function
|
||||
.type setjmp, @function
|
||||
___setjmp:
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
setjmp:
|
||||
#if __SH_FPU_ANY__ || __SH4__
|
||||
add #52, r4
|
||||
fmov.s fr15, @-r4
|
||||
fmov.s fr14, @-r4
|
||||
fmov.s fr13, @-r4
|
||||
fmov.s fr12, @-r4
|
||||
#else
|
||||
add #36, r4
|
||||
#endif
|
||||
sts.l pr, @-r4
|
||||
mov.l r15, @-r4
|
||||
mov.l r14, @-r4
|
||||
mov.l r13, @-r4
|
||||
mov.l r12, @-r4
|
||||
mov.l r11, @-r4
|
||||
mov.l r10, @-r4
|
||||
mov.l r9, @-r4
|
||||
mov.l r8, @-r4
|
||||
rts
|
||||
mov #0, r0
|
||||
@@ -0,0 +1,22 @@
|
||||
/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
mov %rsi,%rax /* val will be longjmp return */
|
||||
test %rax,%rax
|
||||
jnz 1f
|
||||
inc %rax /* if val==0, val=1 per longjmp semantics */
|
||||
1:
|
||||
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),%rdx /* this ends up being the stack pointer */
|
||||
mov %rdx,%rsp
|
||||
mov 56(%rdi),%rdx /* this is the instruction pointer */
|
||||
jmp *%rdx /* goto saved address without altering rsp */
|
||||
@@ -0,0 +1,22 @@
|
||||
/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
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 %rax,%rax /* always return 0 */
|
||||
ret
|
||||
@@ -0,0 +1,22 @@
|
||||
/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
|
||||
.global _longjmp
|
||||
.global longjmp
|
||||
.type _longjmp,@function
|
||||
.type longjmp,@function
|
||||
_longjmp:
|
||||
longjmp:
|
||||
mov %rsi,%rax /* val will be longjmp return */
|
||||
test %rax,%rax
|
||||
jnz 1f
|
||||
inc %rax /* if val==0, val=1 per longjmp semantics */
|
||||
1:
|
||||
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),%rdx /* this ends up being the stack pointer */
|
||||
mov %rdx,%rsp
|
||||
mov 56(%rdi),%rdx /* this is the instruction pointer */
|
||||
jmp *%rdx /* goto saved address without altering rsp */
|
||||
@@ -0,0 +1,22 @@
|
||||
/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
|
||||
.global __setjmp
|
||||
.global _setjmp
|
||||
.global setjmp
|
||||
.type __setjmp,@function
|
||||
.type _setjmp,@function
|
||||
.type setjmp,@function
|
||||
__setjmp:
|
||||
_setjmp:
|
||||
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 %rax,%rax /* always return 0 */
|
||||
ret
|
||||
@@ -0,0 +1,62 @@
|
||||
//! setjmp implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/setjmp.h.html
|
||||
|
||||
#![no_std]
|
||||
|
||||
extern crate platform;
|
||||
|
||||
use platform::types::*;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulong; 22];
|
||||
#[cfg(target_arch = "arm")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulonglong; 32];
|
||||
#[cfg(target_arch = "i386")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulong; 6];
|
||||
#[cfg(target_arch = "m68k")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulong; 39];
|
||||
#[cfg(target_arch = "microblaze")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulong; 18];
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulonglong; 13];
|
||||
#[cfg(target_arch = "mips64")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulonglong; 23];
|
||||
#[cfg(target_arch = "mipsn32")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulonglong; 23];
|
||||
#[cfg(target_arch = "or1k")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulong; 13];
|
||||
#[cfg(target_arch = "powerpc")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulonglong; 56];
|
||||
#[cfg(target_arch = "powerpc64")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [u128; 32];
|
||||
#[cfg(target_arch = "s390x")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulong; 18];
|
||||
#[cfg(target_arch = "sh")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulong; 15];
|
||||
#[cfg(target_arch = "x32")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulonglong; 8];
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type jmp_buf = [c_ulong; 8];
|
||||
|
||||
#[link(name = "setjmp", kind = "static")]
|
||||
extern "C" {
|
||||
fn setjmp(buf: jmp_buf) -> c_int;
|
||||
}
|
||||
#[link(name = "longjmp", kind = "static")]
|
||||
extern "C" {
|
||||
fn longjmp(buf: jmp_buf, val: c_int);
|
||||
}
|
||||
@@ -412,10 +412,10 @@ pub extern "C" fn qsort(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn rand() -> c_int {
|
||||
match RNG {
|
||||
Some(ref mut rng) => rng.gen_range::<c_int>(0, RAND_MAX),
|
||||
Some(ref mut rng) => rng.gen_range(0, RAND_MAX),
|
||||
None => {
|
||||
let mut rng = XorShiftRng::from_seed([1; 16]);
|
||||
let ret = rng.gen_range::<c_int>(0, RAND_MAX);
|
||||
let ret = rng.gen_range(0, RAND_MAX);
|
||||
RNG = Some(rng);
|
||||
ret
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
/rename
|
||||
/scanf
|
||||
/setid
|
||||
/setid
|
||||
/setjmp
|
||||
/sleep
|
||||
/sprintf
|
||||
/stdlib/a64l
|
||||
|
||||
@@ -23,6 +23,7 @@ EXPECT_BINS=\
|
||||
rename \
|
||||
rmdir \
|
||||
scanf \
|
||||
setjmp \
|
||||
sleep \
|
||||
sprintf \
|
||||
stdio/fwrite \
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
jumping...
|
||||
hi from jump
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
int main() {
|
||||
jmp_buf buf;
|
||||
if (setjmp(buf)) {
|
||||
puts("hi from jump");
|
||||
} else {
|
||||
puts("jumping...");
|
||||
longjmp(buf, 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user