]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ix86: restrict use of GOT32X relocs
authorJan Beulich <jbeulich@suse.com>
Fri, 21 Feb 2025 09:26:59 +0000 (10:26 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 21 Feb 2025 09:26:59 +0000 (10:26 +0100)
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.

gas/config/tc-i386.c
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/load4c.d [new file with mode: 0644]
ld/testsuite/ld-i386/load5c.d [new file with mode: 0644]

index d44efe8050974c0382a127d8db9778ffdff74b3d..9adb96ff43309f5f05fe369d25660b1cdd839b0a 100644 (file)
@@ -12932,6 +12932,7 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_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, offsetT insn_start_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
            }
        }
     }
index dc91f6b2aed0c4e973251c48a43c77dcefe7ad66..8236b8fc0ac6232227d50ab0f69e02fe7f209a9c 100644 (file)
@@ -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"
diff --git a/ld/testsuite/ld-i386/load4c.d b/ld/testsuite/ld-i386/load4c.d
new file mode 100644 (file)
index 0000000..8257333
--- /dev/null
@@ -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
diff --git a/ld/testsuite/ld-i386/load5c.d b/ld/testsuite/ld-i386/load5c.d
new file mode 100644 (file)
index 0000000..3e78721
--- /dev/null
@@ -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