Re: implementing linux mmap2 syscall

2002-04-24 Thread Andrew Gallatin


Kenneth Culver writes:
  OK, I THINK I found what calls the actual kernel syscall handler, and
  sets it's args first, but I'm not sure:
  
  from linux_locore.s
  
  NON_GPROF_ENTRY(linux_sigcode)
...

  Does anyone who actually knows assembly have any ideas?

This is the linux sigtramp, or signal trampoline.  It is used to wrap
a signal handler.  Eg, the kernel calls it (by returning to it) when
it delivers a signal.  It calls the apps signal handler.  When the
handler returns, it calls the linux sigreturn system call.

This has essentially nothing to do with system calls.

The system call entry point on x86 is int0x80_syscall, which is
labled:

/*
 * Call gate entry for FreeBSD ELF and Linux/NetBSD syscall (int 0x80)
..

This then calls syscall2(), which calls the linux prepsyscall.

Maybe the argument isn't where you expect it to be, but is there.
Can you make a test program which calls mmap2 with its 6th arg as
something unique like 0xdeadbeef?  Then print out (in hex :) the trapframe
from the linux prepsyscall routine  see if you can find the deadbeef.

Drew

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Brandon S Allbery KF8NH

On Wed, 2002-04-24 at 10:41, Andrew Gallatin wrote:
 Maybe the argument isn't where you expect it to be, but is there.
 Can you make a test program which calls mmap2 with its 6th arg as
 something unique like 0xdeadbeef?  Then print out (in hex :) the trapframe
 from the linux prepsyscall routine  see if you can find the deadbeef.

My recollection is that beyond 5 arguments, a pointer to the remaining
ones is passed.  (But my recollection may be wrong and I don't wish to
subject myself to the source cesspool at the moment)

-- 
brandon s. allbery   [os/2][linux][solaris][japh]  [EMAIL PROTECTED]
system administrator  [WAY too many hats][EMAIL PROTECTED]
electrical and computer engineeringKF8NH
carnegie mellon university  [better check the oblivious first -ke6sls]


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Andrew Gallatin


Brandon S Allbery KF8NH writes:
  On Wed, 2002-04-24 at 10:41, Andrew Gallatin wrote:
   Maybe the argument isn't where you expect it to be, but is there.
   Can you make a test program which calls mmap2 with its 6th arg as
   something unique like 0xdeadbeef?  Then print out (in hex :) the trapframe
   from the linux prepsyscall routine  see if you can find the deadbeef.
  
  My recollection is that beyond 5 arguments, a pointer to the remaining
  ones is passed.  (But my recollection may be wrong and I don't wish to
  subject myself to the source cesspool at the moment)
  

I think that's how it used to work.  Apparently, they've changed it
recently and they now pass 6 args in registers.  Eg, in the linux
kernel sources, old_mmap() fetches its args via copy_from_user(),
whereas the newer sys_mmap2() doesn't.

Drew

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver

I tried printing out everything in the trapframe in hex and nothing looke
remotely right.

Ken

On 24 Apr 2002, Brandon S Allbery KF8NH wrote:

 On Wed, 2002-04-24 at 10:41, Andrew Gallatin wrote:
  Maybe the argument isn't where you expect it to be, but is there.
  Can you make a test program which calls mmap2 with its 6th arg as
  something unique like 0xdeadbeef?  Then print out (in hex :) the trapframe
  from the linux prepsyscall routine  see if you can find the deadbeef.

 My recollection is that beyond 5 arguments, a pointer to the remaining
 ones is passed.  (But my recollection may be wrong and I don't wish to
 subject myself to the source cesspool at the moment)

 --
 brandon s. allbery   [os/2][linux][solaris][japh]  [EMAIL PROTECTED]
 system administrator  [WAY too many hats][EMAIL PROTECTED]
 electrical and computer engineeringKF8NH
 carnegie mellon university  [better check the oblivious first -ke6sls]





To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver


 Brandon S Allbery KF8NH writes:
   On Wed, 2002-04-24 at 10:41, Andrew Gallatin wrote:
Maybe the argument isn't where you expect it to be, but is there.
Can you make a test program which calls mmap2 with its 6th arg as
something unique like 0xdeadbeef?  Then print out (in hex :) the trapframe
from the linux prepsyscall routine  see if you can find the deadbeef.
  
   My recollection is that beyond 5 arguments, a pointer to the remaining
   ones is passed.  (But my recollection may be wrong and I don't wish to
   subject myself to the source cesspool at the moment)
  

 I think that's how it used to work.  Apparently, they've changed it
 recently and they now pass 6 args in registers.  Eg, in the linux
 kernel sources, old_mmap() fetches its args via copy_from_user(),
 whereas the newer sys_mmap2() doesn't.

 Drew

Yep, according to the docs and source code I looked at in the linux
kernel, the sixth arg is in the ebp register. I've looked all over the
FreeBSD kernel and the linux emulator for the place that actually sets
these, and unfortunately, due to my lack of asm coding knowledge, I can't
find anything.

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver

 libc sets it before it enters the kernel.  Then on kernel entry we save
 ebp in the trapframe.

So in the case of linux emulation, the glibc that we're using in the
linux-ulator isn't setting it properly? I'm using the linux_base-7 port
for this, so as far as I can tell, it should work... assuming linux_base-7
is meant to run on a linux-2.4.x kernel (or kernel that's emulating that).

I may have screwed up my linux libs somehow or another too... could this
be causing the behavior I'm seeing?

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread John Baldwin


On 24-Apr-2002 Kenneth Culver wrote:
 libc sets it before it enters the kernel.  Then on kernel entry we save
 ebp in the trapframe.
 
 So in the case of linux emulation, the glibc that we're using in the
 linux-ulator isn't setting it properly? I'm using the linux_base-7 port
 for this, so as far as I can tell, it should work... assuming linux_base-7
 is meant to run on a linux-2.4.x kernel (or kernel that's emulating that).
 
 I may have screwed up my linux libs somehow or another too... could this
 be causing the behavior I'm seeing?

Maybe.  You could always try finding the mmap2() entry point and dissassembling
it to see what it is doing.

 Ken

-- 

John Baldwin [EMAIL PROTECTED]http://www.FreeBSD.org/~jhb/
Power Users Use the Power to Serve!  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread John Baldwin


On 24-Apr-2002 Kenneth Culver wrote:

 Brandon S Allbery KF8NH writes:
   On Wed, 2002-04-24 at 10:41, Andrew Gallatin wrote:
Maybe the argument isn't where you expect it to be, but is there.
Can you make a test program which calls mmap2 with its 6th arg as
something unique like 0xdeadbeef?  Then print out (in hex :) the
trapframe
from the linux prepsyscall routine  see if you can find the deadbeef.
  
   My recollection is that beyond 5 arguments, a pointer to the remaining
   ones is passed.  (But my recollection may be wrong and I don't wish to
   subject myself to the source cesspool at the moment)
  

 I think that's how it used to work.  Apparently, they've changed it
 recently and they now pass 6 args in registers.  Eg, in the linux
 kernel sources, old_mmap() fetches its args via copy_from_user(),
 whereas the newer sys_mmap2() doesn't.

 Drew

 Yep, according to the docs and source code I looked at in the linux
 kernel, the sixth arg is in the ebp register. I've looked all over the
 FreeBSD kernel and the linux emulator for the place that actually sets
 these, and unfortunately, due to my lack of asm coding knowledge, I can't
 find anything.

libc sets it before it enters the kernel.  Then on kernel entry we save ebp
in the trapframe.

-- 

John Baldwin [EMAIL PROTECTED]http://www.FreeBSD.org/~jhb/
Power Users Use the Power to Serve!  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver

  libc sets it before it enters the kernel.  Then on kernel entry we save
  ebp in the trapframe.

 So in the case of linux emulation, the glibc that we're using in the
 linux-ulator isn't setting it properly? I'm using the linux_base-7 port
 for this, so as far as I can tell, it should work... assuming linux_base-7
 is meant to run on a linux-2.4.x kernel (or kernel that's emulating that).

 I may have screwed up my linux libs somehow or another too... could this
 be causing the behavior I'm seeing?

 Ken


OK, I removed the linux_base packages that I had on here, and made some
changes to the linux-ulator (added the arg[5] = tf-tf_ebp, and then
re-installed the linux_base-7.1 package, and now things are working...
winex is working fine now. :-) I'll clean up my changes to the
linux-ulator, and submit them as a pr.

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver


   libc sets it before it enters the kernel.  Then on kernel entry we save
   ebp in the trapframe.
 
  So in the case of linux emulation, the glibc that we're using in the
  linux-ulator isn't setting it properly? I'm using the linux_base-7 port
  for this, so as far as I can tell, it should work... assuming linux_base-7
  is meant to run on a linux-2.4.x kernel (or kernel that's emulating that).
 
  I may have screwed up my linux libs somehow or another too... could this
  be causing the behavior I'm seeing?
 
  Ken
 
 
 OK, I removed the linux_base packages that I had on here, and made some
 changes to the linux-ulator (added the arg[5] = tf-tf_ebp, and then
 re-installed the linux_base-7.1 package, and now things are working...
 winex is working fine now. :-) I'll clean up my changes to the
 linux-ulator, and submit them as a pr.

I'm actually still not seeing a match between what's in  truss, and what's
in my printed-out args, but it seems to be working anyway...

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver

 I'm actually still not seeing a match between what's in  truss, and what's
 in my printed-out args, but it seems to be working anyway...

Argh, it's not working again... It was working on an install of ms office,
but it won't work on some old windows game.. (winex) and it's still not
setting the last arg (or register properly):

truss output:

linux_mmap2(0x6543,0x10,0x3,0x11,0x9,0x6) = 1698889728
(0x6543)

notice that the last arg is 0x6, that's the page offset...

what the kernel prints for the same call:

mmap2(0x6543, 1048576, 3, 0x0011, 9, 0)

notice that they both have all the same values until you get to the last
one... at which point the value is wrong... Apparently this only causes
problems on some windows programs that one may try to execute, and not on
others...

So, where can I force this to get set?

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver

 Here's where it happens:
 sys/i386/linux/linux_sysvec.c

 static void
 linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params)
 {
 args[0] = tf-tf_ebx;
 args[1] = tf-tf_ecx;
 args[2] = tf-tf_edx;
 args[3] = tf-tf_esi;
 args[4] = tf-tf_edi;
 *params = NULL; /* no copyin */
 }

 You probably want to add:
   args[5] = tf-tf_ebp;
 so that it ends up in the syscallargs struct.

Yeah, I did that... it still doesn't work, tf_ebp isn't getting set... So
I'm thinking that either I have a glibc that's too old, or something else
is wrong...


 For FreeBSD syscalls, we copy this from the top of stack for the number of
 32 bit words specified in the syscall table in i386/trap.c:
 if (params  (i = narg * sizeof(int)) 
 (error = copyin(params, (caddr_t)args, (u_int)i))) {
 (narg comes from the syscall table).

OK, that gives me an idea...

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver

 RCS file: /home/ncvs/src/sys/i386/linux/linux_sysvec.c,v
 retrieving revision 1.99
 diff -u -2 -r1.99 linux_sysvec.c
 --- linux_sysvec.c  4 Apr 2002 17:49:46 -   1.99
 +++ linux_sysvec.c  24 Apr 2002 23:57:23 -
 @@ -711,4 +711,5 @@
 args[3] = tf-tf_esi;
 args[4] = tf-tf_edi;
 +   args[5] = tf-tf_ebp;
 *params = NULL; /* no copyin */
  }

 Cheers,
 -Peter
 --
 Peter Wemm - [EMAIL PROTECTED]; [EMAIL PROTECTED]; [EMAIL PROTECTED]
 All of this is for nothing if we don't go to the stars - JMS/B5


 To Unsubscribe: send mail to [EMAIL PROTECTED]
 with unsubscribe freebsd-current in the body of the message


yeah, I did that already, and have been running with that since yesterday
:-P

still not working right though... I think it has something to do with that
nargs thing... I'm checking that out now...

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Peter Wemm

Kenneth Culver wrote:
 
  Brandon S Allbery KF8NH writes:
On Wed, 2002-04-24 at 10:41, Andrew Gallatin wrote:
 Maybe the argument isn't where you expect it to be, but is there.
 Can you make a test program which calls mmap2 with its 6th arg as
 something unique like 0xdeadbeef?  Then print out (in hex :) the trapf
rame
 from the linux prepsyscall routine  see if you can find the deadbeef.
   
My recollection is that beyond 5 arguments, a pointer to the remaining
ones is passed.  (But my recollection may be wrong and I don't wish to
subject myself to the source cesspool at the moment)
   
 
  I think that's how it used to work.  Apparently, they've changed it
  recently and they now pass 6 args in registers.  Eg, in the linux
  kernel sources, old_mmap() fetches its args via copy_from_user(),
  whereas the newer sys_mmap2() doesn't.
 
  Drew
 
 Yep, according to the docs and source code I looked at in the linux
 kernel, the sixth arg is in the ebp register. I've looked all over the
 FreeBSD kernel and the linux emulator for the place that actually sets
 these, and unfortunately, due to my lack of asm coding knowledge, I can't
 find anything.

Here's where it happens:
sys/i386/linux/linux_sysvec.c

static void
linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params)
{
args[0] = tf-tf_ebx;
args[1] = tf-tf_ecx;
args[2] = tf-tf_edx;
args[3] = tf-tf_esi;
args[4] = tf-tf_edi;
*params = NULL; /* no copyin */
}

You probably want to add:
args[5] = tf-tf_ebp;
so that it ends up in the syscallargs struct.

For FreeBSD syscalls, we copy this from the top of stack for the number of
32 bit words specified in the syscall table in i386/trap.c:
if (params  (i = narg * sizeof(int)) 
(error = copyin(params, (caddr_t)args, (u_int)i))) {
(narg comes from the syscall table).

Cheers,
-Peter
--
Peter Wemm - [EMAIL PROTECTED]; [EMAIL PROTECTED]; [EMAIL PROTECTED]
All of this is for nothing if we don't go to the stars - JMS/B5


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver

Alright, so I got tired of trying to figure out if glibc is doing
something wierd or wrong so I downloaded the source for it, and I'm
looking at it now... (for version 2.2.2 which is what we have on FreeBSD's
linux_base-7) and here's what I'm seeing:

pushl %ebp
pushl %ebx
pushl %esi
pushl %edi

movl OFFLO(%esp), %edx
movl OFFHI(%esp), %ecx
testl $0xfff, %edx
jne L(einval)
shrdl $12, %ecx, %edx   /* mmap2 takes the offset in
pages.  */
shrl $12, %ecx
jne L(einval)
movl %edx, %ebp

So above I'm seeing the offset arg get into register %ebp, which is what
we expect...

movl ADDR(%esp), %ebx
movl LEN(%esp), %ecx
movl PROT(%esp), %edx
movl FLAGS(%esp), %esi
movl FD(%esp), %edi

Then I'm seeing all the other args getting put into the registers they
belong in... (which matches up with our linux_prepsyscall() function)

movl $SYS_ify(mmap2), %eax  /* System call number in %eax.  */

/* Do the system call trap.  */
L(do_syscall):
int $0x80

Now I'm seeing the int 0x80 trap

/* Restore registers.  */
popl %edi
popl %esi
popl %ebx
popl %ebp


So, as far as I can tell, this version of glibc is doing the Right Thing,
and the ebp register is getting messed up somewhere along the line in
either the assembly code that handles the 0x80 trap in FreeBSD, or in
syscall2 (I think it's probably the asm that handles the 0x80 trap)...

Can anyone confirm this?

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-23 Thread Kenneth Culver

  Basically, linux_mmap2 takes 6 args, and this looks here like only 5 args are
  making it in... I checked this because the sixth argument to linux_mmap2() in
  truss was showing 0x6, but when I printed out that arg from the kernel, it
  was showing 0x0. Am I correct here?
 
  Ken
   
Yes.  According to http://john.fremlin.de/linux/asm/, linux used to
parse only 5 args but now it parses six.  Try adding:
   args[5] = tf-tf_ebp;
   
   I don't think that arg is there:
  
   Apr 23 10:36:13 ken /kernel: tf-tf_ebp = -1077938040
  
   Ken

 My guess is that we're not doing something we should be doing in
 int0x80_syscall in order to get that last arg.  But I do not have
 enough x86 knowledge to understand how the trapframe is constructed,
 so I cannot tell what needs to be done.

 Perhaps somebody with more x86 fu can help.

 Sorry,

Crap, I don't know what's going on either, I was just looking at the asm
in src/sys/i386/i386/exception.s, but I'm not very good with asm either,
Can anyone help? I'm cross-posting to -current since nobody on hackers or
emulation is able to help.

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message



Re: implementing linux mmap2 syscall

2002-04-23 Thread Kenneth Culver

 Kenneth Culver writes:
   OK, I found another problem, here it is:
  
   static void
   linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t
   *params)
   {
  args[0] = tf-tf_ebx;
  args[1] = tf-tf_ecx;
  args[2] = tf-tf_edx;
  args[3] = tf-tf_esi;
  args[4] = tf-tf_edi;
  *params = NULL; /* no copyin */
   }
  
   Basically, linux_mmap2 takes 6 args, and this looks here like only 5 args are
   making it in... I checked this because the sixth argument to linux_mmap2() in
   truss was showing 0x6, but when I printed out that arg from the kernel, it
   was showing 0x0. Am I correct here?
  
   Ken

 Yes.  According to http://john.fremlin.de/linux/asm/, linux used to
 parse only 5 args but now it parses six.  Try adding:
 args[5] = tf-tf_ebp;

 Drew


OK, I THINK I found what calls the actual kernel syscall handler, and
sets it's args first, but I'm not sure:

from linux_locore.s

NON_GPROF_ENTRY(linux_sigcode)
call*LINUX_SIGF_HANDLER(%esp)
lealLINUX_SIGF_SC(%esp),%ebx/* linux scp */
movlLINUX_SC_GS(%ebx),%gs
movl%esp, %ebx  /* pass sigframe */
push%eax/* fake ret addr */
movl$LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
int $0x80   /* enter kernel with args
*/
0:  jmp 0b
ALIGN_TEXT

I think the stuff above copies the args, and whatnot, but I'm not really
sure where it does this exactly...

It calls LINUX_SIGF_HANDLER, which then calls %esp's sf_handler function.
That is where I draw a blank, I don't know which function this is calling,
and can't find where it's being set. I think this might be what I want to
change though. :-P

Does anyone who actually knows assembly have any ideas?

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with unsubscribe freebsd-current in the body of the message