From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/7919 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: Moving forward with sh2/nommu Date: Tue, 9 Jun 2015 23:30:50 -0400 Message-ID: <20150610033050.GS17573@brightrain.aerifal.cx> References: <20150601151107.GA20759@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="YZVh52eu0Ophig4D" X-Trace: ger.gmane.org 1433907070 7686 80.91.229.3 (10 Jun 2015 03:31:10 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 10 Jun 2015 03:31:10 +0000 (UTC) Cc: rob@landley.net Bcc: "D. Jeff Dionne" To: musl@lists.openwall.com Original-X-From: musl-return-7932-gllmg-musl=m.gmane.org@lists.openwall.com Wed Jun 10 05:31:09 2015 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1Z2WjM-0005WT-9T for gllmg-musl@m.gmane.org; Wed, 10 Jun 2015 05:31:08 +0200 Original-Received: (qmail 26194 invoked by uid 550); 10 Jun 2015 03:31:06 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 26165 invoked from network); 10 Jun 2015 03:31:04 -0000 Content-Disposition: inline In-Reply-To: <20150601151107.GA20759@brightrain.aerifal.cx> User-Agent: Mutt/1.5.21 (2010-09-15) Original-Sender: Rich Felker Xref: news.gmane.org gmane.linux.lib.musl.general:7919 Archived-At: --YZVh52eu0Ophig4D Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 --YZVh52eu0Ophig4D Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="fdpic_elf_loader.diff" --- 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 --YZVh52eu0Ophig4D Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="musl_sh2_v2.diff" 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 + +/* 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 --YZVh52eu0Ophig4D Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="config.mak" # 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 = --YZVh52eu0Ophig4D Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="specs.sheb" *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=*:%