DragonFly users List (threaded) for 2007-11
DragonFly BSD
DragonFly users List (threaded) for 2007-11
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

gcc update (was: Re: va_copy() problem)


From: "Simon 'corecode' Schubert" <corecode@xxxxxxxxxxxx>
Date: Mon, 12 Nov 2007 21:27:17 +0100

Johannes Hofmann wrote:
> Hello,
> 
> I see crashes with a string handling library on DragonFly.
> The problem can be reduced to the test program below. It crashes on
> DragonFly when compiled with "gcc -O2 -o foo foo.c". Without -O2 it 
> runs fine. No problems on Linux with or without -O2.
> Can anyone spot the problem? I think its related to the use of
> va_copy().

No, the problem is that gcc uses %ebx after a function call, which it is
not allowed to do:

void
string_printfa(struct string *s, char *format, ...) {
 8048682:       55                      push   %ebp
 8048683:       89 e5                   mov    %esp,%ebp
 8048685:       56                      push   %esi
 8048686:       53                      push   %ebx
 8048687:       83 ec 10                sub    $0x10,%esp
 804868a:       8b 5d 08                mov    0x8(%ebp),%ebx

^^^^ loads ebx

 804868d:       8b 75 0c                mov    0xc(%ebp),%esi
        va_list va, va1;
        int n;

        va_start(va, format);
 8048690:       8d 45 10                lea    0x10(%ebp),%eax
 8048693:       89 45 f4                mov    %eax,0xfffffff4(%ebp)

        for (;;) {
                va_copy(va1, va);
 8048696:       8b 45 f4                mov    0xfffffff4(%ebp),%eax
 8048699:       89 45 f0                mov    %eax,0xfffffff0(%ebp)
                n = vsnprintf(s->str + s->len, s->size - s->len, format,
va1);
 804869c:       8b 53 08                mov    0x8(%ebx),%edx

^^^ uses ebx

 804869f:       50                      push   %eax
 80486a0:       56                      push   %esi
 80486a1:       8b 43 04                mov    0x4(%ebx),%eax
 80486a4:       29 d0                   sub    %edx,%eax
 80486a6:       50                      push   %eax
 80486a7:       03 13                   add    (%ebx),%edx
 80486a9:       52                      push   %edx
 80486aa:       e8 01 fe ff ff          call   80484b0 <vsnprintf@plt>

^^^^ call

 80486af:       89 c1                   mov    %eax,%ecx

                if (n < s->size - s->len) {
 80486b1:       8b 53 08                mov    0x8(%ebx),%edx

^^^^ continues using ebx.  WRONG.

 80486b4:       8b 43 04                mov    0x4(%ebx),%eax
 80486b7:       29 d0                   sub    %edx,%eax
 80486b9:       83 c4 10                add    $0x10,%esp
 80486bc:       39 c1                   cmp    %eax,%ecx
 80486be:       7d 0d                   jge    80486cd <string_printfa+0x4b>

However, gcc34 also has the same bug, so I am at loss here.

Or does the ABI dictate that %ebx needs to be restored?  Seems that
linux/glibc doesn't clobber ebx.

cheers
  simon

Attachment: signature.asc
Description: OpenPGP digital signature



[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]