linux.h revision 117395
1/* Definitions of target machine for GNU compiler,
2   for PowerPC machines running Linux.
3   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4   Free Software Foundation, Inc.
5   Contributed by Michael Meissner (meissner@cygnus.com).
6
7This file is part of GNU CC.
8
9GNU CC is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2, or (at your option)
12any later version.
13
14GNU CC is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU CC; see the file COPYING.  If not, write to
21the Free Software Foundation, 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA.  */
23
24#undef MD_EXEC_PREFIX
25#undef MD_STARTFILE_PREFIX
26
27#undef TARGET_OS_CPP_BUILTINS
28#define TARGET_OS_CPP_BUILTINS()          \
29  do                                      \
30    {                                     \
31      builtin_define_std ("PPC");         \
32      builtin_define ("__ELF__");         \
33      builtin_define_std ("powerpc");     \
34      builtin_assert ("cpu=powerpc");     \
35      builtin_assert ("machine=powerpc"); \
36    }                                     \
37  while (0)
38
39#undef	CPP_OS_DEFAULT_SPEC
40#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
41
42/* The GNU C++ standard library currently requires _GNU_SOURCE being
43   defined on glibc-based systems. This temporary hack accomplishes this,
44   it should go away as soon as libstdc++-v3 has a real fix.  */
45#undef CPLUSPLUS_CPP_SPEC
46#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
47
48#undef LINK_SHLIB_SPEC
49#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
50
51#undef	LIB_DEFAULT_SPEC
52#define LIB_DEFAULT_SPEC "%(lib_linux)"
53
54#undef	STARTFILE_DEFAULT_SPEC
55#define STARTFILE_DEFAULT_SPEC "%(startfile_linux)"
56
57#undef	ENDFILE_DEFAULT_SPEC
58#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)"
59
60#undef	LINK_START_DEFAULT_SPEC
61#define LINK_START_DEFAULT_SPEC "%(link_start_linux)"
62
63#undef	LINK_OS_DEFAULT_SPEC
64#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
65
66#undef TARGET_VERSION
67#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)");
68
69/* Override rs6000.h definition.  */
70#undef ASM_APP_ON
71#define ASM_APP_ON "#APP\n"
72
73/* Override rs6000.h definition.  */
74#undef ASM_APP_OFF
75#define ASM_APP_OFF "#NO_APP\n"
76
77/* For backward compatibility, we must continue to use the AIX
78   structure return convention.  */
79#undef DRAFT_V4_STRUCT_RET
80#define DRAFT_V4_STRUCT_RET 1
81
82/* Do code reading to identify a signal frame, and set the frame
83   state data appropriately.  See unwind-dw2.c for the structs.  */
84
85#ifdef IN_LIBGCC2
86#include <signal.h>
87
88/* During the 2.5 kernel series the kernel ucontext was changed, but
89   the new layout is compatible with the old one, so we just define
90   and use the old one here for simplicity and compatibility.  */
91
92struct kernel_old_ucontext {
93  unsigned long     uc_flags;
94  struct ucontext  *uc_link;
95  stack_t           uc_stack;
96  struct sigcontext_struct uc_mcontext;
97  sigset_t          uc_sigmask;
98};
99
100enum { SIGNAL_FRAMESIZE = 64 };
101#endif
102
103#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
104  do {									\
105    unsigned char *pc_ = (CONTEXT)->ra;					\
106    struct sigcontext *sc_;						\
107    long new_cfa_;							\
108    int i_;								\
109									\
110    /* li r0, 0x7777; sc  (sigreturn old)  */				\
111    /* li r0, 0x0077; sc  (sigreturn new)  */				\
112    /* li r0, 0x6666; sc  (rt_sigreturn old)  */			\
113    /* li r0, 0x00AC; sc  (rt_sigreturn new)  */			\
114    if (*(unsigned int *) (pc_+4) != 0x44000002)			\
115      break;								\
116    if (*(unsigned int *) (pc_+0) == 0x38007777				\
117	|| *(unsigned int *) (pc_+0) == 0x38000077)			\
118      {									\
119	struct sigframe {						\
120	  char gap[SIGNAL_FRAMESIZE];					\
121	  struct sigcontext sigctx;					\
122	} *rt_ = (CONTEXT)->cfa;					\
123	sc_ = &rt_->sigctx;						\
124      }									\
125    else if (*(unsigned int *) (pc_+0) == 0x38006666			\
126	     || *(unsigned int *) (pc_+0) == 0x380000AC)		\
127      {									\
128	struct rt_sigframe {						\
129	  char gap[SIGNAL_FRAMESIZE];					\
130	  unsigned long _unused[2];					\
131	  struct siginfo *pinfo;					\
132	  void *puc;							\
133	  struct siginfo info;						\
134	  struct kernel_old_ucontext uc;				\
135	} *rt_ = (CONTEXT)->cfa;					\
136	sc_ = &rt_->uc.uc_mcontext;					\
137      }									\
138    else								\
139      break;								\
140    									\
141    new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM];			\
142    (FS)->cfa_how = CFA_REG_OFFSET;					\
143    (FS)->cfa_reg = STACK_POINTER_REGNUM;				\
144    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
145    									\
146    for (i_ = 0; i_ < 32; i_++)						\
147      if (i_ != STACK_POINTER_REGNUM)					\
148	{	    							\
149	  (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
150	  (FS)->regs.reg[i_].loc.offset 				\
151	    = (long)&(sc_->regs->gpr[i_]) - new_cfa_;			\
152	}								\
153									\
154    (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;	\
155    (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset 			\
156      = (long)&(sc_->regs->link) - new_cfa_;				\
157									\
158    (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET;			\
159    (FS)->regs.reg[CR0_REGNO].loc.offset 				\
160      = (long)&(sc_->regs->nip) - new_cfa_;				\
161    (FS)->retaddr_column = CR0_REGNO;					\
162    goto SUCCESS;							\
163  } while (0)
164
165