i386: Allow GOT32 relocations against ABS symbols
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 7 Feb 2022 23:22:19 +0000 (15:22 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 8 Feb 2022 00:04:10 +0000 (16:04 -0800)
GOT32 relocations are allowed since absolute value + addend is stored in
the GOT slot.

Tested on glibc 2.35 build with GCC 11.2 and -Os.

bfd/

PR ld/28870
* elfxx-x86.c (_bfd_elf_x86_valid_reloc_p): Also allow GOT32
relocations.

ld/

PR ld/28870
* testsuite/ld-i386/i386.exp: Run pr28870.
* testsuite/ld-i386/pr28870.d: New file.
* testsuite/ld-i386/pr28870.s: Likewise.

bfd/elfxx-x86.c
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/pr28870.d [new file with mode: 0644]
ld/testsuite/ld-i386/pr28870.s [new file with mode: 0644]

index 7ac2411fc80d2f23eff352629c8e9bd275fe63bc..d00dc45677b71832789002b9321f93a7951f4685 100644 (file)
@@ -1942,9 +1942,9 @@ _bfd_elf_x86_valid_reloc_p (asection *input_section,
       irel = *rel;
 
       /* Only allow relocations against absolute symbol, which can be
-        resolved as absolute value + addend.  GOTPCREL relocations
-        are allowed since absolute value + addend is stored in the
-        GOT slot.  */
+        resolved as absolute value + addend.  GOTPCREL and GOT32
+        relocations are allowed since absolute value + addend is
+        stored in the GOT slot.  */
       if (bed->target_id == X86_64_ELF_DATA)
        {
          r_type &= ~R_X86_64_converted_reloc_bit;
@@ -1965,7 +1965,9 @@ _bfd_elf_x86_valid_reloc_p (asection *input_section,
       else
        valid_p = (r_type == R_386_32
                   || r_type == R_386_16
-                  || r_type == R_386_8);
+                  || r_type == R_386_8
+                  || r_type == R_386_GOT32
+                  || r_type == R_386_GOT32X);
 
       if (valid_p)
        *no_dynreloc_p = true;
index fe36b0fb53358aa1fdfdc3d648d7dff7c20c6f80..82e14ab38d05b842b8a7c4271c5bd771fdfaa1cb 100644 (file)
@@ -509,6 +509,7 @@ run_dump_test "pr27491-3"
 run_dump_test "pr27491-4"
 run_dump_test "dt-relr-1a"
 run_dump_test "dt-relr-1b"
+run_dump_test "pr28870"
 
 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/pr28870.d b/ld/testsuite/ld-i386/pr28870.d
new file mode 100644 (file)
index 0000000..8e9b9fb
--- /dev/null
@@ -0,0 +1,10 @@
+#as: --32
+#ld: --no-dynamic-linker -m elf_i386 -pie
+#readelf: -s --wide
+
+#...
+Symbol table '.symtab' contains [0-9]+ entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+#...
+ +[a-f0-9]+: 00000002     0 NOTYPE  LOCAL  DEFAULT  ABS foo
+#pass
diff --git a/ld/testsuite/ld-i386/pr28870.s b/ld/testsuite/ld-i386/pr28870.s
new file mode 100644 (file)
index 0000000..8e32047
--- /dev/null
@@ -0,0 +1,6 @@
+       .text
+       .globl _start
+_start:
+       addl    foo@GOT(%ebx), %eax
+       cmpl    $0, foo@GOT(%ebx)
+foo = 2