mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@libc.org>
To: musl@lists.openwall.com
Cc: rob@landley.net
Subject: Re: Moving forward with sh2/nommu
Date: Tue, 9 Jun 2015 23:30:50 -0400	[thread overview]
Message-ID: <20150610033050.GS17573@brightrain.aerifal.cx> (raw)
In-Reply-To: <20150601151107.GA20759@brightrain.aerifal.cx>

[-- Attachment #1: Type: text/plain, Size: 5492 bytes --]

On Mon, Jun 01, 2015 at 11:11:07AM -0400, Rich Felker wrote:
> [resent to musl list]
> 
> Here's a summary of the issues we need to work through to get a modern
> SH2/nommu-targetted musl/toolchain out of the proof-of-concept stage
> and to the point where it's something people can use roughly 'out of
> the box':
> 
> Kernel issues:
> 
> 1. Kernel should support loading plain ELF directly, unmodified. Right

I have a patch to do this, not polished but it works. It also...

> 2. Kernel insists on having a stack size set in the PT_GNU_STACK
>    program header; if it's 0 (the default ld produces) then execve
>    fails. It should just provide a default, probably 128k (equal to
>    MMU-ful Linux).

...uses a default stack size of 128k if the header is 0, and...

> 3. Kernel uses the stack for brk too, growing brk from the opposite
>    end. This is horribly buggy/dangerous. Just dummying out brk to

...set the brk size to zero so that brk will always fail.

> 4. Syscall trap numbers differ on SH2 vs SH3/4. Presumably the reason
>    is that these two SH2A hardware traps overlap with the syscall
>    range used by SH3/4 ABI:

I haven't patched this yet. I'd like to use 31 (0x1f) as the new
universal SH syscall trap number, instead of 22. More details on the
reasons later.

> musl issues:
> 
> 1. We need runtime detection for the right trap number to use for
>    syscalls. Right now I've got the trap numbers hard-coded for SH2 in
>    my local tree.

I've written the runtime detection, but I'd rather not have to use it.
I managed to avoid inlining a big conditional at each syscall, but
there are still multiple ugly issues:

- The cancellable syscall code has two different instruction addresses
  where the actual syscall could take place (depending on which trap
  instruction is used), whereas the current musl C code assumes that
  there's exactly one instruction pointer range where cancellation may
  be acted upon. I have code to allow a second range but it's ugly.

- The sigreturn (sa_restorer) functions need to use runtime selection,
  which precludes putting them in the canonical form they usually
  have. At some point in the past, not using the exact instruction
  sequences expected for these functions confused gdb, but I suspect
  that's a non-issue on modern versions. Alternatively we could have
  sigreturn.c pass different versions of the sigreturn functions to
  the kernel depending on which syscall ABI is in use at runtime, but
  this requires bolting on new arch-specific logic to something that's
  normally not arch-specific, so I prefer just having the conditionals
  in the sigreturn functions.

- The syscall asm requires an extra register clobber to be able to do
  the runtime trap number switching.

An alternate design I considered was simply patching the trap number
in the .text for SH2, since there's no memory protection, but of
course this would preclude execute-in-place from ROM, etc. so I don't
think it's a proper solution. It is much less invasive, though.

> 2. We need additional runtime detection options for atomics: interrupt
>    masking for plain SH2, and the new CAS instruction for SH2J.

This is the one thing I haven't done, so currently the atomic macros
are using GUSA which is non-atomic and unsafe on SH2 (if an interrupt
happens with invalid stack pointer, memory will be corrupted). This
could be part of the random crashing I've been experiencing (although
I reproduced it without musl) so I'll try to add them next.

> 3. We need sh/vfork.s since the default vfork.c just uses fork, which
>    won't work. I have a version locally but it doesn't make sense to
>    commit without runtime trap number selection.

Done and updated to use runtime selection in the (ugly) patch.

> 4. As long as we're using the FDPIC ELF header flag to get
>    binfmt_elf_fdpic.c to load binaries, the startup code needs to call
>    the personality() syscall to switch back. I have a local hack for
>    doing this in rcrt1.o which is probably not worth upstreaming if we
>    can just make the kernel do it right.

No longer needed because of the kernel patch to load normal ELF.

> 5. The brk workaround I'm doing now can't be upstreamed without a
>    reliable runtime way to distinguish nommu. To put it in malloc.c
>    this would have to be a cross-arch solution. What might make more
>    sense is putting it in syscall_arch.h for sh, where we already
>    have to check for SH2 to determine the right trap number; the
>    inline syscall code can just do if (nr==SYS_brk&&IS_SH2) return 0;

Commit 276904c2f6bde3a31a24ebfa201482601d18b4f9 in musl solves this in
a general manner, even though it's no longer needed with my kernel
patch applied.

One more musl-side issue I neglected to mention is the __unmapself.s
can't work on SH2 because the SH2 trap/interrupt mechanism requires
the userspace stack pointer to be valid at all times. This is now
solved upstream in commit c30cbcb0a646b1f13a22c645616dce624465b883,
but activating it for SH2 requires removing
src/thread/sh/__unmapself.s so the generic C file gets used.

The attached patch covers everything described above that's not
already upstream, and is sufficient to build musl for sh2 with
musl-cross targeting "sheb-linux-musl". I used gcc 4.7.3 because later
versions break the kernel. The attached config.mak for musl shows the
configure options I used. The attached sheb.specs file is how I got
gcc to do always-PIE without breaking the kernel.

Rich

[-- Attachment #2: fdpic_elf_loader.diff --]
[-- Type: text/plain, Size: 1969 bytes --]

--- fs/binfmt_elf_fdpic.c.orig
+++ fs/binfmt_elf_fdpic.c
@@ -103,14 +103,27 @@
 core_initcall(init_elf_fdpic_binfmt);
 module_exit(exit_elf_fdpic_binfmt);
 
+static int is_fdpic(struct elfhdr *hdr)
+{
+#ifdef CONFIG_MMU
+	return 1;
+#else
+	return elf_check_fdpic(hdr);
+#endif
+}
+
 static int is_elf_fdpic(struct elfhdr *hdr, struct file *file)
 {
 	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
 		return 0;
 	if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN)
 		return 0;
-	if (!elf_check_arch(hdr) || !elf_check_fdpic(hdr))
+	if (!elf_check_arch(hdr))
 		return 0;
+#ifdef CONFIG_MMU
+	if (!elf_check_fdpic(hdr))
+		return 0;
+#endif
 	if (!file->f_op->mmap)
 		return 0;
 	return 1;
@@ -269,7 +282,7 @@
 
 	}
 
-	if (elf_check_const_displacement(&exec_params.hdr))
+	if (elf_check_const_displacement(&exec_params.hdr) || !is_fdpic(&exec_params.hdr))
 		exec_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;
 
 	/* perform insanity checks on the interpreter */
@@ -306,9 +319,9 @@
 
 	retval = -ENOEXEC;
 	if (stack_size == 0)
-		goto error;
+		stack_size = 131072;
 
-	if (elf_check_const_displacement(&interp_params.hdr))
+	if (elf_check_const_displacement(&interp_params.hdr) || !is_fdpic(&interp_params.hdr))
 		interp_params.flags |= ELF_FDPIC_FLAG_CONSTDISP;
 
 	/* flush all traces of the currently running executable */
@@ -319,7 +332,8 @@
 	/* there's now no turning back... the old userspace image is dead,
 	 * defunct, deceased, etc.
 	 */
-	set_personality(PER_LINUX_FDPIC);
+	if (is_fdpic(&exec_params.hdr))
+		set_personality(PER_LINUX_FDPIC);
 	if (elf_read_implies_exec(&exec_params.hdr, executable_stack))
 		current->personality |= READ_IMPLIES_EXEC;
 
@@ -400,8 +414,6 @@
 
 	current->mm->brk = current->mm->start_brk;
 	current->mm->context.end_brk = current->mm->start_brk;
-	current->mm->context.end_brk +=
-		(stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
 	current->mm->start_stack = current->mm->start_brk + stack_size;
 #endif
 

[-- Attachment #3: musl_sh2_v2.diff --]
[-- Type: text/plain, Size: 13622 bytes --]

diff --git a/Makefile b/Makefile
index 2eb7b30..51baeab 100644
--- a/Makefile
+++ b/Makefile
@@ -108,6 +108,8 @@ $(NOSSP_SRCS:%.c=%.o) $(NOSSP_SRCS:%.c=%.lo): CFLAGS += $(CFLAGS_NOSSP)
 
 $(CRT_LIBS:lib/%=crt/%): CFLAGS += -DCRT
 
+$(patsubst %.c,%.o,$(wildcard src/complex/*.c)): CFLAGS += -fno-PIC -fno-PIE
+
 # This incantation ensures that changes to any subarch asm files will
 # force the corresponding object file to be rebuilt, even if the implicit
 # rule below goes indirectly through a .sub file.
diff --git a/arch/sh/pthread_arch.h b/arch/sh/pthread_arch.h
index 65c389f..0960422 100644
--- a/arch/sh/pthread_arch.h
+++ b/arch/sh/pthread_arch.h
@@ -9,3 +9,14 @@ static inline struct pthread *__pthread_self()
 #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 8)
 
 #define CANCEL_REG_IP 17
+
+#ifdef SHARED
+__attribute__((__visibility__("hidden")))
+#endif
+extern const char __cp_begin[1], __cp_end[1],
+	__cp2_begin[1], __cp2_end[1];
+
+#define IN_CP(ip) ((uintptr_t)(ip)-(uintptr_t)__cp_begin \
+	< (uintptr_t)__cp_end-(uintptr_t)__cp_begin \
+	|| (uintptr_t)(ip)-(uintptr_t)__cp2_begin \
+	< (uintptr_t)__cp2_end-(uintptr_t)__cp2_begin)
diff --git a/arch/sh/src/__set_thread_area.c b/arch/sh/src/__set_thread_area.c
index e69de29..a723ff2 100644
--- a/arch/sh/src/__set_thread_area.c
+++ b/arch/sh/src/__set_thread_area.c
@@ -0,0 +1,21 @@
+#include "pthread_impl.h"
+#include "libc.h"
+#include <elf.h>
+
+/* Also perform sh-specific init */
+
+__attribute__((__visibility__("hidden"))) int __sh2_abi;
+
+int __set_thread_area(void *p)
+{
+	size_t *aux;
+	__asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
+	for (aux=libc.auxv; *aux; aux+=2) {
+		if (*aux != AT_PLATFORM) continue;
+		const char *s = (void *)aux[1];
+		if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
+		__sh2_abi = 1;
+		break;
+	}
+	return 0;
+}
diff --git a/arch/sh/src/atomic.c b/arch/sh/src/atomic.c
index f8c615f..b3a8968 100644
--- a/arch/sh/src/atomic.c
+++ b/arch/sh/src/atomic.c
@@ -27,6 +27,8 @@
 
 #define CPU_HAS_LLSC 0x0040
 
+#define __hwcap 0
+
 int __sh_cas(volatile int *p, int t, int s)
 {
 	if (__hwcap & CPU_HAS_LLSC) return __sh_cas_llsc(p, t, s);
diff --git a/arch/sh/src/sh/sh_syscall.s b/arch/sh/src/sh/sh_syscall.s
index e69de29..546ae07 100644
--- a/arch/sh/src/sh/sh_syscall.s
+++ b/arch/sh/src/sh/sh_syscall.s
@@ -0,0 +1,38 @@
+.hidden __sh_syscall
+.global __sh_syscall
+.type __sh_syscall,@function
+__sh_syscall:
+	mov.l r0,@-r15
+	mov.l r2,@-r15
+
+	mova  1f, r0
+	mov.l 1f, r2
+	add   r0, r2
+	mov.l @r2, r2
+	tst   r2, r2
+
+	mov.l @r15+, r2
+	mov.l @r15+, r0
+
+	bt    3f
+	bra   2f
+	 nop
+	.align 2
+	.hidden __sh2_abi
+1:	.long __sh2_abi@PCREL
+
+2:	trapa #38
+	bra 1f
+	 nop
+
+3:	trapa #22
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+	or    r0, r0
+
+1:	neg r2, r2
+	add #__sh_syscall-9f, r2
+9:	braf r2
+	 nop
diff --git a/arch/sh/syscall_arch.h b/arch/sh/syscall_arch.h
index 7ee21a5..b56dfbf 100644
--- a/arch/sh/syscall_arch.h
+++ b/arch/sh/syscall_arch.h
@@ -3,26 +3,25 @@
 ((union { long long ll; long l[2]; }){ .ll = x }).l[1]
 #define __SYSCALL_LL_O(x) __SYSCALL_LL_E((x))
 
-/* The extra OR instructions are to work around a hardware bug:
- * http://documentation.renesas.com/doc/products/mpumcu/tu/tnsh7456ae.pdf
- */
-#define __asm_syscall(trapno, ...) do {   \
-	__asm__ __volatile__ (                \
-		"trapa #" #trapno "\n"            \
-		"or r0, r0\n"                     \
-		"or r0, r0\n"                     \
-		"or r0, r0\n"                     \
-		"or r0, r0\n"                     \
-		"or r0, r0\n"                     \
-	: "=r"(r0) : __VA_ARGS__ : "memory"); \
-	return r0;                            \
-	} while (0)
+#define __SYSCALL_ASM "\n"           \
+"	mov.l 1f, r2\n"              \
+"	.align 2\n"                  \
+"2:	braf r2\n"                   \
+"	 nop\n"                      \
+"	.hidden __sh_syscall\n"      \
+"1:	.long __sh_syscall@PCREL\n"  \
+"3:	\n"
+
+#define __asm_syscall(...) \
+	__asm__ __volatile__ ( __SYSCALL_ASM \
+	: "=r"(r0) : __VA_ARGS__ : "memory", "r2", "t" )
 
 static inline long __syscall0(long n)
 {
 	register long r3 __asm__("r3") = n;
 	register long r0 __asm__("r0");
-	__asm_syscall(16, "r"(r3));
+	__asm_syscall("r"(r3));
+	return r0;
 }
 
 static inline long __syscall1(long n, long a)
@@ -30,7 +29,8 @@ static inline long __syscall1(long n, long a)
 	register long r3 __asm__("r3") = n;
 	register long r4 __asm__("r4") = a;
 	register long r0 __asm__("r0");
-	__asm_syscall(17, "r"(r3), "r"(r4));
+	__asm_syscall("r"(r3), "r"(r4));
+	return r0;
 }
 
 static inline long __syscall2(long n, long a, long b)
@@ -39,7 +39,8 @@ static inline long __syscall2(long n, long a, long b)
 	register long r4 __asm__("r4") = a;
 	register long r5 __asm__("r5") = b;
 	register long r0 __asm__("r0");
-	__asm_syscall(18, "r"(r3), "r"(r4), "r"(r5));
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5));
+	return r0;
 }
 
 static inline long __syscall3(long n, long a, long b, long c)
@@ -49,7 +50,8 @@ static inline long __syscall3(long n, long a, long b, long c)
 	register long r5 __asm__("r5") = b;
 	register long r6 __asm__("r6") = c;
 	register long r0 __asm__("r0");
-	__asm_syscall(19, "r"(r3), "r"(r4), "r"(r5), "r"(r6));
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5), "r"(r6));
+	return r0;
 }
 
 static inline long __syscall4(long n, long a, long b, long c, long d)
@@ -60,7 +62,8 @@ static inline long __syscall4(long n, long a, long b, long c, long d)
 	register long r6 __asm__("r6") = c;
 	register long r7 __asm__("r7") = d;
 	register long r0 __asm__("r0");
-	__asm_syscall(20, "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7));
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7));
+	return r0;
 }
 
 static inline long __syscall5(long n, long a, long b, long c, long d, long e)
@@ -71,7 +74,8 @@ static inline long __syscall5(long n, long a, long b, long c, long d, long e)
 	register long r6 __asm__("r6") = c;
 	register long r7 __asm__("r7") = d;
 	register long r0 __asm__("r0") = e;
-	__asm_syscall(21, "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "0"(r0));
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "0"(r0));
+	return r0;
 }
 
 static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
@@ -83,5 +87,6 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
 	register long r7 __asm__("r7") = d;
 	register long r0 __asm__("r0") = e;
 	register long r1 __asm__("r1") = f;
-	__asm_syscall(22, "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "0"(r0), "r"(r1));
+	__asm_syscall("r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "0"(r0), "r"(r1));
+	return r0;
 }
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index f6f3b14..0ab80e2 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -42,6 +42,8 @@ void __init_libc(char **envp, char *pn)
 	__init_tls(aux);
 	__init_ssp((void *)aux[AT_RANDOM]);
 
+	if (__syscall(SYS_personality, 0) == -1) a_crash();
+
 	if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
 		&& !aux[AT_SECURE]) return;
 
diff --git a/src/internal/sh/syscall.s b/src/internal/sh/syscall.s
index d00712a..23feb32 100644
--- a/src/internal/sh/syscall.s
+++ b/src/internal/sh/syscall.s
@@ -2,10 +2,6 @@
 .hidden __syscall
 .type   __syscall, @function
 __syscall:
-	! The kernel syscall entry point documents that the trap number indicates
-	! the number of arguments being passed, but it then ignores that information.
-	! Since we do not actually know how many arguments are being passed, we will
-	! say there are six, since that is the maximum we support here.
 	mov r4, r3
 	mov r5, r4
 	mov r6, r5
@@ -13,11 +9,13 @@ __syscall:
 	mov.l @r15, r7
 	mov.l @(4,r15), r0
 	mov.l @(8,r15), r1
-	trapa #22
-	or r0, r0
-	or r0, r0
-	or r0, r0
-	or r0, r0
-	or r0, r0
+
+	mov.l 1f, r2
+	.align 2
+2:	braf r2
+	 nop
+	.hidden __sh_syscall
+1:	.long __sh_syscall@PCREL
+
 	rts
 	 nop
diff --git a/src/process/sh/vfork.s b/src/process/sh/vfork.s
index e69de29..9c61d03 100644
--- a/src/process/sh/vfork.s
+++ b/src/process/sh/vfork.s
@@ -0,0 +1,23 @@
+.global __vfork
+.weak vfork
+.type __vfork,@function
+.type vfork,@function
+__vfork:
+vfork:
+	mov #95, r3
+	add r3, r3
+
+	mov.l 1f, r2
+	.align 2
+2:	braf r2
+	 nop
+	.hidden __sh_syscall
+1:	.long __sh_syscall@PCREL
+
+	mov r0, r4
+	mov.l 1f, r0
+2:	braf r0
+	 nop
+	.align 2
+	.hidden __syscall_ret
+1:	.long __syscall_ret@PLT-(2b+4-.)
diff --git a/src/signal/sh/restore.s b/src/signal/sh/restore.s
index ab26034..f1b462c 100644
--- a/src/signal/sh/restore.s
+++ b/src/signal/sh/restore.s
@@ -2,23 +2,18 @@
 .type   __restore, @function
 __restore:
 	mov   #119, r3  !__NR_sigreturn
-	trapa #16
-
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
+	bra 1f
+	 nop
 
 .global __restore_rt
 .type   __restore_rt, @function
 __restore_rt:
 	mov   #100, r3  !__NR_rt_sigreturn
 	add   #73, r3
-	trapa #16
 
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
+1:	mov.l 1f, r2
+	.align 2
+2:	braf r2
+	 nop
+	.hidden __sh_syscall
+1:	.long __sh_syscall@PCREL
diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c
index 0151a1a..5ddd304 100644
--- a/src/thread/pthread_cancel.c
+++ b/src/thread/pthread_cancel.c
@@ -57,6 +57,11 @@ __attribute__((__visibility__("hidden")))
 #endif
 extern const char __cp_begin[1], __cp_end[1];
 
+#ifndef IN_CP
+#define IN_CP(ip) ((uintptr_t)(ip)-(uintptr_t)__cp_begin \
+	< (uintptr_t)__cp_end-(uintptr_t)__cp_begin)
+#endif
+
 static void cancel_handler(int sig, siginfo_t *si, void *ctx)
 {
 	pthread_t self = __pthread_self();
@@ -68,7 +73,7 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx)
 
 	_sigaddset(&uc->uc_sigmask, SIGCANCEL);
 
-	if (self->cancelasync || ip >= __cp_begin && ip < __cp_end) {
+	if (self->cancelasync || IN_CP(ip)) {
 		((char **)&uc->uc_mcontext)[CANCEL_REG_IP] = (char *)__cp_cancel;
 		return;
 	}
diff --git a/src/thread/sh/__set_thread_area.s b/src/thread/sh/__set_thread_area.s
index d9f1181..e69de29 100644
--- a/src/thread/sh/__set_thread_area.s
+++ b/src/thread/sh/__set_thread_area.s
@@ -1,6 +0,0 @@
-.global __set_thread_area
-.type   __set_thread_area, @function
-__set_thread_area:
-	ldc r4, gbr
-	rts
-	 mov #0, r0
diff --git a/src/thread/sh/__unmapself.s b/src/thread/sh/__unmapself.s
deleted file mode 100644
index b34c3c8..0000000
--- a/src/thread/sh/__unmapself.s
+++ /dev/null
@@ -1,22 +0,0 @@
-.text
-.global __unmapself
-.type   __unmapself, @function
-__unmapself:
-	mov   #91, r3  ! SYS_munmap
-	trapa #18
-
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
-
-	mov   #1, r3   ! SYS_exit
-	mov   #0, r4
-	trapa #17
-
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
-	or    r0, r0
diff --git a/src/thread/sh/clone.s b/src/thread/sh/clone.s
index d6c9184..5fc97fc 100644
--- a/src/thread/sh/clone.s
+++ b/src/thread/sh/clone.s
@@ -9,7 +9,7 @@ __clone:
 	and   r0, r5
 
 	mov   r4, r1         ! r1 = fn
-	mov   r7, r2         ! r2 = arg
+	mov.l r7, @-r5       ! (r5) = arg
 
 	mov   #120,     r3   ! r3 = __NR_clone
 	mov   r6,       r4   ! r4 = flags
@@ -17,13 +17,13 @@ __clone:
 	mov.l @r15,     r6   ! r6 = ptid
 	mov.l @(8,r15), r7   ! r7 = ctid
 	mov.l @(4,r15), r0   ! r0 = tls
-	trapa #21
 
-	or r0, r0
-	or r0, r0
-	or r0, r0
-	or r0, r0
-	or r0, r0
+3:	mov.l 1f, r2
+	.align 2
+2:	braf r2
+	 nop
+	.hidden __sh_syscall
+1:	.long __sh_syscall@PCREL
 
 	cmp/eq #0, r0
 	bt     1f
@@ -34,14 +34,9 @@ __clone:
 
 1:	! we are the child, call fn(arg)
 	jsr    @r1
-	 mov   r2, r4
+	 mov.l @r15+, r4
 
 	mov   #1, r3   ! __NR_exit
 	mov   r0, r4
-	trapa #17
-
-	or   r0, r0
-	or   r0, r0
-	or   r0, r0
-	or   r0, r0
-	or   r0, r0
+	bra   3b
+	 nop
diff --git a/src/thread/sh/syscall_cp.s b/src/thread/sh/syscall_cp.s
index 6b28ddf..f8bb607 100644
--- a/src/thread/sh/syscall_cp.s
+++ b/src/thread/sh/syscall_cp.s
@@ -1,4 +1,8 @@
 .text
+.global __cp2_begin
+.hidden __cp2_begin
+.global __cp2_end
+.hidden __cp2_end
 .global __cp_begin
 .hidden __cp_begin
 .global __cp_end
@@ -11,28 +15,58 @@
 .type   __syscall_cp_asm, @function
 __syscall_cp_asm:
 
-__cp_begin:
-	mov.l @r4, r4
-	tst   r4, r4
-	bt    2f
-
-	mov.l L1, r0
-	braf  r0
-	 nop
-1:
-
-.align 2
-L1:	.long __cancel@PLT-(1b-.)
+	mova  1f, r0
+	mov.l 1f, r2
+	add   r0, r2
+	mov.l @r1, r2
+	tst   r2, r2
 
-2:	mov   r5, r3
+	! setup syscall args
+	mov   r4, r2
+	mov   r5, r3
 	mov   r6, r4
 	mov   r7, r5
 	mov.l @r15, r6
 	mov.l @(4,r15), r7
 	mov.l @(8,r15), r0
 	mov.l @(12,r15), r1
-	trapa #22
 
+	bt    __cp_begin
+	bra   __cp2_begin
+	 nop
+	.align 2
+	.hidden __sh2_abi
+1:	.long __sh2_abi@PCREL
+
+2:
+__cp2_begin:
+	mov.l @r2, r2
+	tst   r2, r2
+	bt    2f
+
+	mov.l 1f, r0
+	.align 2
+	braf  r0
+	 nop
+1:	.long __cancel@PCREL
+
+2:	trapa #38
+__cp2_end:
+	rts
+	 nop
+
+__cp_begin:
+	mov.l @r2, r2
+	tst   r2, r2
+	bt    2f
+
+	mov.l 1f, r0
+	.align 2
+	braf  r0
+	 nop
+1:	.long __cancel@PCREL
+
+2:	trapa #22
 __cp_end:
 	! work around hardware bug
 	or   r0, r0
@@ -40,6 +74,5 @@ __cp_end:
 	or   r0, r0
 	or   r0, r0
 	or   r0, r0
-
 	rts
 	 nop
diff --git a/src/unistd/sh/pipe.s b/src/unistd/sh/pipe.s
index d865ae3..ba3ea10 100644
--- a/src/unistd/sh/pipe.s
+++ b/src/unistd/sh/pipe.s
@@ -2,14 +2,13 @@
 .type   pipe, @function
 pipe:
 	mov    #42, r3
-	trapa  #17
 
-	! work around hardware bug
-	or     r0, r0
-	or     r0, r0
-	or     r0, r0
-	or     r0, r0
-	or     r0, r0
+	mov.l 1f, r2
+	.align 2
+2:	braf r2
+	 nop
+	.hidden __sh_syscall
+1:	.long __sh_syscall@PCREL
 
 	cmp/pz r0
 	bt     1f

[-- Attachment #4: config.mak --]
[-- Type: text/plain, Size: 1039 bytes --]

# This version of config.mak was generated by:
# ./configure --prefix=/opt/sheb-linux-musl/sheb-linux-musl CC=sheb-linux-musl-gcc CFLAGS='-fPIC -m2' --disable-shared
# Any changes made here will be lost if configure is re-run
ARCH = sh
SUBARCH = eb-nofpu
ASMSUBARCH = eb-nofpu
prefix = /opt/sheb-linux-musl/sheb-linux-musl
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
libdir = $(prefix)/lib
includedir = $(prefix)/include
syslibdir = /lib
CC = sheb-linux-musl-gcc
CFLAGS = -Os -pipe -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables -Wa,--noexecstack -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-arith -fPIC -m2
CFLAGS_C99FSE = -std=c99 -nostdinc -ffreestanding -fexcess-precision=standard -frounding-math
CFLAGS_MEMOPS = -fno-tree-loop-distribute-patterns
CFLAGS_NOSSP = -fno-stack-protector
CPPFLAGS = 
LDFLAGS = -Wl,--hash-style=both 
CROSS_COMPILE = 
LIBCC = -lgcc
OPTIMIZE_GLOBS = internal/*.c malloc/*.c string/*.c
SHARED_LIBS =
ALL_TOOLS =
TOOL_LIBS =

[-- Attachment #5: specs.sheb --]
[-- Type: text/plain, Size: 5188 bytes --]

*asm:
%(subtarget_asm_endian_spec) %{mrelax:-relax %(subtarget_asm_relax_spec)}%(subtarget_asm_isa_spec) %(subtarget_asm_spec)%{m2a:--isa=sh2a} %{m2a-single:--isa=sh2a} %{m2a-single-only:--isa=sh2a} %{m2a-nofpu:--isa=sh2a-nofpu} %{m5-compact*:--isa=SHcompact} %{m5-32media*:--isa=SHmedia --abi=32} %{m5-64media*:--isa=SHmedia --abi=64} %{m4al:-dsp} %{mcut2-workaround:-cut2-workaround}

*asm_debug:


*asm_final:


*asm_options:
%{-target-help:%:print-asm-header()} %{v} %{w:-W} %{I*} %a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}

*invoke_as:
%{!fwpa:   %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}   %{!S:-o %|.s |
 as %(asm_options) %m.s %A }  }

*cpp:
 %(subtarget_cpp_spec) 

*cpp_options:
%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps*:-fpch-preprocess}

*cpp_debug_options:
%{d*}

*cpp_unique_options:
%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I %{MD:-MD %{!o:%b.d}%{o*:%.d%*}} %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}} %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}} %{remap} %{g3|ggdb3|gstabs3|gcoff3|gxcoff3|gvms3:-dD} %{!iplugindir*:%{fplugin*:%:find-plugindir()}} %{H} %C %{D*&U*&A*} %{i*} %Z %i %{fmudflap:-D_MUDFLAP -include mf-runtime.h} %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h} %{E|M|MM:%W{o*}}

*trad_capable_cpp:
cc1 -E %{traditional|traditional-cpp:-traditional-cpp}

*cc1:
%{profile:-p}

*cc1_options:
%{D__KERNEL__:;:-fPIE} %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %{!iplugindir*:%{fplugin*:%:find-plugindir()}} %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{aux-info*} %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)}  %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}}  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{Qy:} %{-help:--help} %{-target-help:--target-help} %{-version:--version} %{-help=*:--help=%*} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants} %{coverage:-fprofile-arcs -ftest-coverage}

*cc1plus:


*link_gcc_c_sequence:
%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}

*link_ssp:
%{fstack-protector:}

*endfile:
crtendS.o%s crtn.o%s

*link:
%{!static:--eh-frame-hdr} -m %(link_emul_prefix)%{m5-compact*|m5-32media*:32}%{m5-64media*:64}%{!m1:%{!m2:%{!m3*:%{!m4*:%{!m5*:%(link_default_cpu_emul)}}}}}%(subtarget_link_emul_suffix) %{mrelax:-relax} %(subtarget_link_spec)

*lib:
%{pthread:-lpthread}    %{shared:-lc}    %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}

*mfwrap:
 %{static: %{fmudflap|fmudflapth:  --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc --wrap=mmap --wrap=mmap64 --wrap=munmap --wrap=alloca} %{fmudflapth: --wrap=pthread_create}} %{fmudflap|fmudflapth: --wrap=main}

*mflib:
%{fmudflap|fmudflapth: -export-dynamic}

*link_gomp:


*libgcc:
-lgcc -lgcc_eh

*startfile:
%{!shared:rcrt1.o%s}    crti.o%s crtbeginS.o%s

*cross_compile:
1

*version:
4.7.3

*multilib:
. ;

*multilib_defaults:
mb m1

*multilib_extra:


*multilib_matches:


*multilib_exclusions:


*multilib_options:


*linker:
collect2

*linker_plugin_file:


*lto_wrapper:


*lto_gcc:


*link_libgcc:
%D

*md_exec_prefix:


*md_startfile_prefix:


*md_startfile_prefix_1:


*startfile_prefix_spec:


*sysroot_spec:
--sysroot=%R

*sysroot_suffix_spec:


*sysroot_hdrs_suffix_spec:


*self_spec:


*subtarget_cpp_spec:
   %{posix:-D_POSIX_SOURCE}    %{pthread:-D_REENTRANT -D_PTHREADS} 

*link_emul_prefix:
sh%{ml:l}elf

*link_default_cpu_emul:


*subtarget_link_emul_suffix:
_linux

*subtarget_link_spec:
%{shared:-shared}    %{!static:      %{rdynamic:-export-dynamic}      -dynamic-linker %{mglibc:/lib/ld-linux.so.2;:%{muclibc:/lib/ld-uClibc.so.0;:%{mbionic:/system/bin/linker;:/lib/ld-musl-sheb-nofpu.so.1}}}}    %{static:-static}

*subtarget_asm_endian_spec:
%{ml:-little} %{!ml:-big}

*subtarget_asm_relax_spec:
%{m4*:-isa=sh4-up}

*subtarget_asm_isa_spec:


*subtarget_asm_spec:


*link_command:
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:    %(linker) %{!fno-use-linker-plugin:%{flto|flto=*|fuse-linker-plugin:     -plugin %(linker_plugin_file)     -plugin-opt=%(lto_wrapper)     -plugin-opt=-fresolution=%u.res     %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}}     }}%{flto|flto=*:%<fcompare-debug*}     %{flto} %{flto=*} %l %{pie:} %{!nostdlib:%{!r:%{!shared:-shared -Bsymbolic -Bstatic -z stack-size=131072}}} %X %{o*} %{e*} %{N} %{n} %{r}    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}    %{static:} %{L*} %(mfwrap) %(link_libgcc) %o    %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}    %{fgnu-tm:%:include(libitm.spec)%(link_itm)}    %(mflib)  %{fsplit-stack: --wrap=pthread_create}    %{fprofile-arcs|fprofile-generate*|
 coverage:-lgcov}    %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}    %{!nostdlib:%{!nostartfiles:%E}} %{T*} }}}}}}


  parent reply	other threads:[~2015-06-10  3:30 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-01 15:11 Rich Felker
2015-06-02  6:09 ` Rob Landley
2015-06-02 16:45   ` Rich Felker
2015-06-02 23:49     ` Rich Felker
2015-06-10  3:30 ` Rich Felker [this message]
2015-06-11  4:02   ` Rob Landley
2015-06-11 15:12     ` Rich Felker
2015-06-11 17:22       ` Rich Felker
2015-06-12  4:26         ` Yoshinori Sato
2015-06-12  4:35           ` Rich Felker
2015-06-12  4:49             ` uClinux.org
2015-06-12  6:37               ` Rich Felker
2015-06-12  6:46                 ` D. Jeff Dionne
2015-06-12  4:08       ` Yoshinori Sato
2015-06-12  4:28         ` Rich Felker
2015-06-16  6:38           ` Yoshinori Sato
2015-06-16  7:02             ` Rich Felker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150610033050.GS17573@brightrain.aerifal.cx \
    --to=dalias@libc.org \
    --cc=musl@lists.openwall.com \
    --cc=rob@landley.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).