linux.h revision 90075
150397Sobrien/* Definitions for Intel 386 running Linux-based GNU systems with ELF format. 290075Sobrien Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002 390075Sobrien Free Software Foundation, Inc. 418334Speter Contributed by Eric Youngdale. 518334Speter Modified for stabs-in-ELF by H.J. Lu. 618334Speter 718334SpeterThis file is part of GNU CC. 818334Speter 918334SpeterGNU CC is free software; you can redistribute it and/or modify 1018334Speterit under the terms of the GNU General Public License as published by 1118334Speterthe Free Software Foundation; either version 2, or (at your option) 1218334Speterany later version. 1318334Speter 1418334SpeterGNU CC is distributed in the hope that it will be useful, 1518334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of 1618334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1718334SpeterGNU General Public License for more details. 1818334Speter 1918334SpeterYou should have received a copy of the GNU General Public License 2018334Speteralong with GNU CC; see the file COPYING. If not, write to 2118334Speterthe Free Software Foundation, 59 Temple Place - Suite 330, 2218334SpeterBoston, MA 02111-1307, USA. */ 2318334Speter 2418334Speter#define LINUX_DEFAULT_ELF 2518334Speter 2690075Sobrien/* Output at beginning of assembler file. */ 2790075Sobrien/* The .file command should always begin the output. */ 2890075Sobrien#undef ASM_FILE_START 2990075Sobrien#define ASM_FILE_START(FILE) \ 3090075Sobrien do { \ 3190075Sobrien output_file_directive (FILE, main_input_filename); \ 3290075Sobrien if (ix86_asm_dialect == ASM_INTEL) \ 3390075Sobrien fputs ("\t.intel_syntax\n", FILE); \ 3490075Sobrien } while (0) 3518334Speter 3618334Speter#undef TARGET_VERSION 3718334Speter#define TARGET_VERSION fprintf (stderr, " (i386 Linux/ELF)"); 3818334Speter 3918334Speter/* The svr4 ABI for the i386 says that records and unions are returned 4018334Speter in memory. */ 4118334Speter#undef DEFAULT_PCC_STRUCT_RETURN 4218334Speter#define DEFAULT_PCC_STRUCT_RETURN 1 4318334Speter 4450397Sobrien#undef ASM_COMMENT_START 4550397Sobrien#define ASM_COMMENT_START "#" 4650397Sobrien 4718334Speter#undef DBX_REGISTER_NUMBER 4818334Speter#define DBX_REGISTER_NUMBER(n) \ 4990075Sobrien (TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n]) 5018334Speter 5190075Sobrien/* Output assembler code to FILE to call the profiler. 5290075Sobrien To the best of my knowledge, no Linux libc has required the label 5390075Sobrien argument to mcount. */ 5418334Speter 5590075Sobrien#define NO_PROFILE_COUNTERS 5690075Sobrien 5718334Speter#undef FUNCTION_PROFILER 5818334Speter#define FUNCTION_PROFILER(FILE, LABELNO) \ 5918334Speter{ \ 6018334Speter if (flag_pic) \ 6190075Sobrien fprintf (FILE, "\tcall\t*mcount@GOT(%%ebx)\n"); \ 6218334Speter else \ 6390075Sobrien fprintf (FILE, "\tcall\tmcount\n"); \ 6418334Speter} 6518334Speter 6690075Sobrien/* True if it is possible to profile code that does not have a frame 6790075Sobrien pointer. 6890075Sobrien 6990075Sobrien The GLIBC version of mcount for the x86 assumes that there is a 7090075Sobrien frame, so we cannot allow profiling without a frame pointer. */ 7190075Sobrien 7290075Sobrien#undef TARGET_ALLOWS_PROFILING_WITHOUT_FRAME_POINTER 7390075Sobrien#define TARGET_ALLOWS_PROFILING_WITHOUT_FRAME_POINTER false 7490075Sobrien 7518334Speter#undef SIZE_TYPE 7618334Speter#define SIZE_TYPE "unsigned int" 7718334Speter 7818334Speter#undef PTRDIFF_TYPE 7918334Speter#define PTRDIFF_TYPE "int" 8018334Speter 8118334Speter#undef WCHAR_TYPE 8218334Speter#define WCHAR_TYPE "long int" 8318334Speter 8418334Speter#undef WCHAR_TYPE_SIZE 8518334Speter#define WCHAR_TYPE_SIZE BITS_PER_WORD 8618334Speter 8718334Speter#undef CPP_PREDEFINES 8890075Sobrien#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dlinux -Asystem=posix" 8918334Speter 9018334Speter#undef CPP_SPEC 9148743Sobrien#ifdef USE_GNULIBC_1 9250397Sobrien#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}" 9318334Speter#else 9450397Sobrien#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" 9518334Speter#endif 9618334Speter 9750397Sobrien#undef CC1_SPEC 9850397Sobrien#define CC1_SPEC "%(cc1_cpu) %{profile:-p}" 9948743Sobrien 10018334Speter/* Provide a LINK_SPEC appropriate for Linux. Here we provide support 10118334Speter for the special GCC options -static and -shared, which allow us to 10218334Speter link things in one of these three modes by applying the appropriate 10318334Speter combinations of options at link-time. We like to support here for 10418334Speter as many of the other GNU linker options as possible. But I don't 10518334Speter have the time to search for those flags. I am sure how to add 10618334Speter support for -soname shared_object_name. H.J. 10718334Speter 10818334Speter I took out %{v:%{!V:-V}}. It is too much :-(. They can use 10918334Speter -Wl,-V. 11018334Speter 11118334Speter When the -shared link option is used a final link is not being 11218334Speter done. */ 11318334Speter 11490075Sobrien/* If ELF is the default format, we should not use /lib/elf. */ 11518334Speter 11618334Speter#undef LINK_SPEC 11748743Sobrien#ifdef USE_GNULIBC_1 11818334Speter#ifndef LINUX_DEFAULT_ELF 11918334Speter#define LINK_SPEC "-m elf_i386 %{shared:-shared} \ 12018334Speter %{!shared: \ 12118334Speter %{!ibcs: \ 12218334Speter %{!static: \ 12318334Speter %{rdynamic:-export-dynamic} \ 12418334Speter %{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \ 12518334Speter %{!rpath:-rpath /lib/elf/}} %{static:-static}}}" 12618334Speter#else 12718334Speter#define LINK_SPEC "-m elf_i386 %{shared:-shared} \ 12818334Speter %{!shared: \ 12918334Speter %{!ibcs: \ 13018334Speter %{!static: \ 13118334Speter %{rdynamic:-export-dynamic} \ 13218334Speter %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \ 13318334Speter %{static:-static}}}" 13418334Speter#endif 13550397Sobrien#else 13648743Sobrien#define LINK_SPEC "-m elf_i386 %{shared:-shared} \ 13748743Sobrien %{!shared: \ 13848743Sobrien %{!ibcs: \ 13948743Sobrien %{!static: \ 14048743Sobrien %{rdynamic:-export-dynamic} \ 14148743Sobrien %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ 14248743Sobrien %{static:-static}}}" 14350397Sobrien#endif 14418334Speter 14550397Sobrien/* A C statement (sans semicolon) to output to the stdio stream 14650397Sobrien FILE the assembler definition of uninitialized global DECL named 14750397Sobrien NAME whose size is SIZE bytes and alignment is ALIGN bytes. 14850397Sobrien Try to use asm_output_aligned_bss to implement this macro. */ 14950397Sobrien 15050397Sobrien#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ 15150397Sobrien asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN) 15250397Sobrien 15350397Sobrien/* A C statement to output to the stdio stream FILE an assembler 15450397Sobrien command to advance the location counter to a multiple of 1<<LOG 15550397Sobrien bytes if it is within MAX_SKIP bytes. 15650397Sobrien 15750397Sobrien This is used to align code labels according to Intel recommendations. */ 15850397Sobrien 15950397Sobrien#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN 16052284Sobrien#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \ 16152284Sobrien do { \ 16252284Sobrien if ((LOG) != 0) { \ 16352284Sobrien if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \ 16452284Sobrien else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \ 16552284Sobrien } \ 16652284Sobrien } while (0) 16750397Sobrien#endif 16890075Sobrien 16990075Sobrien#if defined(__PIC__) && defined (USE_GNULIBC_1) 17090075Sobrien/* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr, 17190075Sobrien __environ and atexit. We have to make sure they are in the .dynsym 17290075Sobrien section. We do this by forcing the assembler to create undefined 17390075Sobrien references to these symbols in the object file. */ 17490075Sobrien#undef CRT_CALL_STATIC_FUNCTION 17590075Sobrien#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ 17690075Sobrien asm (SECTION_OP "\n\t" \ 17790075Sobrien "call " USER_LABEL_PREFIX #FUNC "\n" \ 17890075Sobrien TEXT_SECTION_ASM_OP "\n\t" \ 17990075Sobrien ".extern ___brk_addr\n\t" \ 18090075Sobrien ".type ___brk_addr,@object\n\t" \ 18190075Sobrien ".extern __environ\n\t" \ 18290075Sobrien ".type __environ,@object\n\t" \ 18390075Sobrien ".extern atexit\n\t" \ 18490075Sobrien ".type atexit,@function"); 18590075Sobrien#endif 18690075Sobrien 18790075Sobrien/* Handle special EH pointer encodings. Absolute, pc-relative, and 18890075Sobrien indirect are handled automatically. */ 18990075Sobrien#define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(FILE, ENCODING, SIZE, ADDR, DONE) \ 19090075Sobrien do { \ 19190075Sobrien if ((SIZE) == 4 && ((ENCODING) & 0x70) == DW_EH_PE_datarel) \ 19290075Sobrien { \ 19390075Sobrien fputs (ASM_LONG, FILE); \ 19490075Sobrien assemble_name (FILE, XSTR (ADDR, 0)); \ 19590075Sobrien fputs (((ENCODING) & DW_EH_PE_indirect ? "@GOT" : "@GOTOFF"), FILE); \ 19690075Sobrien goto DONE; \ 19790075Sobrien } \ 19890075Sobrien } while (0) 19990075Sobrien 20090075Sobrien/* Used by crtstuff.c to initialize the base of data-relative relocations. 20190075Sobrien These are GOT relative on x86, so return the pic register. */ 20290075Sobrien#ifdef __PIC__ 20390075Sobrien#define CRT_GET_RFIB_DATA(BASE) \ 20490075Sobrien { \ 20590075Sobrien register void *ebx_ __asm__("ebx"); \ 20690075Sobrien BASE = ebx_; \ 20790075Sobrien } 20890075Sobrien#else 20990075Sobrien#define CRT_GET_RFIB_DATA(BASE) \ 21090075Sobrien __asm__ ("call\t.LPR%=\n" \ 21190075Sobrien ".LPR%=:\n\t" \ 21290075Sobrien "popl\t%0\n\t" \ 21390075Sobrien /* Due to a GAS bug, this cannot use EAX. That encodes \ 21490075Sobrien smaller than the traditional EBX, which results in the \ 21590075Sobrien offset being off by one. */ \ 21690075Sobrien "addl\t$_GLOBAL_OFFSET_TABLE_+[.-.LPR%=],%0" \ 21790075Sobrien : "=d"(BASE)) 21890075Sobrien#endif 21990075Sobrien 22090075Sobrien/* Do code reading to identify a signal frame, and set the frame 22190075Sobrien state data appropriately. See unwind-dw2.c for the structs. */ 22290075Sobrien 22390075Sobrien#ifdef IN_LIBGCC2 22490075Sobrien#include <signal.h> 22590075Sobrien#include <sys/ucontext.h> 22690075Sobrien#endif 22790075Sobrien 22890075Sobrien#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \ 22990075Sobrien do { \ 23090075Sobrien unsigned char *pc_ = (CONTEXT)->ra; \ 23190075Sobrien struct sigcontext *sc_; \ 23290075Sobrien long new_cfa_; \ 23390075Sobrien \ 23490075Sobrien /* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */ \ 23590075Sobrien if (*(unsigned short *)(pc_+0) == 0xb858 \ 23690075Sobrien && *(unsigned int *)(pc_+2) == 119 \ 23790075Sobrien && *(unsigned short *)(pc_+6) == 0x80cd) \ 23890075Sobrien sc_ = (CONTEXT)->cfa + 4; \ 23990075Sobrien /* movl $__NR_rt_sigreturn,%eax ; int $0x80 */ \ 24090075Sobrien else if (*(unsigned char *)(pc_+0) == 0xb8 \ 24190075Sobrien && *(unsigned int *)(pc_+1) == 173 \ 24290075Sobrien && *(unsigned short *)(pc_+5) == 0x80cd) \ 24390075Sobrien { \ 24490075Sobrien struct rt_sigframe { \ 24590075Sobrien int sig; \ 24690075Sobrien struct siginfo *pinfo; \ 24790075Sobrien void *puc; \ 24890075Sobrien struct siginfo info; \ 24990075Sobrien struct ucontext uc; \ 25090075Sobrien } *rt_ = (CONTEXT)->cfa; \ 25190075Sobrien sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext; \ 25290075Sobrien } \ 25390075Sobrien else \ 25490075Sobrien break; \ 25590075Sobrien \ 25690075Sobrien new_cfa_ = sc_->esp; \ 25790075Sobrien (FS)->cfa_how = CFA_REG_OFFSET; \ 25890075Sobrien (FS)->cfa_reg = 4; \ 25990075Sobrien (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \ 26090075Sobrien \ 26190075Sobrien /* The SVR4 register numbering macros aren't usable in libgcc. */ \ 26290075Sobrien (FS)->regs.reg[0].how = REG_SAVED_OFFSET; \ 26390075Sobrien (FS)->regs.reg[0].loc.offset = (long)&sc_->eax - new_cfa_; \ 26490075Sobrien (FS)->regs.reg[3].how = REG_SAVED_OFFSET; \ 26590075Sobrien (FS)->regs.reg[3].loc.offset = (long)&sc_->ebx - new_cfa_; \ 26690075Sobrien (FS)->regs.reg[1].how = REG_SAVED_OFFSET; \ 26790075Sobrien (FS)->regs.reg[1].loc.offset = (long)&sc_->ecx - new_cfa_; \ 26890075Sobrien (FS)->regs.reg[2].how = REG_SAVED_OFFSET; \ 26990075Sobrien (FS)->regs.reg[2].loc.offset = (long)&sc_->edx - new_cfa_; \ 27090075Sobrien (FS)->regs.reg[6].how = REG_SAVED_OFFSET; \ 27190075Sobrien (FS)->regs.reg[6].loc.offset = (long)&sc_->esi - new_cfa_; \ 27290075Sobrien (FS)->regs.reg[7].how = REG_SAVED_OFFSET; \ 27390075Sobrien (FS)->regs.reg[7].loc.offset = (long)&sc_->edi - new_cfa_; \ 27490075Sobrien (FS)->regs.reg[5].how = REG_SAVED_OFFSET; \ 27590075Sobrien (FS)->regs.reg[5].loc.offset = (long)&sc_->ebp - new_cfa_; \ 27690075Sobrien (FS)->regs.reg[8].how = REG_SAVED_OFFSET; \ 27790075Sobrien (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \ 27890075Sobrien (FS)->retaddr_column = 8; \ 27990075Sobrien goto SUCCESS; \ 28090075Sobrien } while (0) 281