[llvm-bugs] [Bug 28098] New: Inline assembly, instruction order and register clobbering on Aarch64
via llvm-bugs
llvm-bugs at lists.llvm.org
Sun Jun 12 10:22:44 PDT 2016
https://llvm.org/bugs/show_bug.cgi?id=28098
Bug ID: 28098
Summary: Inline assembly, instruction order and register
clobbering on Aarch64
Product: clang
Version: 3.7
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: -New Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: the.arul at gmail.com
CC: llvm-bugs at lists.llvm.org
Classification: Unclassified
Created attachment 16521
--> https://llvm.org/bugs/attachment.cgi?id=16521&action=edit
Source for example
The attached program should write out two strings, "A TEST!" and "Blow up!" but
the second write causes a segfault. Here's output from GDB:
0x00000000004005c0 <+0>: stp x29, x30, [sp,#-16]!
0x00000000004005c4 <+4>: mov x29, sp
0x00000000004005c8 <+8>: sub sp, sp, #0x30
0x00000000004005cc <+12>: adrp x8, 0x400000
0x00000000004005d0 <+16>: add x8, x8, #0x6d8
0x00000000004005d4 <+20>: adrp x9, 0x400000
0x00000000004005d8 <+24>: add x9, x9, #0x460
0x00000000004005dc <+28>: adrp x10, 0x400000
0x00000000004005e0 <+32>: add x10, x10, #0x6d0
0x00000000004005e4 <+36>: stur wzr, [x29,#-4]
0x00000000004005e8 <+40>: stur w0, [x29,#-8]
0x00000000004005ec <+44>: stur x1, [x29,#-16]
0x00000000004005f0 <+48>: str x10, [sp,#24]
0x00000000004005f4 <+52>: str x9, [sp,#16]
0x00000000004005f8 <+56>: ldr x9, [sp,#24]
0x00000000004005fc <+60>: ldr x10, [sp,#16]
0x0000000000400600 <+64>: mov x0, x9
0x0000000000400604 <+68>: blr x10
0x0000000000400608 <+72>: str x9, [sp,#24]
0x000000000040060c <+76>: str x10, [sp,#16]
0x0000000000400610 <+80>: mov x0, x8
0x0000000000400614 <+84>: bl 0x400460 <puts at plt>
=> 0x0000000000400618 <+88>: mov w11, wzr
0x000000000040061c <+92>: str w0, [sp,#12]
0x0000000000400620 <+96>: mov w0, w11
0x0000000000400624 <+100>: mov sp, x29
0x0000000000400628 <+104>: ldp x29, x30, [sp],#16
0x000000000040062c <+108>: ret
Near the start of the function the x8 register is set as:
0x00000000004005cc <+12>: adrp x8, 0x400000
0x00000000004005d0 <+16>: add x8, x8, #0x6d8
Inspecting the combined address yields the valid string:
(gdb) p (char *)(0x400000 + 0x6d8)
$1 = 0x4006d8 "Blow up!"
However the indirect call to `puts` via inline assembly:
0x0000000000400604 <+68>: blr x10
Mutates the x8 register before it's written out with the value of 64:
(gdb) b *0x0000000000400600
Breakpoint 2 at 0x400600
(gdb) r
Starting program: /opt/asm/test
Breakpoint 2, 0x0000000000400600 in main ()
(gdb) watch $x8 == 64
Watchpoint 3: $x8 == 64
(gdb) c
Continuing.
Watchpoint 3: $x8 == 64
Old value = 0
New value = 1
0x0000007fb7ebb3c8 in _IO_new_file_write () from /lib64/libc.so.6
(gdb) bt
#0 0x0000007fb7ebb3c8 in _IO_new_file_write () from /lib64/libc.so.6
#1 0x0000007fb7ebcb24 in __GI__IO_do_write () from /lib64/libc.so.6
#2 0x0000007fb7ebcf30 in __GI__IO_file_overflow () from /lib64/libc.so.6
#3 0x0000007fb7eb1c80 in puts () from /lib64/libc.so.6
#4 0x0000000000400608 in main ()
One way to work around this issue is adding x8 to the list of clobbered
registers:
__asm__("MOV x0, %0 \n"
"BLR %1 \n"
: "+r"(str), "+r"(putsptr) :: "x0", "x8");
But this feels wrong, since the x8 register is defined by the ABI as "indirect
result location register", so technically any BLR instruction should clobber
it.
Note this wouldn't be an issue hadn't the instructions been rather aggressively
reordered, GCC 5.3.1 produces "more expected" result and works out of the box:
0x00000000004005c0 <+0>: stp x29, x30, [sp,#-48]!
0x00000000004005c4 <+4>: mov x29, sp
0x00000000004005c8 <+8>: str w0, [x29,#28]
0x00000000004005cc <+12>: str x1, [x29,#16]
0x00000000004005d0 <+16>: adrp x0, 0x400000
0x00000000004005d4 <+20>: add x0, x0, #0x6c0
0x00000000004005d8 <+24>: str x0, [x29,#40]
0x00000000004005dc <+28>: adrp x0, 0x400000
0x00000000004005e0 <+32>: add x0, x0, #0x460
0x00000000004005e4 <+36>: str x0, [x29,#32]
0x00000000004005e8 <+40>: ldr x1, [x29,#40]
0x00000000004005ec <+44>: ldr x0, [x29,#32]
0x00000000004005f0 <+48>: mov x2, x1
0x00000000004005f4 <+52>: mov x1, x0
0x00000000004005f8 <+56>: mov x0, x2
0x00000000004005fc <+60>: blr x1
0x0000000000400600 <+64>: str x2, [x29,#40]
0x0000000000400604 <+68>: str x1, [x29,#32]
0x0000000000400608 <+72>: adrp x0, 0x400000
0x000000000040060c <+76>: add x0, x0, #0x6c8
0x0000000000400610 <+80>: bl 0x400460 <puts at plt>
0x0000000000400614 <+84>: mov w0, #0x0 // #0
0x0000000000400618 <+88>: ldp x29, x30, [sp],#48
0x000000000040061c <+92>: ret
-Pavel
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160612/5a2d0789/attachment.html>
More information about the llvm-bugs
mailing list