diff options
Diffstat (limited to 'libc/sysdeps/linux/bfin/bits')
-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 |
3 files changed, 150 insertions, 16 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) { \ |