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