Re: implementing linux mmap2 syscall
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
> 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
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
> 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
> 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
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
> 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
> > > 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
> > 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
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
> 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
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
> > 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
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
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
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
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
> 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
> > > > 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
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
> > 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
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
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
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
> 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
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
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
> > 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
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
> 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
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