1 /* Definitions for AMD x86-64 running Linux-based GNU systems with ELF format. 2 Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. 3 Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h. 4 5 This file is part of GNU CC. 6 7 GNU CC is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 GNU CC is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GNU CC; see the file COPYING. If not, write to 19 the Free Software Foundation, 59 Temple Place - Suite 330, 20 Boston, MA 02111-1307, USA. */ 21 22 #define LINUX_DEFAULT_ELF 23 24 #define TARGET_VERSION fprintf (stderr, " (x86-64 Linux/ELF)"); 25 26 #define TARGET_OS_CPP_BUILTINS() \ 27 do \ 28 { \ 29 builtin_define_std ("linux"); \ 30 builtin_define_std ("unix"); \ 31 builtin_define ("__gnu_linux__"); \ 32 builtin_define ("__ELF__"); \ 33 builtin_assert ("system=posix"); \ 34 if (flag_pic) \ 35 { \ 36 builtin_define ("__PIC__"); \ 37 builtin_define ("__pic__"); \ 38 } \ 39 if (TARGET_64BIT) \ 40 { \ 41 builtin_define ("__LP64__"); \ 42 builtin_define ("_LP64"); \ 43 } \ 44 } \ 45 while (0) 46 47 #undef CPP_SPEC 48 #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" 49 50 /* The svr4 ABI for the i386 says that records and unions are returned 51 in memory. In the 64bit compilation we will turn this flag off in 52 override_options, as we never do pcc_struct_return scheme on this target. */ 53 #undef DEFAULT_PCC_STRUCT_RETURN 54 #define DEFAULT_PCC_STRUCT_RETURN 1 55 56 /* Provide a LINK_SPEC. Here we provide support for the special GCC 57 options -static and -shared, which allow us to link things in one 58 of these three modes by applying the appropriate combinations of 59 options at link-time. 60 61 When the -shared link option is used a final link is not being 62 done. */ 63 64 #undef LINK_SPEC 65 #define LINK_SPEC "%{!m32:-m elf_x86_64} %{m32:-m elf_i386} \ 66 %{shared:-shared} \ 67 %{!shared: \ 68 %{!static: \ 69 %{rdynamic:-export-dynamic} \ 70 %{m32:%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ 71 %{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \ 72 %{static:-static}}" 73 74 #undef STARTFILE_SPEC 75 #define STARTFILE_SPEC \ 76 "%{!shared: \ 77 %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \ 78 %{!p:%{profile:gcrt1.o%s} %{!profile:crt1.o%s}}}} \ 79 crti.o%s %{static:crtbeginT.o%s} \ 80 %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}" 81 82 #undef ENDFILE_SPEC 83 #define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" 84 85 #define MULTILIB_DEFAULTS { "m64" } 86 87 #define SUBTARGET_FILE_END(FILE) \ 88 do { \ 89 named_section_flags (".note.GNU-stack", \ 90 SECTION_DEBUG \ 91 | (trampolines_created ? SECTION_CODE : 0)); \ 92 } while (0) 93 94 /* Do code reading to identify a signal frame, and set the frame 95 state data appropriately. See unwind-dw2.c for the structs. 96 Don't use this at all if inhibit_libc is used. */ 97 98 #ifndef inhibit_libc 99 #ifdef IN_LIBGCC2 100 #include <signal.h> 101 #include <sys/ucontext.h> 102 #endif 103 104 #ifdef __x86_64__ 105 #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ 106 do { \ 107 unsigned char *pc_ = (CONTEXT)->ra; \ 108 struct sigcontext *sc_; \ 109 long new_cfa_; \ 110 \ 111 /* movq __NR_rt_sigreturn, %rax ; syscall */ \ 112 if (*(unsigned char *)(pc_+0) == 0x48 \ 113 && *(unsigned long *)(pc_+1) == 0x050f0000000fc0c7) \ 114 { \ 115 struct ucontext *uc_ = (CONTEXT)->cfa; \ 116 sc_ = (struct sigcontext *) &uc_->uc_mcontext; \ 117 } \ 118 else \ 119 break; \ 120 \ 121 new_cfa_ = sc_->rsp; \ 122 (FS)->cfa_how = CFA_REG_OFFSET; \ 123 /* Register 7 is rsp */ \ 124 (FS)->cfa_reg = 7; \ 125 (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \ 126 \ 127 /* The SVR4 register numbering macros aren't usable in libgcc. */ \ 128 (FS)->regs.reg[0].how = REG_SAVED_OFFSET; \ 129 (FS)->regs.reg[0].loc.offset = (long)&sc_->rax - new_cfa_; \ 130 (FS)->regs.reg[1].how = REG_SAVED_OFFSET; \ 131 (FS)->regs.reg[1].loc.offset = (long)&sc_->rdx - new_cfa_; \ 132 (FS)->regs.reg[2].how = REG_SAVED_OFFSET; \ 133 (FS)->regs.reg[2].loc.offset = (long)&sc_->rcx - new_cfa_; \ 134 (FS)->regs.reg[3].how = REG_SAVED_OFFSET; \ 135 (FS)->regs.reg[3].loc.offset = (long)&sc_->rbx - new_cfa_; \ 136 (FS)->regs.reg[4].how = REG_SAVED_OFFSET; \ 137 (FS)->regs.reg[4].loc.offset = (long)&sc_->rsi - new_cfa_; \ 138 (FS)->regs.reg[5].how = REG_SAVED_OFFSET; \ 139 (FS)->regs.reg[5].loc.offset = (long)&sc_->rdi - new_cfa_; \ 140 (FS)->regs.reg[6].how = REG_SAVED_OFFSET; \ 141 (FS)->regs.reg[6].loc.offset = (long)&sc_->rbp - new_cfa_; \ 142 (FS)->regs.reg[8].how = REG_SAVED_OFFSET; \ 143 (FS)->regs.reg[8].loc.offset = (long)&sc_->r8 - new_cfa_; \ 144 (FS)->regs.reg[9].how = REG_SAVED_OFFSET; \ 145 (FS)->regs.reg[9].loc.offset = (long)&sc_->r9 - new_cfa_; \ 146 (FS)->regs.reg[10].how = REG_SAVED_OFFSET; \ 147 (FS)->regs.reg[10].loc.offset = (long)&sc_->r10 - new_cfa_; \ 148 (FS)->regs.reg[11].how = REG_SAVED_OFFSET; \ 149 (FS)->regs.reg[11].loc.offset = (long)&sc_->r11 - new_cfa_; \ 150 (FS)->regs.reg[12].how = REG_SAVED_OFFSET; \ 151 (FS)->regs.reg[12].loc.offset = (long)&sc_->r12 - new_cfa_; \ 152 (FS)->regs.reg[13].how = REG_SAVED_OFFSET; \ 153 (FS)->regs.reg[13].loc.offset = (long)&sc_->r13 - new_cfa_; \ 154 (FS)->regs.reg[14].how = REG_SAVED_OFFSET; \ 155 (FS)->regs.reg[14].loc.offset = (long)&sc_->r14 - new_cfa_; \ 156 (FS)->regs.reg[15].how = REG_SAVED_OFFSET; \ 157 (FS)->regs.reg[15].loc.offset = (long)&sc_->r15 - new_cfa_; \ 158 (FS)->regs.reg[16].how = REG_SAVED_OFFSET; \ 159 (FS)->regs.reg[16].loc.offset = (long)&sc_->rip - new_cfa_; \ 160 (FS)->retaddr_column = 16; \ 161 goto SUCCESS; \ 162 } while (0) 163 #else /* ifdef __x86_64__ */ 164 #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ 165 do { \ 166 unsigned char *pc_ = (CONTEXT)->ra; \ 167 struct sigcontext *sc_; \ 168 long new_cfa_; \ 169 \ 170 /* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */ \ 171 if (*(unsigned short *)(pc_+0) == 0xb858 \ 172 && *(unsigned int *)(pc_+2) == 119 \ 173 && *(unsigned short *)(pc_+6) == 0x80cd) \ 174 sc_ = (CONTEXT)->cfa + 4; \ 175 /* movl $__NR_rt_sigreturn,%eax ; int $0x80 */ \ 176 else if (*(unsigned char *)(pc_+0) == 0xb8 \ 177 && *(unsigned int *)(pc_+1) == 173 \ 178 && *(unsigned short *)(pc_+5) == 0x80cd) \ 179 { \ 180 struct rt_sigframe { \ 181 int sig; \ 182 struct siginfo *pinfo; \ 183 void *puc; \ 184 struct siginfo info; \ 185 struct ucontext uc; \ 186 } *rt_ = (CONTEXT)->cfa; \ 187 sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext; \ 188 } \ 189 else \ 190 break; \ 191 \ 192 new_cfa_ = sc_->esp; \ 193 (FS)->cfa_how = CFA_REG_OFFSET; \ 194 (FS)->cfa_reg = 4; \ 195 (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \ 196 \ 197 /* The SVR4 register numbering macros aren't usable in libgcc. */ \ 198 (FS)->regs.reg[0].how = REG_SAVED_OFFSET; \ 199 (FS)->regs.reg[0].loc.offset = (long)&sc_->eax - new_cfa_; \ 200 (FS)->regs.reg[3].how = REG_SAVED_OFFSET; \ 201 (FS)->regs.reg[3].loc.offset = (long)&sc_->ebx - new_cfa_; \ 202 (FS)->regs.reg[1].how = REG_SAVED_OFFSET; \ 203 (FS)->regs.reg[1].loc.offset = (long)&sc_->ecx - new_cfa_; \ 204 (FS)->regs.reg[2].how = REG_SAVED_OFFSET; \ 205 (FS)->regs.reg[2].loc.offset = (long)&sc_->edx - new_cfa_; \ 206 (FS)->regs.reg[6].how = REG_SAVED_OFFSET; \ 207 (FS)->regs.reg[6].loc.offset = (long)&sc_->esi - new_cfa_; \ 208 (FS)->regs.reg[7].how = REG_SAVED_OFFSET; \ 209 (FS)->regs.reg[7].loc.offset = (long)&sc_->edi - new_cfa_; \ 210 (FS)->regs.reg[5].how = REG_SAVED_OFFSET; \ 211 (FS)->regs.reg[5].loc.offset = (long)&sc_->ebp - new_cfa_; \ 212 (FS)->regs.reg[8].how = REG_SAVED_OFFSET; \ 213 (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \ 214 (FS)->retaddr_column = 8; \ 215 goto SUCCESS; \ 216 } while (0) 217 #endif /* ifdef __x86_64__ */ 218 #endif /* ifdef inhibit_libc */ 219