arch: ppc: new port

arm_linker_fix
William Pitcock 2018-02-02 18:45:42 +00:00
parent 66919bb222
commit f3fe8ea781
7 changed files with 294 additions and 0 deletions

View File

@ -17,3 +17,4 @@ Right now these archs are supported:
* x86_64
* armv6+ (`arm`)
* aarch64
* ppc

62
arch/ppc/defs.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef __ARCH_PPC_DEFS_H
#define __ARCH_PPC_DEFS_H
#define REG_R0 (0)
#define REG_R1 (1)
#define REG_R2 (2)
#define REG_R3 (3)
#define REG_R4 (4)
#define REG_R5 (5)
#define REG_R6 (6)
#define REG_R7 (7)
#define REG_R8 (8)
#define REG_R9 (9)
#define REG_R10 (10)
#define REG_R11 (11)
#define REG_R12 (12)
#define REG_R13 (13)
#define REG_R14 (14)
#define REG_R15 (15)
#define REG_R16 (16)
#define REG_R17 (17)
#define REG_R18 (18)
#define REG_R19 (19)
#define REG_R20 (20)
#define REG_R21 (21)
#define REG_R22 (22)
#define REG_R23 (23)
#define REG_R24 (24)
#define REG_R25 (25)
#define REG_R26 (26)
#define REG_R27 (27)
#define REG_R28 (28)
#define REG_R29 (29)
#define REG_R30 (30)
#define REG_R31 (31)
#define REG_R32 (32)
#define REG_R33 (33)
#define REG_R34 (34)
#define REG_R35 (35)
#define REG_R36 (36)
#define REG_R37 (37)
#define REG_R38 (38)
#define REG_R39 (39)
#define REG_R40 (40)
#define REG_R41 (41)
#define REG_R42 (42)
#define REG_R43 (43)
#define REG_R44 (44)
#define REG_R45 (45)
#define REG_R46 (46)
#define REG_R47 (47)
/* sp register is actually %r1 */
#define REG_SP REG_R1
/* nip register is actually %srr0 (r32) */
#define REG_NIP REG_R32
/* lnk register is actually r32 */
#define REG_LNK REG_R36
#endif

45
arch/ppc/getcontext.c Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stddef.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
int
__getcontext(ucontext_t *ucp)
{
#ifdef SYS_swapcontext
int r;
r = syscall(SYS_swapcontext, ucp, NULL, sizeof(ucontext_t));
if (r < 0)
{
errno = -r;
return -1;
}
return 0;
#else
errno = ENOSYS;
return -1;
#endif
}
extern __typeof(__getcontext) getcontext __attribute__((weak, __alias__("__getcontext")));

75
arch/ppc/makecontext.c Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stddef.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include "defs.h"
extern void __start_context(void);
void
__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
greg_t *sp, *argp;
va_list va;
int i;
unsigned int uc_link, stack_args;
stack_args = argc > 8 ? argc - 8 : 0;
uc_link = stack_args + 1;
sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp -= (uc_link + 1);
sp = (greg_t *) (((uintptr_t) sp & -16L) - 8);
ucp->uc_mcontext.gregs[REG_NIP] = (uintptr_t) func;
ucp->uc_mcontext.gregs[REG_LNK] = (uintptr_t) &__start_context;
ucp->uc_mcontext.gregs[REG_R31] = (uintptr_t) ucp->uc_link;
ucp->uc_mcontext.gregs[REG_SP] = (uintptr_t) sp;
sp[0] = (uintptr_t) &__start_context;
sp[uc_link] = (uintptr_t) ucp->uc_link;
argp = &sp[2];
va_start(va, argc);
for (i = 0; i < argc; i++)
switch (i)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
ucp->uc_mcontext.gregs[i + 3] = va_arg (va, greg_t);
break;
default:
*argp++ = va_arg (va, greg_t);
break;
}
va_end(va);
}
extern __typeof(__makecontext) makecontext __attribute__((weak, __alias__("__makecontext")));

45
arch/ppc/setcontext.c Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stddef.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
int
__setcontext(const ucontext_t *ucp)
{
#ifdef SYS_swapcontext
int r;
r = syscall(SYS_swapcontext, NULL, (void *) ucp, sizeof(ucontext_t));
if (r < 0)
{
errno = -r;
return -1;
}
return r;
#else
errno = ENOSYS;
return -1;
#endif
}
extern __typeof(__setcontext) setcontext __attribute__((weak, __alias__("__setcontext")));

21
arch/ppc/startcontext.S Normal file
View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
.globl __start_context;
__start_context:
/* get the proper context into position and test for NULL */
mr. 3,31
beq hosed
bl __setcontext@local
hosed:
b exit@GOT

45
arch/ppc/swapcontext.c Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018 William Pitcock <nenolod@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#define _GNU_SOURCE
#include <stddef.h>
#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
int
__swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
{
#ifdef SYS_swapcontext
int r;
r = syscall(SYS_swapcontext, oucp, ucp, sizeof(ucontext_t));
if (r < 0)
{
errno = -r;
return -1;
}
return r;
#else
errno = ENOSYS;
return -1;
#endif
}
extern __typeof(__swapcontext) swapcontext __attribute__((weak, __alias__("__swapcontext")));