bug-mes
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Update on wip-arm-bootstrap


From: Jan Nieuwenhuizen
Subject: Re: Update on wip-arm-bootstrap
Date: Sun, 21 Feb 2021 19:28:55 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)

Jan Nieuwenhuizen writes:

Hi Danny!

>> On Thu, 18 Feb 2021 22:52:57 +0100
>> Jan Nieuwenhuizen <janneke@gnu.org> wrote:
>> Since this only affects the syscall interface and since also our
>> ELF headers specify EABI, I would just change the syscalls to EABI:
>> Just put the syscall number into r7 and use svc 0.
>
> Oh, if that's all we should be able to find and fix it?

I took a stab at it and created the attached patch, also on
wip-arm-bootstrap now.  This allows creating simple binaries using
gcc-core-mesboot0 and glibc-mesboot0 that run, like "return 42" and even
"exit (42)".  But something like puts or printf segfaults "Illegal
instruction" in strlen:

--8<---------------cut here---------------start------------->8---
(gdb) disas /r
Dump of assembler code for function strlen:
   0x0000d160 <+0>:     03 10 c0 e3     bic     r1, r0, #3
=> 0x0000d164 <+4>:     04 20 91 e4     ldr     r2, [r1], #4
--8<---------------cut here---------------end--------------->8---

makes no sens to me?  So, trying to build the first glibc-based gcc

--8<---------------cut here---------------start------------->8---
./pre-inst-env guix build -e '(@@ (gnu packages commencement) gcc-mesboot0)'
--8<---------------cut here---------------end--------------->8---

still fails during configure.  Seems like I'm stuck here again,
hopefully you can spot some silly mistake in my patch or have another
helpful insight :-)

Greetings,
Janneke

>From dda9f6d081d68848a1d602c375e0d7a8871e4ae4 Mon Sep 17 00:00:00 2001
From: "Jan (janneke) Nieuwenhuizen" <janneke@gnu.org>
Date: Sat, 20 Feb 2021 15:32:53 +0100
Subject: [PATCH 8/8] bootstrappable: arm: Support EABI system calls.
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=UTF-8

* sysdeps/unix/sysv/linux/arm/sysdep.h (DO_CALL,INLINE_SYSCALL)
[__ARM_EABI__]: Use eabi calling convention for syscalls.
* sysdeps/arm/dl-machine.h (CLEAR_CACHE): Likewise.
* sysdeps/unix/sysv/linux/arm/brk.c (__brk): Likewise.Likewise.
* sysdeps/unix/sysv/linux/arm/clone.S: Likewise.
* sysdeps/unix/sysv/linux/arm/mmap.S: Likewise.
* sysdeps/unix/sysv/linux/arm/mmap64.S: Likewise.
* sysdeps/unix/sysv/linux/arm/sigrestorer.S: Likewise.
* sysdeps/unix/sysv/linux/arm/socket.S: Likewise.
* sysdeps/unix/sysv/linux/arm/vfork.S: Likewise.
---
 sysdeps/arm/dl-machine.h                  | 14 ++++++
 sysdeps/unix/sysv/linux/arm/brk.c         | 10 +++++
 sysdeps/unix/sysv/linux/arm/clone.S       |  7 +++
 sysdeps/unix/sysv/linux/arm/mmap.S        |  7 +++
 sysdeps/unix/sysv/linux/arm/mmap64.S      |  7 +++
 sysdeps/unix/sysv/linux/arm/sigrestorer.S | 14 ++++++
 sysdeps/unix/sysv/linux/arm/socket.S      |  7 +++
 sysdeps/unix/sysv/linux/arm/sysdep.h      | 54 +++++++++++++++++++++++
 sysdeps/unix/sysv/linux/arm/vfork.S       | 14 ++++++
 9 files changed, 134 insertions(+)

diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
index 2d802b7..02c48bd 100644
--- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h
@@ -32,6 +32,19 @@
   && VALID_ELF_OSABI (hdr[EI_OSABI]) \
   && VALID_ELF_ABIVERSION (hdr[EI_ABIVERSION])
 
+#if __ARM_EABI__
+#define CLEAR_CACHE(BEG,END)                                           \
+{                                                                      \
+  register unsigned long _beg __asm ("a1") = (unsigned long)(BEG);     \
+  register unsigned long _end __asm ("a2") = (unsigned long)(END);     \
+  register unsigned long _flg __asm ("a3") = 0;                                
\
+  __asm __volatile ("mov r7, 0x9f0002\n\t"                             \
+                   "swi 0x0            @ sys_cacheflush"               \
+                   : /* no outputs */                                  \
+                   : /* no inputs */                                   \
+                   : "a1","r7");                                       \
+}
+#else // !__ARM_EABI__
 #define CLEAR_CACHE(BEG,END)                                           \
 {                                                                      \
   register unsigned long _beg __asm ("a1") = (unsigned long)(BEG);     \
@@ -42,6 +55,7 @@
                    : /* no inputs */                                   \
                    : "a1");                                            \
 }
+#endif // !__ARM_EABI__
 
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int __attribute__ ((unused))
diff --git a/sysdeps/unix/sysv/linux/arm/brk.c 
b/sysdeps/unix/sysv/linux/arm/brk.c
index 153d893..d5d0904 100644
--- a/sysdeps/unix/sysv/linux/arm/brk.c
+++ b/sysdeps/unix/sysv/linux/arm/brk.c
@@ -29,12 +29,22 @@ __brk (void *addr)
 {
   void *newbrk;
 
+#if __ARM_EABI__
+  asm ("mov a1, %1\n"  /* save the argment in r0 */
+       "mov r7, %2\n"  /* system call nr in r7 */
+       "swi 0x0\n"     /* do the system call */
+       "mov %0, a1;"   /* keep the return value */
+       : "=r"(newbrk)
+       : "r"(addr), "i" (SYS_ify (brk))
+       : "a1","r7");
+#else // !__ARM_EABI__
   asm ("mov a1, %1\n"  /* save the argment in r0 */
        "swi %2\n"      /* do the system call */
        "mov %0, a1;"   /* keep the return value */
        : "=r"(newbrk) 
        : "r"(addr), "i" (SYS_ify (brk))
        : "a1");
+#endif // !__ARM_EABI__
 
   __curbrk = newbrk;
 
diff --git a/sysdeps/unix/sysv/linux/arm/clone.S 
b/sysdeps/unix/sysv/linux/arm/clone.S
index c9a1ec2..bd088b4 100644
--- a/sysdeps/unix/sysv/linux/arm/clone.S
+++ b/sysdeps/unix/sysv/linux/arm/clone.S
@@ -44,7 +44,14 @@ ENTRY(__clone)
        @ get flags
        mov     r0, r2
        @ new sp is already in r1
+#if __ARM_EABI__
+       str     r7, [sp, #-4]!
+       mov     r7, #SYS_ify(clone)
+       swi     0x0
+       ldr     r7, [sp], #4
+#else // !__ARM_EABI__
        swi     SYS_ify(clone)
+#endif // !__ARM_EABI__
        movs    a1, a1
        blt     PLTJMP(C_SYMBOL_NAME(__syscall_error))
        RETINSTR(movne, pc, lr)
diff --git a/sysdeps/unix/sysv/linux/arm/mmap.S 
b/sysdeps/unix/sysv/linux/arm/mmap.S
index af93c7b..97b4a55 100644
--- a/sysdeps/unix/sysv/linux/arm/mmap.S
+++ b/sysdeps/unix/sysv/linux/arm/mmap.S
@@ -41,7 +41,14 @@ ENTRY (__mmap)
 
        /* do the syscall */
        mov     a1, sp
+#if __ARM_EABI__
+       str     r7, [sp, #-4]!
+       mov     r7, #SYS_ify (mmap)
+       swi     0x0
+       ldr     r7, [sp], #4
+#else // !__ARM_EABI__
        swi     SYS_ify (mmap)
+#endif // !__ARM_EABI__
 
        /* pop args off the stack. */
        add     sp, sp, #16
diff --git a/sysdeps/unix/sysv/linux/arm/mmap64.S 
b/sysdeps/unix/sysv/linux/arm/mmap64.S
index 1f19bf0..8cb40f5 100644
--- a/sysdeps/unix/sysv/linux/arm/mmap64.S
+++ b/sysdeps/unix/sysv/linux/arm/mmap64.S
@@ -36,7 +36,14 @@ ENTRY (__mmap64)
        movs    ip, ip, lsr $12
        bne     .Linval                 @ check for overflow
        mov     ip, r0
+#if __ARM_EABI__
+       str     r7, [sp, #-4]!
+       mov     r7, #SYS_ify (mmap2)
+       swi     0x0
+       ldr     r7, [sp], #4
+#else // !__ARM_EABI__
        swi     SYS_ify (mmap2)
+#endif // !__ARM_EABI__
        cmn     r0, $4096
        LOADREGS(ccfd, sp!, {r4, r5, pc})
        cmn     r0, $ENOSYS
diff --git a/sysdeps/unix/sysv/linux/arm/sigrestorer.S 
b/sysdeps/unix/sysv/linux/arm/sigrestorer.S
index a4769ca..54aa196 100644
--- a/sysdeps/unix/sysv/linux/arm/sigrestorer.S
+++ b/sysdeps/unix/sysv/linux/arm/sigrestorer.S
@@ -24,12 +24,26 @@
 
 #ifdef __NR_sigreturn
 ENTRY(__default_sa_restorer)
+#if __ARM_EABI__
+       str     r7, [sp, #-4]!
+       mov     r7, #SYS_ify(sigreturn)
+       swi     0x0
+       ldr     r7, [sp], #4
+#else // !__ARM_EABI__
        swi     SYS_ify(sigreturn)
+#endif // !__ARM_EABI__
 #endif
 
 #ifdef __NR_rt_sigreturn
 
 ENTRY(__default_rt_sa_restorer)
+#if __ARM_EABI__
+       str     r7, [sp, #-4]!
+       mov     r7, #SYS_ify(rt_sigreturn)
+       swi     0x0
+       ldr     r7, [sp], #4
+#else // !__ARM_EABI__
        swi     SYS_ify(rt_sigreturn)
+#endif // !__ARM_EABI__
 
 #endif
diff --git a/sysdeps/unix/sysv/linux/arm/socket.S 
b/sysdeps/unix/sysv/linux/arm/socket.S
index c8143a2..f0d6e08 100644
--- a/sysdeps/unix/sysv/linux/arm/socket.S
+++ b/sysdeps/unix/sysv/linux/arm/socket.S
@@ -72,7 +72,14 @@ ENTRY (__socket)
        mov a1, $P(SOCKOP_,socket)
        mov a2, sp
 #ifdef __NR_socketcall
+#if __ARM_EABI__
+       str     r7, [sp, #-4]!
+       mov r7, #SYS_ify(socketcall)
+       swi 0x0
+       ldr     r7, [sp], #4
+#else // !__ARM_EABI__
        swi SYS_ify(socketcall)
+#endif // !__ARM_EABI__
 #endif
 
        /* Pop args off the stack */
diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h 
b/sysdeps/unix/sysv/linux/arm/sysdep.h
index 89ad194..f8e88e4 100644
--- a/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -95,10 +95,40 @@
 */
 
 #undef DO_CALL
+#if __ARM_EABI__
+#define DO_CALL(args, syscall_name)            \
+    DOARGS_##args                              \
+    ldr r7, =SYS_ify (syscall_name);           \
+    swi 0x0;                                   \
+    UNDOARGS_##args
+#else //!__ARM_EABI__
 #define DO_CALL(args, syscall_name)            \
     DOARGS_##args                              \
     swi SYS_ify (syscall_name);                \
     UNDOARGS_##args
+#endif //!__ARM_EABI__
+
+#if __ARM_EABI__
+
+#define DOARGS_0 str r7, [sp, $-4]!;
+#define DOARGS_1 str r7, [sp, $-4]!;
+#define DOARGS_2 str r7, [sp, $-4]!;
+#define DOARGS_3 str r7, [sp, $-4]!;
+#define DOARGS_4 str r7, [sp, $-4]!;
+#define DOARGS_5 mov ip, sp; stmfd sp!, {r4, r7}; ldmia ip, {r4, r7};
+#define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5, r7}; ldmia ip, {r4, r5, r7};
+#define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6, r7}; ldmia ip, {r4, r5, 
r6, r7};
+
+#define UNDOARGS_0 ldr r7, [sp], $4;
+#define UNDOARGS_1 ldr r7, [sp], $4;
+#define UNDOARGS_2 ldr r7, [sp], $4;
+#define UNDOARGS_3 ldr r7, [sp], $4;
+#define UNDOARGS_4 ldr r7, [sp], $4;
+#define UNDOARGS_5 ldmfd sp!, {r4, r7};
+#define UNDOARGS_6 ldmfd sp!, {r4, r5, r7};
+#define UNDOARGS_7 ldmfd sp!, {r4, r5, r6, r7};
+
+#else //!__ARM_EABI__
 
 #define DOARGS_0 /* nothing */
 #define DOARGS_1 /* nothing */
@@ -118,11 +148,34 @@
 #define UNDOARGS_6 ldmfd sp!, {r4, r5};
 #define UNDOARGS_7 ldmfd sp!, {r4, r5, r6};
 
+#endif //!__ARM_EABI__
+
 #else /* not __ASSEMBLER__ */
 
 /* Define a macro which expands into the inline wrapper code for a system
    call.  */
 #undef INLINE_SYSCALL
+
+#if __ARM_EABI__
+#define INLINE_SYSCALL(name, nr, args...)                      \
+  ({ unsigned int _sys_result;                                 \
+     {                                                         \
+       register int _a1 asm ("a1");                            \
+       LOAD_ARGS_##nr (args)                                   \
+       asm volatile ("mov      r7, %1\n\t"                     \
+                    "swi       $0      @ syscall " #name       \
+                    : "=r" (_a1)                               \
+                    : "i" (SYS_ify(name)) ASM_ARGS_##nr        \
+                    : "a1", "r7", "memory");                   \
+       _sys_result = _a1;                                      \
+     }                                                         \
+     if (_sys_result >= (unsigned int) -4095)                  \
+       {                                                       \
+        __set_errno (-_sys_result);                            \
+        _sys_result = (unsigned int) -1;                       \
+       }                                                       \
+     (int) _sys_result; })
+#else //!__ARM_EABI__
 #define INLINE_SYSCALL(name, nr, args...)                      \
   ({ unsigned int _sys_result;                                 \
      {                                                         \
@@ -140,6 +193,7 @@
         _sys_result = (unsigned int) -1;                       \
        }                                                       \
      (int) _sys_result; })
+#endif //!__ARM_EABI__
 
 #define LOAD_ARGS_0()
 #define ASM_ARGS_0
diff --git a/sysdeps/unix/sysv/linux/arm/vfork.S 
b/sysdeps/unix/sysv/linux/arm/vfork.S
index b10117e..ba2259d 100644
--- a/sysdeps/unix/sysv/linux/arm/vfork.S
+++ b/sysdeps/unix/sysv/linux/arm/vfork.S
@@ -29,7 +29,14 @@
 ENTRY (__vfork)
 
 #ifdef __NR_vfork
+#if __ARM_EABI__
+       str     r7, [sp, #-4]!
+       mov     r7, #__NR_vfork
+       swi     0x0
+       ldr     r7, [sp], #4
+#else // !__ARM_EABI__
        swi     __NR_vfork
+#endif // !__ARM_EABI__
        cmn     a1, #4096
        RETINSTR(movcc, pc, lr)
 
@@ -40,7 +47,14 @@ ENTRY (__vfork)
 #endif
 
        /* If we don't have vfork, fork is close enough.  */
+#if __ARM_EABI__
+       str     r7, [sp, #-4]!
+       mov     r7, #__NR_fork
+       swi     0x0
+       ldr     r7, [sp], #4
+#else // !__ARM_EABI__
        swi     __NR_fork
+#endif // !__ARM_EABI__
        cmn     a1, #4096
        RETINSTR(movcc, pc, lr)
        b       PLTJMP(C_SYMBOL_NAME(__syscall_error))
-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com

-- 
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com

reply via email to

[Prev in Thread] Current Thread [Next in Thread]