diff options
Diffstat (limited to 'libc')
| -rw-r--r-- | libc/sysdeps/linux/bfin/bits/elf-fdpic.h | 115 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/bits/mman.h | 11 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/bits/syscalls.h | 40 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/brk.c | 2 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/bsd-_setjmp.S | 9 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/clone.c | 24 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/crt1.S | 122 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/crti.S | 73 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/crtn.S | 65 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/crtreloc.c | 145 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/link.h | 127 | ||||
| -rw-r--r-- | libc/sysdeps/linux/bfin/setjmp.S | 9 | 
12 files changed, 650 insertions, 92 deletions
| diff --git a/libc/sysdeps/linux/bfin/bits/elf-fdpic.h b/libc/sysdeps/linux/bfin/bits/elf-fdpic.h new file mode 100644 index 000000000..0dbb54b4c --- /dev/null +++ b/libc/sysdeps/linux/bfin/bits/elf-fdpic.h @@ -0,0 +1,115 @@ +/* Copyright 2003, 2004 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. + +In addition to the permissions in the GNU Lesser General Public +License, the Free Software Foundation gives you unlimited +permission to link the compiled version of this file with other +programs, and to distribute those programs without any restriction +coming from the use of this file.  (The GNU Lesser General Public +License restrictions do apply in other respects; for example, they +cover modification of the file, and distribution when not linked +into another program.) + +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.  */ + +#ifndef _BITS_ELF_FDPIC_H +#define _BITS_ELF_FDPIC_H + +/* These data structures are described in the FDPIC ABI extension. +   The kernel passes a process a memory map, such that for every LOAD +   segment there is an elf32_fdpic_loadseg entry.  A pointer to an +   elf32_fdpic_loadmap is passed in GR8 at start-up, and a pointer to +   an additional such map is passed in GR9 for the interpreter, when +   there is one.  */ + +#include <elf.h> + +/* This data structure represents a PT_LOAD segment.  */ +struct elf32_fdpic_loadseg +{ +  /* Core address to which the segment is mapped.  */ +  Elf32_Addr addr; +  /* VMA recorded in the program header.  */ +  Elf32_Addr p_vaddr; +  /* Size of this segment in memory.  */ +  Elf32_Word p_memsz; +}; + +struct elf32_fdpic_loadmap { +  /* Protocol version number, must be zero.  */ +  Elf32_Half version; +  /* Number of segments in this map.  */ +  Elf32_Half nsegs; +  /* The actual memory map.  */ +  struct elf32_fdpic_loadseg segs[/*nsegs*/]; +}; + +struct elf32_fdpic_loadaddr { +  struct elf32_fdpic_loadmap *map; +  void *got_value; +}; + +/* Map a pointer's VMA to its corresponding address according to the +   load map.  */ +inline static void * +__reloc_pointer (void *p, +		 const struct elf32_fdpic_loadmap *map) +{ +  int c; + +#if 0 +  if (map->version != 0) +    /* Crash.  */ +    ((void(*)())0)(); +#endif + +  /* No special provision is made for NULL.  We don't want NULL +     addresses to go through relocation, so they shouldn't be in +     .rofixup sections, and, if they're present in dynamic +     relocations, they shall be mapped to the NULL address without +     undergoing relocations.  */ + +  for (c = 0; +       /* Take advantage of the fact that the loadmap is ordered by +	  virtual addresses.  In general there will only be 2 entries, +	  so it's not profitable to do a binary search.  */ +       c < map->nsegs && p >= (void*)map->segs[c].p_vaddr; +       c++) +    { +      /* This should be computed as part of the pointer comparison +	 above, but we want to use the carry in the comparison, so we +	 can't convert it to an integer type beforehand.  */ +      unsigned long offset = p - (void*)map->segs[c].p_vaddr; +      /* We only check for one-past-the-end for the last segment, +	 assumed to be the data segment, because other cases are +	 ambiguous in the absence of padding between segments, and +	 rofixup already serves as padding between text and data. +	 Unfortunately, unless we special-case the last segment, we +	 fail to relocate the _end symbol.  */ +      if (offset < map->segs[c].p_memsz +	  || (offset == map->segs[c].p_memsz && c + 1 == map->nsegs)) +	return (char*)map->segs[c].addr + offset; +    } +	      +  /* We might want to crash instead.  */ +  return (void*)-1; +} + +# define __RELOC_POINTER(ptr, loadaddr) \ +  (__reloc_pointer ((void*)(ptr), \ +		    (loadaddr).map)) + +#endif /* _BITS_ELF_FDPIC_H */ diff --git a/libc/sysdeps/linux/bfin/bits/mman.h b/libc/sysdeps/linux/bfin/bits/mman.h index d57eeb587..c75ff4b0d 100644 --- a/libc/sysdeps/linux/bfin/bits/mman.h +++ b/libc/sysdeps/linux/bfin/bits/mman.h @@ -72,16 +72,15 @@  /* Flags for `mremap'.  */  #ifdef __USE_GNU  # define MREMAP_MAYMOVE	1 -# define MREMAP_FIXED	2  #endif  /* Advice to `madvise'.  */  #ifdef __USE_BSD -# define MADV_NORMAL	 0	/* No further special treatment.  */ -# define MADV_RANDOM	 1	/* Expect random page references.  */ -# define MADV_SEQUENTIAL 2	/* Expect sequential page references.  */ -# define MADV_WILLNEED	 3	/* Will need these pages.  */ -# define MADV_DONTNEED	 4	/* Don't need these pages.  */ +# define MADV_NORMAL	 0x0	/* No further special treatment.  */ +# define MADV_RANDOM	 0x1	/* Expect random page references.  */ +# define MADV_SEQUENTIAL 0x2	/* Expect sequential page references.  */ +# define MADV_WILLNEED	 0x3	/* Will need these pages.  */ +# define MADV_DONTNEED	 0x4	/* Don't need these pages.  */  #endif  /* The POSIX people had to invent similar names for the same things.  */ diff --git a/libc/sysdeps/linux/bfin/bits/syscalls.h b/libc/sysdeps/linux/bfin/bits/syscalls.h index d8d628cab..5ffaa7a8b 100644 --- a/libc/sysdeps/linux/bfin/bits/syscalls.h +++ b/libc/sysdeps/linux/bfin/bits/syscalls.h @@ -4,25 +4,45 @@  # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."  #endif -#include <features.h> -  /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel   * header files.  It also defines the traditional `SYS_<name>' macros for older   * programs.  */  #include <bits/sysnum.h> -/* This code is mostly cut & paste from the uClinux bfin port */ +#ifndef __set_errno +# define __set_errno(val) ((*__errno_location ()) = (val)) +#endif + +#ifndef SYS_ify +# define SYS_ify(syscall_name)  (__NR_##syscall_name) +#endif  #ifndef __ASSEMBLER__ -#define __syscall_return(type, res)					\ -do {									\ -	if ((unsigned long)(res) >= (unsigned long)(-125)) 		\ -	{	__set_errno(-(res));					\ -		res = -1;						\ -	}								\ -	return (type) (res);						\ +/* user-visible error numbers are in the range -1 - -4095: see <asm-frv/errno.h> */ +#if defined _LIBC && !defined __set_errno +# define __syscall_return(type, res) \ +do { \ +        unsigned long __sr2 = (res);		    			    \ +	if (__builtin_expect ((unsigned long)(__sr2)			    \ +			      >= (unsigned long)(-4095), 0)) {		    \ +		extern int __syscall_error (int);			    \ +		return (type) __syscall_error (__sr2);		    	    \ +	}								    \ +	return (type) (__sr2); 						    \ +} while (0) +#else +# define __syscall_return(type, res) \ +do { \ +        unsigned long __sr2 = (res);		    			    \ +	if (__builtin_expect ((unsigned long)(__sr2)			    \ +			      >= (unsigned long)(-4095), 0)) {		    \ +		__set_errno (-__sr2);				    	    \ +		__sr2 = -1; 						    \ +	}								    \ +	return (type) (__sr2); 						    \  } while (0) +#endif  #define _syscall0(type,name)						\  type name(void) {							\ diff --git a/libc/sysdeps/linux/bfin/brk.c b/libc/sysdeps/linux/bfin/brk.c index 3b261697b..5735321bb 100644 --- a/libc/sysdeps/linux/bfin/brk.c +++ b/libc/sysdeps/linux/bfin/brk.c @@ -4,9 +4,9 @@   * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.   */ +#include <errno.h>  #include <unistd.h>  #include <sys/syscall.h> -#include <errno.h>  libc_hidden_proto(brk) diff --git a/libc/sysdeps/linux/bfin/bsd-_setjmp.S b/libc/sysdeps/linux/bfin/bsd-_setjmp.S index 6f17a6025..69ae8f878 100644 --- a/libc/sysdeps/linux/bfin/bsd-_setjmp.S +++ b/libc/sysdeps/linux/bfin/bsd-_setjmp.S @@ -7,11 +7,11 @@  #include <bits/setjmp.h>  .text -.global _setjmp; -.type	_setjmp,STT_FUNC; +.global __setjmp; +.type	__setjmp,STT_FUNC;  .align 4; -_setjmp: +__setjmp:  	[--SP] = P0;	// Save P0  	P0 = R0;  	R0 = [SP++]; @@ -90,8 +90,7 @@ _setjmp:  	R0 = RETS;  	[P0 + 0x9C] = R0; -	R0 = [P0 + 0x20];  	R0 = 0;  	RTS; -.size _setjmp,.-_setjmp +.size __setjmp,.-__setjmp diff --git a/libc/sysdeps/linux/bfin/clone.c b/libc/sysdeps/linux/bfin/clone.c index f326f00a0..fbf43ade9 100644 --- a/libc/sysdeps/linux/bfin/clone.c +++ b/libc/sysdeps/linux/bfin/clone.c @@ -15,6 +15,7 @@ clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg)  	if (fn && child_stack) { +#ifdef __BFIN_FDPIC__  	__asm__ __volatile__ (  			"r1 = %2;"  			"r0 = %3;" @@ -25,6 +26,28 @@ clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg)  			"if !cc jump xxx;"	/* if (rval != 0) skip to parent */  			"r0 = %4;"  			"p0 = %5;" +			"fp = 0;" +			"p1 = [p0];" +			"p3 = [p0 + 4];" +			"call (p1);"	/* Call cloned function */ +			"p0 = %6;" +			"excpt 0;"	/* Call sys_exit */ +			"xxx: nop;" +			: "=d" (rval) +			: "i" (__NR_clone), "a" (child_stack), "a" (flags), "a" (arg), "a" (fn), "i" (__NR_exit) +			: "CC", "R0", "R1", "P0"); +#else +	__asm__ __volatile__ ( +			"r1 = %2;" +			"r0 = %3;" +			"P0 = %1;" +			"excpt 0;"	 /*Call sys_clone*/ +			"%0  = r0;" +			"cc = r0 == 0;" +			"if !cc jump xxx;"	/* if (rval != 0) skip to parent */ +			"r0 = %4;" +			"p0 = %5;" +			"fp = 0;"  			"call (p0);"	/* Call cloned function */  			"p0 = %6;"  			"excpt 0;"	/* Call sys_exit */ @@ -32,6 +55,7 @@ clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg)  			: "=d" (rval)  			: "i" (__NR_clone), "a" (child_stack), "a" (flags), "a" (arg), "a" (fn), "i" (__NR_exit)  			: "CC", "R0", "R1", "P0"); +#endif  	}  	return rval;  } diff --git a/libc/sysdeps/linux/bfin/crt1.S b/libc/sysdeps/linux/bfin/crt1.S index b9b6e3b86..ead8dbfbe 100644 --- a/libc/sysdeps/linux/bfin/crt1.S +++ b/libc/sysdeps/linux/bfin/crt1.S @@ -1,23 +1,35 @@ -/* Initial C runtime code for Blackfin - * - * Copyright (C) 2004-2006 Erik Andersen <andersen@uclibc.org> - * - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - */ +/* Copyright (C) 1991, 1992 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 Library General Public License as +published by the Free Software Foundation; either version 2 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 Library 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.  */ +  /* When we enter this piece of code, the user stack looks like this: -* [SP] argc            argument counter (integer) +*      argc            argument counter (integer)  *      argv[0]         program name (pointer)  *      argv[1...N]     program args (pointers)  *      NULL  *      env[0...N]      environment variables (pointers)  *      NULL - +	  *   When we are done here, we want  *	R0=argc -*	R1=argv -*	R2=__init -*	SP=__fini +*	R1=*argv[0] +*	R2=*envp[0]    */  #include <features.h> @@ -29,44 +41,86 @@  .global ___uClibc_main;  .type	___uClibc_main,STT_FUNC; -#define __UCLIBC_CTOR_DTOR__ -#if defined(__UCLIBC_CTOR_DTOR__) -.weak	__init; -.weak	__fini; -#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,STT_FUNC;  __start: +#ifdef __BFIN_FDPIC__ +	/* P0 contains a pointer to the program's load map.  */ +	call	.Lcall; +.Lcall: +	R4 = RETS; +	SP += -12; +	R0.L = .Lcall; +	R0.H = .Lcall; +	R1.L = __ROFIXUP_LIST__; +	R1.H = __ROFIXUP_LIST__; +	R2.L = __ROFIXUP_END__; +	R2.H = __ROFIXUP_END__; +	R1 = R1 - R0; +	R1 = R1 + R4; +	R2 = R2 - R0; +	R2 = R2 + R4; +	R0 = P0; +	CALL	___self_reloc; +	SP += 12; +	P3 = R0; +#endif +  /*	clear the frame pointer and the L registers.  */  	FP = 0;  	L0 = 0;  	L1 = 0;  	L2 = 0;  	L3 = 0; - -/*	Load register R0 (argc) from the stack to its final resting place */ +	 +/*	Load register R1 (argc) from the stack to its final resting place */  	P0 = SP; -	R0 = [P0++]; +	R1 = [P0++]; -/*	Copy argv pointer into R1 */ -	R1 = P0; +/*	Copy argv pointer into R2 -- which its final resting place */ +	R2 = P0; -#if defined(__UCLIBC_CTOR_DTOR__) -/*	Load __init into R2 */ -	R2.H = __init; -	R2.L = __init; +/*	Skip to the end of argv and put a pointer to the environment in +	[SP + 12] */ +	R3 = R1; +	R3 <<= 2; +	R3 += 4; +	R3 = R2 + R3; -/*	Load __fini onto the stack */ -	SP += -16; +	SP += -24; +	[SP + 12] = R3; + +/*	Ok, now run uClibc's main() -- shouldn't return */ +#if defined L_crt1 && defined __UCLIBC_CTOR_DTOR__ +#ifdef __BFIN_FDPIC__ +	R3 = [P3 + __init@FUNCDESC_GOT17M4]; +#else +	R3.H = __init; +	R3.L = __init; +#endif +	[SP+16] = R3; +#ifdef __BFIN_FDPIC__ +	R3 = [P3 + __fini@FUNCDESC_GOT17M4]; +#else  	R3.H = __fini;  	R3.L = __fini; -	[SP+12] = R3; -#else -/*	Just fixup the stack */ -	sp += -12; +#endif +	[SP+20] = R3; +#else /* no ctor/dtor handling */ +	R3 = 0; +	[SP + 16] = R3; +	[SP + 20] = R3;  #endif -/*	Ok, now run uClibc's main() -- shouldn't return */ +#ifdef __BFIN_FDPIC__ +	R0 = [P3 + _main@FUNCDESC_GOT17M4]; +#else +	R0.H = _main; +	R0.L = _main; +#endif  	jump.l	___uClibc_main; - -.size __start,.-__start diff --git a/libc/sysdeps/linux/bfin/crti.S b/libc/sysdeps/linux/bfin/crti.S index 56b268a28..7c10392d8 100644 --- a/libc/sysdeps/linux/bfin/crti.S +++ b/libc/sysdeps/linux/bfin/crti.S @@ -1,17 +1,62 @@ -	.section .init -	.section .fini +/* Specialized code needed to support construction and destruction of +   file-scope objects in C++ and Java code, and to support exception handling. +   Copyright (C) 1999 Free Software Foundation, Inc. +   Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca). -.text; -.align 2 -.global __init; -.type __init, STT_FUNC; -__init: -	LINK 0; -	SP += -12; +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING.  If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA.  */ -.align 2 -.global __fini; -.type __fini, STT_FUNC; +/* As a special exception, if you link this library with files +   compiled with GCC to produce an executable, this does not cause +   the resulting executable to be covered by the GNU General Public License. +   This exception does not however invalidate any other reasons why +   the executable file might be covered by the GNU General Public License.  */ + +/* + * This file just supplies function prologues for the .init and .fini + * sections.  It is linked in before crtbegin.o. + */ + +	.file   "crti.o" +	.ident  "GNU C crti.o" + +	.section .init +	.globl  __init +	.type   __init,@function +__init: +#if defined __ID_SHARED_LIB__ +	[--SP] = P5; +#elif defined __BFIN_FDPIC__ +	[--SP] = P3;  +#endif +	LINK 12; +#if defined __ID_SHARED_LIB__ +	P5 = [P5 + _current_shared_library_p5_offset_] +#endif	 +	.section .fini +	.globl  __fini +	.type   __fini,@function  __fini: -	LINK 0; -	SP += -12; +#if defined __ID_SHARED_LIB__ +	[--SP] = P5;  +#elif defined __BFIN_FDPIC__ +	[--SP] = P3;  +#endif +	LINK 12;  +#if defined __ID_SHARED_LIB__ +	P5 = [P5 + _current_shared_library_p5_offset_] +#endif	 diff --git a/libc/sysdeps/linux/bfin/crtn.S b/libc/sysdeps/linux/bfin/crtn.S index 11ba9420d..add0b7162 100644 --- a/libc/sysdeps/linux/bfin/crtn.S +++ b/libc/sysdeps/linux/bfin/crtn.S @@ -1,18 +1,53 @@ -	.section .init -	.section .fini +/* Specialized code needed to support construction and destruction of +   file-scope objects in C++ and Java code, and to support exception handling. +   Copyright (C) 1999 Free Software Foundation, Inc. +   Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca). + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING.  If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA.  */ -.text; -.align 2 -.global __init; -.type __init, STT_FUNC; -	SP += 12; -	UNLINK; +/* As a special exception, if you link this library with files +   compiled with GCC to produce an executable, this does not cause +   the resulting executable to be covered by the GNU General Public License. +   This exception does not however invalidate any other reasons why +   the executable file might be covered by the GNU General Public License.  */ + +/* + * This file supplies function epilogues for the .init and .fini sections. + * It is linked in after all other files. + */ + +	.file   "crtn.o" +	.ident  "GNU C crtn.o" + +	.section .init +	unlink;  +#if defined __ID_SHARED_LIB__ +	P5 = [SP++]; +#elif defined __BFIN_FDPIC__ +	P3 = [SP++]; +#endif  	rts; -	.size	__init, .-__init -.align 2 -.global __fini; -.type __fini, STT_FUNC; -	SP += 12; -	UNLINK; + +	.section .fini +	unlink; +#if defined __ID_SHARED_LIB__ +	P5 = [SP++]; +#elif defined __BFIN_FDPIC__ +	P3 = [SP++]; +#endif  	rts; -	.size	__fini, .-__fini diff --git a/libc/sysdeps/linux/bfin/crtreloc.c b/libc/sysdeps/linux/bfin/crtreloc.c new file mode 100644 index 000000000..4df304346 --- /dev/null +++ b/libc/sysdeps/linux/bfin/crtreloc.c @@ -0,0 +1,145 @@ +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +   written by Alexandre Oliva <aoliva@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. + +In addition to the permissions in the GNU Lesser General Public +License, the Free Software Foundation gives you unlimited +permission to link the compiled version of this file with other +programs, and to distribute those programs without any restriction +coming from the use of this file.  (The GNU Lesser General Public +License restrictions do apply in other respects; for example, they +cover modification of the file, and distribution when not linked +into another program.) + +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.  */ + +#ifdef __BFIN_FDPIC__ + +#define _GNU_SOURCE 1 +#include <sys/types.h> +#include <link.h> + +/* This file is to be compiled into crt object files, to enable +   executables to easily self-relocate.  */ + +#define hidden __attribute__((__visibility__("hidden"))) + +union word { +    char c[4]; +    void *v; +}; + +/* 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) +	    { +	      unsigned char *c = ptr; +	      int i; +	      unsigned long v = 0; +	      for (i = 0; i < 4; i++) +		v |= c[i] << 8 * i; +	      pt = (void *)v; +	    } +	  else +	    pt = *(void**)ptr; +	  pt = __reloc_pointer (pt, map); +	  if ((long)ptr & 3) +	    { +	      unsigned char *c = ptr; +	      int i; +	      unsigned long v = (unsigned long)pt; +	      for (i = 0; i < 4; i++, v >>= 8) +		c[i] = v; +	    } +	  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 + +#endif /* __BFIN_FDPIC__ */ diff --git a/libc/sysdeps/linux/bfin/link.h b/libc/sysdeps/linux/bfin/link.h new file mode 100644 index 000000000..59caefc62 --- /dev/null +++ b/libc/sysdeps/linux/bfin/link.h @@ -0,0 +1,127 @@ +/* Data structure for communication from the run-time dynamic linker for +   loaded ELF shared objects. +   Copyright (C) 1995-1999, 2000, 2001, 2004 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.  */ + +#ifndef	_LINK_H +#define	_LINK_H	1 + +#include <features.h> +#include <elf.h> +#include <dlfcn.h> +#include <sys/types.h> + +/* We use this macro to refer to ELF types independent of the native wordsize. +   `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'.  */ +#define ElfW(type)	_ElfW (Elf, __ELF_NATIVE_CLASS, type) +#define _ElfW(e,w,t)	_ElfW_1 (e, w, _##t) +#define _ElfW_1(e,w,t)	e##w##t + +#include <bits/elfclass.h>		/* Defines __ELF_NATIVE_CLASS.  */ + +/* Rendezvous structure used by the run-time dynamic linker to communicate +   details of shared object loading to the debugger.  If the executable's +   dynamic section has a DT_DEBUG element, the run-time linker sets that +   element's value to the address where this structure can be found.  */ + +struct r_debug +  { +    int r_version;		/* Version number for this protocol.  */ + +    struct link_map *r_map;	/* Head of the chain of loaded objects.  */ + +    /* This is the address of a function internal to the run-time linker, +       that will always be called when the linker begins to map in a +       library or unmap it, and again when the mapping change is complete. +       The debugger can set a breakpoint at this address if it wants to +       notice shared object mapping changes.  */ +    ElfW(Addr) r_brk; +    enum +      { +	/* This state value describes the mapping change taking place when +	   the `r_brk' address is called.  */ +	RT_CONSISTENT,		/* Mapping change is complete.  */ +	RT_ADD,			/* Beginning to add a new object.  */ +	RT_DELETE		/* Beginning to remove an object mapping.  */ +      } r_state; + +    ElfW(Addr) r_ldbase;	/* Base address the linker is loaded at.  */ +  }; + +/* This is the instance of that structure used by the dynamic linker.  */ +extern struct r_debug _r_debug; + +/* This symbol refers to the "dynamic structure" in the `.dynamic' section +   of whatever module refers to `_DYNAMIC'.  So, to find its own +   `struct r_debug', a program could do: +     for (dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn) +       if (dyn->d_tag == DT_DEBUG) +	 r_debug = (struct r_debug *) dyn->d_un.d_ptr; +   */ +extern ElfW(Dyn) _DYNAMIC[]; + +#if defined __BFIN_FDPIC__ +# include <bits/elf-fdpic.h> +#endif + +/* Structure describing a loaded shared object.  The `l_next' and `l_prev' +   members form a chain of all the shared objects loaded at startup. + +   These data structures exist in space used by the run-time dynamic linker; +   modifying them may have disastrous results.  */ + +struct link_map +  { +    /* These first few members are part of the protocol with the debugger. +       This is the same format used in SVR4.  */ + +#ifdef __BFIN_FDPIC__ +    struct elf32_fdpic_loadaddr l_addr; +#else +    ElfW(Addr) l_addr;		/* Base address shared object is loaded at.  */ +#endif +    char *l_name;		/* Absolute file name object was found in.  */ +    ElfW(Dyn) *l_ld;		/* Dynamic section of the shared object.  */ +    struct link_map *l_next, *l_prev; /* Chain of loaded objects.  */ +  }; + +#ifdef __USE_GNU + +struct dl_phdr_info +  { +#ifdef __BFIN_FDPIC__ +    struct elf32_fdpic_loadaddr dlpi_addr; +#else +    ElfW(Addr) dlpi_addr; +#endif +    const char *dlpi_name; +    const ElfW(Phdr) *dlpi_phdr; +    ElfW(Half) dlpi_phnum; +  }; + +__BEGIN_DECLS + +extern int dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, +					     size_t size, void *data), +			    void *data) __THROW; + +__END_DECLS + +#endif + +#endif /* link.h */ diff --git a/libc/sysdeps/linux/bfin/setjmp.S b/libc/sysdeps/linux/bfin/setjmp.S index 7194a1508..7ca92106f 100644 --- a/libc/sysdeps/linux/bfin/setjmp.S +++ b/libc/sysdeps/linux/bfin/setjmp.S @@ -98,10 +98,5 @@ ___sigsetjmp:  	[P0 + 0x9C] = R0;  	R0 = [P0 + 0x20]; -	CC = R1 == 1; -	IF CC JUMP finished; -	CALL ___sigjmp_save; -finished: -	R0 = 0; -	RTS; -.size ___sigsetjmp,.-___sigsetjmp +	JUMP.L ___sigjmp_save;  +.size ___sigsetjmp, .-___sigsetjmp | 
