]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ix86: tighten convert-load-reloc checking
authorJan Beulich <jbeulich@suse.com>
Fri, 21 Feb 2025 09:22:50 +0000 (10:22 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 21 Feb 2025 09:22:50 +0000 (10:22 +0100)
Just like was done recently for x86-64 (commit 4998f9ea9d35): Even if
the assembler avoids using the relaxable relocation for inapplicable
insns, the relocation type can still appear for other reasons. Be more
thorough in the opcode checking we do, to avoid bogusly altering other
insns.

Furthermore correct an opcode mask (even if with the added condition
that's now fully benign).

bfd/elf32-i386.c
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-i386/load8.d [new file with mode: 0644]
ld/testsuite/ld-i386/load8.s [new file with mode: 0644]

index 78ca74e247265fd12802d397fcd9f584805debcd..ca82016fafc6ef9f872516c8b1c3b1cc8fc55a76 100644 (file)
@@ -1453,15 +1453,16 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
                  modrm = 0xc0 | (modrm & 0x38) >> 3;
                  opcode = 0xf7;
                }
-             else
+             else if ((opcode | 0x38) == 0x3b)
                {
                  /* Convert "binop foo@GOT(%reg1), %reg2" to
                     "binop $foo, %reg2".  */
-                 modrm = (0xc0
-                          | (modrm & 0x38) >> 3
-                          | (opcode & 0x3c));
+                 modrm = 0xc0 | ((modrm & 0x38) >> 3) | (opcode & 0x38);
                  opcode = 0x81;
                }
+             else
+               return true;
+
              bfd_put_8 (abfd, modrm, contents + roff - 1);
              r_type = R_386_32;
            }
index 16b9fb87e213c5735d9bfd45dff6ca52d48a0c95..f84b4d4fe59a93b86601e1033c805393964cdc34 100644 (file)
@@ -373,6 +373,7 @@ run_dump_test "load5a"
 run_dump_test "load5b"
 run_dump_test "load6"
 run_dump_test "load7"
+run_dump_test "load8"
 run_dump_test "pr19175"
 run_dump_test "pr19615"
 run_dump_test "pr19636-1a"
diff --git a/ld/testsuite/ld-i386/load8.d b/ld/testsuite/ld-i386/load8.d
new file mode 100644 (file)
index 0000000..c114721
--- /dev/null
@@ -0,0 +1,14 @@
+#as: --32 -mrelax-relocations=yes
+#ld: -melf_i386 -z noseparate-code
+#objdump: -dw
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+8048074 <_start>:
+[      ]*[a-f0-9]+:    12 05 90 90 04 08       adc    0x8049090,%al
+[      ]*[a-f0-9]+:    6b 05 90 90 04 08 01    imul   \$(0x)?1,0x8049090,%eax
+[      ]*[a-f0-9]+:    84 35 90 90 04 08       test   %dh,0x8049090
+[      ]*[a-f0-9]+:    87 05 90 90 04 08       xchg   %eax,0x8049090
+#pass
diff --git a/ld/testsuite/ld-i386/load8.s b/ld/testsuite/ld-i386/load8.s
new file mode 100644 (file)
index 0000000..87131f9
--- /dev/null
@@ -0,0 +1,21 @@
+       .data
+       .type   bar, @object
+bar:
+       .byte   1
+       .size   bar, .-bar
+
+       .text
+       .globl  _start
+       .type   _start, @function
+_start:
+       # Other insns must not be accidentally transformed.
+       adc     0, %al
+       .reloc .-4, R_386_GOT32X, bar
+       imul    $1, 0, %eax
+       .reloc .-5, R_386_GOT32X, bar
+       test    %dh, 0
+       .reloc .-4, R_386_GOT32X, bar
+       xchg    0, %eax
+       .reloc .-4, R_386_GOT32X, bar
+
+       .size   _start, .-_start