linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Richard B. Johnson" <root@chaos.analogic.com>
To: dvorak <dvorak@xs4all.nl>
Cc: linux-kernel@vger.kernel.org
Subject: Re: Syscall changes registers beyond %eax, on linux-i386
Date: Thu, 19 Sep 2002 12:11:58 -0400 (EDT)	[thread overview]
Message-ID: <Pine.LNX.3.95.1020919115049.14758A-100000@chaos.analogic.com> (raw)
In-Reply-To: <20020919144533.GB2976@xs4all.nl>

On Thu, 19 Sep 2002, dvorak wrote:

> Hi,
> 
> recently i came across a situation were on linux-i386 not only %eax was
> altered after a syscall but also %ebx. I tracked this problem down, to
> gcc re-using a variable passed to a function.
> 
> This was found on a debian system with a 2.4.17 kernel compiled with gcc
> 2.95.2 and verified on another system, kernel 2.4.18 compiled with 2.95.4 
> Attached is small program to test for this 'bug'
> 
> a syscall gets his data off the stack, the stack looks like:
> 
> saved(edx)
> saved(ecx)
> saved(ebx)
> return_addres 	(somewhere in entry.S)
> 
> When the syscall is called.
> 
> the register came there through use of 'SAVE_ALL'.
> 
> After the syscall returns these registers are restored using RESTORE_ALL
> and execution is transferred to userland again.
> 
> A short snippet of sys_poll, with irrelavant data removed.
> 
> sys_poll(struct pollfd *ufds, .. , ..) {
>     ...
>     ufds++;
>     ...
> }
> 
> It seems that gcc in certain cases optimizes in such a way that it changes
> the variable ufds as placed on the stack directly. Which results in saved(ebx)
> being overwritten and thus in a changed %ebx on return from the system call.
> 

The 'C' compiler must make room on the stack for any local
variables except register types. If it was doing as you state, you
couldn't even execute a "hello world" program. Further, the local
variables are after the return address. It would screw up the return
address and you'd go off into hyper-space upon return.


> I don't know if this is considered a bug, and if it is, from whom.
> If it's not a bug it means low-level userland programs need to be rewritten
> to store all registers on a syscall and restore them on return.
>

No. Various 'C' implementers have standardized calling methods even
though it's not part of the 'C' standard. gcc and others assume that
a called procedure is not going to change any segments or index registers.
There are various optimization things, like "-fcaller-saves" where the
called procedure can destroy anything. You may be using something that
was wrongly compiled using that switch.

 
> It shouldn't be a bug in gcc, since the C-standard doesn't talk about how to 
> pass variables and stuff. So it seems like a kernel(-gcc-interaction) bug.
> 
> To solve this issue 2 solutions spring to mind
> 1) add a flag to gcc to tell it that it shouldn't do this optimization, this
>    won't work with the gcc's already out there.
> 2) When calling a syscall explicitly push all variable an extra time, since
>    the code in entry.S doesn't know the amount of variables to a syscall it
>    needs to push all theoretical 6 parameters every time, a not so nice
>    overhead.
> 
>

There is a bug in some other code. Try this. It will show
that ebx is not being killed in a syscall. You can prove
that this code works by changing ebx to eax, which will
get destroyed and print "Broken" before exit.


#include <stdio.h>
#include <unistd.h>

void barf(void);
void barf()
{
    puts("Broken\n");
    exit(0);
}

int main()
{
    __asm__ __volatile__("movl	$0xdeadface, %ebx\n");
    (void)getpid();
    __asm__ __volatile__("cmpl	$0xdeadface, %ebx\n"
                         "jnz   barf\n");

    return 0;
}


Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).
The US military has given us many words, FUBAR, SNAFU, now ENRON.
Yes, top management were graduates of West Point and Annapolis.


  reply	other threads:[~2002-09-19 16:04 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-09-19 14:45 Syscall changes registers beyond %eax, on linux-i386 dvorak
2002-09-19 16:11 ` Richard B. Johnson [this message]
2002-09-19 17:09   ` Brian Gerst
2002-09-19 17:22     ` Richard B. Johnson
2002-09-19 17:51       ` Brian Gerst
2002-09-19 18:30         ` Richard B. Johnson
2002-09-19 17:59       ` dvorak
2002-09-19 18:32         ` Richard B. Johnson
2002-09-19 17:44 Petr Vandrovec
2002-09-19 18:04 ` Brian Gerst
2002-09-19 18:30   ` Richard Henderson
2002-09-19 18:51     ` Brian Gerst
2002-09-19 18:57       ` Richard Henderson
2002-09-19 19:40         ` Richard B. Johnson
2002-09-19 19:41           ` Richard Henderson
2002-09-19 19:53             ` Richard B. Johnson
2002-09-19 22:46               ` J.A. Magallon
2002-09-20 12:27                 ` Richard B. Johnson
2002-09-20 17:16                   ` Richard Henderson
2002-09-22  1:33               ` Pavel Machek
2002-09-23 13:11                 ` Richard B. Johnson
2002-09-23 18:31                   ` Pavel Machek
2002-09-19 19:18       ` Richard B. Johnson
2002-09-19 19:24   ` Daniel Jacobowitz
2002-09-19 20:25     ` Mikael Pettersson
2002-09-20  8:32       ` george anzinger
2002-09-21  6:19         ` Richard Henderson
2002-09-21  8:09           ` george anzinger
2002-09-21 15:08             ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.LNX.3.95.1020919115049.14758A-100000@chaos.analogic.com \
    --to=root@chaos.analogic.com \
    --cc=dvorak@xs4all.nl \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).