linux.h revision 122180
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#define LINK_GCC_C_SEQUENCE_SPEC \
52  "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
53
54#undef	LIB_DEFAULT_SPEC
55#define LIB_DEFAULT_SPEC "%(lib_linux)"
56
57#undef	STARTFILE_DEFAULT_SPEC
58#define STARTFILE_DEFAULT_SPEC "%(startfile_linux)"
59
60#undef	ENDFILE_DEFAULT_SPEC
61#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)"
62
63#undef	LINK_START_DEFAULT_SPEC
64#define LINK_START_DEFAULT_SPEC "%(link_start_linux)"
65
66#undef	LINK_OS_DEFAULT_SPEC
67#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
68
69#undef TARGET_VERSION
70#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)");
71
72/* Override rs6000.h definition.  */
73#undef ASM_APP_ON
74#define ASM_APP_ON "#APP\n"
75
76/* Override rs6000.h definition.  */
77#undef ASM_APP_OFF
78#define ASM_APP_OFF "#NO_APP\n"
79
80/* For backward compatibility, we must continue to use the AIX
81   structure return convention.  */
82#undef DRAFT_V4_STRUCT_RET
83#define DRAFT_V4_STRUCT_RET 1
84
85/* Do code reading to identify a signal frame, and set the frame
86   state data appropriately.  See unwind-dw2.c for the structs.  */
87
88#ifdef IN_LIBGCC2
89#include <signal.h>
90
91/* During the 2.5 kernel series the kernel ucontext was changed, but
92   the new layout is compatible with the old one, so we just define
93   and use the old one here for simplicity and compatibility.  */
94
95struct kernel_old_ucontext {
96  unsigned long     uc_flags;
97  struct ucontext  *uc_link;
98  stack_t           uc_stack;
99  struct sigcontext_struct uc_mcontext;
100  sigset_t          uc_sigmask;
101};
102
103enum { SIGNAL_FRAMESIZE = 64 };
104#endif
105
106#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
107  do {									\
108    unsigned char *pc_ = (CONTEXT)->ra;					\
109    struct sigcontext *sc_;						\
110    long new_cfa_;							\
111    int i_;								\
112									\
113    /* li r0, 0x7777; sc  (sigreturn old)  */				\
114    /* li r0, 0x0077; sc  (sigreturn new)  */				\
115    /* li r0, 0x6666; sc  (rt_sigreturn old)  */			\
116    /* li r0, 0x00AC; sc  (rt_sigreturn new)  */			\
117    if (*(unsigned int *) (pc_+4) != 0x44000002)			\
118      break;								\
119    if (*(unsigned int *) (pc_+0) == 0x38007777				\
120	|| *(unsigned int *) (pc_+0) == 0x38000077)			\
121      {									\
122	struct sigframe {						\
123	  char gap[SIGNAL_FRAMESIZE];					\
124	  struct sigcontext sigctx;					\
125	} *rt_ = (CONTEXT)->cfa;					\
126	sc_ = &rt_->sigctx;						\
127      }									\
128    else if (*(unsigned int *) (pc_+0) == 0x38006666			\
129	     || *(unsigned int *) (pc_+0) == 0x380000AC)		\
130      {									\
131	struct rt_sigframe {						\
132	  char gap[SIGNAL_FRAMESIZE];					\
133	  unsigned long _unused[2];					\
134	  struct siginfo *pinfo;					\
135	  void *puc;							\
136	  struct siginfo info;						\
137	  struct kernel_old_ucontext uc;				\
138	} *rt_ = (CONTEXT)->cfa;					\
139	sc_ = &rt_->uc.uc_mcontext;					\
140      }									\
141    else								\
142      break;								\
143    									\
144    new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM];			\
145    (FS)->cfa_how = CFA_REG_OFFSET;					\
146    (FS)->cfa_reg = STACK_POINTER_REGNUM;				\
147    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
148    									\
149    for (i_ = 0; i_ < 32; i_++)						\
150      if (i_ != STACK_POINTER_REGNUM)					\
151	{	    							\
152	  (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
153	  (FS)->regs.reg[i_].loc.offset 				\
154	    = (long)&(sc_->regs->gpr[i_]) - new_cfa_;			\
155	}								\
156									\
157    (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;	\
158    (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset 			\
159      = (long)&(sc_->regs->link) - new_cfa_;				\
160									\
161    (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET;			\
162    (FS)->regs.reg[CR0_REGNO].loc.offset 				\
163      = (long)&(sc_->regs->nip) - new_cfa_;				\
164    (FS)->retaddr_column = CR0_REGNO;					\
165    goto SUCCESS;							\
166  } while (0)
167
168