glibc/sysdeps/i386/sysdep.h
Adhemerval Zanella b5b7fb76e1 i386: Use comdat instead of .gnu.linkonce for i386 setup pic register (BZ #20543)
GCC has moved from using .gnu.linkonce for i386 setup pic register with
minimum current version (as for binutils minimum binutils that support
comdat).

Trying to pinpoint when binutils has added comdat support for i686, it
seems it was around 2004 [1].  I also checking with some ancient
binutils older than 2.16 I see:

test.o: In function `__x86.get_pc_thunk.bx':
test.o(.text.__x86.get_pc_thunk.bx+0x0): multiple definition of `__x86.get_pc_thunk.bx'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../i386-linux-gnu/crti.o(.gnu.linkonce.t.__x86.get_pc_thunk.bx+0x0): first defined here

Which seems that such version can not handle either comdat at all or
a mix of linkonce and comdat.  For binutils 2.16.1 I am getting a
different issue trying to link a binary with and more recent
ctri.o (unrecognized relocation (0x2b) in section `.init', which is
R_386_GOT32X and old binutils won't generate it anyway).

So I think that either unlikely someone will use an older binutils than
the one used to glibc and even this scenario may fail with some issue
as the R_386_GOT32X.  Also, 2.16.1 is quite old and not really supported
(glibc itself required 2.25).

Checked on i686-linux-gnu.

[1] https://gcc.gnu.org/ml/gcc/2004-05/msg00030.html
2020-02-28 13:58:08 -03:00

118 lines
3.9 KiB
C

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