[klibc] [PATCH] add mips64 support
YunQiang Su
wzssyqa at gmail.com
Mon Mar 10 23:21:32 PDT 2014
From: Dejan Latinovic <Dejan.Latinovic at imgtec.com>
---
usr/include/arch/mips64/klibc/archconfig.h | 3 +
usr/include/arch/mips64/klibc/archsetjmp.h | 39 ++++++
usr/include/arch/mips64/machine/asm.h | 76 ++++++++++
usr/include/fcntl.h | 2 +-
usr/include/sys/md.h | 1 +
usr/include/sys/resource.h | 4 +-
usr/klibc/arch/mips64/Kbuild | 13 +-
usr/klibc/arch/mips64/crt0.S | 25 ++++
usr/klibc/arch/mips64/klibc.ld | 214 +++++++++++++++++++++++++++++
usr/klibc/arch/mips64/pipe.S | 15 ++
usr/klibc/arch/mips64/setjmp.S | 80 +++++++++++
usr/klibc/arch/mips64/syscall.S | 15 ++
usr/klibc/arch/mips64/sysstub.ph | 29 ++++
usr/klibc/arch/mips64/vfork.S | 15 ++
14 files changed, 528 insertions(+), 3 deletions(-)
create mode 100644 usr/include/arch/mips64/klibc/archsetjmp.h
create mode 100644 usr/include/arch/mips64/machine/asm.h
create mode 100644 usr/klibc/arch/mips64/crt0.S
create mode 100644 usr/klibc/arch/mips64/klibc.ld
create mode 100644 usr/klibc/arch/mips64/pipe.S
create mode 100644 usr/klibc/arch/mips64/setjmp.S
create mode 100644 usr/klibc/arch/mips64/syscall.S
create mode 100644 usr/klibc/arch/mips64/sysstub.ph
create mode 100644 usr/klibc/arch/mips64/vfork.S
diff --git a/usr/include/arch/mips64/klibc/archconfig.h b/usr/include/arch/mips64/klibc/archconfig.h
index 4d856a5..b403090 100644
--- a/usr/include/arch/mips64/klibc/archconfig.h
+++ b/usr/include/arch/mips64/klibc/archconfig.h
@@ -15,4 +15,7 @@
/* We can use RT signals on MIPS */
#define _KLIBC_USE_RT_SIG 1
+/* MIPS has architecture-specific code for vfork() */
+#define _KLIBC_REAL_VFORK 1
+
#endif /* _KLIBC_ARCHCONFIG_H */
diff --git a/usr/include/arch/mips64/klibc/archsetjmp.h b/usr/include/arch/mips64/klibc/archsetjmp.h
new file mode 100644
index 0000000..1fbe83e
--- /dev/null
+++ b/usr/include/arch/mips64/klibc/archsetjmp.h
@@ -0,0 +1,39 @@
+/*
+ * arch/mips/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+struct __jmp_buf {
+ unsigned long __s0;
+ unsigned long __s1;
+ unsigned long __s2;
+ unsigned long __s3;
+ unsigned long __s4;
+ unsigned long __s5;
+ unsigned long __s6;
+ unsigned long __s7;
+ unsigned long __gp;
+ unsigned long __sp;
+ unsigned long __s8;
+ unsigned long __ra;
+ unsigned long __f20;
+ unsigned long __f21;
+ unsigned long __f22;
+ unsigned long __f23;
+ unsigned long __f24;
+ unsigned long __f25;
+ unsigned long __f26;
+ unsigned long __f27;
+ unsigned long __f28;
+ unsigned long __f29;
+ unsigned long __f30;
+ unsigned long __f31;
+ unsigned long __fcr31;
+ unsigned long __unused;
+} __attribute__ ((aligned(8)));
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _KLIBC_ARCHSETJMP_H */
diff --git a/usr/include/arch/mips64/machine/asm.h b/usr/include/arch/mips64/machine/asm.h
new file mode 100644
index 0000000..0b8cece
--- /dev/null
+++ b/usr/include/arch/mips64/machine/asm.h
@@ -0,0 +1,76 @@
+/*
+ * arch/mips/include/machine/asm.h
+ */
+
+#ifndef _MACHINE_ASM_H
+#define _MACHINE_ASM_H
+
+/*
+ * Symbolic register names for 32 bit ABI
+ */
+
+#define zero $0 /* wired zero */
+#define AT $1 /* assembler temp - uppercase because of ".set at" */
+#define v0 $2 /* return value */
+#define v1 $3
+#define a0 $4 /* argument registers */
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8 /* caller saved */
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define s0 $16 /* callee saved */
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24 /* caller saved */
+#define t9 $25
+#define jp $25 /* PIC jump register */
+#define k0 $26 /* kernel scratch */
+#define k1 $27
+#define gp $28 /* global pointer */
+#define sp $29 /* stack pointer */
+#define fp $30 /* frame pointer */
+#define s8 $30 /* same like fp! */
+#define ra $31 /* return address */
+
+/*
+ * LEAF - declare leaf routine
+ */
+#define LEAF(symbol) \
+ .globl symbol; \
+ .align 2; \
+ .type symbol, at function; \
+ .ent symbol,0; \
+symbol: .frame sp,0,ra
+
+
+/*
+ * NESTED - declare nested routine entry point
+ */
+#define NESTED(symbol, framesize, rpc) \
+ .globl symbol; \
+ .align 2; \
+ .type symbol, at function; \
+ .ent symbol,0; \
+symbol: .frame sp, framesize, rpc
+
+/*
+ * END - mark end of function
+ */
+#define END(function) \
+ .end function; \
+ .size function,.-function
+
+
+#endif /* _MACHINE_ASM_H */
diff --git a/usr/include/fcntl.h b/usr/include/fcntl.h
index bbd6917..09ba2f2 100644
--- a/usr/include/fcntl.h
+++ b/usr/include/fcntl.h
@@ -9,7 +9,7 @@
#include <klibc/compiler.h>
#include <klibc/seek.h>
#include <sys/types.h>
-#if defined(__mips__) && !defined(__mips64__)
+#if defined(__mips__) && !defined(__mips64)
# include <klibc/archfcntl.h>
#endif
#include <linux/fcntl.h>
diff --git a/usr/include/sys/md.h b/usr/include/sys/md.h
index 184e4aa..7be8ead 100644
--- a/usr/include/sys/md.h
+++ b/usr/include/sys/md.h
@@ -26,6 +26,7 @@
#define LEVEL_FAULTY (-5)
#define MAX_MD_DEVS 256 /* Max number of md dev */
+#include <endian.h>
#include <linux/raid/md_u.h>
#include <linux/raid/md_p.h>
diff --git a/usr/include/sys/resource.h b/usr/include/sys/resource.h
index 5d8bd52..35398a7 100644
--- a/usr/include/sys/resource.h
+++ b/usr/include/sys/resource.h
@@ -12,6 +12,8 @@
__extern int getpriority(int, int);
__extern int setpriority(int, int, int);
-__extern int getrusage(int, struct rusage *);
+#if !defined(__mips64)
+ __extern int getrusage(int, struct rusage *);
+#endif
#endif /* _SYS_RESOURCE_H */
diff --git a/usr/klibc/arch/mips64/Kbuild b/usr/klibc/arch/mips64/Kbuild
index 970c0f8..972e450 100644
--- a/usr/klibc/arch/mips64/Kbuild
+++ b/usr/klibc/arch/mips64/Kbuild
@@ -1,3 +1,14 @@
#
-# klibc files for mips64
+# klibc files for mips
#
+
+klib-y := pipe.o vfork.o setjmp.o syscall.o
+
+klib-y += ../../libgcc/__clzsi2.o ../../libgcc/__ashldi3.o
+klib-y += ../../libgcc/__ashrdi3.o ../../libgcc/__lshrdi3.o
+klib-y += ../../libgcc/__divdi3.o ../../libgcc/__moddi3.o
+klib-y += ../../libgcc/__udivdi3.o ../../libgcc/__umoddi3.o
+klib-y += ../../libgcc/__udivmoddi4.o
+
+always := crt0.o
+targets := crt0.o
diff --git a/usr/klibc/arch/mips64/crt0.S b/usr/klibc/arch/mips64/crt0.S
new file mode 100644
index 0000000..142d9f2
--- /dev/null
+++ b/usr/klibc/arch/mips64/crt0.S
@@ -0,0 +1,25 @@
+#
+# arch/mips/crt0.S
+#
+# Does arch-specific initialization and invokes __libc_init
+# with the appropriate arguments.
+#
+# See __static_init.c or __shared_init.c for the expected
+# arguments.
+#
+
+#include <machine/asm.h>
+
+NESTED(__start, 32, sp)
+ subu sp, 32
+ sw zero, 16(sp)
+
+ lui gp, %hi(_gp) # Initialize gp
+ addiu gp, gp, _gp
+
+ addiu a0, sp, 32 # Pointer to ELF entry structure
+ move a1, v0 # Kernel-provided atexit() pointer
+
+ jal __libc_init
+
+ END(__start)
diff --git a/usr/klibc/arch/mips64/klibc.ld b/usr/klibc/arch/mips64/klibc.ld
new file mode 100644
index 0000000..5a2a7a6
--- /dev/null
+++ b/usr/klibc/arch/mips64/klibc.ld
@@ -0,0 +1,214 @@
+/* Linker script for klibc.so, needed because of the the damned
+ GNU ld script headers problem */
+
+ENTRY(__start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ /* This address needs to be reachable using normal inter-module
+ calls, and work on the memory models for this architecture */
+ /* 2 MB -- the normal starting point for text is 4 MB */
+ . = 0x00200400;
+ .interp : { *(.interp) }
+ .reginfo : { *(.reginfo) }
+ .dynamic : { *(.dynamic) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.dyn :
+ {
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
+ *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
+ *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
+ *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+ }
+ .rela.dyn :
+ {
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
+ *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
+ *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
+ *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init :
+ {
+ KEEP (*(.init))
+ } =0
+ .plt : { *(.plt) }
+ .text :
+ {
+ _ftext = . ;
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.mips16.fn.*) *(.mips16.call.*)
+ } =0
+ .fini :
+ {
+ KEEP (*(.fini))
+ } =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+ .rodata1 : { *(.rodata1) }
+ .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) }
+ .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
+ .eh_frame_hdr : { *(.eh_frame_hdr) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN(8192);
+ /* Ensure the __preinit_array_start label is properly aligned. We
+ could instead move the label definition inside the section, but
+ the linker would then create the section even if it turns out to
+ be empty, which isn't pretty. */
+ . = ALIGN(32 / 8);
+ PROVIDE (__preinit_array_start = .);
+ .preinit_array : { *(.preinit_array) }
+ PROVIDE (__preinit_array_end = .);
+ PROVIDE (__init_array_start = .);
+ .init_array : { *(.init_array) }
+ PROVIDE (__init_array_end = .);
+ PROVIDE (__fini_array_start = .);
+ .fini_array : { *(.fini_array) }
+ PROVIDE (__fini_array_end = .);
+ .data :
+ {
+ _fdata = . ;
+ *(.data .data.* .gnu.linkonce.d.*)
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+ .eh_frame : { KEEP (*(.eh_frame)) }
+ .gcc_except_table : { *(.gcc_except_table) }
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin*.o(.ctors))
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin*.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .jcr : { KEEP (*(.jcr)) }
+ _gp = ALIGN(16) + 0x7ff0;
+ .got : { *(.got.plt) *(.got) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata :
+ {
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ }
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ _fbss = .;
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ PROVIDE (___sbss_start = .);
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ PROVIDE (__sbss_end = .);
+ PROVIDE (___sbss_end = .);
+ }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = .;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+ /DISCARD/ : { *(.note.GNU-stack) }
+}
diff --git a/usr/klibc/arch/mips64/pipe.S b/usr/klibc/arch/mips64/pipe.S
new file mode 100644
index 0000000..932fc08
--- /dev/null
+++ b/usr/klibc/arch/mips64/pipe.S
@@ -0,0 +1,15 @@
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+LEAF(pipe)
+ li v0, __NR_pipe
+ syscall
+ bnez a3, 1f
+ sw v0, (a0)
+ sw v1, 4(a0)
+ li v0, 0
+ b 2f
+1: sw v0, errno
+ li v0, -1
+2: jr ra
+ END(pipe)
diff --git a/usr/klibc/arch/mips64/setjmp.S b/usr/klibc/arch/mips64/setjmp.S
new file mode 100644
index 0000000..68eed19
--- /dev/null
+++ b/usr/klibc/arch/mips64/setjmp.S
@@ -0,0 +1,80 @@
+#
+# arch/mips/setjmp.S
+#
+# setjmp/longjmp for the MIPS architecture
+#
+# The jmp_buf is assumed to contain the following, in order:
+# s0..s7
+# gp
+# sp
+# s8
+# ra
+# f20..f31
+# fcr31
+#
+
+#include <machine/asm.h>
+
+LEAF(setjmp)
+ sw s0, 0(a0)
+ sw s1, 4(a0)
+ sw s2, 8(a0)
+ sw s3, 12(a0)
+ sw s4, 16(a0)
+ sw s5, 20(a0)
+ sw s6, 24(a0)
+ sw s7, 28(a0)
+ sw gp, 32(a0)
+ sw sp, 36(a0)
+ sw s8, 40(a0)
+ sw ra, 44(a0)
+ cfc1 t0,$31
+ swc1 $f20,48(a0)
+ swc1 $f21,52(a0)
+ swc1 $f22,56(a0)
+ swc1 $f23,60(a0)
+ swc1 $f24,64(a0)
+ swc1 $f25,68(a0)
+ swc1 $f26,72(a0)
+ swc1 $f27,76(a0)
+ swc1 $f28,80(a0)
+ swc1 $f29,84(a0)
+ swc1 $f30,88(a0)
+ swc1 $f31,92(a0)
+ sw t0,96(a0)
+ move v0,zero
+ jr ra
+
+ END(setjmp)
+
+LEAF(longjmp)
+ lw s0, 0(a0)
+ lw s1, 4(a0)
+ lw s2, 8(a0)
+ lw s3, 12(a0)
+ lw s4, 16(a0)
+ lw s5, 20(a0)
+ lw s6, 24(a0)
+ lw s7, 28(a0)
+ lw gp, 32(a0)
+ lw sp, 36(a0)
+ lw s8, 40(a0)
+ lw ra, 44(a0)
+ lw t0, 96(a0)
+ lwc1 $f20,48(a0)
+ lwc1 $f21,52(a0)
+ lwc1 $f22,56(a0)
+ lwc1 $f23,60(a0)
+ lwc1 $f24,64(a0)
+ lwc1 $f25,68(a0)
+ lwc1 $f26,72(a0)
+ lwc1 $f27,76(a0)
+ lwc1 $f28,80(a0)
+ lwc1 $f29,84(a0)
+ lwc1 $f30,88(a0)
+ lwc1 $f31,92(a0)
+ ctc1 t0,$31
+ move v0,a1
+ jr ra
+
+ END(longjmp)
diff --git a/usr/klibc/arch/mips64/syscall.S b/usr/klibc/arch/mips64/syscall.S
new file mode 100644
index 0000000..cca0db2
--- /dev/null
+++ b/usr/klibc/arch/mips64/syscall.S
@@ -0,0 +1,15 @@
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+ .set noreorder
+
+LEAF(__syscall_common)
+ syscall
+ beqz a3, 1f
+ # sw is actually two instructions; the first one goes
+ # in the branch delay slot
+ # XXX: Break this up manually; as it is now it generates warnings.
+ sw v0, errno
+ li v0, -1
+1: jr ra
+ END(__syscall_common)
diff --git a/usr/klibc/arch/mips64/sysstub.ph b/usr/klibc/arch/mips64/sysstub.ph
new file mode 100644
index 0000000..3689529
--- /dev/null
+++ b/usr/klibc/arch/mips64/sysstub.ph
@@ -0,0 +1,29 @@
+# -*- perl -*-
+#
+# arch/mips/sysstub.ph
+#
+# Script to generate system call stubs
+#
+
+# On MIPS, most system calls follow the standard convention, with the
+# system call number in r0 (v0), return an error value in r19 (a3) as
+# well as the return value in r0 (v0).
+
+sub make_sysstub($$$$$@) {
+ my($outputdir, $fname, $type, $sname, $stype, @args) = @_;
+
+ $stype = $stype || 'common';
+ open(OUT, '>', "${outputdir}/${fname}.S");
+ print OUT "#include <machine/asm.h>\n";
+ print OUT "#include <asm/unistd.h>\n";
+ print OUT "\n";
+ print OUT "\t.set noreorder\n";
+ print OUT "\n";
+ print OUT "LEAF(${fname})\n";
+ print OUT "\tj\t__syscall_${stype}\n";
+ print OUT "\t li\tv0, __NR_${sname}\n";
+ print OUT "\tEND(${fname})\n";
+ close(OUT);
+}
+
+1;
diff --git a/usr/klibc/arch/mips64/vfork.S b/usr/klibc/arch/mips64/vfork.S
new file mode 100644
index 0000000..9aa955a
--- /dev/null
+++ b/usr/klibc/arch/mips64/vfork.S
@@ -0,0 +1,15 @@
+#include <machine/asm.h>
+#include <asm/unistd.h>
+
+#define CLONE_VM 0x00000100
+#define CLONE_VFORK 0x00004000
+#define SIGCHLD 18
+
+ .set noreorder
+
+LEAF(vfork)
+ li a0, CLONE_VFORK | CLONE_VM | SIGCHLD
+ li a1, 0
+ j __syscall_common
+ li v0, __NR_clone
+ END(vfork)
--
1.8.3.4 (Apple Git-47)
More information about the klibc
mailing list