http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55940
Bug #: 55940
Summary: Incorrect code for accessing parameters with 32-bit
Intel hosts
Classification: Unclassified
Product: gcc
Version: 4.7.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: [email protected]
ReportedBy: [email protected]
There are some reports about incorrect compiled Linux kernel modules for
VirtualBox. I've debugged one report (see here:
https://www.virtualbox.org/ticket/11035) and saw that the compiler generated
invalid code for accessing parameters inside a function. When it should read
the parameter from the stack it reads the parameter from a register.
I don't know exactly under which circumstance this happens but this seems to be
related to 32-bit x86 targets. The function VBoxHost_RTR0MemObjGetPagePhysAddr
is marked as __attribute__((cdelc, regparm(0))). The pre-processed
memobj-r0drv.i file is attached to that ticket. The generated code is part of
the vboxdrv.ko file which is also attached to the ticket.
The following code is generated to access the first function parameter (keep
cdecl in mind!):
VBoxHost_RTR0MemObjGetPagePhysAddr():
/usr/src/virtualbox-bin-4.2.4_81684/vboxhost/vboxdrv/r0drv/memobj-r0drv.c:268
955e: 8b 0f mov (%edi),%ecx
9560: 8b 47 04 mov 0x4(%edi),%eax
/usr/src/virtualbox-bin-4.2.4_81684/vboxhost/vboxdrv/r0drv/memobj-r0drv.c:272
9563: 8d 91 00 10 00 00 lea 0x1000(%ecx),%edx
So the function is using the EDI register to access the parameter while it
should read the parameter from the stack.
The C code of this function looks (see memobj-r0drv.i) is:
RTHCPHYS __attribute__((cdecl,regparm(0)))
VBoxHost_RTR0MemObjGetPagePhysAddr(RTR0MEMOBJ MemObj, size_t iPage)
{
PRTR0MEMOBJINTERNAL pMem;
size_t cPages;
do { if (__builtin_expect(!!(!(( (uintptr_t)(MemObj) + 0x1000U >= 0x2000U
))), 0)) return ((~(RTHCPHYS)0)); } while (0);
...
(Explanation of the code: This is actually a sanity check if the pointer is
valid; the value must be either less than 0xFFFFF000U or greater than
0x00000FFFU).
Unfortunately I cannot reproduce this problem myself (gcc 4.7.2 on my Linux
distribution creates correct code). The gcc compiler the user is using is
gcc version 4.7.2 (Exherbo gcc-4.7.2-r2)
(see comment 18 in the above ticket).