https://sourceware.org/bugzilla/show_bug.cgi?id=30919
Bug ID: 30919 Summary: Assembly Syntax Bugs in GAS Product: binutils Version: 2.41 Status: UNCONFIRMED Severity: normal Priority: P2 Component: binutils Assignee: unassigned at sourceware dot org Reporter: soomink at kaist dot ac.kr Target Milestone: --- When I tested GNU AS 2.41 for my research, I found several interesting bug cases. # ARMv8 ### Discard assembly lines First, GAS ignores syntax bugs and produce different assembly code. ``` $ cat buggy1.s lsr R0, #1, 1<<4 $ /bin/arm-linux-gnueabi-as buggy1.s -o buggy1.o $ bin/arm-linux-gnueabi-objdump -d buggy1.o buggy1.o: file format elf32-littlearm Disassembly of section .text: 00000000 <.text>: 0: e1a000a0 lsr r0, r0, #1 ``` # Arch64 Also, GAS recognizes registers and expressions as labels. In the following example, GAS treats register D0, register H0, and expression 1<<4 as labels. ``` $ cat buggy2.s tbz X0, [1], D0 tbnz X0, [1], H0 adrp X0, 1<<4 $ ./bin/aarch64-linux-gnu-as buggy2.s -o buggy2.o buggy2.o: file format elf64-littleaarch64 0000000000000000 <.text>: 0: 36080000 tbz w0, #1, 0 <D0> 4: 37080000 tbnz w0, #1, 0 <H0> 8: 90000000 adrp x0, 0 <.text> ``` # MIPS GAS transforms a memory operand as immediate value in case of syscall, break, c2, and c3 instructions. ``` $ ./bin/mips-linux-gnu-as buggy3.s -o buggy3.o $ cat buggy3.s syscall (1) break (2) c2 (3) c3 (4) $ objdump -d buggy3.o buggy3.o: file format elf32-tradbigmips Disassembly of section .text: 00000000 <.text>: 0: 0000004c syscall 0x1 4: 0002000d break 0x2 8: 4a000003 c2 0x3 c: 4e000004 c3 0x4 ``` # RISC-V GAS transforms a memory operand as an immediate value in case of j, jal, jalr, and jr instructions. ``` $ cat buggy4.s j (1) jal (2) jalr (a3) jr (a4) $ ./bin/riscv-linux-gnu-as buggy4.s -o buggy4.o $ ./bin/objdump -d buggy4.o buggy4.o: file format elf64-littleriscv Disassembly of section .text: 0000000000000000 <.text>: 0: 0000006f j 0 <.text> 4: 000000ef jal 4 <.text+0x4> 8: 000680e7 jalr a3 c: 00070067 jr a4 Disassembly of section .text: ``` # x86-64 ### Transform register Also, we found that GAS silently changes the size of registers without any WARNING message. We found such cases from ltr, lldt, verr, and verw instructions. ``` $ cat buggy5.s .intel_syntax noprefix ltr ECX lldt ESI verr EBP verw ECX $ ./bin/as --32 buggy5.s -o buggy5.o $ ./bin/objdump -d buggy5.o -M intel buggy5.o: file format elf32-i386 Disassembly of section .text: 00000000 <.text>: 0: 0f 00 d9 ltr cx 3: 0f 00 d6 lldt si 6: 0f 00 e5 verr bp 9: 0f 00 e9 verw cx ``` ### Inprecisely check memory size We found that GAS does not correctly check memory size when it handles invlpg, clfush, cldemote, prefetch, prefetchw, clwb, clfushopt, prefetchnta, prefetcht0, prefetcht1, prefetcht2, and prefetchwt1 instructions. ``` $ cat buggy6.s .intel_syntax noprefix invlpg QWORD PTR [EAX] clflush DWORD PTR [EAX] cldemote DWORD PTR [EAX] prefetch QWORD PTR [EAX] prefetchw QWORD PTR [EAX] $ ./bin/as --32 buggy6.s -o buggy6.o $ ./bin/objdump -d -M intel buggy6.o buggy6.o: file format elf32-i386 Disassembly of section .text: 00000000 <.text>: 0: 0f 01 38 invlpg BYTE PTR [eax] 3: 0f ae 38 clflush BYTE PTR [eax] 6: 0f 1c 00 cldemote BYTE PTR [eax] 9: 0f 0d 00 prefetch BYTE PTR [eax] c: 0f 0d 08 prefetchw BYTE PTR [eax] ``` ### Memory operand to immediate value GAS transforms a memory operand as an immediate value when it handles jecxz, jcxz, loop, loope, and loopne instructions. ``` $ cat buggy7.s .intel_syntax noprefix jecxz QWORD PTR [1] jcxz ZMMWORD PTR [1] loop XMMWORD PTR [1] loope ZMMWORD PTR [1] loopne DWORD PTR [1] $ ./bin/as buggy7.s --32 $ ./bin/objdump -d buggy7.o buggy7.o: file format elf32-i386 Disassembly of section .text: 00000000 <.text>: 0: e3 00 jecxz 0x2 2: 67 e3 00 jcxz 0x5 5: e2 00 loop 0x7 7: e1 00 loope 0x9 9: e0 00 loopne 0xb ``` -- You are receiving this mail because: You are on the CC list for the bug.