linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Brian Gerst <bgerst@didntduck.org>
To: root@chaos.analogic.com
Cc: dvorak <dvorak@xs4all.nl>, linux-kernel@vger.kernel.org
Subject: Re: Syscall changes registers beyond %eax, on linux-i386
Date: Thu, 19 Sep 2002 13:09:20 -0400	[thread overview]
Message-ID: <3D8A04C0.6050508@didntduck.org> (raw)
In-Reply-To: Pine.LNX.3.95.1020919115049.14758A-100000@chaos.analogic.com

Richard B. Johnson wrote:
> 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.

The bug is only with _some_ syscalls, and getpid() is not one of them, 
so your example is flawed.  It happens when a syscall modifies one of 
it's parameter values.  The solution is to assign the parameter to a 
local variable before modifying it.

--
				Brian Gerst


  reply	other threads:[~2002-09-19 17: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
2002-09-19 17:09   ` Brian Gerst [this message]
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=3D8A04C0.6050508@didntduck.org \
    --to=bgerst@didntduck.org \
    --cc=dvorak@xs4all.nl \
    --cc=linux-kernel@vger.kernel.org \
    --cc=root@chaos.analogic.com \
    /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).