Message ID | 3361197.V25eIC5XRa@fomalhaut |
---|---|
State | New |
Headers | show |
Series | [x86] Change EH pointer encodings to PC relative on Windows | expand |
On Thu, Jul 1, 2021 at 6:44 PM Eric Botcazou <botcazou@adacore.com> wrote: > > Hi, > > 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. */ > > #undef SUBTARGET_OVERRIDE_OPTIONS > #define SUBTARGET_OVERRIDE_OPTIONS > \ > do { > \ > flag_pic = TARGET_64BIT ? 1 : 0; \ > } while (0) > > The reason is that the linker builds a .reloc section that collects all 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 (the 64-bit > compiler always uses the native SEH) because the loader corrupts the .eh_frame > section when processing the relocations contained in the .reloc section. > > The attached patch simply forces the PIC encodings for EH on PE-COFF targets. > > Tested on x86/Windows, OK for all active branches? OK. Richard. > > 2021-07-01 Eric Botcazou <ebotcazou@adacore.com> > > * config/i386/i386.c (asm_preferred_eh_data_format): Always use the > PIC encodings for PE-COFF targets. > > -- > Eric Botcazou
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 2fbaae7cd02..cff26909292 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -21930,10 +21930,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 @@ -21942,9 +21944,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; }