]>
Commit | Line | Data |
---|---|---|
9ec36da5 | 1 | /* Definitions for Intel 386 running Linux-based GNU systems with ELF format. |
cea3bd3e RH |
2 | Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002 |
3 | Free Software Foundation, Inc. | |
bb1835d2 RK |
4 | Contributed by Eric Youngdale. |
5 | Modified for stabs-in-ELF by H.J. Lu. | |
4a86a6d2 RK |
6 | |
7 | This file is part of GNU CC. | |
8 | ||
9 | GNU CC is free software; you can redistribute it and/or modify | |
10 | it under the terms of the GNU General Public License as published by | |
11 | the Free Software Foundation; either version 2, or (at your option) | |
12 | any later version. | |
13 | ||
14 | GNU CC is distributed in the hope that it will be useful, | |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | GNU General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
20 | along with GNU CC; see the file COPYING. If not, write to | |
97aadbb9 RK |
21 | the Free Software Foundation, 59 Temple Place - Suite 330, |
22 | Boston, MA 02111-1307, USA. */ | |
1cf549b1 | 23 | |
bb1835d2 RK |
24 | #define LINUX_DEFAULT_ELF |
25 | ||
d984704d DN |
26 | /* Output at beginning of assembler file. */ |
27 | /* The .file command should always begin the output. */ | |
28 | #undef ASM_FILE_START | |
29 | #define ASM_FILE_START(FILE) \ | |
30 | do { \ | |
31 | output_file_directive (FILE, main_input_filename); \ | |
c93e80a5 | 32 | if (ix86_asm_dialect == ASM_INTEL) \ |
d984704d | 33 | fputs ("\t.intel_syntax\n", FILE); \ |
d984704d DN |
34 | } while (0) |
35 | ||
c3b11311 | 36 | #define TARGET_VERSION fprintf (stderr, " (i386 Linux/ELF)"); |
bb1835d2 RK |
37 | |
38 | /* The svr4 ABI for the i386 says that records and unions are returned | |
39 | in memory. */ | |
40 | #undef DEFAULT_PCC_STRUCT_RETURN | |
41 | #define DEFAULT_PCC_STRUCT_RETURN 1 | |
42 | ||
bebc4663 JL |
43 | #undef ASM_COMMENT_START |
44 | #define ASM_COMMENT_START "#" | |
45 | ||
bb1835d2 | 46 | #undef DBX_REGISTER_NUMBER |
0f7fa3d0 JH |
47 | #define DBX_REGISTER_NUMBER(n) \ |
48 | (TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n]) | |
bb1835d2 | 49 | |
dcacfa04 ZW |
50 | /* Output assembler code to FILE to call the profiler. |
51 | To the best of my knowledge, no Linux libc has required the label | |
52 | argument to mcount. */ | |
53 | ||
54 | #define NO_PROFILE_COUNTERS | |
bb1835d2 | 55 | |
a5fa1ecd JH |
56 | #undef MCOUNT_NAME |
57 | #define MCOUNT_NAME "mcount" | |
d345a981 | 58 | |
a7943381 | 59 | /* The GLIBC version of mcount for the x86 assumes that there is a |
4da5f005 MM |
60 | frame, so we cannot allow profiling without a frame pointer. */ |
61 | ||
a7943381 RH |
62 | #undef SUBTARGET_FRAME_POINTER_REQUIRED |
63 | #define SUBTARGET_FRAME_POINTER_REQUIRED current_function_profile | |
4da5f005 | 64 | |
1cf549b1 RS |
65 | #undef SIZE_TYPE |
66 | #define SIZE_TYPE "unsigned int" | |
bb1835d2 | 67 | |
1cf549b1 RS |
68 | #undef PTRDIFF_TYPE |
69 | #define PTRDIFF_TYPE "int" | |
bb1835d2 | 70 | |
1cf549b1 RS |
71 | #undef WCHAR_TYPE |
72 | #define WCHAR_TYPE "long int" | |
bb1835d2 | 73 | |
1cf549b1 RS |
74 | #undef WCHAR_TYPE_SIZE |
75 | #define WCHAR_TYPE_SIZE BITS_PER_WORD | |
bb1835d2 | 76 | |
f23a084d NB |
77 | #define TARGET_OS_CPP_BUILTINS() \ |
78 | do \ | |
79 | { \ | |
80 | builtin_define_std ("linux"); \ | |
81 | builtin_define_std ("unix"); \ | |
82 | builtin_define ("__ELF__"); \ | |
83 | builtin_define ("__gnu_linux__"); \ | |
84 | builtin_assert ("system=posix"); \ | |
85 | if (flag_pic) \ | |
86 | { \ | |
87 | builtin_define ("__PIC__"); \ | |
88 | builtin_define ("__pic__"); \ | |
89 | } \ | |
90 | } \ | |
91 | while (0) | |
1cf549b1 | 92 | |
bb1835d2 | 93 | #undef CPP_SPEC |
5f62d4e1 | 94 | #ifdef USE_GNULIBC_1 |
f23a084d | 95 | #define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" |
5f62d4e1 | 96 | #else |
f23a084d | 97 | #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" |
5f62d4e1 | 98 | #endif |
1cf549b1 | 99 | |
b52fbc26 RK |
100 | #undef CC1_SPEC |
101 | #define CC1_SPEC "%(cc1_cpu) %{profile:-p}" | |
102 | ||
c3b11311 | 103 | /* Provide a LINK_SPEC appropriate for Linux. Here we provide support |
bb1835d2 RK |
104 | for the special GCC options -static and -shared, which allow us to |
105 | link things in one of these three modes by applying the appropriate | |
106 | combinations of options at link-time. We like to support here for | |
107 | as many of the other GNU linker options as possible. But I don't | |
108 | have the time to search for those flags. I am sure how to add | |
109 | support for -soname shared_object_name. H.J. | |
110 | ||
111 | I took out %{v:%{!V:-V}}. It is too much :-(. They can use | |
112 | -Wl,-V. | |
113 | ||
114 | When the -shared link option is used a final link is not being | |
115 | done. */ | |
116 | ||
892a2d68 | 117 | /* If ELF is the default format, we should not use /lib/elf. */ |
bb1835d2 RK |
118 | |
119 | #undef LINK_SPEC | |
5f62d4e1 | 120 | #ifdef USE_GNULIBC_1 |
bb1835d2 RK |
121 | #ifndef LINUX_DEFAULT_ELF |
122 | #define LINK_SPEC "-m elf_i386 %{shared:-shared} \ | |
123 | %{!shared: \ | |
124 | %{!ibcs: \ | |
125 | %{!static: \ | |
126 | %{rdynamic:-export-dynamic} \ | |
127 | %{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \ | |
128 | %{!rpath:-rpath /lib/elf/}} %{static:-static}}}" | |
22cc53bc | 129 | #else |
bb1835d2 RK |
130 | #define LINK_SPEC "-m elf_i386 %{shared:-shared} \ |
131 | %{!shared: \ | |
132 | %{!ibcs: \ | |
133 | %{!static: \ | |
134 | %{rdynamic:-export-dynamic} \ | |
135 | %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \ | |
136 | %{static:-static}}}" | |
22cc53bc | 137 | #endif |
5f62d4e1 RK |
138 | #else |
139 | #define LINK_SPEC "-m elf_i386 %{shared:-shared} \ | |
140 | %{!shared: \ | |
141 | %{!ibcs: \ | |
142 | %{!static: \ | |
143 | %{rdynamic:-export-dynamic} \ | |
144 | %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ | |
145 | %{static:-static}}}" | |
146 | #endif | |
6c2afd82 | 147 | |
17d6fedc | 148 | /* A C statement (sans semicolon) to output to the stdio stream |
ca4fca3e | 149 | FILE the assembler definition of uninitialized global DECL named |
17d6fedc JM |
150 | NAME whose size is SIZE bytes and alignment is ALIGN bytes. |
151 | Try to use asm_output_aligned_bss to implement this macro. */ | |
152 | ||
ca4fca3e DE |
153 | #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ |
154 | asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN) | |
de3eb7b7 L |
155 | |
156 | /* A C statement to output to the stdio stream FILE an assembler | |
157 | command to advance the location counter to a multiple of 1<<LOG | |
158 | bytes if it is within MAX_SKIP bytes. | |
159 | ||
160 | This is used to align code labels according to Intel recommendations. */ | |
161 | ||
80de1662 | 162 | #ifdef HAVE_GAS_MAX_SKIP_P2ALIGN |
8c8a9717 JM |
163 | #define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \ |
164 | do { \ | |
0385ba57 | 165 | if ((LOG) != 0) { \ |
8401285e | 166 | if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \ |
8c8a9717 | 167 | else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \ |
0385ba57 | 168 | } \ |
8c8a9717 | 169 | } while (0) |
80de1662 | 170 | #endif |
373368fd JJ |
171 | |
172 | #if defined(__PIC__) && defined (USE_GNULIBC_1) | |
173 | /* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr, | |
cea3bd3e RH |
174 | __environ and atexit. We have to make sure they are in the .dynsym |
175 | section. We do this by forcing the assembler to create undefined | |
176 | references to these symbols in the object file. */ | |
177 | #undef CRT_CALL_STATIC_FUNCTION | |
178 | #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ | |
179 | asm (SECTION_OP "\n\t" \ | |
180 | "call " USER_LABEL_PREFIX #FUNC "\n" \ | |
181 | TEXT_SECTION_ASM_OP "\n\t" \ | |
182 | ".extern ___brk_addr\n\t" \ | |
183 | ".type ___brk_addr,@object\n\t" \ | |
184 | ".extern __environ\n\t" \ | |
185 | ".type __environ,@object\n\t" \ | |
186 | ".extern atexit\n\t" \ | |
187 | ".type atexit,@function"); | |
373368fd | 188 | #endif |
1020a5ab | 189 | |
1066e2b5 RH |
190 | /* Handle special EH pointer encodings. Absolute, pc-relative, and |
191 | indirect are handled automatically. */ | |
192 | #define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \ | |
193 | do { \ | |
194 | if ((SIZE) == 4 && ((ENCODING) & 0x70) == DW_EH_PE_datarel) \ | |
195 | { \ | |
301d03af | 196 | fputs (ASM_LONG, FILE); \ |
1066e2b5 RH |
197 | assemble_name (FILE, XSTR (ADDR, 0)); \ |
198 | fputs (((ENCODING) & DW_EH_PE_indirect ? "@GOT" : "@GOTOFF"), FILE); \ | |
199 | goto DONE; \ | |
200 | } \ | |
201 | } while (0) | |
202 | ||
203 | /* Used by crtstuff.c to initialize the base of data-relative relocations. | |
204 | These are GOT relative on x86, so return the pic register. */ | |
205 | #ifdef __PIC__ | |
206 | #define CRT_GET_RFIB_DATA(BASE) \ | |
207 | { \ | |
208 | register void *ebx_ __asm__("ebx"); \ | |
209 | BASE = ebx_; \ | |
210 | } | |
211 | #else | |
212 | #define CRT_GET_RFIB_DATA(BASE) \ | |
213 | __asm__ ("call\t.LPR%=\n" \ | |
214 | ".LPR%=:\n\t" \ | |
215 | "popl\t%0\n\t" \ | |
216 | /* Due to a GAS bug, this cannot use EAX. That encodes \ | |
217 | smaller than the traditional EBX, which results in the \ | |
218 | offset being off by one. */ \ | |
219 | "addl\t$_GLOBAL_OFFSET_TABLE_+[.-.LPR%=],%0" \ | |
220 | : "=d"(BASE)) | |
221 | #endif | |
222 | ||
1020a5ab RH |
223 | /* Do code reading to identify a signal frame, and set the frame |
224 | state data appropriately. See unwind-dw2.c for the structs. */ | |
225 | ||
226 | #ifdef IN_LIBGCC2 | |
a7475ab1 HPN |
227 | /* There's no sys/ucontext.h for some (all?) libc1, so no |
228 | signal-turned-exceptions for them. There's also no configure-run for | |
229 | the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H. Using the | |
230 | target libc1 macro should be enough. */ | |
231 | #ifndef USE_GNULIBC_1 | |
1020a5ab RH |
232 | #include <signal.h> |
233 | #include <sys/ucontext.h> | |
1020a5ab RH |
234 | |
235 | #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ | |
236 | do { \ | |
237 | unsigned char *pc_ = (CONTEXT)->ra; \ | |
238 | struct sigcontext *sc_; \ | |
239 | long new_cfa_; \ | |
240 | \ | |
241 | /* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */ \ | |
242 | if (*(unsigned short *)(pc_+0) == 0xb858 \ | |
243 | && *(unsigned int *)(pc_+2) == 119 \ | |
244 | && *(unsigned short *)(pc_+6) == 0x80cd) \ | |
245 | sc_ = (CONTEXT)->cfa + 4; \ | |
246 | /* movl $__NR_rt_sigreturn,%eax ; int $0x80 */ \ | |
247 | else if (*(unsigned char *)(pc_+0) == 0xb8 \ | |
248 | && *(unsigned int *)(pc_+1) == 173 \ | |
249 | && *(unsigned short *)(pc_+5) == 0x80cd) \ | |
250 | { \ | |
251 | struct rt_sigframe { \ | |
252 | int sig; \ | |
253 | struct siginfo *pinfo; \ | |
254 | void *puc; \ | |
255 | struct siginfo info; \ | |
256 | struct ucontext uc; \ | |
257 | } *rt_ = (CONTEXT)->cfa; \ | |
258 | sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext; \ | |
259 | } \ | |
260 | else \ | |
261 | break; \ | |
262 | \ | |
263 | new_cfa_ = sc_->esp; \ | |
264 | (FS)->cfa_how = CFA_REG_OFFSET; \ | |
265 | (FS)->cfa_reg = 4; \ | |
266 | (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \ | |
267 | \ | |
268 | /* The SVR4 register numbering macros aren't usable in libgcc. */ \ | |
269 | (FS)->regs.reg[0].how = REG_SAVED_OFFSET; \ | |
270 | (FS)->regs.reg[0].loc.offset = (long)&sc_->eax - new_cfa_; \ | |
271 | (FS)->regs.reg[3].how = REG_SAVED_OFFSET; \ | |
272 | (FS)->regs.reg[3].loc.offset = (long)&sc_->ebx - new_cfa_; \ | |
273 | (FS)->regs.reg[1].how = REG_SAVED_OFFSET; \ | |
274 | (FS)->regs.reg[1].loc.offset = (long)&sc_->ecx - new_cfa_; \ | |
275 | (FS)->regs.reg[2].how = REG_SAVED_OFFSET; \ | |
276 | (FS)->regs.reg[2].loc.offset = (long)&sc_->edx - new_cfa_; \ | |
277 | (FS)->regs.reg[6].how = REG_SAVED_OFFSET; \ | |
278 | (FS)->regs.reg[6].loc.offset = (long)&sc_->esi - new_cfa_; \ | |
279 | (FS)->regs.reg[7].how = REG_SAVED_OFFSET; \ | |
280 | (FS)->regs.reg[7].loc.offset = (long)&sc_->edi - new_cfa_; \ | |
281 | (FS)->regs.reg[5].how = REG_SAVED_OFFSET; \ | |
282 | (FS)->regs.reg[5].loc.offset = (long)&sc_->ebp - new_cfa_; \ | |
283 | (FS)->regs.reg[8].how = REG_SAVED_OFFSET; \ | |
284 | (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \ | |
285 | (FS)->retaddr_column = 8; \ | |
286 | goto SUCCESS; \ | |
287 | } while (0) | |
a7475ab1 HPN |
288 | #endif /* not USE_GNULIBC_1 */ |
289 | #endif /* IN_LIBGCC2 */ |