This is GCC Bugzilla
This is GCC Bugzilla Version 2.20+
View Bug Activity | Format For Printing | Clone This Bug
# gcc -v Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: ../gcc-4.4.0/configure --prefix=/usr/local/dist --program-prefix=dist- --without-doc --enable-bootstrap Thread model: posix gcc version 4.4.0 (GCC) I just compiled to gcc 4.4.0 (replacing my 4.2.2 version) and found that the function_graph tracer in linux broke. Investigating it further, I found that gcc did not properly assign the constraints used in arch/x86/kernel/ftrace.c (Linux 2.6.30-rc5). Maybe the constraints are not assigned properly, but it worked in all my previous versions of gcc, and I do not see anything wrong with it. Here's the code (prepare_ftrace_return): unsigned long return_hooker = (unsigned long) &return_to_handler; [...] /* * Protect against fault, even if it shouldn't * happen. This tool is too much intrusive to * ignore such a protection. */ asm volatile( "1: " _ASM_MOV " (%[parent]), %[old]\n" "2: " _ASM_MOV " %[return_hooker], (%[parent])\n" " movl $0, %[faulted]\n" "3:\n" ".section .fixup, \"ax\"\n" "4: movl $1, %[faulted]\n" " jmp 3b\n" ".previous\n" _ASM_EXTABLE(1b, 4b) _ASM_EXTABLE(2b, 4b) : [old] "=r" (old), [faulted] "=r" (faulted) : [parent] "r" (parent), [return_hooker] "r" (return_hooker) : "memory" ); Here's what gcc 4.2.2 does (working): ffffffff80228893: 48 c7 c0 3d be 20 80 mov $0xffffffff8020be3d,%rax ffffffff8022889a: 4c 8b 27 mov (%rdi),%r12 ffffffff8022889d: 48 89 07 mov %rax,(%rdi) ffffffff802288a0: b8 00 00 00 00 mov $0x0,%eax ffffffff802288a5: 85 c0 test %eax,%eax The return_hooker is put into %rax, old is %r12 and all is fine. But gcc 4.4.0 decided to use %r12 for both the return_hooker and old! ffffffff80229503: 49 c7 c4 7d bf 20 80 mov $0xffffffff8020bf7d,%r12 ffffffff8022950a: 4c 8b 27 mov (%rdi),%r12 ffffffff8022950d: 4c 89 27 mov %r12,(%rdi) ffffffff80229510: b8 00 00 00 00 mov $0x0,%eax ffffffff80229515: 85 c0 test %eax,%eax Thus overwriting the return_hooker variable before it is used as an input! Is there something wrong with the constraints, or is this indeed a bug in GCC?
What GCC is doing is correct according to the source you gave it. The source needs to be modified to mark old as being an early clobber. Like: asm volatile( "1: " _ASM_MOV " (%[parent]), %[old]\n" "2: " _ASM_MOV " %[return_hooker], (%[parent])\n" " movl $0, %[faulted]\n" "3:\n" ".section .fixup, \"ax\"\n" "4: movl $1, %[faulted]\n" " jmp 3b\n" ".previous\n" _ASM_EXTABLE(1b, 4b) _ASM_EXTABLE(2b, 4b) : [old] "=&r" (old), [faulted] "=r" (faulted) : [parent] "r" (parent), [return_hooker] "r" (return_hooker) : "memory" );