forked from ariadne/libucontext
arch: ppc64: now working
parent
9e5aba6b48
commit
71979e9cf6
|
@ -21,3 +21,4 @@ Right now these archs are supported and should work on bare metal:
|
||||||
These archs require kernel assistance and use a syscall (the only assembly is the trampoline):
|
These archs require kernel assistance and use a syscall (the only assembly is the trampoline):
|
||||||
|
|
||||||
* ppc
|
* ppc
|
||||||
|
* ppc64 (ELFv2 ABI spec only, ELFv1 not supported)
|
||||||
|
|
|
@ -56,7 +56,10 @@
|
||||||
/* nip register is actually %srr0 (r32) */
|
/* nip register is actually %srr0 (r32) */
|
||||||
#define REG_NIP REG_R32
|
#define REG_NIP REG_R32
|
||||||
|
|
||||||
/* lnk register is actually r32 */
|
/* entry register is actually %r12 */
|
||||||
|
#define REG_ENTRY REG_R12
|
||||||
|
|
||||||
|
/* lnk register is actually %r36 */
|
||||||
#define REG_LNK REG_R36
|
#define REG_LNK REG_R36
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,10 +39,11 @@ __makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
|
||||||
sp -= (uc_link + 1);
|
sp -= (uc_link + 1);
|
||||||
sp = (greg_t *) (((uintptr_t) sp & -16L));
|
sp = (greg_t *) (((uintptr_t) sp & -16L));
|
||||||
|
|
||||||
ucp->uc_mcontext.gp_regs[REG_NIP] = (uintptr_t) func;
|
ucp->uc_mcontext.gp_regs[REG_NIP] = (uintptr_t) func;
|
||||||
ucp->uc_mcontext.gp_regs[REG_LNK] = (uintptr_t) &__start_context;
|
ucp->uc_mcontext.gp_regs[REG_LNK] = (uintptr_t) &__start_context;
|
||||||
ucp->uc_mcontext.gp_regs[REG_R31] = (uintptr_t) ucp->uc_link;
|
ucp->uc_mcontext.gp_regs[REG_SP] = (uintptr_t) sp;
|
||||||
ucp->uc_mcontext.gp_regs[REG_SP] = (uintptr_t) sp;
|
ucp->uc_mcontext.gp_regs[REG_ENTRY] = (uintptr_t) func;
|
||||||
|
ucp->uc_mcontext.gp_regs[REG_R31] = (uintptr_t) ucp->uc_link;
|
||||||
|
|
||||||
sp[0] = (uintptr_t) &__start_context;
|
sp[0] = (uintptr_t) &__start_context;
|
||||||
sp[uc_link] = (uintptr_t) ucp->uc_link;
|
sp[uc_link] = (uintptr_t) ucp->uc_link;
|
||||||
|
|
|
@ -13,12 +13,19 @@
|
||||||
.globl __start_context;
|
.globl __start_context;
|
||||||
.hidden __start_context;
|
.hidden __start_context;
|
||||||
__start_context:
|
__start_context:
|
||||||
/* get the proper context into position and test for NULL */
|
cmpdi 31,0 /* test if ucontext link pointer is null */
|
||||||
mr. 3,31
|
beq do_exit /* if it is, exit */
|
||||||
beq hosed
|
|
||||||
bl __setcontext
|
|
||||||
nop
|
|
||||||
|
|
||||||
hosed:
|
/* now, call SYS_swapcontext */
|
||||||
|
mr 4,31 /* ucp is in r31 */
|
||||||
|
li 3,0 /* don't care about restoring, set oucp to NULL */
|
||||||
|
li 5,1696 /* sizeof(ucontext_t) */
|
||||||
|
li 0,249 /* SYS_swapcontext */
|
||||||
|
sc
|
||||||
|
|
||||||
|
/* we should not wind back up here, if we do, exit with -1 */
|
||||||
|
li 3,-1
|
||||||
|
|
||||||
|
do_exit:
|
||||||
b exit@GOT
|
b exit@GOT
|
||||||
nop
|
nop
|
||||||
|
|
Loading…
Reference in New Issue