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*} }}}}}}
next prev 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).