Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug
Bug#: 40132
Product:  
Component:  
Status: RESOLVED
Resolution: INVALID
Assigned To: Not yet assigned to anyone <unassigned@gcc.gnu.org>
Host:
Reported against  
Priority:  
Severity:  
Target Milestone:  
 
 
Target:
Reporter: Steven Rostedt <rostedt@goodmis.org>
Add CC:
CC:
Remove selected CCs
Build:
URL:
Summary:
Keywords:
Known to work:
Known to fail:

Attachment Description Type Created Size Actions
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 40132 depends on: Show dependency tree
Show dependency graph
Bug 40132 blocks:

Additional Comments:






View Bug Activity   |   Format For Printing   |   Clone This Bug


Description:   Last confirmed: Opened: 2009-05-13 16:52
# 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?

------- Comment #1 From Andrew Pinski 2009-05-13 17:17 -------
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"
        );

Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug