]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] wrong code on m68k with -mlong-jump-table-offsets and -malign-int (PR target...
authorMikael Pettersson <mikpelinux@gmail.com>
Mon, 11 Dec 2023 15:40:41 +0000 (08:40 -0700)
committerJeff Law <jlaw@ventanamicro.com>
Mon, 11 Dec 2023 15:41:37 +0000 (08:41 -0700)
On m68k the compiler assumes that the PC-relative jump-via-jump-table
instruction and the jump table are adjacent with no padding in between.

When -mlong-jump-table-offsets is combined with -malign-int, a 2-byte
nop may be inserted before the jump table, causing the jump to add the
fetched offset to the wrong PC base and thus jump to the wrong address.

Fixed by referencing the jump table via its label. On the test case
in the PR the object code change is (the moveal at 16 is the nop):

    a:  6536            bcss 42 <f+0x42>
    c:  e588            lsll #2,%d0
    e:  203b 0808       movel %pc@(18 <f+0x18>,%d0:l),%d0
-  12:  4efb 0802       jmp %pc@(16 <f+0x16>,%d0:l)
+  12:  4efb 0804       jmp %pc@(18 <f+0x18>,%d0:l)
   16:  284c            moveal %a4,%a4
   18:  0000 0020       orib #32,%d0
   1c:  0000 002c       orib #44,%d0

Bootstrapped and tested on m68k-linux-gnu, no regressions.

Note: I don't have commit rights to I would need assistance applying this.

PR target/112413
gcc/

* config/m68k/linux.h (ASM_RETURN_CASE_JUMP): For
TARGET_LONG_JUMP_TABLE_OFFSETS, reference the jump table
via its label.
* config/m68k/m68kelf.h (ASM_RETURN_CASE_JUMP): Likewise.
* config/m68k/netbsd-elf.h (ASM_RETURN_CASE_JUMP): Likewise.

gcc/config/m68k/linux.h
gcc/config/m68k/m68kelf.h
gcc/config/m68k/netbsd-elf.h

index 2e1cb5498b86f053d1e9b7c530648dfa186ca4c4..37069c4d0826207b4f619054bdfd4eb027ed093e 100644 (file)
@@ -102,12 +102,12 @@ along with GCC; see the file COPYING3.  If not see
        if (ADDRESS_REG_P (operands[0]))                \
          return "jmp %%pc@(2,%0:l)";                   \
        else if (TARGET_LONG_JUMP_TABLE_OFFSETS)        \
-         return "jmp %%pc@(2,%0:l)";                   \
+         return "jmp %%pc@(%l1,%0:l)";                 \
        else                                            \
          return "ext%.l %0\n\tjmp %%pc@(2,%0:l)";      \
       }                                                        \
     else if (TARGET_LONG_JUMP_TABLE_OFFSETS)           \
-      return "jmp %%pc@(2,%0:l)";                      \
+      return "jmp %%pc@(%l1,%0:l)";                    \
     else                                               \
       return "jmp %%pc@(2,%0:w)";                      \
   } while (0)
index 01ee724ef2bba84992c5bc86c5b17e09ea71d523..f89c9b70455b9045adc9ceeb62f051aff9cc1ec6 100644 (file)
@@ -59,12 +59,12 @@ along with GCC; see the file COPYING3.  If not see
        if (ADDRESS_REG_P (operands[0]))                \
          return "jmp %%pc@(2,%0:l)";                   \
        else if (TARGET_LONG_JUMP_TABLE_OFFSETS)        \
-         return "jmp %%pc@(2,%0:l)";                   \
+         return "jmp %%pc@(%l1,%0:l)";                 \
        else                                            \
          return "ext%.l %0\n\tjmp %%pc@(2,%0:l)";      \
       }                                                        \
     else if (TARGET_LONG_JUMP_TABLE_OFFSETS)           \
-      return "jmp %%pc@(2,%0:l)";                      \
+      return "jmp %%pc@(%l1,%0:l)";                    \
     else                                               \
       return "jmp %%pc@(2,%0:w)";                      \
   } while (0)
index 4d4a6d71cc45e8c52bb35e007c06b97d249f767b..6ba581b7b18bd9749e26fbe31e2c0ed824ab6d10 100644 (file)
@@ -137,12 +137,12 @@ while (0)
        if (ADDRESS_REG_P (operands[0]))                \
          return "jmp %%pc@(2,%0:l)";                   \
        else if (TARGET_LONG_JUMP_TABLE_OFFSETS)        \
-         return "jmp %%pc@(2,%0:l)";                   \
+         return "jmp %%pc@(%l1,%0:l)";                 \
        else                                            \
          return "ext%.l %0\n\tjmp %%pc@(2,%0:l)";      \
       }                                                        \
     else if (TARGET_LONG_JUMP_TABLE_OFFSETS)           \
-      return "jmp %%pc@(2,%0:l)";                      \
+      return "jmp %%pc@(%l1,%0:l)";                    \
     else                                               \
       return "jmp %%pc@(2,%0:w)";                      \
   } while (0)