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-hackers" in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Kenneth Culver

> 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...
>
Ehh, apparently sy_narg is getting set correctly too:

struct  linux_mmap2_args {
l_ulong addr;   char addr_[PAD_(l_ulong)];
l_ulong len;char len_[PAD_(l_ulong)];
l_ulong prot;   char prot_[PAD_(l_ulong)];
l_ulong flags;  char flags_[PAD_(l_ulong)];
l_ulong fd; char fd_[PAD_(l_ulong)];
l_ulong pgoff;  char pgoff_[PAD_(l_ulong)];
};

#define AS(name) (sizeof(struct name) / sizeof(register_t))

{ AS(linux_mmap2_args), (sy_call_t *)linux_mmap2 }

not that it really matters, the linux_prepsyscall is setting the params to
null:

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;
args[5] = tf->tf_ebp;
*params = NULL; /* no copyin */
}

so the code in syscall2 will not even bother to try to copy in the args...
it just uses whatever linux_prepsyscall tells it to use, and completely
ignores nargs... at least as far as I can tell...

Ken


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" 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-hackers" 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-hackers" 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-hackers" in the body of the message



Re: implementing linux mmap2 syscall

2002-04-24 Thread Peter Wemm

Kenneth Culver wrote:
> > 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

Try this:

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-hackers" 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-hackers" 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-hackers" 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-hackers" 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-hackers" 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-hackers" 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-hackers" 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-hackers" 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-hackers" 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-hackers" 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-hackers" in the body of the message



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-hackers" 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-hackers" 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-hackers" in the body of the message



Re: implementing linux mmap2 syscall

2002-04-23 Thread Andrew Gallatin


Kenneth Culver writes:
 > >  > 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,

Drew

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" 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


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



Re: implementing linux mmap2 syscall

2002-04-23 Thread Andrew Gallatin


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

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



Re: implementing linux mmap2 syscall

2002-04-22 Thread Kenneth Culver

On Monday 22 April 2002 10:06 am, you wrote:
> Kenneth Culver writes:
>  > static inline unsigned long do_mmap(struct file *file, unsigned long
>  > addr,
>
> <..>
>
>  >ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >>
>  > PAGE_SHIFT); out:
>  >return ret;
>  > }
>  >
>  > This is what mmap2 does:
>  >
>  > andstatic inline long do_mmap2(
>  >unsigned long addr, unsigned long len,
>  >unsigned long prot, unsigned long flags,
>  >unsigned long fd, unsigned long pgoff)
>
> <...>
>
>  >error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
>  >
>  >
>  > So what it looks like to me is that mmap2 expects an offset that's
>  > already page-aligned (I'm not sure if this is the right way to say it),
>  > where mmap doesn't. the FreeBSD code in the linuxulator basically just
>  > takes the offset
>
> To me, it looks like mmap2 takes an offset that's a page index, rather
> than a byte position.   Since linux passes the offset with a 32-bit
> long, rather than a 64-bit off_t like we do, they need to do this in
> order to be able to map offsets larger than 4GB into a file.
>
> For linux_mmap2, I'd think we want to do roughly the same things as
> linux_mmap, but with bsd_args.pos = ctob((off_t)linux_args.pos)
>
> Drew
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

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



Re: implementing linux mmap2 syscall

2002-04-22 Thread Terry Lambert

Kenneth Culver wrote:
> > This is too much work.
> >
> > Basically, it just wants to bitch when the offset is not page
> > aligned, and then call the old mmap if it doesn't bitch.
> >
> OK, I think I can do that, thanks for the help. Will anyone be interested in
> patches when/if I get this working? I also implemented ftruncate64 (which
> just calls ftruncate).

Sure.  PR them, and then send email to whoever CVS says touched
them last.

-- Terry

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



Re: implementing linux mmap2 syscall

2002-04-22 Thread Kenneth Culver

> Basically, it just wants to bitch when the offset is not page
> aligned, and then call the old mmap if it doesn't bitch.
>
Basically I misunderstood what the linux mmap2 was doing, it recieves an
offset as a number of pages, not as bytes, so by definition it's already
page aligned. All I have to do is convert the number of pages to a number
of bytes and pass it along to FreeBSD's mmap.

Thanks!

Ken


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



Re: implementing linux mmap2 syscall

2002-04-22 Thread Terry Lambert

Kenneth Culver wrote:
> So what it looks like to me is that mmap2 expects an offset that's already
> page-aligned (I'm not sure if this is the right way to say it), where mmap
> doesn't. the FreeBSD code in the linuxulator basically just takes the offset
> that is passed in with the linux mmap, and uses that to call FreeBSD's mmap
> (the kernel version, not the one called from userland). So basically I'm
> kinda stuck as to what to do to implement linux's mmap2. The only thing I can
> think of is to implement a FreeBSD "mmap2" that basically assumes that the
> offset passed in is already page aligned or whatever, and just uses it, and
> then have linux_mmap2() just call the FreeBSD mmap2(). Any ideas?

This is too much work.

Basically, it just wants to bitch when the offset is not page
aligned, and then call the old mmap if it doesn't bitch.

-- Terry

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



Re: implementing linux mmap2 syscall

2002-04-22 Thread Kenneth Culver

On Monday 22 April 2002 06:29 am, you wrote:
> Kenneth Culver wrote:
> > So what it looks like to me is that mmap2 expects an offset that's
> > already page-aligned (I'm not sure if this is the right way to say it),
> > where mmap doesn't. the FreeBSD code in the linuxulator basically just
> > takes the offset that is passed in with the linux mmap, and uses that to
> > call FreeBSD's mmap (the kernel version, not the one called from
> > userland). So basically I'm kinda stuck as to what to do to implement
> > linux's mmap2. The only thing I can think of is to implement a FreeBSD
> > "mmap2" that basically assumes that the offset passed in is already page
> > aligned or whatever, and just uses it, and then have linux_mmap2() just
> > call the FreeBSD mmap2(). Any ideas?
>
> This is too much work.
>
> Basically, it just wants to bitch when the offset is not page
> aligned, and then call the old mmap if it doesn't bitch.
>
OK, I think I can do that, thanks for the help. Will anyone be interested in 
patches when/if I get this working? I also implemented ftruncate64 (which 
just calls ftruncate). 

Ken

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



Re: implementing linux mmap2 syscall

2002-04-22 Thread Kenneth Culver

>  > AHH, ok I was wondering where PAGE_SHIFT was for FreeBSD. I guess ctob
>  > does what I need it to. I think that's probably why it still wasn't
>  > working yet... I think it also has to be page aligned before you pass it
>  > in though, I have to look at linux's do_mmap_pgoff() (I think that's the
>  > right function name) to see if it's expecting an already page-aligned arg,
>  > or if it's aligning it before it uses it.
>
> The name implies that do_mmap_pgoff() takes page-shift'ed args.
> An offset specified as a page-shift is page-aligned by definition.
> Eg, when you call ctob(pgoff) this turns out to be (pgoff <<
> PAGE_SHIFT) bytes.
>
> Drew
>
>
That makes sense, regular linux mmap seems to expect the offset to be in
bytes (from linux's mmap):

ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);

Where linux's mmap2 does this:

error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);

so this looks to me like do_mmap_pgoff expects a page-aligned offset,
meaning that the difference between a regular linux mmap, and linux's
mmap2 is that mmap expects bytes, and mmap2 expects a page offset
instead...


even more is that linux's old_mmap (the one that we actually emulate in
linux_mmap(), calls do_mmap2 with these args:

err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);

so, I'll just do the ctob() and see what happens. :-)

Ken


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



Re: implementing linux mmap2 syscall

2002-04-22 Thread Andrew Gallatin


Kenneth Culver writes:
 > > To me, it looks like mmap2 takes an offset that's a page index, rather
 > > than a byte position.   Since linux passes the offset with a 32-bit
 > > long, rather than a 64-bit off_t like we do, they need to do this in
 > > order to be able to map offsets larger than 4GB into a file.
 > >
 > > For linux_mmap2, I'd think we want to do roughly the same things as
 > > linux_mmap, but with bsd_args.pos = ctob((off_t)linux_args.pos)
 > >
 > > Drew
 > >
 > >
 > AHH, ok I was wondering where PAGE_SHIFT was for FreeBSD. I guess ctob
 > does what I need it to. I think that's probably why it still wasn't
 > working yet... I think it also has to be page aligned before you pass it
 > in though, I have to look at linux's do_mmap_pgoff() (I think that's the
 > right function name) to see if it's expecting an already page-aligned arg,
 > or if it's aligning it before it uses it.

The name implies that do_mmap_pgoff() takes page-shift'ed args.
An offset specified as a page-shift is page-aligned by definition.
Eg, when you call ctob(pgoff) this turns out to be (pgoff <<
PAGE_SHIFT) bytes. 

Drew



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



Re: implementing linux mmap2 syscall

2002-04-22 Thread Kenneth Culver

> To me, it looks like mmap2 takes an offset that's a page index, rather
> than a byte position.   Since linux passes the offset with a 32-bit
> long, rather than a 64-bit off_t like we do, they need to do this in
> order to be able to map offsets larger than 4GB into a file.
>
> For linux_mmap2, I'd think we want to do roughly the same things as
> linux_mmap, but with bsd_args.pos = ctob((off_t)linux_args.pos)
>
> Drew
>
>
AHH, ok I was wondering where PAGE_SHIFT was for FreeBSD. I guess ctob
does what I need it to. I think that's probably why it still wasn't
working yet... I think it also has to be page aligned before you pass it
in though, I have to look at linux's do_mmap_pgoff() (I think that's the
right function name) to see if it's expecting an already page-aligned arg,
or if it's aligning it before it uses it.

Thanks

Ken


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



implementing linux mmap2 syscall

2002-04-21 Thread Kenneth Culver

Hi,
I have recently been trying to implement the linux mmap2 syscall into our 
linuxulator, and I have run into a little problem. 

I looked at the code that was used to implement the regular linux_mmap 
syscall, and I've also looked in the linux kernel at the code that they use 
for mmap and mmap2. Basically this is in the linux kernel:

This is what mmap does in linux...

static inline unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
{
unsigned long ret = -EINVAL;
if ((offset + PAGE_ALIGN(len)) < offset)
goto out;
if (!(offset & ~PAGE_MASK))
ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
out:
return ret;
}

This is what mmap2 does:

andstatic inline long do_mmap2(
unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
int error = -EBADF;
struct file * file = NULL;

flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
file = fget(fd);
if (!file)
goto out;
}

down_write(¤t->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(¤t->mm->mmap_sem);

if (file)
fput(file);
out:
return error;
}

So what it looks like to me is that mmap2 expects an offset that's already 
page-aligned (I'm not sure if this is the right way to say it), where mmap 
doesn't. the FreeBSD code in the linuxulator basically just takes the offset 
that is passed in with the linux mmap, and uses that to call FreeBSD's mmap 
(the kernel version, not the one called from userland). So basically I'm 
kinda stuck as to what to do to implement linux's mmap2. The only thing I can 
think of is to implement a FreeBSD "mmap2" that basically assumes that the 
offset passed in is already page aligned or whatever, and just uses it, and 
then have linux_mmap2() just call the FreeBSD mmap2(). Any ideas?

Ken

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