diff mbox

Fix MIPS N64 build.

Message ID ebb8b84e-b898-4781-a51a-130c80dff155@BAMAIL02.ba.imgtec.org
State Accepted
Commit 5eddde8f094ef52dca06695cc598e3b2556dcccb
Headers show

Commit Message

Steve Ellcey Feb. 13, 2014, 10:33 p.m. UTC
Uclibc is not building for MIPS N64 because pread is trying to use the
pread/pwrite system calls instead of pread64/pwrite64.  This patch fixes
the problem and was tested with LFS enabled and disabled.

Signed-off-by: Steve Ellcey <sellcey@mips.com>
---
 libc/sysdeps/linux/mips/pread_write.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Waldemar Brodkorb Feb. 14, 2014, 2:21 p.m. UTC | #1
Hi Steve,
Steve Ellcey  wrote,

> Uclibc is not building for MIPS N64 because pread is trying to use the
> pread/pwrite system calls instead of pread64/pwrite64.  This patch fixes
> the problem and was tested with LFS enabled and disabled.

I think you mean MIPS64 N32.
 
> Signed-off-by: Steve Ellcey <sellcey@mips.com>
> ---
>  libc/sysdeps/linux/mips/pread_write.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c
> index 3dc97c9..1220fec 100644
> --- a/libc/sysdeps/linux/mips/pread_write.c
> +++ b/libc/sysdeps/linux/mips/pread_write.c
> @@ -13,14 +13,14 @@
>  /* We should generalize this for 32bit userlands w/64bit regs.  This applies
>   * to the x86_64 x32 and the mips n32 ABIs.  */
>  #if _MIPS_SIM == _MIPS_SIM_NABI32
> -# define __NR___syscall_pread __NR_pread
> +# define __NR___syscall_pread __NR_pread64
>  static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf, size_t, count, off_t, offset)
>  # define MY_PREAD(fd, buf, count, offset) \
>  	__syscall_pread(fd, buf, count, offset)
>  # define MY_PREAD64(fd, buf, count, offset) \
>  	__syscall_pread(fd, buf, count, offset)
>  
> -# define __NR___syscall_pwrite __NR_pwrite
> +# define __NR___syscall_pwrite __NR_pwrite64
>  static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf, size_t, count, off_t, offset)
>  # define MY_PWRITE(fd, buf, count, offset) \
>  	__syscall_pwrite(fd, buf, count, offset)
> -- 

Works for me, too.
Did you start any real machine or emulator with this? I get bus
errors after executing any application.

best regards
 Waldemar
Steve Ellcey Feb. 14, 2014, 4:15 p.m. UTC | #2
On Fri, 2014-02-14 at 15:21 +0100, Waldemar Brodkorb wrote:
> Hi Steve,
> Steve Ellcey  wrote,
> 
> > Uclibc is not building for MIPS N64 because pread is trying to use the
> > pread/pwrite system calls instead of pread64/pwrite64.  This patch fixes
> > the problem and was tested with LFS enabled and disabled.
> 
> I think you mean MIPS64 N32.

You are right, I did mean N32.  I also forgot to credit you in the
comment since I got the change from you originally.  Sorry about that.

Steve Ellcey
sellcey@mips.com
Bernhard Reutner-Fischer Feb. 15, 2014, 10:14 a.m. UTC | #3
On Fri, Feb 14, 2014 at 03:21:32PM +0100, Waldemar Brodkorb wrote:
> Hi Steve,
> Steve Ellcey  wrote,
> 
> > Uclibc is not building for MIPS N64 because pread is trying to use the
> > pread/pwrite system calls instead of pread64/pwrite64.  This patch fixes
> > the problem and was tested with LFS enabled and disabled.
> 
> I think you mean MIPS64 N32.
>  
> > Signed-off-by: Steve Ellcey <sellcey@mips.com>
> > ---
> >  libc/sysdeps/linux/mips/pread_write.c |    4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c
> > index 3dc97c9..1220fec 100644
> > --- a/libc/sysdeps/linux/mips/pread_write.c
> > +++ b/libc/sysdeps/linux/mips/pread_write.c
> > @@ -13,14 +13,14 @@
> >  /* We should generalize this for 32bit userlands w/64bit regs.  This applies
> >   * to the x86_64 x32 and the mips n32 ABIs.  */
> >  #if _MIPS_SIM == _MIPS_SIM_NABI32
> > -# define __NR___syscall_pread __NR_pread
> > +# define __NR___syscall_pread __NR_pread64
> >  static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf, size_t, count, off_t, offset)
> >  # define MY_PREAD(fd, buf, count, offset) \
> >  	__syscall_pread(fd, buf, count, offset)
> >  # define MY_PREAD64(fd, buf, count, offset) \
> >  	__syscall_pread(fd, buf, count, offset)
> >  
> > -# define __NR___syscall_pwrite __NR_pwrite
> > +# define __NR___syscall_pwrite __NR_pwrite64
> >  static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf, size_t, count, off_t, offset)
> >  # define MY_PWRITE(fd, buf, count, offset) \
> >  	__syscall_pwrite(fd, buf, count, offset)
> > -- 
> 
> Works for me, too.
> Did you start any real machine or emulator with this? I get bus
> errors after executing any application.

I suspect this needs a different register passing handling
(__LONG_LONG_PAIR) then.
Steve Ellcey Feb. 28, 2014, 12:12 a.m. UTC | #4
On Sat, 2014-02-15 at 11:14 +0100, Bernhard Reutner-Fischer wrote:
> On Fri, Feb 14, 2014 at 03:21:32PM +0100, Waldemar Brodkorb wrote:

> > Works for me, too.
> > Did you start any real machine or emulator with this? I get bus
> > errors after executing any application.
> 
> I suspect this needs a different register passing handling
> (__LONG_LONG_PAIR) then.

Waldemar,  I did run a pread/pwrite test case compiled with "-mips64r2
-mabi=n32" on both big-endian and a little-endian systems.  I did not
get a bus error in either case when calling pread or pwrite.  I also
tried calling pread64 and pwrite64 instead but those worked as well.  Do
you have a small test case that fails for you that you could send me?

I think the Bernhard's comment about __LONG_LONG_PAIR is correct and
my best guess as to the fix would be to change all of the

		__syscall_pwrite(fd, buf, count, offset)

lines in libc/sysdeps/linux/mips/pread_write.c to be:

		__syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR ((long) (offset >> 31), (long) offset))

but I was hoping to reproduce the error first, then try this fix. Since
the current code works for me I am not sure how to test this change.

Note that when testing this I did use my current patch of changing
__NR_pread and __NR_write to __NR_pread64 and __NR_write64.

Steve Ellcey
sellcey@mips.com
Waldemar Brodkorb Feb. 28, 2014, 6:31 a.m. UTC | #5
Hi Steve,
Steve Ellcey wrote,

> On Sat, 2014-02-15 at 11:14 +0100, Bernhard Reutner-Fischer wrote:
> > On Fri, Feb 14, 2014 at 03:21:32PM +0100, Waldemar Brodkorb wrote:
> 
> > > Works for me, too.
> > > Did you start any real machine or emulator with this? I get bus
> > > errors after executing any application.
> > 
> > I suspect this needs a different register passing handling
> > (__LONG_LONG_PAIR) then.
> 
> Waldemar,  I did run a pread/pwrite test case compiled with "-mips64r2
> -mabi=n32" on both big-endian and a little-endian systems.  I did not
> get a bus error in either case when calling pread or pwrite.  I also
> tried calling pread64 and pwrite64 instead but those worked as well.  Do
> you have a small test case that fails for you that you could send me?
> 
> I think the Bernhard's comment about __LONG_LONG_PAIR is correct and
> my best guess as to the fix would be to change all of the
> 
> 		__syscall_pwrite(fd, buf, count, offset)
> 
> lines in libc/sysdeps/linux/mips/pread_write.c to be:
> 
> 		__syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR ((long) (offset >> 31), (long) offset))
> 
> but I was hoping to reproduce the error first, then try this fix. Since
> the current code works for me I am not sure how to test this change.
> 
> Note that when testing this I did use my current patch of changing
> __NR_pread and __NR_write to __NR_pread64 and __NR_write64.

Oh I am so sorry. I made it unclear. The bus errors and segfaults I
get while booting a linux MIPS64 N32 system in qemu are not related to
this patch. I was just wondering if you also get problems when using
a complete linux system with MIPS64 N32. I am still investigating.

best regards
        Waldemar
Steve Ellcey Feb. 28, 2014, 5:35 p.m. UTC | #6
On Fri, 2014-02-28 at 07:31 +0100, Waldemar Brodkorb wrote:

> Oh I am so sorry. I made it unclear. The bus errors and segfaults I
> get while booting a linux MIPS64 N32 system in qemu are not related to
> this patch. I was just wondering if you also get problems when using
> a complete linux system with MIPS64 N32. I am still investigating.
> 
> best regards
>         Waldemar

I haven't built a complete linux system with MIPS64 N32, we have a
couple of MIPS64 systems here that I am testing on and they have 64 bit
kernels so I can build and test 64 bit executables on them but all the
linux commands look to be (MIPS32) O32 objects.

Steve Ellcey
Steve Ellcey March 10, 2014, 10:43 p.m. UTC | #7
On Sat, 2014-02-15 at 11:14 +0100, Bernhard Reutner-Fischer wrote:
> On Fri, Feb 14, 2014 at 03:21:32PM +0100, Waldemar Brodkorb wrote:
> > Hi Steve,
> > Steve Ellcey  wrote,
> > 
> > > Uclibc is not building for MIPS N64 because pread is trying to use the
> > > pread/pwrite system calls instead of pread64/pwrite64.  This patch fixes
> > > the problem and was tested with LFS enabled and disabled.
> > 
> > I think you mean MIPS64 N32.
> >  
> > > Signed-off-by: Steve Ellcey <sellcey@mips.com>
> > > ---
> > >  libc/sysdeps/linux/mips/pread_write.c |    4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c
> > > index 3dc97c9..1220fec 100644
> > > --- a/libc/sysdeps/linux/mips/pread_write.c
> > > +++ b/libc/sysdeps/linux/mips/pread_write.c
> > > @@ -13,14 +13,14 @@
> > >  /* We should generalize this for 32bit userlands w/64bit regs.  This applies
> > >   * to the x86_64 x32 and the mips n32 ABIs.  */
> > >  #if _MIPS_SIM == _MIPS_SIM_NABI32
> > > -# define __NR___syscall_pread __NR_pread
> > > +# define __NR___syscall_pread __NR_pread64
> > >  static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf, size_t, count, off_t, offset)
> > >  # define MY_PREAD(fd, buf, count, offset) \
> > >  	__syscall_pread(fd, buf, count, offset)
> > >  # define MY_PREAD64(fd, buf, count, offset) \
> > >  	__syscall_pread(fd, buf, count, offset)
> > >  
> > > -# define __NR___syscall_pwrite __NR_pwrite
> > > +# define __NR___syscall_pwrite __NR_pwrite64
> > >  static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf, size_t, count, off_t, offset)
> > >  # define MY_PWRITE(fd, buf, count, offset) \
> > >  	__syscall_pwrite(fd, buf, count, offset)
> > > -- 
> > 
> > Works for me, too.
> > Did you start any real machine or emulator with this? I get bus
> > errors after executing any application.
> 
> I suspect this needs a different register passing handling
> (__LONG_LONG_PAIR) then.

Bernhard,

I looked into __LONG_LONG_PAIR but that is used to pass a 64 bit value
in two 32 bit registers.  In this case (MIPS N32 mode) we are passing a
32 bit value (offset) in a 64 bit register and the system interface
already takes care of any extension from 32 bits to 64 bits that is
needed.  I did some more testing of pread and pwrite and it seems to be
working fine.  Waldemar's comment about bus errors was not about this
pread/pwrite patch but issues with booting an N32 MIPS linux kernel.
Can this patch go ahead and be checked in to uclibc?

Steve Ellcey
sellcey@mips.com
Bernhard Reutner-Fischer March 12, 2014, 8:05 p.m. UTC | #8
On Mon, Mar 10, 2014 at 03:43:59PM -0700, Steve Ellcey wrote:
> On Sat, 2014-02-15 at 11:14 +0100, Bernhard Reutner-Fischer wrote:
> > On Fri, Feb 14, 2014 at 03:21:32PM +0100, Waldemar Brodkorb wrote:
> > > Hi Steve,
> > > Steve Ellcey  wrote,
> > > 
> > > > Uclibc is not building for MIPS N64 because pread is trying to use the
> > > > pread/pwrite system calls instead of pread64/pwrite64.  This patch fixes
> > > > the problem and was tested with LFS enabled and disabled.
> > > 
> > > I think you mean MIPS64 N32.
> > >  
> > > > Signed-off-by: Steve Ellcey <sellcey@mips.com>
> > > > ---
> > > >  libc/sysdeps/linux/mips/pread_write.c |    4 ++--
> > > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c
> > > > index 3dc97c9..1220fec 100644
> > > > --- a/libc/sysdeps/linux/mips/pread_write.c
> > > > +++ b/libc/sysdeps/linux/mips/pread_write.c
> > > > @@ -13,14 +13,14 @@
> > > >  /* We should generalize this for 32bit userlands w/64bit regs.  This applies
> > > >   * to the x86_64 x32 and the mips n32 ABIs.  */
> > > >  #if _MIPS_SIM == _MIPS_SIM_NABI32
> > > > -# define __NR___syscall_pread __NR_pread
> > > > +# define __NR___syscall_pread __NR_pread64
> > > >  static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf, size_t, count, off_t, offset)
> > > >  # define MY_PREAD(fd, buf, count, offset) \
> > > >  	__syscall_pread(fd, buf, count, offset)
> > > >  # define MY_PREAD64(fd, buf, count, offset) \
> > > >  	__syscall_pread(fd, buf, count, offset)
> > > >  
> > > > -# define __NR___syscall_pwrite __NR_pwrite
> > > > +# define __NR___syscall_pwrite __NR_pwrite64
> > > >  static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf, size_t, count, off_t, offset)
> > > >  # define MY_PWRITE(fd, buf, count, offset) \
> > > >  	__syscall_pwrite(fd, buf, count, offset)
> > > > -- 
> > > 
> > > Works for me, too.
> > > Did you start any real machine or emulator with this? I get bus
> > > errors after executing any application.
> > 
> > I suspect this needs a different register passing handling
> > (__LONG_LONG_PAIR) then.
> 
> Bernhard,
> 
> I looked into __LONG_LONG_PAIR but that is used to pass a 64 bit value
> in two 32 bit registers.  In this case (MIPS N32 mode) we are passing a
> 32 bit value (offset) in a 64 bit register and the system interface
> already takes care of any extension from 32 bits to 64 bits that is
> needed.  I did some more testing of pread and pwrite and it seems to be
> working fine.  Waldemar's comment about bus errors was not about this
> pread/pwrite patch but issues with booting an N32 MIPS linux kernel.

I see.

> Can this patch go ahead and be checked in to uclibc?

It unconditionally uses the 64 variants of the syscall which presumably
would have failed on you iff there was an N32 that did not have the 64
syscalls..

Applied, thanks.
diff mbox

Patch

diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c
index 3dc97c9..1220fec 100644
--- a/libc/sysdeps/linux/mips/pread_write.c
+++ b/libc/sysdeps/linux/mips/pread_write.c
@@ -13,14 +13,14 @@ 
 /* We should generalize this for 32bit userlands w/64bit regs.  This applies
  * to the x86_64 x32 and the mips n32 ABIs.  */
 #if _MIPS_SIM == _MIPS_SIM_NABI32
-# define __NR___syscall_pread __NR_pread
+# define __NR___syscall_pread __NR_pread64
 static _syscall4(ssize_t, __syscall_pread, int, fd, void *, buf, size_t, count, off_t, offset)
 # define MY_PREAD(fd, buf, count, offset) \
 	__syscall_pread(fd, buf, count, offset)
 # define MY_PREAD64(fd, buf, count, offset) \
 	__syscall_pread(fd, buf, count, offset)
 
-# define __NR___syscall_pwrite __NR_pwrite
+# define __NR___syscall_pwrite __NR_pwrite64
 static _syscall4(ssize_t, __syscall_pwrite, int, fd, const void *, buf, size_t, count, off_t, offset)
 # define MY_PWRITE(fd, buf, count, offset) \
 	__syscall_pwrite(fd, buf, count, offset)