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.

Reply via email to