Blame sysdeps/i386/sysdep.h

Packit 6c4009
/* Assembler macros for i386.
Packit 6c4009
   Copyright (C) 1991-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <sysdeps/x86/sysdep.h>
Packit 6c4009
Packit 6c4009
#include <features.h> /* For __GNUC_PREREQ.  */
Packit 6c4009
Packit 6c4009
/* It is desirable that the names of PIC thunks match those used by
Packit 6c4009
   GCC so that multiple copies are eliminated by the linker.  Because
Packit 6c4009
   GCC 4.6 and earlier use __i686 in the names, it is necessary to
Packit 6c4009
   override that predefined macro.  */
Packit 6c4009
#if defined __i686 && defined __ASSEMBLER__
Packit 6c4009
#undef __i686
Packit 6c4009
#define __i686 __i686
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef	__ASSEMBLER__
Packit 6c4009
# define GET_PC_THUNK(reg) __x86.get_pc_thunk.reg
Packit 6c4009
#else
Packit 6c4009
# define GET_PC_THUNK_STR(reg) "__x86.get_pc_thunk." #reg
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef	__ASSEMBLER__
Packit 6c4009
Packit 6c4009
/* Syntactic details of assembler.  */
Packit 6c4009
Packit 6c4009
/* If compiled for profiling, call `mcount' at the start of each function.  */
Packit 6c4009
#ifdef	PROF
Packit 6c4009
/* The mcount code relies on a normal frame pointer being on the stack
Packit 6c4009
   to locate our caller, so push one just for its benefit.  */
Packit 6c4009
#define CALL_MCOUNT \
Packit 6c4009
  pushl %ebp; cfi_adjust_cfa_offset (4); movl %esp, %ebp; \
Packit 6c4009
  cfi_def_cfa_register (ebp); call JUMPTARGET(mcount); \
Packit 6c4009
  popl %ebp; cfi_def_cfa (esp, 4);
Packit 6c4009
#else
Packit 6c4009
#define CALL_MCOUNT		/* Do nothing.  */
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#define	PSEUDO(name, syscall_name, args)				      \
Packit 6c4009
  .globl syscall_error;							      \
Packit 6c4009
lose: SYSCALL_PIC_SETUP							      \
Packit 6c4009
  jmp JUMPTARGET(syscall_error);					      \
Packit 6c4009
  ENTRY (name)								      \
Packit 6c4009
  DO_CALL (syscall_name, args);						      \
Packit 6c4009
  jb lose
Packit 6c4009
Packit 6c4009
# define SETUP_PIC_REG(reg) \
Packit 6c4009
  .ifndef GET_PC_THUNK(reg);						      \
Packit 6c4009
  .section .gnu.linkonce.t.GET_PC_THUNK(reg),"ax",@progbits;		      \
Packit 6c4009
  .globl GET_PC_THUNK(reg);						      \
Packit 6c4009
  .hidden GET_PC_THUNK(reg);						      \
Packit 6c4009
  .p2align 4;								      \
Packit 6c4009
  .type GET_PC_THUNK(reg),@function;					      \
Packit 6c4009
GET_PC_THUNK(reg):							      \
Packit 6c4009
  movl (%esp), %e##reg;							      \
Packit 6c4009
  ret;									      \
Packit 6c4009
  .size GET_PC_THUNK(reg), . - GET_PC_THUNK(reg);			      \
Packit 6c4009
  .previous;								      \
Packit 6c4009
  .endif;								      \
Packit 6c4009
  call GET_PC_THUNK(reg)
Packit 6c4009
Packit 6c4009
# define LOAD_PIC_REG(reg) \
Packit 6c4009
  SETUP_PIC_REG(reg); addl $_GLOBAL_OFFSET_TABLE_, %e##reg
Packit 6c4009
Packit 6c4009
#undef JUMPTARGET
Packit 6c4009
#ifdef PIC
Packit 6c4009
#define JUMPTARGET(name)	name##@PLT
Packit 6c4009
#define SYSCALL_PIC_SETUP \
Packit 6c4009
    pushl %ebx;								      \
Packit 6c4009
    cfi_adjust_cfa_offset (4);						      \
Packit 6c4009
    call 0f;								      \
Packit 6c4009
0:  popl %ebx;								      \
Packit 6c4009
    cfi_adjust_cfa_offset (-4);						      \
Packit 6c4009
    addl $_GLOBAL_OFFSET_TABLE_+[.-0b], %ebx;
Packit 6c4009
Packit 6c4009
#else
Packit 6c4009
#define JUMPTARGET(name)	name
Packit 6c4009
#define SYSCALL_PIC_SETUP	/* Nothing.  */
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#else /* __ASSEMBLER__ */
Packit 6c4009
Packit 6c4009
# define SETUP_PIC_REG_STR(reg)						\
Packit 6c4009
  ".ifndef " GET_PC_THUNK_STR (reg) "\n"				\
Packit 6c4009
  ".section .gnu.linkonce.t." GET_PC_THUNK_STR (reg) ",\"ax\",@progbits\n" \
Packit 6c4009
  ".globl " GET_PC_THUNK_STR (reg) "\n"					\
Packit 6c4009
  ".hidden " GET_PC_THUNK_STR (reg) "\n"				\
Packit 6c4009
  ".p2align 4\n"							\
Packit 6c4009
  ".type " GET_PC_THUNK_STR (reg) ",@function\n"			\
Packit 6c4009
GET_PC_THUNK_STR (reg) ":"						\
Packit 6c4009
  "movl (%%esp), %%e" #reg "\n"						\
Packit 6c4009
  "ret\n"								\
Packit 6c4009
  ".size " GET_PC_THUNK_STR (reg) ", . - " GET_PC_THUNK_STR (reg) "\n"	\
Packit 6c4009
  ".previous\n"								\
Packit 6c4009
  ".endif\n"								\
Packit 6c4009
  "call " GET_PC_THUNK_STR (reg)
Packit 6c4009
Packit 6c4009
# define LOAD_PIC_REG_STR(reg) \
Packit 6c4009
  SETUP_PIC_REG_STR (reg) "\naddl $_GLOBAL_OFFSET_TABLE_, %%e" #reg
Packit 6c4009
Packit 6c4009
#endif	/* __ASSEMBLER__ */