Package: src:klibc Version: 2.0.2-1 This patch add mips64(el) support for klibc, please consider to merge it.
Thanks. -- Yunqiang Su
Author: Dejan Latinovic <[email protected]> diff --git a/debian/changelog b/debian/changelog index e1cdb9d..6bbed83 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -klibc (2.0.2-1) unstable; urgency=low +klibc (2.0.2-1+mips64.5) unstable; urgency=low * New upstream release (dash, arm) - drop merged patches diff --git a/debian/patches/fix-mips64-port.diff b/debian/patches/fix-mips64-port.diff new file mode 100644 index 0000000..97b851b --- /dev/null +++ b/debian/patches/fix-mips64-port.diff @@ -0,0 +1,596 @@ +--- 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 */ +--- /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 */ +--- /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,@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,@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 */ +--- 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> +--- 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 */ +--- 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 +--- /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) +--- /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) } ++} +--- /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) +--- /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) +--- /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) +--- /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; +--- /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) +--- 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/debian/patches/series b/debian/patches/series index c3df0dc..aa0cb63 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -4,3 +4,4 @@ klibc-linux-libc-dev insmod multiarch-include-path Fix-minimal-mv-to-work-across-fs +fix-mips64-port.diff diff --git a/debian/rules b/debian/rules index ec55d7d..18bb884 100755 --- a/debian/rules +++ b/debian/rules @@ -30,6 +30,9 @@ endif ifneq (,$(findstring $(DEB_HOST_ARCH),mips mipsel)) DEB_MAKE_ENVVARS := ARCH=mips endif +ifneq (,$(findstring $(DEB_HOST_ARCH),mips64 mips64el)) +DEB_MAKE_ENVVARS := ARCH=mips64 +endif ifeq ($(DEB_HOST_ARCH),sh4) DEB_MAKE_ENVVARS := ARCH=sh endif

