| xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | /* Assembler macros for i386. | 
|  | 2 | Copyright (C) 1991-2016 Free Software Foundation, Inc. | 
|  | 3 | This file is part of the GNU C Library. | 
|  | 4 |  | 
|  | 5 | The GNU C Library is free software; you can redistribute it and/or | 
|  | 6 | modify it under the terms of the GNU Lesser General Public | 
|  | 7 | License as published by the Free Software Foundation; either | 
|  | 8 | version 2.1 of the License, or (at your option) any later version. | 
|  | 9 |  | 
|  | 10 | The GNU C Library is distributed in the hope that it will be useful, | 
|  | 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | 13 | Lesser General Public License for more details. | 
|  | 14 |  | 
|  | 15 | You should have received a copy of the GNU Lesser General Public | 
|  | 16 | License along with the GNU C Library; if not, see | 
|  | 17 | <http://www.gnu.org/licenses/>.  */ | 
|  | 18 |  | 
|  | 19 | #include <sysdeps/generic/sysdep.h> | 
|  | 20 |  | 
|  | 21 | #include <features.h> /* For __GNUC_PREREQ.  */ | 
|  | 22 |  | 
|  | 23 | /* It is desirable that the names of PIC thunks match those used by | 
|  | 24 | GCC so that multiple copies are eliminated by the linker.  Because | 
|  | 25 | GCC 4.6 and earlier use __i686 in the names, it is necessary to | 
|  | 26 | override that predefined macro.  */ | 
|  | 27 | #if defined __i686 && defined __ASSEMBLER__ | 
|  | 28 | #undef __i686 | 
|  | 29 | #define __i686 __i686 | 
|  | 30 | #endif | 
|  | 31 |  | 
|  | 32 | #ifdef	__ASSEMBLER__ | 
|  | 33 | # define GET_PC_THUNK(reg) __x86.get_pc_thunk.reg | 
|  | 34 | #else | 
|  | 35 | # define GET_PC_THUNK_STR(reg) "__x86.get_pc_thunk." #reg | 
|  | 36 | #endif | 
|  | 37 |  | 
|  | 38 | #ifdef	__ASSEMBLER__ | 
|  | 39 |  | 
|  | 40 | /* Syntactic details of assembler.  */ | 
|  | 41 |  | 
|  | 42 | /* ELF uses byte-counts for .align, most others use log2 of count of bytes.  */ | 
|  | 43 | #define ALIGNARG(log2) 1<<log2 | 
|  | 44 | #define ASM_SIZE_DIRECTIVE(name) .size name,.-name; | 
|  | 45 |  | 
|  | 46 |  | 
|  | 47 | /* Define an entry point visible from C. | 
|  | 48 |  | 
|  | 49 | There is currently a bug in gdb which prevents us from specifying | 
|  | 50 | incomplete stabs information.  Fake some entries here which specify | 
|  | 51 | the current source file.  */ | 
|  | 52 | #define	ENTRY(name)							      \ | 
|  | 53 | .globl C_SYMBOL_NAME(name);						      \ | 
|  | 54 | .type C_SYMBOL_NAME(name),@function;					      \ | 
|  | 55 | .align ALIGNARG(4);							      \ | 
|  | 56 | C_LABEL(name)								      \ | 
|  | 57 | cfi_startproc;							      \ | 
|  | 58 | CALL_MCOUNT | 
|  | 59 |  | 
|  | 60 | #undef	END | 
|  | 61 | #define END(name)							      \ | 
|  | 62 | cfi_endproc;								      \ | 
|  | 63 | ASM_SIZE_DIRECTIVE(name) | 
|  | 64 |  | 
|  | 65 | #define ENTRY_CHK(name) ENTRY (name) | 
|  | 66 | #define END_CHK(name) END (name) | 
|  | 67 |  | 
|  | 68 | /* If compiled for profiling, call `mcount' at the start of each function.  */ | 
|  | 69 | #ifdef	PROF | 
|  | 70 | /* The mcount code relies on a normal frame pointer being on the stack | 
|  | 71 | to locate our caller, so push one just for its benefit.  */ | 
|  | 72 | #define CALL_MCOUNT \ | 
|  | 73 | pushl %ebp; cfi_adjust_cfa_offset (4); movl %esp, %ebp; \ | 
|  | 74 | cfi_def_cfa_register (ebp); call JUMPTARGET(mcount); \ | 
|  | 75 | popl %ebp; cfi_def_cfa (esp, 4); | 
|  | 76 | #else | 
|  | 77 | #define CALL_MCOUNT		/* Do nothing.  */ | 
|  | 78 | #endif | 
|  | 79 |  | 
|  | 80 | /* Since C identifiers are not normally prefixed with an underscore | 
|  | 81 | on this system, the asm identifier `syscall_error' intrudes on the | 
|  | 82 | C name space.  Make sure we use an innocuous name.  */ | 
|  | 83 | #define	syscall_error	__syscall_error | 
|  | 84 | #define mcount		_mcount | 
|  | 85 |  | 
|  | 86 | #define	PSEUDO(name, syscall_name, args)				      \ | 
|  | 87 | .globl syscall_error;							      \ | 
|  | 88 | lose: SYSCALL_PIC_SETUP							      \ | 
|  | 89 | jmp JUMPTARGET(syscall_error);					      \ | 
|  | 90 | ENTRY (name)								      \ | 
|  | 91 | DO_CALL (syscall_name, args);						      \ | 
|  | 92 | jb lose | 
|  | 93 |  | 
|  | 94 | #undef	PSEUDO_END | 
|  | 95 | #define	PSEUDO_END(name)						      \ | 
|  | 96 | END (name) | 
|  | 97 |  | 
|  | 98 | # define SETUP_PIC_REG(reg) \ | 
|  | 99 | .ifndef GET_PC_THUNK(reg);						      \ | 
|  | 100 | .section .gnu.linkonce.t.GET_PC_THUNK(reg),"ax",@progbits;		      \ | 
|  | 101 | .globl GET_PC_THUNK(reg);						      \ | 
|  | 102 | .hidden GET_PC_THUNK(reg);						      \ | 
|  | 103 | .p2align 4;								      \ | 
|  | 104 | .type GET_PC_THUNK(reg),@function;					      \ | 
|  | 105 | GET_PC_THUNK(reg):							      \ | 
|  | 106 | movl (%esp), %e##reg;							      \ | 
|  | 107 | ret;									      \ | 
|  | 108 | .size GET_PC_THUNK(reg), . - GET_PC_THUNK(reg);			      \ | 
|  | 109 | .previous;								      \ | 
|  | 110 | .endif;								      \ | 
|  | 111 | call GET_PC_THUNK(reg) | 
|  | 112 |  | 
|  | 113 | # define LOAD_PIC_REG(reg) \ | 
|  | 114 | SETUP_PIC_REG(reg); addl $_GLOBAL_OFFSET_TABLE_, %e##reg | 
|  | 115 |  | 
|  | 116 | #undef JUMPTARGET | 
|  | 117 | #ifdef PIC | 
|  | 118 | #define JUMPTARGET(name)	name##@PLT | 
|  | 119 | #define SYSCALL_PIC_SETUP \ | 
|  | 120 | pushl %ebx;								      \ | 
|  | 121 | cfi_adjust_cfa_offset (4);						      \ | 
|  | 122 | call 0f;								      \ | 
|  | 123 | 0:  popl %ebx;								      \ | 
|  | 124 | cfi_adjust_cfa_offset (-4);						      \ | 
|  | 125 | addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ebx; | 
|  | 126 |  | 
|  | 127 | #else | 
|  | 128 | #define JUMPTARGET(name)	name | 
|  | 129 | #define SYSCALL_PIC_SETUP	/* Nothing.  */ | 
|  | 130 | #endif | 
|  | 131 |  | 
|  | 132 | /* Local label name for asm code. */ | 
|  | 133 | #ifndef L | 
|  | 134 | #define L(name)		.L##name | 
|  | 135 | #endif | 
|  | 136 |  | 
|  | 137 | #define atom_text_section .section ".text.atom", "ax" | 
|  | 138 |  | 
|  | 139 | #else /* __ASSEMBLER__ */ | 
|  | 140 |  | 
|  | 141 | # define SETUP_PIC_REG_STR(reg)						\ | 
|  | 142 | ".ifndef " GET_PC_THUNK_STR (reg) "\n"				\ | 
|  | 143 | ".section .gnu.linkonce.t." GET_PC_THUNK_STR (reg) ",\"ax\",@progbits\n" \ | 
|  | 144 | ".globl " GET_PC_THUNK_STR (reg) "\n"					\ | 
|  | 145 | ".hidden " GET_PC_THUNK_STR (reg) "\n"				\ | 
|  | 146 | ".p2align 4\n"							\ | 
|  | 147 | ".type " GET_PC_THUNK_STR (reg) ",@function\n"			\ | 
|  | 148 | GET_PC_THUNK_STR (reg) ":"						\ | 
|  | 149 | "movl (%%esp), %%e" #reg "\n"						\ | 
|  | 150 | "ret\n"								\ | 
|  | 151 | ".size " GET_PC_THUNK_STR (reg) ", . - " GET_PC_THUNK_STR (reg) "\n"	\ | 
|  | 152 | ".previous\n"								\ | 
|  | 153 | ".endif\n"								\ | 
|  | 154 | "call " GET_PC_THUNK_STR (reg) | 
|  | 155 |  | 
|  | 156 | # define LOAD_PIC_REG_STR(reg) \ | 
|  | 157 | SETUP_PIC_REG_STR (reg) "\naddl $_GLOBAL_OFFSET_TABLE_, %%e" #reg | 
|  | 158 |  | 
|  | 159 | #endif	/* __ASSEMBLER__ */ |