]> gcc.gnu.org Git - gcc.git/commitdiff
Change EH pointer encodings to PC relative on Windows
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 2 Jul 2021 08:21:11 +0000 (10:21 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Fri, 2 Jul 2021 08:33:31 +0000 (10:33 +0200)
A big difference between ELF and PE-COFF is that, with the latter, you can
build position-independent executables or DLLs without generating PIC; as
a  matter of fact, flag_pic has historically been forced to 0 for 32-bit:

/* Don't allow flag_pic to propagate since gas may produce invalid code
   otherwise.  */

\
do {
        \
  flag_pic = TARGET_64BIT ? 1 : 0; \
} while (0)

The reason is that the linker builds a .reloc section that collects the
absolute relocations in the generated binary, and the loader uses them to
relocate it at load time if need be (e.g. if --dynamicbase is enabled).

Up to binutils 2.35, the GNU linker didn't build the .reloc section for
executables and defaulted to --enable-auto-image-base for DLLs, which means
that DLLs had an essentially unique load address and, therefore, need not
be relocated by the loader in most cases.

With binutils 2.36 and later, the GNU linker builds a .reloc section for
executables (thus making them PIE), --enable-auto-image-base is disabled
and --dynamicbase is enabled by default, which means that essentially all
the binaries are relocated at load time.

This badly breaks the 32-bit compiler configured to use DWARF-2 EH because
the loader corrupts the .eh_frame section when processing the relocations
contained in the .reloc section.

gcc/
* config/i386/i386.c (asm_preferred_eh_data_format): Always use the
PIC encodings for PE-COFF targets.

gcc/config/i386/i386.c

index 06ad1b2274e3ae14cfe7064410fdc606396e3014..103fa10a9c5f0fde65a4fdbbb2f4a7ebd3308e9b 100644 (file)
@@ -21350,10 +21350,12 @@ ix86_stack_protect_fail (void)
    After all, the relocation needed is the same as for the call insn.
    Whether or not a particular assembler allows us to enter such, I
    guess we'll have to see.  */
+
 int
 asm_preferred_eh_data_format (int code, int global)
 {
-  if (flag_pic)
+  /* PE-COFF is effectively always -fPIC because of the .reloc section.  */
+  if (flag_pic || TARGET_PECOFF)
     {
       int type = DW_EH_PE_sdata8;
       if (!TARGET_64BIT
@@ -21362,9 +21364,11 @@ asm_preferred_eh_data_format (int code, int global)
        type = DW_EH_PE_sdata4;
       return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
     }
+
   if (ix86_cmodel == CM_SMALL
       || (ix86_cmodel == CM_MEDIUM && code))
     return DW_EH_PE_udata4;
+
   return DW_EH_PE_absptr;
 }
 \f
This page took 0.09295 seconds and 5 git commands to generate.