diff options
-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 |