[uClibc-cvs] uClibc/libc/sysdeps/linux/frv Makefile, NONE, 1.1 __init_brk.c, NONE, 1.1 __longjmp.S, NONE, 1.1 _mmap.c, NONE, 1.1 brk.c, NONE, 1.1 clone.S, NONE, 1.1 crt0.S, NONE, 1.1 crti.S, NONE, 1.1 crtn.S, NONE, 1.1 crtreloc.c, NONE, 1.1 dl-iterate-phdr.c, NONE, 1.1 sbrk.c, NONE, 1.1 setjmp.S, NONE, 1.1 sysdep.c, NONE, 1.1 vfork.S, NONE, 1.1

Erik Andersen andersen at uclibc.org
Wed Feb 18 08:04:52 UTC 2004


Update of /var/cvs/uClibc/libc/sysdeps/linux/frv
In directory nail:/tmp/cvs-serv7699/libc/sysdeps/linux/frv

Added Files:
	Makefile __init_brk.c __longjmp.S _mmap.c brk.c clone.S crt0.S 
	crti.S crtn.S crtreloc.c dl-iterate-phdr.c sbrk.c setjmp.S 
	sysdep.c vfork.S 
Log Message:
Alexandre Oliva writes:

This patch adds code to uClibc to support a new ABI designed for the
FR-V architecture, that enables text segments of executables and
shared libraries to be shared by multiple processes on an OS such as
uClinux, that can run on FR-V processors without an MMU.

Patches for binutils and GCC have just been posted in the
corresponding mailing lists.  The binutils patch was approved,
but there's one additional patch pending review, that I posted
this week.  An updated GCC patch will be posted to
gcc-patches at gcc.gnu.org as soon as I complete testing (I used a
known-good compiler to test the uClibc patch below).

Since the existing dynamic loader code didn't support independent
relocation of segments, it required changes that were somewhat
extensive.  I've added a number of new machine-specific macros to try
to keep the platform and ABI-specific details outside the generic
code.  I hope this is not a problem.



--- NEW FILE: crti.S ---
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.  */

	.section .init,"x"
	.p2align 2
	.globl _init
	.type	_init, @function
_init:
	addi sp,#-16,sp
	st.p fp, @(sp,gr0)
	mov sp, fp
	movsg lr, gr5
	sti gr15, @(fp,4) 
	sti gr5, @(fp,8)
	
	.section .fini,"x"
	.p2align 2
	.globl _fini
	.type	_fini, @function
_fini:
	addi sp,#-16,sp
	st.p fp, @(sp,gr0)
	mov sp, fp
	movsg lr, gr5
	sti gr15, @(fp,4)
	sti gr5, @(fp,8)

--- NEW FILE: crtreloc.c ---
/* Copyright (C) 2003 Free Software Foundation, Inc.
   written by Alexandre Oliva <aoliva at redhat.com>
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.  */

#define _GNU_SOURCE
#include <link.h>

#include <sys/types.h>

#include <elf.h>
#include <bits/elf-fdpic.h>

/* This file is to be compiled into crt object files, to enable
   executables to easily self-relocate.  */

#define hidden __attribute__((__visibility__("hidden")))

/* Compute the runtime address of pointer in the range [p,e), and then
   map the pointer pointed by it.  */
inline static void ***
reloc_range_indirect (void ***p, void ***e,
		      const struct elf32_fdpic_loadmap *map)
{
  while (p < e)
    {
      void *ptr = __reloc_pointer (*p, map);
      if (ptr)
	{
	  void *pt;
	  if ((long)ptr & 3)
	    __builtin_memcpy(&pt, ptr, sizeof(pt));
	  else
	    pt = *(void**)ptr;
	  pt = __reloc_pointer (pt, map);
	  if ((long)ptr & 3)
	    __builtin_memcpy(ptr, &pt, sizeof(pt));
	  else
	    *(void**)ptr = pt;
	}
      p++;
    }
  return p;
}

/* Call __reloc_range_indirect for the given range except for the last
   entry, whose contents are only relocated.  It's expected to hold
   the GOT value.  */
void* hidden
__self_reloc (const struct elf32_fdpic_loadmap *map,
	      void ***p, void ***e)
{
  p = reloc_range_indirect (p, e-1, map);

  if (p >= e)
    return (void*)-1;
  
  return __reloc_pointer (*p, map);
}

#if 0
/* These are other functions that might be useful, but that we don't
   need.  */

/* Remap pointers in [p,e).  */
inline static void**
reloc_range (void **p, void **e,
	     const struct elf32_fdpic_loadmap *map)
{
  while (p < e)
    {
      *p = __reloc_pointer (*p, map);
      p++;
    }
  return p;
}

/* Remap p, adjust e by the same offset, then map the pointers in the
   range determined by them.  */
void hidden
__reloc_range (const struct elf32_fdpic_loadmap *map,
	       void **p, void **e)
{
  void **old = p;

  p = __reloc_pointer (p, map);
  e += p - old;
  reloc_range (p, e, map);
}

/* Remap p, adjust e by the same offset, then map pointers referenced
   by the (unadjusted) pointers in the range.  Return the relocated
   value of the last pointer in the range.  */
void* hidden
__reloc_range_indirect (const struct elf32_fdpic_loadmap *map,
			void ***p, void ***e)
{
  void ***old = p;

  p = __reloc_pointer (p, map);
  e += p - old;
  return reloc_range_indirect (p, e, map);
}
#endif

--- NEW FILE: setjmp.S ---
#include <features.h>
#define _SETJMP_H
#define _ASM
#include <bits/setjmp.h>

	.text

/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
   We cannot do it in C because it must be a tail-call, so frame-unwinding
   in setjmp doesn't clobber the state restored by longjmp.  */

	.global _setjmp
	.type	_setjmp, at function
_setjmp:
	setlos	#0, gr9
	bra	.Lsigsetjmp_intern
	.size	_setjmp,.-_setjmp
	
/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
   We cannot do it in C because it must be a tail-call, so frame-unwinding
   in setjmp doesn't clobber the state restored by longjmp.  */

	.align 4
	.type	setjmp, at function
	.globl	setjmp
setjmp:	
	setlos	#1, gr9
	bra	.Lsigsetjmp_intern
	.size	setjmp,.-setjmp
	
# setjmp/longjmp for Frv.  The jmpbuf looks like this:
#	
# Register	jmpbuf offset
# R16-R31	0x0-0x03c
# R48-R63	0x40-0x7c
# FR16-FR31     0x80-0xbc
# FR48-FR63     0xc0-0xfc
# LR            0x100
# SP            0x104
# FP            0x108

	.global	__sigsetjmp
	.type	__sigsetjmp, at function
__sigsetjmp:
.Lsigsetjmp_intern:
	stdi	gr16, @(gr8,0)
	stdi	gr18, @(gr8,8)
	stdi 	gr20, @(gr8,16)
	stdi	gr22, @(gr8,24)
	stdi	gr24, @(gr8,32)
	stdi	gr26, @(gr8,40)
	stdi	gr28, @(gr8,48)
	stdi	gr30, @(gr8,56)
#if __FRV_GPR__ != 32
	stdi	gr48, @(gr8,64)
	stdi	gr50, @(gr8,72)
	stdi	gr52, @(gr8,80)
	stdi	gr54, @(gr8,88)
	stdi	gr56, @(gr8,96)
	stdi	gr58, @(gr8,104)
	stdi	gr60, @(gr8,112)
	stdi	gr62, @(gr8,120)
#endif

#if __FRV_FPR__ != 0
	stdfi	fr16, @(gr8,128)
	stdfi	fr18, @(gr8,136)
	stdfi 	fr20, @(gr8,144)
	stdfi	fr22, @(gr8,152)
	stdfi	fr24, @(gr8,160)
	stdfi	fr26, @(gr8,168)
	stdfi	fr28, @(gr8,176)
	stdfi	fr30, @(gr8,184)
#if __FRV_FPR__ != 32
	stdfi	fr48, @(gr8,192)
	stdfi	fr50, @(gr8,200)
	stdfi	fr52, @(gr8,208)
	stdfi	fr54, @(gr8,216)
	stdfi	fr56, @(gr8,224)
	stdfi	fr58, @(gr8,232)
	stdfi	fr60, @(gr8,240)
	stdfi	fr62, @(gr8,248)
#endif
#endif

        movsg	lr, gr4
	sti     gr4, @(gr8,256)
	sti     sp, @(gr8,260)
	sti     fp, @(gr8,264)
	
	sethi.p	#gotofffuncdeschi(__sigjmp_save), gr4
	setlo	#gotofffuncdesclo(__sigjmp_save), gr4
	ldd	@(gr15, gr4), gr14
	jmpl	@(gr14, gr0)
	.size	__sigsetjmp,.-__sigsetjmp

--- NEW FILE: brk.c ---
/* From libc-5.3.12 */

#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>

extern void * ___brk_addr;

extern int __init_brk (void);
extern void *_brk(void *ptr);

int brk(void * end_data_seg)
{
    if (__init_brk () == 0)
    {
		___brk_addr = _brk(end_data_seg);
		if (___brk_addr == end_data_seg)
			return 0;
		__set_errno(ENOMEM);
    }
    return -1;
}

--- NEW FILE: crt0.S ---
/* Copyright (C) 1991, 1992, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.  */


/*  Based on ../i386/crt0.S and newlib's libgloss/frv/crt0.S  */

/*
    When we enter this piece of code, the program stack looks like this:
        argc            argument counter (integer)
        argv[0]         program name (pointer)
        argv[1...N]     program args (pointers)
        argv[argc-1]    end of args (integer)
	NULL
        env[0...N]      environment variables (pointers)
        NULL

    Also, GR16 holds a pointer to a memory map.  */

#include <features.h>

	.text
	.global _start
	.type	_start,%function
#if defined L_crt0 || defined L_Scrt0 || ! defined __UCLIBC_CTOR_DTOR__
	.type __uClibc_main,%function
#else
	.weak	_init
	.weak	_fini
	.type	__uClibc_start_main,%function
#endif
/* Stick in a dummy reference to main(), so that if an application
 * is linking when the main() function is in a static library (.a)
 * we can be sure that main() actually gets linked in */
	.type	main,%function
_start:
	/* At program start-up, gr16 contains a pointer to a memory
	   map, that we use to relocate addresses.  */
	call	.Lcall
.Lcall:
	movsg	lr, gr4
	sethi.p	#gprelhi(.Lcall), gr5
	setlo	#gprello(.Lcall), gr5
	sub.p	gr4, gr5, gr4
	/* gr4 now holds the _gp address.  */
	
	mov	gr16, gr8
	sethi.p #gprelhi(__ROFIXUP_LIST__), gr9
	sethi	#gprelhi(__ROFIXUP_END__), gr10
	setlo.p #gprello(__ROFIXUP_LIST__), gr9
	setlo	#gprello(__ROFIXUP_END__), gr10
	add.p	gr9, gr4, gr9
	add	gr10, gr4, gr10
	call	__self_reloc
	mov.p	gr8, gr17
	mov	gr8, gr15
	/* gr17 now holds the self-relocated _GLOBAL_OFFSET_TABLE_
	address, because the linker added its unrelocated address as
	the last entry in the ROFIXUP list, and __self_reloc returns
	the last entry, relocated.  */

	/* Prepare arguments for uClibc main.  */
	ld	@(sp, gr0), gr8
	slli	gr8, #2, gr10
	add	sp, gr10, gr10
	addi.p	sp, #4, gr9
	addi	gr10, #8, gr10

	/* Set up an invalid (NULL return address, NULL frame pointer)
	   callers stack frame so anybody unrolling the stack knows where
	   to stop */
	mov	gr0, fp
	movgs	gr0, lr

#if (defined L_crt1 || defined L_gcrt1 || defined L_Scrt1) && defined __UCLIBC_CTOR_DTOR__
	/* Pass .init and .fini arguments to __uClibc_start_main().  */
	sethi.p	#gotfuncdeschi(_init), gr11
	sethi	#gotfuncdeschi(_fini), gr12
	setlo.p	#gotfuncdesclo(_init), gr11
	setlo	#gotfuncdesclo(_fini), gr12
	ld.p	@(gr11, gr17), gr11
	mov	gr17, gr15
	ld.p	@(gr12, gr17), gr12
	call	__uClibc_start_main
#else
	mov.p	gr17, gr15
	call	__uClibc_main
#endif	

	/* Crash if somehow `exit' returns anyways.  */
	jmpl	@(gr0,gr0)
.size _start,.-_start

#if defined L_gcrt1 && defined __UCLIBC_PROFILING__
# include "./gmon-start.S"
#endif

--- NEW FILE: __init_brk.c ---
/* From libc-5.3.12 */

#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>

void * ___brk_addr = 0;

#define __NR__brk __NR_brk
_syscall1(void *, _brk, void *, ptr);

int
__init_brk (void)
{
    if (___brk_addr == 0)
    {
		___brk_addr = _brk(0);
		if (___brk_addr == 0)
		{
		  __set_errno(ENOMEM);
		  return -1;
		}
    }
    return 0;
}

--- NEW FILE: dl-iterate-phdr.c ---
/* Copyright 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.  */

#define _GNU_SOURCE
#include <link.h>

extern int __attribute__((__weak__))
__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
				    size_t size, void *data),
		   void *data);

/* Define it as a pointer, such that we get a pointer to the global
   function descriptor, that won't be optimized away by the
   linker.  */
static int (*ptr) (int (*callback) (struct dl_phdr_info *info,
				    size_t size, void *data),
		   void *data) = __dl_iterate_phdr;

int
dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
				  size_t size, void *data),
		 void *data)
{
  if (ptr)
    return ptr (callback, data);

  return 0;
}

--- NEW FILE: Makefile ---
# Makefile for uClibc
#
# Copyright (C) 2000-2003 Erik Andersen <andersen at uclibc.org>
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU Library General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
# details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

TOPDIR=../../../../
include $(TOPDIR)Rules.mak
ASFLAGS=$(CFLAGS)

CRT0_SRC = crt0.S
CRT0_OBJ = crt0.o crt1.o # gcrt1.o
SCRT0_OBJ = $(patsubst %,S%, $(CRT0_OBJ))
CRT0_DEPS=gmon-start.S

CTOR_TARGETS = crti.o crtn.o

SSRC=__longjmp.S setjmp.S clone.S vfork.S
ifeq ($(strip $(UCLIBC_PROFILING)),y)
SSRC+=mcount.S
endif
SOBJS=$(patsubst %.S,%.o, $(SSRC))

CSRC=_mmap.c sysdep.c brk.c sbrk.c __init_brk.c dl-iterate-phdr.c
COBJS=$(patsubst %.c,%.o, $(CSRC))

OBJS=$(SOBJS) $(COBJS)

all: $(OBJS) $(LIBC)

$(LIBC): ar-target 

ar-target: $(OBJS) $(CRT0_OBJ) $(SCRT0_OBJ) $(CTOR_TARGETS)
	$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
	$(INSTALL) -d $(TOPDIR)lib
	cp $(CRT0_OBJ) $(SCRT0_OBJ) $(CTOR_TARGETS) $(TOPDIR)lib/

$(CRT0_OBJ): $(CRT0_SRC) crtreloc.o
	$(CC) $(CFLAGS) -DL_$* -r -nostdlib $< crtreloc.o -o $*.o
	$(STRIPTOOL) -x -R .note -R .comment $*.o

crtreloc.o: crtreloc.c
	$(CC) $(CFLAGS) -c $< -o $@

$(SCRT0_OBJ): $(CRT0_SRC) Scrtreloc.o
	$(CC) $(CFLAGS) -fPIE -DL_$* -r -nostdlib $< Scrtreloc.o -o $*.o
	$(STRIPTOOL) -x -R .note -R .comment $*.o

Scrtreloc.o: crtreloc.c
	$(CC) $(CFLAGS) -fPIE -c $< -o $@

$(CTOR_TARGETS): %.o : %.S
	$(CC) $(CFLAGS) -c $< -o $@
	$(STRIPTOOL) -x -R .note -R .comment $*.o

$(SOBJS): %.o : %.S
	$(CC) $(CFLAGS) -c $< -o $@
	$(STRIPTOOL) -x -R .note -R .comment $*.o

$(COBJS): %.o : %.c
	$(CC) $(CFLAGS) -c $< -o $@
	$(STRIPTOOL) -x -R .note -R .comment $*.o

ifeq ($(strip $(UCLIBC_PROFILING)),y)
SAFECFLAGS := $(filter-out -g,$(CFLAGS))
gmon-start.S: ../common/gmon-start.c
	$(CC) $(SAFECFLAGS) -c $< -S -o $*.S
gcrt1.o: $(CRT0_DEPS)
endif

headers:


clean:
	rm -f *.[oa] *~ core
	rm -f bits/sysnum.h


--- NEW FILE: _mmap.c ---
/* Copyright (C) 1997, 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Daniel Jacobowitz <dan at debian.org>, 1999.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

/* Massivly hacked up for uClibc by Erik Andersen */

/* Extracted from ../common/mmap64.c by Alexandre Oliva <aoliva at redhat.com>

   We don't want to use the old mmap interface.  */

#include <features.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mman.h>

#define __NR___syscall_mmap2	    __NR_mmap2
static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr, 
	size_t, len, int, prot, int, flags, int, fd, off_t, offset);

/* This is always 12, even on architectures where PAGE_SHIFT != 12.  */
# ifndef MMAP2_PAGE_SHIFT
#  define MMAP2_PAGE_SHIFT 12
# endif

__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
{
    if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) {
	__set_errno (EINVAL);
	return MAP_FAILED;
    }
    return(__syscall_mmap2(addr, len, prot, flags, fd, (off_t) (offset >> MMAP2_PAGE_SHIFT)));
}

--- NEW FILE: clone.S ---
/* Copyright (C) 2003 Free Software Foudnation, Inc.
   This file is part of the GNU C Library.
   Contributed by Alexandre Oliva <aoliva at redhat.com>, 2003.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

/* clone() is even more special than fork() as it mucks with stacks
   and invokes a function in the right context after its all over.  */

#include <asm/unistd.h>
#define _ERRNO_H	1
#include <bits/errno.h>

	.text
	.globl	__clone
	.type __clone, at function
/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
__clone:
	/* Sanity check arguments.  */
	cmp.p	gr8, gr0, icc0
	cmp	gr9, gr0, icc1
	mov.p	gr8, gr4
	beq	icc0, #0, .Lerror
	mov.p	gr11, gr5
	beq	icc1, #0, .Lerror

	mov.p	gr10, gr8
	setlos	#__NR_clone, gr7
	tra	gr0,gr0

	cmp	gr8, gr0, icc0
	bgtlr	icc0, #1
	beq	icc0, #0, .Lthread_start

.Lsys_error:
	sethi.p	#gotofffuncdeschi(__syscall_error), gr14
	setlo	#gotofffuncdesclo(__syscall_error), gr14
	ldd	@(gr14, gr15), gr14
	jmpl	@(gr14, gr0)

.Lerror:
	setlos.p #-EINVAL, gr7
	bra	.Lsys_error

###############################################################################
#
# come here as the new thread [GR4 is fn, GR5 is arg]
#
###############################################################################
.Lthread_start:
	/* Save the PIC register.  */
	mov	gr15, gr17

	/* Call the user's function.  */
	ldd.p	@(gr4, gr0), gr14
	mov	gr5, gr8
	calll	@(gr14, gr0)

	/* Call _exit, rather simply inlining the syscall, such that
	   breakpoints work.*/

	mov.p	gr17, gr15
	call	_exit

	/* Should never get here.  */
	jmpl	@(gr0, gr0)
	.size	__clone,.-__clone

.weak	clone
	clone = __clone

--- NEW FILE: crtn.S ---
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.  */

	.section .init,"x"
	.globl _init
	.type	_init, @function
	ldi @(fp,8), gr5
	ld @(sp,gr0), fp
	addi sp,#16,sp
	jmpl @(gr5,gr0)
	.size	_init, .-_init
	
	.section .fini,"x"
	.globl _fini
	.type	_fini, @function
	ldi @(fp,8), gr5
	ld @(sp,gr0), fp
	addi sp,#16,sp
	jmpl @(gr5,gr0)
	.size	_fini, .-_fini

--- NEW FILE: vfork.S ---
/* Copyright (C) 2003 Free Software Foudnation, Inc.
   This file is part of the GNU C Library.
   Contributed by David Howells <dhowells at redhat.com>, 2003.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <asm/unistd.h>
#define _ERRNO_H       1
#include <bits/errno.h>

       .text
       .globl  __libc_vfork
       .type __libc_vfork, at function
/* int vfork(void) */
__libc_vfork:
       setlos  #__NR_vfork, gr7
       tira    gr0, #0

       cmp     gr8, gr0, icc0
       bplr    icc0, #2

       sethi.p #gotofffuncdeschi(__syscall_error), gr14
       setlo   #gotofffuncdesclo(__syscall_error), gr14
       ldd     @(gr14, gr15), gr14
       jmpl    @(gr14, gr0)

       .size   vfork,.-vfork

.weak vfork
.global vfork
.set vfork, __libc_vfork

--- NEW FILE: __longjmp.S ---
#define _SETJMP_H
#define _ASM
#include <bits/setjmp.h>

# setjmp/longjmp for Frv.  The jmpbuf looks like this:
#	
# Register	jmpbuf offset
# R16-R31	0x0-0x03c
# R48-R63	0x40-0x7c
# FR16-FR31     0x80-0xbc
# FR48-FR63     0xc0-0xfc
# LR            0x100
# SP            0x104
# FP            0x108
#
# R8 contains the pointer to jmpbuf

	.text
	.global	__longjmp
	.type	__longjmp, at function
__longjmp:
	lddi	@(gr8,0), gr16
	lddi	@(gr8,8), gr18
	lddi 	@(gr8,16), gr20
	lddi	@(gr8,24), gr22
	lddi	@(gr8,32), gr24
	lddi	@(gr8,40), gr26
	lddi	@(gr8,48), gr28
	lddi	@(gr8,56), gr30
#if __FRV_GPR__ != 32
	lddi	@(gr8,64), gr48
	lddi	@(gr8,72), gr50
	lddi	@(gr8,80), gr52
	lddi	@(gr8,88), gr54
	lddi	@(gr8,96), gr56
	lddi	@(gr8,104), gr58
	lddi	@(gr8,112), gr60
	lddi	@(gr8,120), gr62
#endif

#if __FRV_FPR__ != 0
	lddfi	@(gr8,128), fr16
	lddfi	@(gr8,136), fr18
	lddfi 	@(gr8,144), fr20
	lddfi	@(gr8,152), fr22
	lddfi	@(gr8,160), fr24
	lddfi	@(gr8,168), fr26
	lddfi	@(gr8,176), fr28
	lddfi	@(gr8,184), fr30
#if __FRV_FPR__ != 32
	lddfi	@(gr8,192), fr48
	lddfi	@(gr8,200), fr50
	lddfi	@(gr8,208), fr52
	lddfi	@(gr8,216), fr54
	lddfi	@(gr8,224), fr56
	lddfi	@(gr8,232), fr58
	lddfi	@(gr8,240), fr60
	lddfi	@(gr8,248), fr62
#endif
#endif

        ldi     @(gr8,256), gr4
	movgs   gr4,lr

        ldi     @(gr8,260), sp
        ldi     @(gr8,264), fp
	
# Value to return is in r9.  If zero, return 1
	cmp	gr9, gr0, icc0
	setlos	#1, gr8
	ckne	icc0, cc4
	cmov	gr9, gr8, cc4, 1
	ret
.Lend2:
	.size	__longjmp,.Lend2-__longjmp

--- NEW FILE: sbrk.c ---
/* From libc-5.3.12 */

#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>

extern void * ___brk_addr;

extern int __init_brk (void);
extern void *_brk(void *ptr);

void *
sbrk(intptr_t increment)
{
    if (__init_brk () == 0)
    {
		char * tmp = (char*)___brk_addr+increment;
		___brk_addr = _brk(tmp);
		if (___brk_addr == tmp)
			return tmp-increment;
		__set_errno(ENOMEM);
		return ((void *) -1);
    }
    return ((void *) -1);
}

--- NEW FILE: sysdep.c ---
/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <errno.h>

/* This routine is jumped to by all the syscall handlers, to stash
   an error number into errno.  */
int __syscall_error (int err_no)
{
  __set_errno (err_no);
  return -1;
}




More information about the uClibc-cvs mailing list