Remove PowerPC sysdep files for GNU Hurd and GNU Mach.

This commit is contained in:
Thomas Schwinge 2012-11-01 19:41:23 +01:00
parent 4da224a2d1
commit 6f796e1b52
15 changed files with 5 additions and 1501 deletions

View File

@ -1,3 +1,8 @@
2012-11-01 Thomas Schwinge <thomas@codesourcery.com>
* sysdeps/mach/hurd/powerpc: Remove directory.
* sysdeps/mach/powerpc: Likewise.
2012-11-01 Andreas Schwab <schwab@linux-m68k.org>
* scripts/check-local-headers.sh: Ignore c++ headers.

View File

@ -1,79 +0,0 @@
/* Machine-dependent signal context structure for GNU Hurd. PowerPC version.
Copyright (C) 2001,02 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <http://www.gnu.org/licenses/>. */
#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
#endif
#ifndef sc_pc
/* Signal handlers are actually called:
void handler (int sig, int code, struct sigcontext *scp); */
/* State of this thread when the signal was taken. */
struct sigcontext
{
/* These first members are machine-independent. */
int sc_onstack; /* Nonzero if running on sigstack. */
__sigset_t sc_mask; /* Blocked signals to restore. */
/* MiG reply port this thread is using. */
unsigned int sc_reply_port;
/* Port this thread is doing an interruptible RPC on. */
unsigned int sc_intr_port;
/* Error code associated with this signal (interpreted as `error_t'). */
int sc_error;
/* All following members are machine-dependent. The rest of this
structure is written to be laid out identically to:
{
struct ppc_thread_state basic;
struct ppc_exc_state exc;
struct ppc_float_state fpu;
}
trampoline.c knows this, so it must be changed if this changes. */
#define sc_ppc_thread_state sc_srr0 /* Beginning of correspondence. */
#define sc_pc sc_srr0 /* For sysdeps/generic/profil-counter.h. */
unsigned int sc_srr0;
unsigned int sc_srr1;
unsigned int sc_gprs[32];
unsigned int sc_cr;
unsigned int sc_xer;
unsigned int sc_lr;
unsigned int sc_ctr;
unsigned int sc_mq;
unsigned int sc_ts_pad;
#define sc_ppc_exc_state sc_dar
unsigned int sc_dar;
unsigned int sc_dsisr;
unsigned int sc_exception;
unsigned int sc_es_pad0;
unsigned int sc_es_pad1[4];
#define sc_ppc_float_state sc_fprs[0]
double sc_fprs[32];
unsigned int sc_fpscr_pad;
unsigned int sc_fpscr;
};
#endif /* sc_pc */

View File

@ -1,73 +0,0 @@
/* Translate Mach exception codes into signal numbers. PowerPC version.
Copyright (C) 1991,92,94,96,97,2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <hurd.h>
#include <hurd/signal.h>
#include <mach/exception.h>
/* Translate the Mach exception codes, as received in an `exception_raise' RPC,
into a signal number and signal subcode. */
void
_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo)
{
detail->error = 0;
switch (detail->exc)
{
default:
*signo = SIGIOT;
detail->code = detail->exc;
break;
case EXC_BAD_ACCESS:
if (detail->exc_code == KERN_PROTECTION_FAILURE)
*signo = SIGSEGV;
else
*signo = SIGBUS;
detail->code = detail->exc_subcode;
detail->error = detail->exc_code;
break;
/* XXX there has got to be something more here */
case EXC_BAD_INSTRUCTION:
*signo = SIGILL;
detail->code = 0;
break;
case EXC_ARITHMETIC:
*signo = SIGFPE;
detail->code = 0;
break;
case EXC_EMULATION:
*signo = SIGEMT;
detail->code = 0;
break;
case EXC_SOFTWARE:
*signo = SIGEMT;
detail->code = 0;
break;
case EXC_BREAKPOINT:
*signo = SIGTRAP;
detail->code = 0;
}
}

View File

@ -1,342 +0,0 @@
/* Initialization code run first thing by the ELF startup code. PowerPC/Hurd.
Copyright (C) 1995-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <assert.h>
#include <ctype.h>
#include <hurd.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sysdep.h>
#include <set-hooks.h>
#include "hurdstartup.h"
#include "hurdmalloc.h" /* XXX */
extern void __mach_init (void);
extern void __init_misc (int, char **, char **);
#ifdef USE_NONOPTION_FLAGS
extern void __getopt_clean_environment (char **);
#endif
#ifndef SHARED
extern void _dl_non_dynamic_init (void) internal_function;
#endif
extern void __libc_global_ctors (void);
unsigned int __hurd_threadvar_max;
unsigned long int __hurd_threadvar_stack_offset;
unsigned long int __hurd_threadvar_stack_mask;
#ifndef SHARED
int __libc_enable_secure;
#endif
int __libc_multiple_libcs attribute_hidden = 1;
extern int __libc_argc attribute_hidden;
extern char **__libc_argv attribute_hidden;
extern char **_dl_argv;
void *(*_cthread_init_routine) (void); /* Returns new SP to use. */
void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__));
#ifndef SHARED
static unsigned int return_address; /* Make init1 return to _start. */
#endif
/* Things that want to be run before _hurd_init or much anything else.
Importantly, these are called before anything tries to use malloc. */
DEFINE_HOOK (_hurd_preinit_hook, (void));
/* We call this once the Hurd magic is all set up and we are ready to be a
Posixoid program. This does the same things the generic version does. */
static void internal_function
posixland_init (int argc, char **argv, char **envp)
{
asm ("li 3,0xbb; .long 0");
__libc_argc = argc;
__libc_argv = argv;
__environ = envp;
#ifndef SHARED
_dl_non_dynamic_init ();
#endif
__init_misc (argc, argv, envp);
#ifdef USE_NONOPTION_FLAGS
/* This is a hack to make the special getopt in GNU libc working. */
__getopt_clean_environment (__environ);
#endif
/* Initialize ctype data. */
__ctype_init ();
#if defined SHARED && !defined NO_CTORS_DTORS_SECTIONS
__libc_global_ctors ();
#endif
}
static void
init1 (int *data)
{
int argc = *data;
char **argv = (char **) &data[1];
char **envp = &argv[argc + 1];
struct hurd_startup_data *d;
while (*envp)
++envp;
d = (void *) ++envp;
/* If we are the bootstrap task started by the kernel,
then after the environment pointers there is no Hurd
data block; the argument strings start there. */
/* OSF Mach starts the bootstrap task with argc == 0.
XXX This fails if a non-bootstrap task gets started
with argc == 0. */
if (argc && (void *) d != argv[0])
{
_hurd_init_dtable = d->dtable;
_hurd_init_dtablesize = d->dtablesize;
#if 0 /* We can't free the old stack because it contains the argument strings. */
{
/* Check if the stack we are now on is different from
the one described by _hurd_stack_{base,size}. */
char dummy;
const vm_address_t newsp = (vm_address_t) &dummy;
if (d->stack_size != 0 && (newsp < d->stack_base ||
newsp - d->stack_base > d->stack_size))
/* The new stack pointer does not intersect with the
stack the exec server set up for us, so free that stack. */
__vm_deallocate (__mach_task_self (), d->stack_base, d->stack_size);
}
#endif
}
if (argc && (void *) d != argv[0] && (d->portarray || d->intarray))
/* Initialize library data structures, start signal processing, etc. */
_hurd_init (d->flags, argv,
d->portarray, d->portarraysize,
d->intarray, d->intarraysize);
#ifndef SHARED
__libc_enable_secure = d->flags & EXEC_SECURE;
#endif
}
static inline void
init (int *data)
{
int argc = *data;
char **argv = (void *) (data + 1);
char **envp = &argv[argc + 1];
struct hurd_startup_data *d;
unsigned long int threadvars[_HURD_THREADVAR_MAX];
/* Provide temporary storage for thread-specific variables on the startup
stack so the cthreads initialization code can use them for malloc et al,
or so we can use malloc below for the real threadvars array. */
memset (threadvars, 0, sizeof threadvars);
__hurd_threadvar_stack_offset = (unsigned long int) threadvars;
while (*envp)
++envp;
d = (void *) ++envp;
/* The user might have defined a value for this, to get more variables.
Otherwise it will be zero on startup. We must make sure it is set
properly before before cthreads initialization, so cthreads can know
how much space to leave for thread variables. */
if (__hurd_threadvar_max < _HURD_THREADVAR_MAX)
__hurd_threadvar_max = _HURD_THREADVAR_MAX;
/* After possibly switching stacks, call `init1' (above) with the user
code as the return address, and the argument data immediately above
that on the stack. */
if (_cthread_init_routine)
{
/* Initialize cthreads, which will allocate us a new stack to run on. */
void *newsp = (*_cthread_init_routine) ();
struct hurd_startup_data *od;
#ifdef SHARED
void *oldsp;
unsigned int i, data_offset;
#endif
/* Copy per-thread variables from that temporary
area onto the new cthread stack. */
memcpy (__hurd_threadvar_location_from_sp (0, newsp),
threadvars, sizeof threadvars);
/* Copy the argdata from the old stack to the new one. */
newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data,
(char *) d - (char *) data);
#ifdef SHARED
/* And readjust the dynamic linker's idea of where the argument
vector lives. */
assert (_dl_argv == argv);
_dl_argv = (void *) ((int *) newsp + 1);
#endif
/* Set up the Hurd startup data block immediately following
the argument and environment pointers on the new stack. */
od = (newsp + ((char *) d - (char *) data));
if (!argc || (void *) argv[0] == d)
/* We were started up by the kernel with arguments on the stack.
There is no Hurd startup data, so zero the block. */
memset (od, 0, sizeof *od);
else
/* Copy the Hurd startup data block to the new stack. */
*od = *d;
#ifndef SHARED
asm ("mtlr %0; mr 1,%1; li 0,0; mr 3,%1; stwu 0,-16(1); b init1"
: : "r" (return_address), "r" (newsp));
(void) init1; /* To avoid `defined but not used' warning. */
/* NOTREACHED */
#else
/* Copy the rest of the stack. Don't call a function to do that,
because that will alter the current stack. */
asm ("mr %0,1" : "=r" (oldsp));
data_offset = (unsigned int) data - (unsigned int) oldsp;
newsp -= data_offset;
for (i = 0; i < data_offset / 4; i++)
((unsigned int *)newsp)[i] = ((unsigned int *)oldsp)[i];
/* Relocate stack frames. */
{
unsigned int *oldframe0 = (unsigned int *)oldsp;
unsigned int *oldframe1 = *(unsigned int **)oldframe0;
unsigned int *oldframe2 = *(unsigned int **)oldframe1;
unsigned int *newframe0 = (unsigned int *)newsp;
unsigned int *newframe1 = newframe0 + (unsigned int)(oldframe1 - oldframe0);
unsigned int *newframe2 = newframe1 + (unsigned int)(oldframe2 - oldframe1);
*(unsigned int **)newframe0 = newframe1;
*(unsigned int **)newframe1 = newframe2;
}
asm ("mr 1,%0; mr 31,%0" : : "r" (newsp)); /* XXX */
init1 (newsp + data_offset);
#endif
}
else
{
/* We are not using cthreads, so we will have just a single allocated
area for the per-thread variables of the main user thread. */
unsigned long int *array;
unsigned int i;
array = malloc (__hurd_threadvar_max * sizeof (unsigned long int));
if (array == NULL)
__libc_fatal ("Can't allocate single-threaded thread variables.");
/* Copy per-thread variables from the temporary array into the
newly malloc'd space. */
memcpy (array, threadvars, sizeof threadvars);
__hurd_threadvar_stack_offset = (unsigned long int) array;
for (i = _HURD_THREADVAR_MAX; i < __hurd_threadvar_max; ++i)
array[i] = 0;
#ifndef SHARED
asm ("mr 3,%0; mtlr %1; addi 1,3,-16; b init1"
: : "r" (data), "r" (return_address));
/* NOTREACHED */
#else
init1 (data);
#endif
}
}
/* Do the first essential initializations that must precede all else. */
static inline void
first_init (void)
{
/* Initialize data structures so we can do RPCs. */
__mach_init ();
RUN_HOOK (_hurd_preinit_hook, ());
}
#ifdef SHARED
/* This function is called specially by the dynamic linker to do early
initialization of the shared C library before normal initializers
expecting a Posixoid environment can run. It gets called with the
stack set up just as the user will see it, so it can switch stacks. */
void
_dl_init_first (int argc, ...)
{
asm ("li 3,0xaa; .long 0");
first_init ();
init (&argc);
}
#endif
#ifdef SHARED
/* The regular posixland initialization is what goes into libc's
normal initializer. */
/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT
pointer in the dynamic section based solely on that. It is convention
for this function to be in the `.init' section, but the symbol name is
the only thing that really matters!! */
strong_alias (posixland_init, _init);
void
__libc_init_first (int argc, char **argv, char **envp)
{
/* Everything was done in the shared library initializer, _init. */
}
#else
strong_alias (posixland_init, __libc_init_first);
void
_hurd_stack_setup (int *data)
{
register unsigned int address;
asm ("mflr %0" : "=r" (address));
return_address = address;
first_init ();
_hurd_startup ((void **) data, &init);
}
#endif
/* This function is defined here so that if this file ever gets into
ld.so we will get a link error. Having this file silently included
in ld.so causes disaster, because the _init definition above will
cause ld.so to gain an init function, which is not a cool thing. */
void
_dl_start (void)
{
abort ();
}

View File

@ -1,98 +0,0 @@
/* Machine-dependent details of interruptible RPC messaging. PowerPC version.
Copyright (C) 1995,96,97,99,2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \
({ \
error_t err; \
asm (".globl _hurd_intr_rpc_msg_do_trap\n" \
".globl _hurd_intr_rpc_msg_in_trap\n" \
" mr 3, %1\n" \
" mr 4, %2\n" \
" mr 5, %3\n" \
" mr 6, %4\n" \
" mr 7, %5\n" \
" mr 8, %6\n" \
" mr 9, %7\n" \
" li 0, -25\n" \
"_hurd_intr_rpc_msg_do_trap: sc\n" \
"_hurd_intr_rpc_msg_in_trap: mr 3, %0\n" \
: "=r" (err) \
: "r" (msg), "r" (option), "r" (send_size), "r" (rcv_size), \
"r" (rcv_name), "r" (timeout), "r" (notify) \
: "0", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); \
err; \
})
static void inline
INTR_MSG_BACK_OUT (struct ppc_thread_state *state)
{
return;
}
#include "hurdfault.h"
/* This cannot be an inline function because it calls setjmp. */
#define SYSCALL_EXAMINE(state, callno) \
({ \
u_int32_t *p = (void *) ((state)->srr0 - 4); \
int result; \
_hurdsig_catch_memory_fault (p) ? 0 : \
({ \
if (result = (*p == 0x44000002)) \
/* The PC is just after an `sc' instruction. \
This is a system call in progress; %r0 holds the call number. */ \
*(callno) = (state)->r0; \
_hurdsig_end_catch_fault (); \
result; \
}); \
})
struct mach_msg_trap_args
{
/* This is the order of arguments to mach_msg_trap. */
mach_msg_header_t *msg;
mach_msg_option_t option;
mach_msg_size_t send_size;
mach_msg_size_t rcv_size;
mach_port_t rcv_name;
mach_msg_timeout_t timeout;
mach_port_t notify;
};
/* This cannot be an inline function because it calls setjmp. */
#define MSG_EXAMINE(state, msgid, rcv_name, send_name, option, timeout) \
({ \
mach_msg_header_t *msg = (mach_msg_header_t *) (state)->r3; \
*(option) = (mach_msg_option_t) (state)->r4; \
*(rcv_name) = (mach_port_t) (state)->r7; \
*(timeout) = (mach_msg_timeout_t) (state)->r8; \
(msg == 0) ? \
({ \
*(send_name) = MACH_PORT_NULL; \
*(msgid) = 0; \
0; \
}) : \
(_hurdsig_catch_memory_fault (msg) ? -1 : \
({ \
*(send_name) = msg->msgh_remote_port; \
*(msgid) = msg->msgh_id; \
_hurdsig_end_catch_fault (); \
0; \
}) \
); \
})

View File

@ -1,56 +0,0 @@
/* Perform a `longjmp' on a Mach thread_state. PowerPC version.
Copyright (C) 1991,94,95,97,2001, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <hurd/signal.h>
#include <setjmp.h>
#include <jmpbuf-offsets.h>
#include <mach/thread_status.h>
/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */
void
_hurd_longjmp_thread_state (void *state, jmp_buf env, int val)
{
struct ppc_thread_state *ts = state;
/* XXX should we set up the FPRs as well? And how? */
ts->r1 = env[0].__jmpbuf[JB_GPR1];
ts->r2 = env[0].__jmpbuf[JB_GPR2];
ts->r14 = env[0].__jmpbuf[JB_GPRS+0];
ts->r15 = env[0].__jmpbuf[JB_GPRS+1];
ts->r16 = env[0].__jmpbuf[JB_GPRS+2];
ts->r17 = env[0].__jmpbuf[JB_GPRS+3];
ts->r18 = env[0].__jmpbuf[JB_GPRS+4];
ts->r19 = env[0].__jmpbuf[JB_GPRS+5];
ts->r20 = env[0].__jmpbuf[JB_GPRS+6];
ts->r21 = env[0].__jmpbuf[JB_GPRS+7];
ts->r22 = env[0].__jmpbuf[JB_GPRS+8];
ts->r23 = env[0].__jmpbuf[JB_GPRS+9];
ts->r24 = env[0].__jmpbuf[JB_GPRS+10];
ts->r25 = env[0].__jmpbuf[JB_GPRS+11];
ts->r26 = env[0].__jmpbuf[JB_GPRS+12];
ts->r27 = env[0].__jmpbuf[JB_GPRS+13];
ts->r28 = env[0].__jmpbuf[JB_GPRS+14];
ts->r29 = env[0].__jmpbuf[JB_GPRS+15];
ts->r30 = env[0].__jmpbuf[JB_GPRS+16];
ts->r31 = env[0].__jmpbuf[JB_GPRS+17];
ts->cr = env[0].__jmpbuf[JB_CR];
ts->r3 = val ?: 1;
ts->srr0 = ts->lr = env[0].__jmpbuf[JB_LR];
}

View File

@ -1,119 +0,0 @@
/* Dump registers. PowerPC/Hurd version.
Copyright (C) 1998, 2001, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <sys/uio.h>
#include <_itoa.h>
/* This prints out the information in the following form: */
static const char dumpform[] = "\
Register dump:\n\
fp0-3: 0000030%0000031% 0000032%0000033% 0000034%0000035% 0000036%0000037%\n\
fp4-7: 0000038%0000039% 000003a%000003b% 000003c%000003d% 000003e%000003f%\n\
fp8-11: 0000040%0000041% 0000042%0000043% 0000044%0000045% 0000046%0000047%\n\
fp12-15: 0000048%0000049% 000004a%000004b% 000004c%000004d% 000004e%000004f%\n\
fp16-19: 0000050%0000051% 0000052%0000053% 0000054%0000055% 0000056%0000057%\n\
fp20-23: 0000058%0000059% 000005a%000005b% 000005c%000005d% 000005e%000005f%\n\
fp24-27: 0000060%0000061% 0000062%0000063% 0000064%0000065% 0000066%0000067%\n\
fp28-31: 0000068%0000069% 000006a%000006b% 000006c%000006d% 000006e%000006f%\n\
r0 =0000002% sp =0000003% r2 =0000004% r3 =0000005%\n\
r4 =0000006% r5 =0000007% r6 =0000008% r7 =0000009% sr0=0000000% sr1=0000001%\n\
r8 =000000a% r9 =000000b% r10=000000c% r11=000000d% cr=0000022% xer=0000023%\n\
r12=000000e% r13=000000f% r14=0000010% r15=0000011% lr=0000024% ctr=0000025%\n\
r16=0000012% r17=0000013% r18=0000014% r19=0000015% mq=0000026% fcr=0000071%\n\
r20=0000016% r21=0000017% r22=0000018% r23=0000019% dar=0000028% dsi=0000029%\n\
r24=000001a% r25=000001b% r26=000001c% r27=000001d% exc=000002a%\n\
r28=000001e% r29=000001f% r30=0000020% r31=0000021%\n\
";
/* Most of the fields are self-explanatory. 'sr0' is the next
instruction to execute, from SRR0, which may have some relationship
with the instruction that caused the exception. 'r3*' is the value
that will be returned in register 3 when the current system call
returns. 'sr1' is SRR1, bits 16-31 of which are copied from the MSR:
16 - External interrupt enable
17 - Privilege level (1=user, 0=supervisor)
18 - FP available
19 - Machine check enable (if clear, processor locks up on machine check)
20 - FP exception mode bit 0 (FP exceptions recoverable)
21 - Single-step trace enable
22 - Branch trace enable
23 - FP exception mode bit 1
25 - exception prefix (if set, exceptions are taken from 0xFFFnnnnn,
otherwise from 0x000nnnnn).
26 - Instruction address translation enabled.
27 - Data address translation enabled.
30 - Exception is recoverable (otherwise, don't try to return).
31 - Little-endian mode enable.
'Trap' is the address of the exception:
00200 - Machine check exception (memory parity error, for instance)
00300 - Data access exception (memory not mapped, see dsisr for why)
00400 - Instruction access exception (memory not mapped)
00500 - External interrupt
00600 - Alignment exception (see dsisr for more information)
00700 - Program exception (illegal/trap instruction, FP exception)
00800 - FP unavailable (should not be seen by user code)
00900 - Decrementer exception (for instance, SIGALRM)
00A00 - I/O controller interface exception
00C00 - System call exception (for instance, kill(3)).
00E00 - FP assist exception (optional FP instructions, etc.)
'dar' is the memory location, for traps 00300, 00400, 00600, 00A00.
'dsisr' has the following bits under trap 00300:
0 - direct-store error exception
1 - no page table entry for page
4 - memory access not permitted
5 - trying to access I/O controller space or using lwarx/stwcx on
non-write-cached memory
6 - access was store
9 - data access breakpoint hit
10 - segment table search failed to find translation (64-bit ppcs only)
11 - I/O controller instruction not permitted
For trap 00400, the same bits are set in SRR1 instead.
For trap 00600, bits 12-31 of the DSISR set to allow emulation of
the instruction without actually having to read it from memory.
*/
#define xtoi(x) (x >= 'a' ? x + 10 - 'a' : x - '0')
static void
register_dump (int fd, struct sigcontext *ctx)
{
char buffer[sizeof(dumpform)];
char *bufferpos;
unsigned regno;
unsigned *regs = (unsigned *)(&ctx->sc_srr0);
memcpy(buffer, dumpform, sizeof(dumpform));
/* Generate the output. */
while ((bufferpos = memchr (buffer, '%', sizeof(dumpform))))
{
regno = xtoi (bufferpos[-1]) | xtoi (bufferpos[-2]) << 4;
memset (bufferpos-2, '0', 3);
_itoa_word (regs[regno], bufferpos+1, 16, 0);
}
/* Write the output. */
write (fd, buffer, sizeof(buffer) - 1);
}
#define REGISTER_DUMP \
register_dump (fd, ctx)

View File

@ -1,185 +0,0 @@
/* Return from signal handler for Hurd. PowerPC version.
Copyright (C) 1996,97,98,2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <hurd.h>
#include <hurd/signal.h>
#include <hurd/threadvar.h>
#include <stdlib.h>
int
__sigreturn (struct sigcontext *scp)
{
struct hurd_sigstate *ss;
mach_port_t *reply_port;
if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
{
errno = EINVAL;
return -1;
}
ss = _hurd_self_sigstate ();
__spin_lock (&ss->lock);
/* Restore the set of blocked signals, and the intr_port slot. */
ss->blocked = scp->sc_mask;
ss->intr_port = scp->sc_intr_port;
/* Check for pending signals that were blocked by the old set. */
if (ss->pending & ~ss->blocked)
{
/* There are pending signals that just became unblocked. Wake up the
signal thread to deliver them. But first, squirrel away SCP where
the signal thread will notice it if it runs another handler, and
arrange to have us called over again in the new reality. */
ss->context = scp;
__spin_unlock (&ss->lock);
__msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ());
/* If a pending signal was handled, sig_post never returned. */
__spin_lock (&ss->lock);
ss->context = NULL;
}
if (scp->sc_onstack)
{
ss->sigaltstack.ss_flags &= ~SS_ONSTACK; /* XXX threadvars */
/* XXX cannot unlock until off sigstack */
abort ();
}
else
__spin_unlock (&ss->lock);
/* Destroy the MiG reply port used by the signal handler, and restore the
reply port in use by the thread when interrupted. */
reply_port =
(mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY);
if (*reply_port)
{
mach_port_t port = *reply_port;
/* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port not to
get another reply port, but avoids mig_dealloc_reply_port trying to
deallocate it after the receive fails (which it will, because the
reply port will be bogus, whether we do this or not). */
*reply_port = MACH_PORT_DEAD;
__mach_port_destroy (__mach_task_self (), port);
}
*reply_port = scp->sc_reply_port;
/* Restore FPU state. */
#define restore_fpr(n) \
asm volatile ("lfd " #n ",%0(31)" : : "i" (n * 4))
asm volatile ("mr 31,%0" : : "r" (scp->sc_fprs));
/* Restore the floating-point control/status register. */
asm volatile ("lfd 0,256(31)");
asm volatile ("mtfsf 0xff,0");
/* Restore floating-point registers. */
restore_fpr (0);
restore_fpr (1);
restore_fpr (2);
restore_fpr (3);
restore_fpr (4);
restore_fpr (5);
restore_fpr (6);
restore_fpr (7);
restore_fpr (8);
restore_fpr (9);
restore_fpr (10);
restore_fpr (11);
restore_fpr (12);
restore_fpr (13);
restore_fpr (14);
restore_fpr (15);
restore_fpr (16);
restore_fpr (17);
restore_fpr (18);
restore_fpr (19);
restore_fpr (20);
restore_fpr (21);
restore_fpr (22);
restore_fpr (23);
restore_fpr (24);
restore_fpr (25);
restore_fpr (26);
restore_fpr (27);
restore_fpr (28);
restore_fpr (29);
restore_fpr (30);
restore_fpr (31);
/* Load all the registers from the sigcontext. */
#define restore_gpr(n) \
asm volatile ("lwz " #n ",%0(31)" : : "i" (n * 4))
asm volatile ("addi 31,31,-188"); /* r31 = scp->gprs */
/* Restore the special purpose registers. */
asm volatile ("lwz 0,128(31); mtcr 0");
asm volatile ("lwz 0,132(31); mtxer 0");
asm volatile ("lwz 0,136(31); mtlr 0");
asm volatile ("lwz 0,-8(31); mtctr 0"); /* XXX this is the PC */
#if 0
asm volatile ("lwz 0,144(31); mtmq %0"); /* PPC601 only */
#endif
/* Restore the normal registers. */
restore_gpr (0);
restore_gpr (1);
restore_gpr (2);
restore_gpr (3);
restore_gpr (4);
restore_gpr (5);
restore_gpr (6);
restore_gpr (7);
restore_gpr (8);
restore_gpr (9);
restore_gpr (10);
restore_gpr (11);
restore_gpr (12);
restore_gpr (13);
restore_gpr (14);
restore_gpr (15);
restore_gpr (16);
restore_gpr (17);
restore_gpr (18);
restore_gpr (19);
restore_gpr (20);
restore_gpr (21);
restore_gpr (22);
restore_gpr (23);
restore_gpr (24);
restore_gpr (25);
restore_gpr (26);
restore_gpr (27);
restore_gpr (28);
restore_gpr (29);
restore_gpr (30);
restore_gpr (31);
/* Return. */
asm volatile ("bctr"); /* XXX CTR is not restored! */
/* NOTREACHED */
return -1;
}
weak_alias (__sigreturn, sigreturn)

View File

@ -1,58 +0,0 @@
/* Startup code for statically linked Hurd/PowerPC binaries.
Copyright (C) 1998,2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
/* These are the various addresses we require. */
.section ".rodata"
.align 2
weak_extern(__libc_csu_init)
weak_extern(__libc_csu_fini)
L(start_addresses):
.long _SDA_BASE_
.long JUMPTARGET(main)
.long JUMPTARGET(__libc_csu_init)
.long JUMPTARGET(__libc_csu_fini)
ASM_SIZE_DIRECTIVE(L(start_addresses))
.section ".text"
ENTRY(_start)
/* Save the stack pointer to pass to _hurd_stack_setup. */
mr r3,r1
/* Set up an initial stack frame. */
li r0,0
stwu r0,-16(r1)
/* Call _hurd_stack_setup. */
bl JUMPTARGET(_hurd_stack_setup)
/* Pass the argument data to __libc_start_main. */
addi r9,r1,16
/* Clear the LR. */
li r0,0
mtlr r0
/* Set r13 to point at the 'small data area', and put the address of
start_addresses in r8... */
lis r8,L(start_addresses)@ha
lwzu r13,L(start_addresses)@l(r8)
/* and continue in libc-start, in glibc. */
b JUMPTARGET(__libc_start_main)
END(_start)
/* Define a symbol for the first piece of initialized data. */
.section ".data"
__data_start:
weak_alias (__data_start, data_start)

View File

@ -1,256 +0,0 @@
/* Set thread_state for sighandler, and sigcontext to recover. For PowerPC.
Copyright (C) 1994,1995,1996,1997,1998,1999,2001,2005
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <hurd/signal.h>
#include <hurd/userlink.h>
#include <thread_state.h>
#include <assert.h>
#include <errno.h>
#include "hurdfault.h"
#include <intr-msg.h>
struct sigcontext *
_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
int signo, struct hurd_signal_detail *detail,
volatile int rpc_wait,
struct machine_thread_all_state *state)
{
void trampoline (void);
void rpc_wait_trampoline (void);
void *volatile sigsp;
struct sigcontext *scp;
if (ss->context)
{
/* We have a previous sigcontext that sigreturn was about
to restore when another signal arrived. We will just base
our setup on that. */
if (! _hurdsig_catch_memory_fault (ss->context))
{
memcpy (&state->basic, &ss->context->sc_ppc_thread_state,
sizeof (state->basic));
memcpy (&state->exc, &ss->context->sc_ppc_exc_state,
sizeof (state->exc));
memcpy (&state->fpu, &ss->context->sc_ppc_float_state,
sizeof (state->fpu));
state->set = (1 << PPC_THREAD_STATE) | (1 << PPC_EXCEPTION_STATE)
| (1 << PPC_FLOAT_STATE);
}
}
if (! machine_get_basic_state (ss->thread, state))
return NULL;
if ((ss->actions[signo].sa_flags & SA_ONSTACK) &&
!(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK)))
{
sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size;
ss->sigaltstack.ss_flags |= SS_ONSTACK;
/* XXX need to set up base of new stack for
per-thread variables, cthreads. */
}
else
sigsp = (char *) state->basic.SP;
/* Set up the sigcontext structure on the stack. This is all the stack
needs, since the args are passed in registers (below). */
sigsp -= sizeof (*scp);
scp = sigsp;
sigsp -= 16; /* Reserve some space for a stack frame. */
if (_hurdsig_catch_memory_fault (scp))
{
/* We got a fault trying to write the stack frame.
We cannot set up the signal handler.
Returning NULL tells our caller, who will nuke us with a SIGILL. */
return NULL;
}
else
{
int ok;
/* Set up the sigcontext from the current state of the thread. */
scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0;
/* struct sigcontext is laid out so that starting at sc_srr0
mimics a struct ppc_thread_state. */
memcpy (&scp->sc_ppc_thread_state,
&state->basic, sizeof (state->basic));
/* struct sigcontext is laid out so that starting at sc_dar
mimics a struct ppc_exc_state. */
ok = machine_get_state (ss->thread, state, PPC_EXCEPTION_STATE,
&state->exc, &scp->sc_ppc_exc_state,
sizeof (state->exc));
/* struct sigcontext is laid out so that starting at sc_fprs[0]
mimics a struct ppc_float_state. */
if (ok)
ok = machine_get_state (ss->thread, state, PPC_FLOAT_STATE,
&state->fpu, &scp->sc_ppc_float_state,
sizeof (state->fpu));
_hurdsig_end_catch_fault ();
if (!ok)
return NULL;
}
/* Modify the thread state to call the trampoline code on the new stack. */
if (rpc_wait)
{
/* The signalee thread was blocked in a mach_msg_trap system call,
still waiting for a reply. We will have it run the special
trampoline code which retries the message receive before running
the signal handler.
To do this we change the OPTION argument in its registers to
enable only message reception, since the request message has
already been sent. */
/* The system call arguments are stored in consecutive registers
starting with r3. */
struct mach_msg_trap_args *args = (void *) &state->basic.r3;
if (_hurdsig_catch_memory_fault (args))
{
/* Faulted accessing ARGS. Bomb. */
return NULL;
}
assert (args->option & MACH_RCV_MSG);
/* Disable the message-send, since it has already completed. The
calls we retry need only wait to receive the reply message. */
args->option &= ~MACH_SEND_MSG;
/* Limit the time to receive the reply message, in case the server
claimed that `interrupt_operation' succeeded but in fact the RPC
is hung. */
args->option |= MACH_RCV_TIMEOUT;
args->timeout = _hurd_interrupted_rpc_timeout;
_hurdsig_end_catch_fault ();
state->basic.PC = (int) rpc_wait_trampoline;
/* After doing the message receive, the trampoline code will need to
update the r3 value to be restored by sigreturn. To simplify
the assembly code, we pass the address of its slot in SCP to the
trampoline code in r10. */
state->basic.r10 = (long int) &scp->sc_gprs[3];
/* We must preserve the mach_msg_trap args in r3..r9.
Pass the handler args to the trampoline code in r11..r13. */
state->basic.r11 = signo;
state->basic.r12 = detail->code;
state->basic.r13 = (int) scp;
}
else
{
state->basic.PC = (int) trampoline;
state->basic.r3 = signo;
state->basic.r4 = detail->code;
state->basic.r5 = (int) scp;
}
state->basic.r1 = (int) sigsp; /* r1 is the stack pointer. */
/* We pass the handler function to the trampoline code in ctr. */
state->basic.ctr = (int) handler;
/* In r15, we store the address of __sigreturn itself,
for the trampoline code to use. */
state->basic.r15 = (int) &__sigreturn;
/* In r16, we save the SCP value to pass to __sigreturn
after the handler returns. */
state->basic.r16 = (int) scp;
/* In r3, we store a pointer to the registers in STATE so that the
trampoline code can load the registers from that. For some reason,
thread_set_state doesn't set all registers. */
state->basic.r17 = state->basic.r3; /* Store the real r3 in r17. */
state->basic.r3 = (int) &state->basic.r0;
return scp;
}
/* The trampoline code follows. This used to be located inside
_hurd_setup_sighandler, but was optimized away by gcc 2.95. */
/* This function sets some registers which the trampoline code uses
and which are not automatically set by thread_set_state.
In r3 we have a pointer to the registers in STATE. */
asm ("trampoline_load_registers:\n"
"lwz 17,68(3)\n" /* The real r3. */
"lwz 4,16(3)\n"
"lwz 5,20(3)\n"
"lwz 6,24(3)\n"
"lwz 7,28(3)\n"
"lwz 8,32(3)\n"
"lwz 9,36(3)\n"
"lwz 10,40(3)\n"
"lwz 11,44(3)\n"
"lwz 12,48(3)\n"
"lwz 13,52(3)\n"
"lwz 14,56(3)\n"
"lwz 15,60(3)\n"
"lwz 16,64(3)\n"
"mr 3,17\n"
"blr\n");
asm ("rpc_wait_trampoline:\n");
/* This is the entry point when we have an RPC reply message to receive
before running the handler. The MACH_MSG_SEND bit has already been
cleared in the OPTION argument in our registers. For our convenience,
r10 points to the sc_regs[3] member of the sigcontext (saved r3). */
asm (/* Retry the interrupted mach_msg system call. */
"bl trampoline_load_registers\n"
"li 0, -25\n" /* mach_msg_trap */
"sc\n"
/* When the sigcontext was saved, r3 was MACH_RCV_INTERRUPTED. But
now the message receive has completed and the original caller of
the RPC (i.e. the code running when the signal arrived) needs to
see the final return value of the message receive in r3. So
store the new r3 value into the sc_regs[3] member of the sigcontext
(whose address is in r10 to make this code simpler). */
"stw 3, 0(10)\n"
/* Since the argument registers needed to have the mach_msg_trap
arguments, we've stored the arguments to the handler function
in registers r11..r13 of the state structure. */
"mr 3,11\n"
"mr 4,12\n"
"mr 5,13\n");
asm ("trampoline:\n");
/* Entry point for running the handler normally. The arguments to the
handler function are already in the standard registers:
r3 SIGNO
r4 SIGCODE
r5 SCP
r16 also contains SCP; this value is callee-saved (and so should not get
clobbered by running the handler). We use this saved value to pass to
__sigreturn, so the handler can clobber the argument registers if it
likes. */
asm ("bl trampoline_load_registers\n"
"bctrl\n" /* Call the handler function. */
"mtctr 15\n" /* Copy &__sigreturn to CTR. */
"mr 3,16\n" /* Copy the saved SCP to r3. */
"bctr\n" /* Call __sigreturn (SCP). */
);

View File

@ -1,77 +0,0 @@
/* Machine-specific definition for spin locks. PowerPC version.
Copyright (C) 1994-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _MACHINE_LOCK_H
#define _MACHINE_LOCK_H
/* The type of a spin lock variable. */
typedef volatile long int __spin_lock_t;
/* Value to initialize `__spin_lock_t' variables to. */
#define __SPIN_LOCK_INITIALIZER 0L
#ifndef _EXTERN_INLINE
#define _EXTERN_INLINE __extern_inline
#endif
/* Unlock LOCK. */
_EXTERN_INLINE void
__spin_unlock (__spin_lock_t *__lock)
{
long int __locked;
__asm__ __volatile__ ("\
0: lwarx %0,0,%1\n\
stwcx. %2,0,%1\n\
bne- 0b\n\
" : "=&r" (__locked) : "r" (__lock), "r" (0) : "cr0");
}
/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */
_EXTERN_INLINE int
__spin_try_lock (register __spin_lock_t *__lock)
{
long int __rtn;
__asm__ __volatile__ ("\
0: lwarx %0,0,%1\n\
stwcx. %2,0,%1\n\
bne- 0b\n\
" : "=&r" (__rtn) : "r" (__lock), "r" (1) : "cr0");
return !__rtn;
}
/* Return nonzero if LOCK is locked. */
_EXTERN_INLINE int
__spin_lock_locked (__spin_lock_t *__lock)
{
long int __rtn;
__asm__ __volatile__ ("\
0: lwarx %0,0,%1\n\
stwcx. %0,0,%1\n\
bne- 0b\n\
" : "=&r" (__rtn) : "r" (__lock) : "cr0");
return __rtn;
}
#endif /* machine-lock.h */

View File

@ -1,41 +0,0 @@
/* Machine-specific function to return the stack pointer. PowerPC version.
Copyright (C) 2001, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <http://www.gnu.org/licenses/>. */
#ifndef _MACHINE_SP_H
#define _MACHINE_SP_H
/* Return the current stack pointer. */
#ifndef _EXTERN_INLINE
/* Make sure this function is included in hurd/threadvar-inlines.c. */
# ifdef _HURD_THREADVAR_H_EXTERN_INLINE
# define _EXTERN_INLINE _HURD_THREADVAR_H_EXTERN_INLINE
# else
# define _EXTERN_INLINE __extern_inline
# endif
#endif
_EXTERN_INLINE void *
__thread_stack_pointer (void)
{
register void *__sp__;
__asm__ ("mr %0, 1" : "=r" (__sp__));
return __sp__;
}
#endif /* machine-sp.h */

View File

@ -1,29 +0,0 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
ENTRY (syscall)
mr r0,r3
mr r3,r4
mr r4,r5
mr r5,r6
mr r6,r7
mr r7,r8
sc
blr
END (syscall)

View File

@ -1,50 +0,0 @@
/* system call details for Mach on PowerPC
Copyright (C) 2001,02 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <http://www.gnu.org/licenses/>. */
#ifndef _MACH_POWERPC_SYSDEP_H
#define _MACH_POWERPC_SYSDEP_H
#define START_ARGS char **sparg
#define SNARF_ARGS(argc, argv, envp) \
do { \
argv = &sparg[1]; \
argc = *(int *)sparg; \
envp = &argv[argc + 1]; \
} while (0)
#define CALL_WITH_SP(fn, sp) \
do { \
register long __sp = (long) sp, __fn = (long) fn; \
asm volatile ("mr 1, %0; mtlr %1; blr" \
: : "r" (__sp), "r" (__fn)); \
} while (0)
#define STACK_GROWTH_DOWN
#define RETURN_TO(sp, pc, retval) \
asm volatile ("mr 1, %0; mtctr %1; mr 3, %2; bctr" \
: : "r" (sp), "r" (pc), "r" (retval))
/* Get the machine-independent Mach definitions. */
#define _MACH_MACHINE_ASM_H 1 /* Kludge to avoid bad Darwin header file. */
#include <sysdeps/mach/sysdep.h>
#undef ENTRY
#include <sysdeps/unix/powerpc/sysdep.h>
#endif /* _MACH_POWERPC_SYSDEP_H */

View File

@ -1,38 +0,0 @@
/* Mach thread state definitions for machine-independent code. PowerPC version
Copyright (C) 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <http://www.gnu.org/licenses/>. */
#include <mach/machine/thread_status.h>
#define MACHINE_THREAD_STATE_FLAVOR PPC_THREAD_STATE
#define MACHINE_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT
#define machine_thread_state ppc_thread_state
#define PC srr0
#define SP r1
#define SYSRETURN r3
struct machine_thread_all_state
{
int set; /* Mask of bits (1 << FLAVOR). */
struct ppc_thread_state basic;
struct ppc_exception_state exc;
struct ppc_float_state fpu;
};
#include <sysdeps/mach/thread_state.h>