提交 1c8eb8ba 编写于 作者: R rofl0r

PPC port cleaned up, static linking works well now.

上级 7669d1e3
......@@ -55,7 +55,7 @@
#define ENOANO 55
#define EBADRQC 56
#define EBADSLT 57
#define EDEADLOCK EDEADLK
#define EDEADLOCK 58
#define EBFONT 59
#define ENOSTR 60
#define ENODATA 61
......
......@@ -12,8 +12,8 @@
#define O_CLOEXEC 02000000
#define O_ASYNC 020000
#define O_DIRECT 0200000
#define O_LARGEFILE 0400000
#define O_DIRECT 0400000
#define O_LARGEFILE 0200000
#define O_NOATIME 01000000
#define O_NDELAY O_NONBLOCK
......@@ -31,3 +31,7 @@
#define F_GETLK 12
#define F_SETLK 13
#define F_SETLKW 14
#define F_SETOWN_EX 15
#define F_GETOWN_EX 16
#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) )
//#define _IOC(a,b,c,d) ( ((a)<<29) | ((b)<<8) | (c) | ((d)<<16) )
//
#define _IOC_SIZEBITS 13
#define _IOC_DIRBITS 3
#define _IOC_NRBITS 8
#define _IOC_TYPEBITS 8
#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
#define _IOC_NONE 1U
#define _IOC_WRITE 2U
#define _IOC_READ 4U
#define _IOC_WRITE 4U
#define _IOC_READ 2U
#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
#define _IOW(a,b,c) _IOC(1,(a),(b),sizeof(c))
#define _IOR(a,b,c) _IOC(2,(a),(b),sizeof(c))
#define _IOWR(a,b,c) _IOC(4,(a),(b),sizeof(c))
#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
#define _IOR(a,b,c) _IOC(_IOC_READ ,(a),(b),sizeof(c))
#define _IOWR(a,b,c) _IOC(_IOC_READ | _IOC_WRITE,(a),(b),sizeof(c))
#define TCGETS 0x5401
#define TCSETS 0x5402
......
......@@ -10,3 +10,6 @@ struct ipc_perm
long __pad1;
long __pad2;
};
#define IPC_64 0x100
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE)
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
typedef unsigned long gregset_t[48];
typedef struct {
double fpregs[32];
double fpscr;
unsigned _pad[2];
} fpregset_t;
typedef struct {
unsigned vrregs[32][4];
unsigned vrsave;
unsigned _pad[2];
unsigned vscr;
} vrregset_t;
typedef struct {
unsigned long __regs[21];
gregset_t gregs;
fpregset_t fpregs;
vrregset_t vrregs __attribute__((__aligned__(16)));
} mcontext_t;
typedef struct __ucontext {
unsigned long uc_flags;
struct __ucontext *uc_link;
stack_t uc_stack;
mcontext_t uc_mcontext;
int uc_pad[7];
struct mcontext_t *uc_regs;
sigset_t uc_sigmask;
unsigned long uc_regspace[128];
int uc_maskext[30];
int uc_pad2[3];
mcontext_t uc_mcontext;
char uc_reg_space[sizeof(mcontext_t) + 12];
} ucontext_t;
#define SA_NOCLDSTOP 1
#define SA_NOCLDWAIT 2
#define SA_SIGINFO 4
#define SA_ONSTACK 0x08000000
#define SA_RESTART 0x10000000
#define SA_NODEFER 0x40000000
#define SA_RESETHAND 0x80000000
#define SA_RESTORER 0x04000000
#define SA_NOCLDSTOP 1U
#define SA_NOCLDWAIT 2U
#define SA_SIGINFO 4U
#define SA_ONSTACK 0x08000000U
#define SA_RESTART 0x10000000U
#define SA_NODEFER 0x40000000U
#define SA_RESETHAND 0x80000000U
#define SA_RESTORER 0x04000000U
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
#ifdef _GNU_SOURCE
struct sigcontext
{
unsigned long trap_no, error_code, oldmask;
unsigned long arm_r0, arm_r1, arm_r2, arm_r3;
unsigned long arm_r4, arm_r5, arm_r6, arm_r7;
unsigned long arm_r8, arm_r9, arm_r10, arm_fp;
unsigned long arm_ip, arm_sp, arm_lr, arm_pc;
unsigned long arm_cpsr, fault_address;
unsigned long _unused[4];
int signal;
unsigned long handler;
unsigned long oldmask;
void *regs; /* originally struct pt_regs _user *regs,
pt_regs is defined in arch/powerpc/include/asm/ptrace.h */
gregset_t gp_regs;
fpregset_t fp_regs;
vrregset_t *v_regs;
long vmx_reserve[33+33+32+1]; /* 33=34 for ppc64 */
};
#define NSIG 64
#endif
......@@ -44,6 +73,7 @@ struct sigcontext
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGIOT 6
#define SIGBUS 7
#define SIGFPE 8
#define SIGKILL 9
......@@ -71,7 +101,3 @@ struct sigcontext
#define SIGPWR 30
#define SIGSYS 31
#define SIGUNUSED SIGSYS
#ifdef _BSD_SOURCE
#define SIGINFO SIGUSR1 /* For NetBSD compatability */
#endif
struct msghdr
{
void *msg_name;
int msg_namelen;
struct iovec *msg_iov;
unsigned long msg_iovlen;
void *msg_control;
unsigned long msg_controllen;
unsigned msg_flags;
};
#define SO_DEBUG 1
#define SO_REUSEADDR 2
#define SO_TYPE 3
#define SO_ERROR 4
#define SO_DONTROUTE 5
#define SO_BROADCAST 6
#define SO_SNDBUF 7
#define SO_RCVBUF 8
#define SO_SNDBUFFORCE 32
#define SO_RCVBUFFORCE 33
#define SO_KEEPALIVE 9
#define SO_OOBINLINE 10
#define SO_NO_CHECK 11
#define SO_PRIORITY 12
#define SO_LINGER 13
#define SO_BSDCOMPAT 14
#define SO_RCVLOWAT 16
#define SO_SNDLOWAT 17
#define SO_RCVTIMEO 18
#define SO_SNDTIMEO 19
#define SO_PASSCRED 20
#define SO_PEERCRED 21
此差异已折叠。
static inline struct pthread *__pthread_self()
{
register char* tp __asm__("r2");
return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
}
#define TLS_ABOVE_TP
#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
// offset of the PC register in mcontext_t, divided by the system wordsize
// the kernel calls the ip "nip", it's the first saved value after the 32
// GPRs.
#define CANCEL_REG_IP 32
#include <string.h>
#include <elf.h>
#define ETC_LDSO_PATH "/etc/ld-musl-powerpc.path"
#define IS_COPY(x) ((x)==R_PPC_COPY)
#define IS_PLT(x) ((x)==R_PPC_JMP_SLOT)
// see linux' arch/powerpc/include/asm/elf.h
static inline void do_single_reloc(
struct dso *self, unsigned char *base_addr,
size_t *reloc_addr, int type, size_t addend,
Sym *sym, size_t sym_size,
struct symdef def, size_t sym_val)
{
switch(type) {
case R_PPC_GLOB_DAT:
case R_PPC_JMP_SLOT:
*reloc_addr = sym_val;
break;
case R_PPC_REL32:
if (sym_val) *reloc_addr += sym_val;
else *reloc_addr += (size_t)base_addr;
break;
case R_PPC_COPY:
memcpy(reloc_addr, (void *)sym_val, sym_size);
break;
case R_PPC_RELATIVE:
*reloc_addr += (size_t)base_addr;
break;
//case R_PPC64_DTPMOD64: //R_X86_64_DTPMOD64:
case R_PPC_DTPMOD32: //R_386_TLS_DTPMOD32:
*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
break;
}
}
#define __SYSCALL_LL_E(x) \
((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
((union { long long ll; long l[2]; }){ .ll = x }).l[1]
#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
#define _NSIG 64
#define __SYSCALL_SSLEN (_NSIG/8)
long (__syscall)(long, ...);
static inline long __syscall0(long n)
{
return (__syscall)(n, 0, 0, 0, 0, 0, 0);
}
static inline long __syscall1(long n, long a)
{
return (__syscall)(n, a, 0, 0, 0, 0, 0);
}
static inline long __syscall2(long n, long a, long b)
{
return (__syscall)(n, a, b, 0, 0, 0, 0);
}
static inline long __syscall3(long n, long a, long b, long c)
{
return (__syscall)(n, a, b, c, 0, 0, 0);
}
static inline long __syscall4(long n, long a, long b, long c, long d)
{
return (__syscall)(n, a, b, c, d, 0, 0);
}
static inline long __syscall5(long n, long a, long b, long c, long d, long e)
{
return (__syscall)(n, a, b, c, d, e, 0);
}
static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
{
return (__syscall)(n, a, b, c, d, e, f);
}
#define __SC_socket 1
#define __SC_bind 2
#define __SC_connect 3
#define __SC_listen 4
#define __SC_accept 5
#define __SC_getsockname 6
#define __SC_getpeername 7
#define __SC_socketpair 8
#define __SC_send 9
#define __SC_recv 10
#define __SC_sendto 11
#define __SC_recvfrom 12
#define __SC_shutdown 13
#define __SC_setsockopt 14
#define __SC_getsockopt 15
#define __SC_sendmsg 16
#define __SC_recvmsg 17
/* $NetBSD: asm.h,v 1.29 2010/03/09 22:36:41 matt Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
* Copyright (C) 1995, 1996 TooLs GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by TooLs GmbH.
* 4. The name of TooLs GmbH may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PPC_BITS_ASM_H_
#define _PPC_BITS_ASM_H_
#define cr0 0
#define cr1 1
#define cr2 2
#define cr3 3
#define cr4 4
#define cr5 5
#define cr6 6
#define cr7 7
/* General Purpose Registers (GPRs) */
#define r0 0
#define r1 1
#define r2 2
#define r3 3
#define r4 4
#define r5 5
#define r6 6
#define r7 7
#define r8 8
#define r9 9
#define r10 10
#define r11 11
#define r12 12
#define r13 13
#define r14 14
#define r15 15
#define r16 16
#define r17 17
#define r18 18
#define r19 19
#define r20 20
#define r21 21
#define r22 22
#define r23 23
#define r24 24
#define r25 25
#define r26 26
#define r27 27
#define r28 28
#define r29 29
#define r30 30
#define r31 31
/* Floating Point Registers (FPRs) */
#define fr0 0
#define fr1 1
#define fr2 2
#define fr3 3
#define fr4 4
#define fr5 5
#define fr6 6
#define fr7 7
#define fr8 8
#define fr9 9
#define fr10 10
#define fr11 11
#define fr12 12
#define fr13 13
#define fr14 14
#define fr15 15
#define fr16 16
#define fr17 17
#define fr18 18
#define fr19 19
#define fr20 20
#define fr21 21
#define fr22 22
#define fr23 23
#define fr24 24
#define fr25 25
#define fr26 26
#define fr27 27
#define fr28 28
#define fr29 29
#define fr30 30
#define fr31 31
#endif /* _PPC_BITS_ASM_H_ */
struct msghdr
{
void *msg_name;
socklen_t msg_namelen;
struct iovec *msg_iov;
int msg_iovlen;
void *msg_control;
socklen_t msg_controllen;
int msg_flags;
};
此差异已折叠。
typedef pthread_t (*__pthread_self_func_t)(void) __attribute__((const));
#define __pthread_self ((__pthread_self_func_t)0xffff0fe0)
#define CANCEL_REG_SP 16
#define CANCEL_REG_IP 18
#include <string.h>
#include <elf.h>
#define ETC_LDSO_PATH "/etc/ld-musl-arm.path"
#define IS_COPY(x) ((x)==R_ARM_COPY)
#define IS_PLT(x) ((x)==R_ARM_JUMP_SLOT)
static inline void do_single_reloc(size_t *reloc_addr, int type, size_t sym_val, size_t sym_size, unsigned char *base_addr, size_t addend)
{
switch(type) {
case R_ARM_ABS32:
*reloc_addr += sym_val;
break;
case R_ARM_GLOB_DAT:
case R_ARM_JUMP_SLOT:
*reloc_addr = sym_val;
break;
case R_ARM_RELATIVE:
*reloc_addr += (size_t)base_addr;
break;
case R_ARM_COPY:
memcpy(reloc_addr, (void *)sym_val, sym_size);
break;
}
}
......@@ -203,6 +203,7 @@ i?86*) ARCH=i386 ;;
x86_64*) ARCH=x86_64 ;;
mips-*|mipsel-*) ARCH=mips ;;
microblaze-*) ARCH=microblaze ;;
powerpc-*) ARCH=powerpc ;;
unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
*) fail "$0: unknown or unsupported target \"$target\"" ;;
esac
......
.weak _init
.weak _fini
.global _start
.type _start, %function
_start:
mr 9, 1 # Save the original stack pointer.
clrrwi 1, 1, 4 # Align the stack to 16 bytes.
lis 13, _SDA_BASE_@ha # r13 points to the small data area.
addi 13, 13, _SDA_BASE_@l
li 0, 0 # Zero the frame pointer.
stwu 1, -16(1) # The initial stack frame.
mtlr 0 # Clear the link register.
stw 0, 0(1) # And save it.
lis 3, main@ha # Get main() ...
addi 3, 3, main@l
lwz 4, 0(9) # and argc...
addi 5, 9, 4 # and argv ...
lis 6, _init@ha # and _init() ...
addi 6, 6, _init@l
lis 7, _fini@ha # and _fini() ...
addi 7, 7, _fini@l
li 8, 0 # ldso_fini == NULL
bl __libc_start_main # Let's go!
b . # Never gets here.
.end _start
.size _start, .-_start
#include <bits/asm.h>
.weak _init
.weak _fini
.global _start
.type _start, %function
_start:
mr r9, r1 // Save the original stack pointer.
clrrwi r1, r1, 4 // Align the stack to 16 bytes.
lis r13, _SDA_BASE_@ha // r13 points to the small data area.
addi r13, r13, _SDA_BASE_@l //
li r0, 0 // Zero the frame pointer.
stwu r1, -16(r1) // The initial stack frame.
mtlr r0 // Clear the link register.
stw r0, 0(r1) // And save it.
lis r3, main@ha // Get main() ...
addi r3, r3, main@l
lwz r4, 0(r9) // and argc...
addi r5, r9, 4 // and argv ...
lis r6, _init@ha // and _init() ...
addi r6, r6, _init@l
lis r7, _fini@ha // and _fini() ...
addi r7, r7, _fini@l
li r8, 0 // ldso_fini == NULL
bl __libc_start_main // Let's go!
b . // Never gets here.
.end _start
.size _start, .-_start
.global __syscall
.type __syscall,@function
__syscall:
mr 0, 3 # Save the system call number
mr 3, 4 # Shift the arguments: arg1
mr 4, 5 # arg2
mr 5, 6 # arg3
mr 6, 7 # arg4
mr 7, 8 # arg5
mr 8, 9 # arg6
sc
bnslr+ # return if not summary overflow
#else error:
# return negated value.
neg 3, 3
blr
.end __syscall
.size __syscall, .-__syscall
#include <bits/asm.h>
.global __syscall
.type __syscall,@function
__syscall:
mflr r0
stw r0, -4(r1) // Save the return address.
mr r0, r3 // Save the system call number
mr r3, r4 // Shift the arguments: arg1
mr r4, r5 // arg2
mr r5, r6 // arg3
mr r6, r7 // arg4
mr r7, r8 // arg5
mr r8, r9 // arg6
sc
mfcr r0 // Check for an error
rlwinm r4, r0, r0, 3, 3 // by checking for bit 28.
cmplwi r0, r4, 0 // It is an error if non-zero.
beq r0, 1f // Jump if not an error.
neg r3, r3 // Negate the error number.
1: lwz r0, -4(r1) // Restore the return address.
mtlr r0
blr
.end __syscall
.size __syscall, .-__syscall
#include <bits/asm.h>
.text
.global dlsym
.type dlsym,@function
dlsym:
mflr r5 // The return address is arg3.
mflr 5 # The return address is arg3.
b __dlsym
.end dlsym
.size dlsym, .-dlsym
# FIXME : does not work, the small data array needs to be relocated.
# see elfspec_ppc.pdf, page 76-84
.global _start
.type _start,@function
_start:
mr 9, 1 # Save the original stack pointer.
clrrwi 1, 1, 4 # Align the stack to 16 bytes.
lis 13, _SDA_BASE_@ha # r13 points to the small data area.
addi 13, 13, _SDA_BASE_@l
li 0, 0 # Zero the frame pointer.
lwz 3, 0(9) # and argc...
addi 4, 9, 4 # and argv ...
mtlr 0 # Clear the link register.
# Go to the musl dynamic linker entry point.
bl __dynlink
cmpi 4, 0, 3, 1 # Check for a 1.
bne 4, . # Stay here
mtlr 3 # Set the link address...
li 3, 0
blr # and go.
.end _start
.size _start, .-_start
#include <bits/asm.h>
.global _start
.type _start,@function
_start:
mr r9, r1 // Save the original stack pointer.
clrrwi r1, r1, 4 // Align the stack to 16 bytes.
lis r13, _SDA_BASE_@ha // r13 points to the small data area.
addi r13, r13, _SDA_BASE_@l //
li r0, 0 // Zero the frame pointer.
lwz r3, 0(r9) // and argc...
addi r4, r9, 4 // and argv ...
mtlr r0 // Clear the link register.
// Go to the musl dynamic linker entry point.
bl __dynlink
cmpi r4, 0, r3, 1 // Check for a 1.
bne r4, . // Stay here
mtlr r3 // Set the link address...
li r3, 0
blr // and go.
.end _start
.size _start, .-_start
.global _longjmp
.global longjmp
.type _longjmp,@function
.type longjmp,@function
_longjmp:
longjmp:
# void longjmp(jmp_buf env, int val);
# put val into return register and restore the env saved in setjmp
# if val(r4) is 0, put 1 there.
# 0) move old return address into r0
lwz 0, 0(3)
# 1) put it into link reg
mtlr 0
#2 ) restore stack ptr
lwz 1, 4(3)
#3) restore control reg
lwz 0, 8(3)
mtcr 0
#4) restore r14-r31
lwz 14, 12(3)
lwz 15, 16(3)
lwz 16, 20(3)
lwz 17, 24(3)
lwz 18, 28(3)
lwz 19, 32(3)
lwz 20, 36(3)
lwz 21, 40(3)
lwz 22, 44(3)
lwz 23, 48(3)
lwz 24, 52(3)
lwz 25, 56(3)
lwz 26, 60(3)
lwz 27, 64(3)
lwz 28, 68(3)
lwz 29, 72(3)
lwz 30, 76(3)
lwz 31, 80(3)
#5) put val into return reg r3
mr 3, 4
#6) check if return value is 0, make it 1 in that case
cmpwi cr7, 4, 0
bne cr7, 1f
li 3, 1
1:
blr
.global __setjmp
.global _setjmp
.global setjmp
.type __setjmp,@function
.type _setjmp,@function
.type setjmp,@function
__setjmp:
_setjmp:
setjmp:
# 0) store IP int 0, then into the jmpbuf pointed to by r3 (first arg)
mflr 0
stw 0, 0(3)
# 1) store reg1 (SP)
stw 1, 4(3)
# 2) store cr
mfcr 0
stw 0, 8(3)
# 3) store r14-31
stw 14, 12(3)
stw 15, 16(3)
stw 16, 20(3)
stw 17, 24(3)
stw 18, 28(3)
stw 19, 32(3)
stw 20, 36(3)
stw 21, 40(3)
stw 22, 44(3)
stw 23, 48(3)
stw 24, 52(3)
stw 25, 56(3)
stw 26, 60(3)
stw 27, 64(3)
stw 28, 68(3)
stw 29, 72(3)
stw 30, 76(3)
stw 31, 80(3)
# 4) set return value to 0
li 3, 0
# 5) return
blr
#include <bits/asm.h>
.global _longjmp
.global longjmp
.type _longjmp,@function
.type longjmp,@function
_longjmp:
longjmp:
cmpi 7, 0, r3, 0
bne 7, 1f
addi r3, r3, 1
1: lmw r8, 4(r3) // load r8-r31
mr r6, r4
mtlr r11
mtcr r12
mr r2, r9
mr r1, r10
blr
#include <bits/asm.h>
.global __setjmp
.global _setjmp
.global setjmp
.type __setjmp,@function
.type _setjmp,@function
.type setjmp,@function
__setjmp:
_setjmp:
setjmp:
mflr r11
mfcr r12
mr r10, r1
mr r9, r2
stmw r8, 0(r3) // save r8-r31
li r3,0
blr
#include <bits/asm.h>
#include <bits/syscall.h>
.global __restore
.type __restore,@function
.type __restore,%function
__restore:
li r0, __NR_sigreturn
li 0, 119 #__NR_sigreturn
sc
.global __restore_rt
.type __restore_rt,@function
.type __restore_rt,%function
__restore_rt:
li r0, __NR_rt_sigreturn
li 0, 172 # __NR_rt_sigreturn
sc
.global sigsetjmp
.type sigsetjmp,%function
sigsetjmp:
#int sigsetjmp(sigjmp_buf buf, int save)
# r3 r4
#0) store save into buf->__fl
stw 4, 256(3)
#1) compare save with 0
cmpwi cr7, 4, 0
#2) if its 0, goto setjmp code
beq- cr7, 1f
#3) else: we must call pthread_sigmask(SIG_SETMASK, 0, (sigset_t *)buf->__ss);
# thus store r3 on the stack, to restore it later
stw 3, -4(1)
# store old link reg
mflr 0
stw 0, -8(1)
# increase stack frame by 16
subi 1, 1, 16
# put pointer to ss buf into r5 (3rd arg)
addi 5, 3, 260
# put "2" i.e. SIG_SETMASK in r3
li 3, 2
li 4, 0
bl pthread_sigmask
#restore sp
addi 1, 1, 16
#restore r3
lwz 3, -4(1)
#restore link reg
lwz 0, -8(1)
mtlr 0
1:
b setjmp
#include <bits/asm.h>
.global sigsetjmp
.type sigsetjmp,@function
sigsetjmp:
lwz r4, 64*4-2*4(r3) // Second last long.
cmpi r4, 0, r4, 0
bne r4, 1f
addi r5, r3, 64*4-1*4 // Address of last long.
li r4, 0
li r3, 2
bl sigprocmask
1: b setjmp
.text
.global __set_thread_area
.type __set_thread_area, %function
__set_thread_area:
# mov pointer in reg3 into r2
mr 2, 3
# put 0 into return reg
li 3, 0
# return
blr
#include <bits/asm.h>
#include <bits/syscall.h>
.text
.global __unmapself
.type __unmapself,%function
__unmapself:
li r0, __NR_munmap
li 0, 91 # __NR_munmap
sc
li r0, __NR_exit
li 0, 1 #__NR_exit
sc
blr
.text
.global __clone
.type __clone, %function
__clone:
# int clone(fn, stack, flags, arg, ptid, tls, ctid)
# a b c d e f g
# 3 4 5 6 7 8 9
# pseudo C code:
# tid = syscall(SYS_clone,c,b,e,f,g);
# if (!tid) syscall(SYS_exit, a(d));
# return tid;
# SYS_clone = 120
# SYS_exit = 1
# in order that the child can find the start func and its arg, we need to store it into
# non-volative regs. to do so, we have to store those 2 regs into our stackframe, so
# we can restore them later.
stw 30, -4(1)
stw 31, -8(1)
subi 1, 1, 16
# save r3 (func) into r30, and r6(arg) into r31
mr 30, 3
mr 31, 6
#move c into first arg
mr 3, 5
#mr 4, 4
mr 5, 7
mr 6, 8
mr 7, 9
# move syscall number into r0
li 0, 120
sc
# check for syscall error
#this code should be more efficient, but it borks
#bns+ 1f # jump to label 1 if no summary overflow.
#else
#neg 3, 3 #negate the result (errno)
#b 2f # jump to epilogue
# this error check code at least does not spoil the clone call.
#mfcr 0 # Check for an error
#rlwinm 4, 0, 0, 3, 3 # by checking for bit 28.
#cmplwi 0, 4, 0 # It is an error if non-zero.
#beq 0, 1f # Jump if not an error.
#neg 3, 3 # Negate the error number.
#b 2f # jump to epilogue
1:
# compare sc result with 0
cmpwi cr7, 3, 0
# if not 0, jump to end
bne cr7, 2f
#else: we're the child
#call funcptr
# move arg (d) into r3
mr 3, 31
#move r30 (funcptr) into CTR reg
mtctr 30
# call CTR reg
bctrl
# mov SYS_exit into r0 (the exit param is already in r3)
li 0, 1
sc
2:
# restore stack
addi 1, 1, 16
lwz 30, -4(1)
lwz 31, -8(1)
blr
#r0: volatile. may be modified during linkage.
#r1: stack frame: 16 byte alignment.
#r2: tls/thread pointer on pp32
#r3,r4: return values, first args
#r5-r10: args
#r11-r12: volatile. may be modified during linkage
#r13: "small data area" pointer
#r14 - r30: local vars
#r31: local or environment pointer
#r1, r14-31: belong to the caller, must be saved and restored
#r0, r3-r12, ctr, xer: volatile, not preserved
#r0,r11,r12: may be altered by cross-module call,
#"a func cannot depend on that these regs have the values placed by the caller"
#the fields CR2,CR2,CR4 of the cond reg must be preserved
#LR (link reg) shall contain the funcs return address
.text
.global __syscall_cp_asm
.type __syscall_cp_asm,%function
__syscall_cp_asm:
# at enter: r3 = pointer to self->cancel, r4: syscall no, r5: first arg, r6: 2nd, r7: 3rd, r8: 4th, r9: 5th, r10: 6th
.global __cp_begin
__cp_begin:
# r3 holds first argument, its a pointer to self->cancel.
# we must compare the dereferenced value with 0 and jump to __cancel if its not
lwz 0, 0(3) #deref pointer into r0
cmpwi cr7, 0, 0 #compare r0 with 0, store result in cr7.
beq+ cr7, 1f #jump to label 1 if r0 was 0
b __cancel #else call cancel
# (the return address is not needed, since __cancel never returns)
1:
#ok, the cancel flag was not set
# syscall: number goes to r0, the rest 3-8
mr 0, 4 # put the system call number into r0
mr 3, 5 # Shift the arguments: arg1
mr 4, 6 # arg2
mr 5, 7 # arg3
mr 6, 8 # arg4
mr 7, 9 # arg5
mr 8, 10 # arg6
sc
.global __cp_end
__cp_end:
bnslr+ # return if no summary overflow.
#else negate result.
neg 3, 3
blr
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册