[v2,5/7] ix86: restrict use of GOT32X relocs

Message ID 09b0fca4-e931-4cfb-b2ad-0d3e4ccf4da4@suse.com
State New
Headers
Series x86: further GOT{,PCREL} related adjustments |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Jan Beulich Feb. 14, 2025, 9:56 a.m. UTC
  The ELF linker rejects use of this reloc type without a base register
for PIC code. Suppress its use by gas in such cases.

To keep things building for non-ELF, include the entire containing if()
in an #ifdef: All consumers of ->fx_tcbit* live in such conditionals as
well, hence there's no reason to keep the producer active.
---
The linker also rejects use of GOT32, but that's an issue the programmer
has to deal with. In the assembler we need to avoid doing something
wrong that the programmer has not explicitly asked for.
---
v2: Add tests. Fix non-ELF build.
  

Patch

--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -12932,6 +12932,7 @@  output_disp (fragS *insn_start_frag, off
 	      else if (object_64bit)
 		continue;
 
+#ifdef OBJ_ELF
 	      /* Check for "call/jmp *mem", "push mem", "mov mem, %reg",
 		 "movrs mem, %reg", "test %reg, mem" and "binop mem, %reg" where
 		 binop is one of adc, add, and, cmp, or, sbb, sub, xor, or imul
@@ -12994,9 +12995,11 @@  output_disp (fragS *insn_start_frag, off
 			}
 		    }
 		  else if (generate_relax_relocations
-			   || (i.rm.mode == 0 && i.rm.regmem == 5))
+			   ? (!shared || i.rm.mode != 0 || i.rm.regmem != 5)
+			   : (!shared && i.rm.mode == 0 && i.rm.regmem == 5))
 		    fixP->fx_tcbit2 = 1;
 		}
+#endif
 	    }
 	}
     }
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -369,8 +369,10 @@  run_dump_test "load2"
 run_dump_test "load3"
 run_dump_test "load4a"
 run_dump_test "load4b"
+run_dump_test "load4c"
 run_dump_test "load5a"
 run_dump_test "load5b"
+run_dump_test "load5c"
 run_dump_test "load6"
 run_dump_test "load7"
 run_dump_test "load8"
--- /dev/null
+++ b/ld/testsuite/ld-i386/load4c.d
@@ -0,0 +1,4 @@ 
+#source: load4.s
+#as: --32 -mshared -mrelax-relocations=yes
+#ld: -Bsymbolic -shared -melf_i386
+#error: direct GOT relocation R_386_GOT32 against `foo' without base register can not be used when making a shared object
--- /dev/null
+++ b/ld/testsuite/ld-i386/load5c.d
@@ -0,0 +1,4 @@ 
+#source: load5.s
+#as: --32 -mshared -mrelax-relocations=yes
+#ld: -Bsymbolic -shared -melf_i386
+#error: direct GOT relocation R_386_GOT32 against `foo' without base register can not be used when making a shared object