http://sourceware.org/bugzilla/show_bug.cgi?id=15602
Bug ID: 15602 Summary: .word L2-L1 fails to diagnose offsets larger than 16 bits, resulting in broken jump tables on m68k Product: binutils Version: 2.24 (HEAD) Status: NEW Severity: normal Priority: P2 Component: gas Assignee: unassigned at sourceware dot org Reporter: mikpe at it dot uu.se The following test case emulates a GCC-generated switch/jump table on m68k-linux: > cat gasbug.s .file "gasbug.s" .text .align 2 .globl main .type main, @function main: moveq #0,%d0 move.w .L1(%pc,%d0.l*2),%d0 jmp %pc@(2,%d0:w) .balignw 2,0x284c .L1: .rept 65536-3 .word .L2-.L1 .endr .L2: moveq #0,%d0 rts .size main, .-main .section .note.GNU-stack,"",@progbits The jump table at L1 contains >32K 16-bit entries, so the value of .L2-.L1 needs more than the 16 bits as emitted by .word. However, GAS fails to diagnose this overflow and instead emits truncated values (0xfffe to be exact). At runtime, the code branches to L1 - 2, executes 0x0002 (harmless), falls through to L1, and SIGILLs because 0xfffe is not a valid opcode. > as -o gasbug.o gasbug.s > gcc -o gasbug gasbug.o > gdb ./gasbug ... Breakpoint 1, 0x800003b8 in main () 1: x/i $pc => 0x800003b8 <main>: moveq #0,%d0 (gdb) stepi 0x800003ba in main () 1: x/i $pc => 0x800003ba <main+2>: movew %pc@(0x800003c2 <main+10>,%d0:l:2),%d0 (gdb) 0x800003be in main () 1: x/i $pc => 0x800003be <main+6>: jmp %pc@(0x800003c2 <main+10>,%d0:w) (gdb) 0x800003c0 in main () 1: x/i $pc => 0x800003c0 <main+8>: orib #-2,%d2 (gdb) 0x800003c4 in main () 1: x/i $pc => 0x800003c4 <main+12>: .short 0xfffe (gdb) Program received signal SIGILL, Illegal instruction. If the operand to .word is a literal >= 64K, then GAS does flag the error: > echo '.word 65536' | as > /dev/null {standard input}: Assembler messages: {standard input}:1: Warning: value 0x10000 truncated to 0x0 Looking at an objdump of gasbug.o it appears that GAS has attempted to route the jump table entries to trampolines, but failed: > objdump -d gasbug.o gasbug.o: file format elf32-m68k Disassembly of section .text: 00000000 <main>: 0: 7000 moveq #0,%d0 2: 303b 0a06 movew %pc@(a <main+0xa>,%d0:l:2),%d0 6: 4efb 0002 jmp %pc@(a <main+0xa>,%d0:w) a: fffe .short 0xfffe (many many more ".short 0xfffe") 20002: fffe .short 0xfffe 20004: 6000 0008 braw 2000e <main+0x2000e> 20008: 60ff 0000 0004 bral 2000e <main+0x2000e> 2000e: 7000 moveq #0,%d0 20010: 4e75 rts This bug is related to <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57583>. -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils