Incompatible calling conventions used by gcc 2.7 and 2.8 (and egcc)? (supersedes older bug reports)
Jean Wolter
jw5@os.inf.tu-dresden.de
Wed Jul 29 06:38:00 GMT 1998
Hello,
some days ago I have submitted two bug reports for gcc 2.8 , one
stating that gcc doesn't clean up the stack correctly after a function
call and the other one stating that gcc uses Pascal calling
conventions for function calls ('ret $4' to return from the function).
Both problems result from a mix of sources and libraries compiled by
gcc 2.7 and 2.8, since gcc 2.7 and gcc 2.8 seem to use different
calling conventions for functions, which return structures or unions.
Both compilers allocate space on the stack and pass the address as an
additional parameter to the function. The problem is, that gcc 2.7
removes the additional parameter after returning from the function and
2.8 removes the parameter while returning from the function (using
'ret $4'). If you mix object files compiled by different gcc versions
you get funny results due to the different stack handling.
Is this a bug or an undocumented incompatibility between gcc 2.7 and
2.8 (and egcc)?
gcc 2.8 (and egcc)
******************
gcc2_compiled.:
.text
.align 16
.globl create_thread
.type create_thread,@function
create_thread:
movl 4(%esp),%eax
movl $-1,(%eax)
movl $-1,4(%eax)
jmp .L1
.align 16
.L1:
movl %eax,%eax
ret $4 <--- remove address of structure
.Lfe1:
.size create_thread,.Lfe1-create_thread
.align 16
.globl test
.type test,@function
test:
subl $8,%esp
pushl %ebp
leal 4(%esp),%eax
pushl $0
pushl $0
pushl $0
pushl %eax
call create_thread
addl $12,%esp <--- remove three parameters
.L2:
popl %ebp
addl $8,%esp
ret
gcc 2.7
*******
create_thread:
movl 4(%esp),%eax
movl $-1,(%eax)
movl $-1,4(%eax)
jmp .L1
.align 16
.L1:
movl %eax,%eax
ret
.Lfe1:
.size create_thread,.Lfe1-create_thread
.align 16
.globl test
.type test,@function
test:
subl $8,%esp
pushl %ebp
leal 4(%esp),%eax
pushl $0
pushl $0
pushl $0
pushl %eax
call create_thread
addl $16,%esp <--- remove three parameters
.L2: plus address of structure
popl %ebp
addl $8,%esp
ret
Jean
PS: The source for the above example:
-------------- next part --------------
typedef struct {
unsigned long low, high;
} l4_low_high_t;
typedef struct {
unsigned version_low:10;
unsigned lthread:7;
unsigned task:11;
unsigned version_high:4;
unsigned site:17;
unsigned chief:11;
unsigned nest:4;
} l4_threadid_struct_t;
typedef union {
l4_low_high_t lh;
l4_threadid_struct_t id;
} l4_threadid_t;
#define L4_INVALID_ID ((l4_threadid_t){lh:{0xffffffff,0xffffffff}})
l4_threadid_t create_thread (int thread_no, void (*function)(void), int *stack);
void test(void);
l4_threadid_t create_thread (int thread_no, void (*function)(void), int *stack)
{
return L4_INVALID_ID;
}
void test(void)
{
l4_threadid_t t = create_thread(0, (void (*)(void))0, (int *)0);
}
More information about the Gcc-bugs
mailing list