https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124027
Bug ID: 124027
Summary: x86 coff -fpic output is not position independent
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: pali at kernel dot org
Target Milestone: ---
-fpic/-fPIC code generated by gcc for 32-bit x86 windows PE coff target is not
position independent.
Take following example C code:
extern int a;
int func(void) { return a; }
compiled by i686-w64-mingw32-gcc -O2 -fPIC produce following object file:
test.o: file format pe-i386
Disassembly of section .text:
00000000 <_func>:
0: a1 00 00 00 00 mov 0x0,%eax
1: dir32 _a
5: c3 ret
It uses absolute dir32 (IMAGE_REL_I386_DIR32) relocation which is not position
independent and hence requires runtime relocation by PE loader.
On the other hand, same code compiled by i686-linux-gnu-gcc for ELF target
produce real position independent code:
test.o: file format elf32-i386
Disassembly of section .text:
00000000 <func>:
0: e8 fc ff ff ff call 1 <func+0x1>
1: R_386_PC32 __x86.get_pc_thunk.ax
5: 05 01 00 00 00 add $0x1,%eax
6: R_386_GOTPC _GLOBAL_OFFSET_TABLE_
a: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
c: R_386_GOT32X a
10: 8b 00 mov (%eax),%eax
12: c3 ret
Disassembly of section .text.__x86.get_pc_thunk.ax:
00000000 <__x86.get_pc_thunk.ax>:
0: 8b 04 24 mov (%esp),%eax
3: c3 ret
For 32-bit x86 COFF output similar position independent code could be generated
too.
For example like this:
.text
.p2align 4
.globl _func
.def _func; .scl 2; .type 32; .endef
_func:
.cfi_startproc
call ___x86.get_pc_thunk.ax
addl $(_a - .), %eax
movl (%eax), %eax
ret
.cfi_endproc
.section .text$__x86.get_pc_thunk.ax,"x"
.linkonce discard
.globl ___x86.get_pc_thunk.ax
.def ___x86.get_pc_thunk.ax; .scl 2; .type 32;
.endef
___x86.get_pc_thunk.ax:
.cfi_startproc
movl (%esp), %eax
ret
.cfi_endproc
GNU AS assembler for this code generates object file:
test.o: file format pe-i386
Disassembly of section .text:
00000000 <_func>:
0: e8 00 00 00 00 call 5 <_func+0x5>
1: DISP32 ___x86.get_pc_thunk.ax
5: 05 05 00 00 00 add $0x5,%eax
6: DISP32 _a
a: 8b 00 mov (%eax),%eax
c: c3 ret
Disassembly of section .text$__x86.get_pc_thunk.ax:
00000000 <___x86.get_pc_thunk.ax>:
0: 8b 04 24 mov (%esp),%eax
3: c3 ret
Which uses only DISP32 (IMAGE_REL_I386_REL32) relocations which are fully
resolved by GNU LD linker and final executable does not require any runtime
relocations by PE loader.