summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2016-02-05 21:07:40 +0100
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2016-02-07 18:23:22 +0100
commitc0a2d0b7edacbc6389574821b0231e07431dabb6 (patch)
treef2d21c6e2fe8f99ccd820d1d406dc5d51419ba77
parentb499fe614ac5b492fc0fdc6e1fbbeeb904674159 (diff)
frv: resurrect port somehow, totally untested
The FR-V port is really broken, and I have no emulator or hardware for this platform. I tried to get some hardware from RedHat, who made the FR-V port initially. Unfortunately Fujitsi didn't agreed to sent me some of their unused spare hardware lying @RedHat. As I invested some time to get stuff compiled, I decided to add the code and may be anytime later I can gain access to some emulator or hardware. GDB simulator for FR-V doesn't support booting Linux AFAIK.
-rw-r--r--Rules.mak4
-rw-r--r--extra/Configs/Config.in.arch6
-rw-r--r--include/link.h6
-rw-r--r--ldso/include/dl-elf.h2
-rw-r--r--ldso/include/dl-hash.h2
-rw-r--r--ldso/ldso/bfin/dl-sysdep.h2
-rw-r--r--ldso/ldso/dl-hash.c4
-rw-r--r--ldso/ldso/fdpic/dl-inlines.h4
-rw-r--r--ldso/ldso/frv/dl-startup.h18
-rw-r--r--ldso/ldso/frv/dl-sysdep.h16
-rw-r--r--ldso/ldso/frv/elfinterp.c67
-rw-r--r--libc/misc/elf/dl-iterate-phdr.c2
-rw-r--r--libc/sysdeps/linux/frv/Makefile59
-rw-r--r--libc/sysdeps/linux/frv/Makefile.arch11
-rw-r--r--libc/sysdeps/linux/frv/bits/fcntl.h3
-rw-r--r--libc/sysdeps/linux/frv/bits/kernel_types.h3
-rw-r--r--libc/sysdeps/linux/frv/bits/stat.h33
-rw-r--r--libc/sysdeps/linux/frv/bits/syscalls.h181
-rw-r--r--libc/sysdeps/linux/frv/bits/uClibc_arch_features.h2
-rw-r--r--libc/sysdeps/linux/frv/crt1.S (renamed from libc/sysdeps/linux/frv/crt0.S)9
-rw-r--r--libc/sysdeps/linux/frv/crtreloc.c50
-rw-r--r--libc/sysdeps/linux/frv/jmpbuf-unwind.h2
-rw-r--r--libc/sysdeps/linux/frv/syscall.c2
23 files changed, 195 insertions, 293 deletions
diff --git a/Rules.mak b/Rules.mak
index 16c1c49af..b1cececcd 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -473,14 +473,12 @@ endif
endif
ifeq ($(TARGET_ARCH),frv)
- CPU_LDFLAGS-$(CONFIG_FRV)+=-Wl,-melf32frvfd
# Using -pie causes the program to have an interpreter, which is
# forbidden, so we must make do with -shared. Unfortunately,
# -shared by itself would get us global function descriptors
# and calls through PLTs, dynamic resolution of symbols, etc,
# which would break as well, but -Bsymbolic comes to the rescue.
- export LDPIEFLAG:=-shared -Wl,-Bsymbolic
- UCLIBC_LDSO=ld.so.1
+ CPU_LDFLAGS-y += -Wl,-melf32frvfd -Wl,-Bsymbolic
endif
ifeq ($(strip $(TARGET_ARCH)),avr32)
diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch
index 0dae84b06..92f45d969 100644
--- a/extra/Configs/Config.in.arch
+++ b/extra/Configs/Config.in.arch
@@ -20,15 +20,15 @@ config UCLIBC_FORMAT_DSBT_ELF
select DOPIC
config UCLIBC_FORMAT_FLAT
bool "STATIC FLAT"
- depends on !ARCH_USE_MMU
+ depends on !ARCH_USE_MMU && !TARGET_frv
select ARCH_HAS_NO_LDSO
config UCLIBC_FORMAT_FLAT_SEP_DATA
bool "STATIC FLAT (sep-data)"
- depends on !ARCH_USE_MMU
+ depends on !ARCH_USE_MMU && !TARGET_frv
select ARCH_HAS_NO_LDSO
config UCLIBC_FORMAT_SHARED_FLAT
bool "SHARED FLAT"
- depends on !ARCH_USE_MMU
+ depends on !ARCH_USE_MMU && !TARGET_frv
select ARCH_HAS_NO_LDSO
help
Pick this one if you are using uClinux and wish to build
diff --git a/include/link.h b/include/link.h
index 67bc80062..711777bae 100644
--- a/include/link.h
+++ b/include/link.h
@@ -79,7 +79,7 @@ extern struct r_debug _r_debug;
*/
extern ElfW(Dyn) _DYNAMIC[];
-#ifdef __FDPIC__
+#if defined(__FRV_FDPIC__) || defined(__BFIN_FDPIC__)
# include <bits/elf-fdpic.h>
#endif
#ifdef __DSBT__
@@ -97,7 +97,7 @@ struct link_map
/* These first few members are part of the protocol with the debugger.
This is the same format used in SVR4. */
-#ifdef __FDPIC__
+#if defined(__FRV_FDPIC__) || defined(__BFIN_FDPIC__)
struct elf32_fdpic_loadaddr l_addr;
#else
#ifdef __DSBT__
@@ -184,7 +184,7 @@ enum
struct dl_phdr_info
{
-#ifdef __FDPIC__
+#if defined(__FRV_FDPIC__) || defined(__BFIN_FDPIC__)
struct elf32_fdpic_loadaddr dlpi_addr;
#else
#ifdef __DSBT__
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index 57f0ddc15..80625fd5b 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -203,7 +203,7 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info
/* Don't adjust .dynamic unnecessarily. For FDPIC targets,
we'd have to walk all the loadsegs to find out if it was
actually unnecessary, so skip this optimization. */
-#if !defined __FDPIC__ && !defined __DSBT__
+#if !defined __FRV_FDPIC__ && !defined __BFIN_FDPIC__ && !defined __DSBT__
if (load_off != 0)
#endif
{
diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h
index 18f21aefa..d6282bb0c 100644
--- a/ldso/include/dl-hash.h
+++ b/ldso/include/dl-hash.h
@@ -135,7 +135,7 @@ struct elf_resolve {
unsigned long data_words;
#endif
-#ifdef __FDPIC__
+#if defined(__FRV_FDPIC__) || defined(__BFIN_FDPIC__)
/* Every loaded module holds a hashtable of function descriptors of
functions defined in it, such that it's easy to release the
memory when the module is dlclose()d. */
diff --git a/ldso/ldso/bfin/dl-sysdep.h b/ldso/ldso/bfin/dl-sysdep.h
index a026b641d..5758117ba 100644
--- a/ldso/ldso/bfin/dl-sysdep.h
+++ b/ldso/ldso/bfin/dl-sysdep.h
@@ -79,7 +79,7 @@ while (0)
#define DL_MAP_SEGMENT(EPNT, PPNT, INFILE, FLAGS) \
__dl_map_segment (EPNT, PPNT, INFILE, FLAGS)
-#if defined(__FDPIC__)
+#if defined(__BFIN_FDPIC__)
#include "../fdpic/dl-sysdep.h"
static __always_inline Elf32_Addr
diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c
index 2c659dc58..740626e27 100644
--- a/ldso/ldso/dl-hash.c
+++ b/ldso/ldso/dl-hash.c
@@ -378,7 +378,7 @@ char *_dl_find_hash(const char *name, struct r_scope_elem *scope, struct elf_res
break;
#endif
case STB_GLOBAL:
-#ifdef __FDPIC__
+#if defined(__FRV_FDPIC__) || defined(__BFIN_FDPIC__)
if (sym_ref)
sym_ref->tpnt = tpnt;
#endif
@@ -387,7 +387,7 @@ char *_dl_find_hash(const char *name, struct r_scope_elem *scope, struct elf_res
break;
}
}
-#ifdef __FDPIC__
+#if defined(__FRV_FDPIC__) || defined(__BFIN_FDPIC__)
if (sym_ref)
sym_ref->tpnt = tpnt;
#endif
diff --git a/ldso/ldso/fdpic/dl-inlines.h b/ldso/ldso/fdpic/dl-inlines.h
index ebbd0334c..a9bfc9311 100644
--- a/ldso/ldso/fdpic/dl-inlines.h
+++ b/ldso/ldso/fdpic/dl-inlines.h
@@ -176,6 +176,10 @@ _dl_funcdesc_for (void *entry_point, void *got_value)
}
entry = htab_find_slot(ht, entry_point, 1, hash_pointer, eq_pointer);
+
+ if (entry == NULL)
+ _dl_exit(1);
+
if (*entry) {
_dl_assert((*entry)->entry_point == entry_point);
return _dl_stabilize_funcdesc(*entry);
diff --git a/ldso/ldso/frv/dl-startup.h b/ldso/ldso/frv/dl-startup.h
index 2aa7baa56..45e9cb9ce 100644
--- a/ldso/ldso/frv/dl-startup.h
+++ b/ldso/ldso/frv/dl-startup.h
@@ -27,9 +27,10 @@
__asm__("" \
" .text\n" \
-" .global _dl_boot\n" \
-" .type _dl_boot,@function\n" \
-"_dl_boot:\n" \
+" .global _start\n" \
+" .type _start,@function\n" \
+" .hidden _start\n" \
+"_start:\n" \
" call .Lcall\n" \
".Lcall:\n" \
" movsg lr, gr4\n" \
@@ -54,18 +55,18 @@ __asm__("" \
" addi.p sp, #4, gr13\n" \
" addi sp, #-8, sp\n" \
" mov.p sp, gr12\n" \
-" call _dl_boot2\n" \
+" call _dl_start\n" \
" ldd.p @(sp, gr0), gr14\n" \
" addi sp, #8, sp\n" \
" movgs gr0, lr\n" \
" jmpl @(gr14, gr0)\n" \
-" .size _dl_boot,.-_dl_boot\n" \
+" .size _start,.-_start\n" \
);
-#define _dl_boot _dl_boot2
-#define DL_BOOT(X) \
+#undef DL_START
+#define DL_START(X) \
static void __attribute__ ((used)) \
-_dl_boot (void *dl_boot_got_pointer, \
+_dl_start (Elf32_Addr dl_boot_got_pointer, \
struct elf32_fdpic_loadmap *dl_boot_progmap, \
struct elf32_fdpic_loadmap *dl_boot_ldsomap, \
Elf32_Dyn *dl_boot_ldso_dyn_pointer, \
@@ -115,6 +116,5 @@ _dl_boot (void *dl_boot_got_pointer, \
while (exec_mod->libtype != elf_executable) \
exec_mod = exec_mod->next; \
dl_main_funcdesc->got_value = exec_mod->loadaddr.got_value; \
- /* _dl_dprintf(2, "entry point is (%x,%x)\n", dl_main_funcdesc->entry_point, dl_main_funcdesc->got_value); */ \
return; \
} while (0)
diff --git a/ldso/ldso/frv/dl-sysdep.h b/ldso/ldso/frv/dl-sysdep.h
index f4e8b4c67..e6bf7f187 100644
--- a/ldso/ldso/frv/dl-sysdep.h
+++ b/ldso/ldso/frv/dl-sysdep.h
@@ -40,9 +40,6 @@ extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden")));
#define SEND_EARLY_STDERR(S) \
do { static char __s[] = (S); SEND_STDERR (__s); } while (0)
-#define DL_RELOC_ADDR(ADDR, LOADADDR) \
- (__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
-
/* Make sure we only load libraries that use the same number of
general-purpose and floating-point registers the dynamic loader was
compiled for. */
@@ -85,3 +82,16 @@ do \
while (0)
#include "../fdpic/dl-sysdep.h"
+
+static __always_inline Elf32_Addr
+elf_machine_load_address (void)
+{
+ return 0;
+}
+
+static __always_inline void
+elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
+ Elf32_Word relative_count)
+{
+ ;
+}
diff --git a/ldso/ldso/frv/elfinterp.c b/ldso/ldso/frv/elfinterp.c
index 6cb09f81f..2c954b3ab 100644
--- a/ldso/ldso/frv/elfinterp.c
+++ b/ldso/ldso/frv/elfinterp.c
@@ -10,6 +10,7 @@
* Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
*/
+#include <sys/cdefs.h> /* __attribute_used__ */
#include <features.h>
/* Program to load an ELF binary on a linux system, and run it.
@@ -31,34 +32,30 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
ElfW(Sym) *symtab;
int symtab_index;
char *rel_addr;
- struct elf_resolve *new_tpnt;
char *new_addr;
struct funcdesc_value funcval;
struct funcdesc_value volatile *got_entry;
char *symname;
+ struct symbol_ref sym_ref;
- rel_addr = DL_RELOC_ADDR (tpnt->dynamic_info[DT_JMPREL],
- tpnt->loadaddr);
+ rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry);
symtab_index = ELF_R_SYM(this_reloc->r_info);
- symtab = (ElfW(Sym) *)(intptr_t)
- DL_RELOC_ADDR (tpnt->dynamic_info[DT_SYMTAB],
- tpnt->loadaddr);
- strtab = DL_RELOC_ADDR (tpnt->dynamic_info[DT_STRTAB], tpnt->loadaddr);
+ symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB];
+ strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
+ sym_ref.sym = &symtab[symtab_index];
+ sym_ref.tpnt = NULL;
symname= strtab + symtab[symtab_index].st_name;
/* Address of GOT entry fix up */
- got_entry = (struct funcdesc_value *)
- DL_RELOC_ADDR (this_reloc->r_offset, tpnt->loadaddr);
+ got_entry = (struct funcdesc_value *) DL_RELOC_ADDR(tpnt->loadaddr, this_reloc->r_offset);
/* Get the address to be used to fill in the GOT entry. */
- new_addr = _dl_find_hash_mod(symname, &_dl_loaded_modules->symbol_scope, NULL, 0,
- &new_tpnt);
+ new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, NULL, 0, &sym_ref);
if (!new_addr) {
- new_addr = _dl_find_hash_mod(symname, NULL, NULL, 0,
- &new_tpnt);
+ new_addr = _dl_find_hash(symname, NULL, NULL, 0, &sym_ref);
if (!new_addr) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
_dl_progname, symname);
@@ -67,7 +64,7 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry)
}
funcval.entry_point = new_addr;
- funcval.got_value = new_tpnt->loadaddr.got_value;
+ funcval.got_value = sym_ref.tpnt->loadaddr.got_value;
#if defined (__SUPPORT_LD_DEBUG__)
if (_dl_debug_bindings)
@@ -103,14 +100,13 @@ _dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope,
int symtab_index;
/* Now parse the relocation information */
- rpnt = (ELF_RELOC *)(intptr_t) DL_RELOC_ADDR (rel_addr, tpnt->loadaddr);
+ rpnt = (ELF_RELOC *) rel_addr;
rel_size = rel_size / sizeof(ELF_RELOC);
- symtab = (ElfW(Sym) *)(intptr_t)
- DL_RELOC_ADDR (tpnt->dynamic_info[DT_SYMTAB], tpnt->loadaddr);
- strtab = DL_RELOC_ADDR (tpnt->dynamic_info[DT_STRTAB], tpnt->loadaddr);
+ symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB];
+ strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
- for (i = 0; i < rel_size; i++, rpnt++) {
+ for (i = 0; i < rel_size; i++, rpnt++) {
int res;
symtab_index = ELF_R_SYM(rpnt->r_info);
@@ -161,24 +157,24 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope,
#if defined (__SUPPORT_LD_DEBUG__)
unsigned long old_val;
#endif
+ struct symbol_ref sym_ref;
- reloc_addr = (unsigned long *)(intptr_t)
- DL_RELOC_ADDR (rpnt->r_offset, tpnt->loadaddr);
+ reloc_addr = (unsigned long *) DL_RELOC_ADDR (tpnt->loadaddr, rpnt->r_offset);
__asm__ ("" : "=r" (reloc_addr_packed) : "0" (reloc_addr));
reloc_type = ELF_R_TYPE(rpnt->r_info);
symtab_index = ELF_R_SYM(rpnt->r_info);
symbol_addr = 0;
+ sym_ref.sym = &symtab[symtab_index];
+ sym_ref.tpnt = NULL;
symname = strtab + symtab[symtab_index].st_name;
if (ELF_ST_BIND (symtab[symtab_index].st_info) == STB_LOCAL) {
- symbol_addr = (unsigned long)
- DL_RELOC_ADDR (symtab[symtab_index].st_value,
- tpnt->loadaddr);
+ symbol_addr = (unsigned long) DL_RELOC_ADDR(tpnt->loadaddr, symtab[symtab_index].st_value);
symbol_tpnt = tpnt;
} else {
symbol_addr = (unsigned long)
- _dl_find_hash_mod(symname, scope, NULL, 0, &symbol_tpnt);
+ _dl_find_hash(symname, scope, NULL, 0, &sym_ref);
/*
* We want to allow undefined references to weak symbols - this might
@@ -191,6 +187,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope,
_dl_progname, strtab + symtab[symtab_index].st_name);
_dl_exit (1);
}
+ symbol_tpnt = sym_ref.tpnt;
}
#if defined (__SUPPORT_LD_DEBUG__)
@@ -276,9 +273,9 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope,
static int
_dl_do_lazy_reloc (struct elf_resolve *tpnt,
- struct r_scope_elem *scope __attribute_used__,
- ELF_RELOC *rpnt, ElfW(Sym) *symtab __attribute_used__,
- char *strtab __attribute_used__)
+ struct r_scope_elem *scope __attribute__((unused)),
+ ELF_RELOC *rpnt, ElfW(Sym) *symtab __attribute__((unused)),
+ char *strtab __attribute__((unused)))
{
int reloc_type;
struct funcdesc_value volatile *reloc_addr;
@@ -288,7 +285,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt,
#endif
reloc_addr = (struct funcdesc_value *)(intptr_t)
- DL_RELOC_ADDR (rpnt->r_offset, tpnt->loadaddr);
+ DL_RELOC_ADDR (tpnt->loadaddr, rpnt->r_offset);
reloc_type = ELF_R_TYPE(rpnt->r_info);
#if defined (__SUPPORT_LD_DEBUG__)
@@ -299,9 +296,7 @@ _dl_do_lazy_reloc (struct elf_resolve *tpnt,
break;
case R_FRV_FUNCDESC_VALUE:
funcval = *reloc_addr;
- funcval.entry_point =
- DL_RELOC_ADDR (funcval.entry_point,
- tpnt->loadaddr);
+ funcval.entry_point = (void *) DL_RELOC_ADDR(tpnt->loadaddr, funcval.entry_point);
funcval.got_value = tpnt->loadaddr.got_value;
*reloc_addr = funcval;
break;
@@ -334,14 +329,14 @@ _dl_parse_relocation_information
int
_dl_parse_copy_information
-(struct dyn_elf *rpnt __attribute_used__,
- unsigned long rel_addr __attribute_used__,
- unsigned long rel_size __attribute_used__)
+(struct dyn_elf *rpnt __attribute__((unused)),
+ unsigned long rel_addr __attribute__((unused)),
+ unsigned long rel_size __attribute__((unused)))
{
return 0;
}
-#ifndef LIBDL
+#ifndef IS_IN_libdl
# include "../../libc/sysdeps/linux/frv/crtreloc.c"
#endif
diff --git a/libc/misc/elf/dl-iterate-phdr.c b/libc/misc/elf/dl-iterate-phdr.c
index 5b86db011..27a92544b 100644
--- a/libc/misc/elf/dl-iterate-phdr.c
+++ b/libc/misc/elf/dl-iterate-phdr.c
@@ -58,7 +58,7 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
/* This entry describes this statically-linked program itself. */
struct dl_phdr_info info;
int ret;
-#if defined(__FDPIC__)
+#if defined(__FRV_FDPIC__) || defined(__BFIN_FDPIC__)
info.dlpi_addr.map = NULL;
info.dlpi_addr.got_value = NULL;
#elif defined(__DSBT__)
diff --git a/libc/sysdeps/linux/frv/Makefile b/libc/sysdeps/linux/frv/Makefile
index 7cdb8eca3..3970f6263 100644
--- a/libc/sysdeps/linux/frv/Makefile
+++ b/libc/sysdeps/linux/frv/Makefile
@@ -1,58 +1,13 @@
# Makefile for uClibc
#
# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
-# ported to FR-V by Alexandre Oliva <aoliva@redhat.com>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
-TOPDIR=../../../../
-include $(TOPDIR)Rules.mak
-
-CRT_SRC := crt0.S
-CRT_OBJ := crt0.o crt1.o
-SCRT_OBJ := $(patsubst %,S%, $(CRT_OBJ))
-
-CTOR_TARGETS := crti.o crtn.o
-
-SSRC := __longjmp.S setjmp.S clone.S vfork.S
-SOBJ := $(patsubst %.S,%.o, $(SSRC))
-
-CSRC = sysdep.c syscall.c brk.c sbrk.c __init_brk.c dl-iterate-phdr.c
-CSRC += xstatconv.c stat.c stat64.c fstat.c fstat64.c lstat.c lstat64.c
-COBJ := $(patsubst %.c,%.o, $(CSRC))
-
-OBJS := $(SOBJ) $(COBJ)
-
-OBJ_LIST := ../../../obj.sysdeps.$(TARGET_ARCH)
-
-all: $(OBJ_LIST)
-
-$(OBJ_LIST): $(OBJS) $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS)
- $(STRIPTOOL) -x -R .note -R .comment $^
- $(INSTALL) -d $(TOPDIR)lib/
- cp $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS) $(TOPDIR)lib/
- echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $@
-
-$(CRT_OBJ): $(CRT_SRC) crtreloc.o
- $(CC) $(ASFLAGS) -DL_$* -r -nostdlib $^ -o $*.o
-
-crtreloc.o: crtreloc.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-$(SCRT_OBJ): $(CRT_SRC) Scrtreloc.o
- $(CC) $(ASFLAGS) $(PIEFLAG) -DL_$* -r -nostdlib $^ -o $*.o
-
-Scrtreloc.o: crtreloc.c
- $(CC) $(CFLAGS) $(PIEFLAG) -c $< -o $@
-
-$(CTOR_TARGETS): %.o : %.S
- $(CC) $(ASFLAGS) $(SSP_DISABLE_FLAGS) -c $< -o $@
-
-$(SOBJ): %.o : %.S
- $(CC) $(ASFLAGS) -c $< -o $@
-
-$(COBJ): %.o : %.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-clean:
- $(RM) *.o *~ core
+top_srcdir=../../../../
+top_builddir=../../../../
+all: objs
+include $(top_builddir)Rules.mak
+include Makefile.arch
+include $(top_srcdir)Makerules
diff --git a/libc/sysdeps/linux/frv/Makefile.arch b/libc/sysdeps/linux/frv/Makefile.arch
new file mode 100644
index 000000000..be48fd007
--- /dev/null
+++ b/libc/sysdeps/linux/frv/Makefile.arch
@@ -0,0 +1,11 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+# ported to FR-V by Alexandre Oliva <aoliva@redhat.com>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+CSRC-y := sysdep.c syscall.c brk.c sbrk.c __init_brk.c dl-iterate-phdr.c
+
+SSRC-y := __longjmp.S setjmp.S clone.S vfork.S
+
diff --git a/libc/sysdeps/linux/frv/bits/fcntl.h b/libc/sysdeps/linux/frv/bits/fcntl.h
index 0ef5f29e9..0581f2bf3 100644
--- a/libc/sysdeps/linux/frv/bits/fcntl.h
+++ b/libc/sysdeps/linux/frv/bits/fcntl.h
@@ -22,6 +22,9 @@
#include <sys/types.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
located on an ext2 file system */
diff --git a/libc/sysdeps/linux/frv/bits/kernel_types.h b/libc/sysdeps/linux/frv/bits/kernel_types.h
index 8403fd3e8..be4fe224f 100644
--- a/libc/sysdeps/linux/frv/bits/kernel_types.h
+++ b/libc/sysdeps/linux/frv/bits/kernel_types.h
@@ -31,6 +31,9 @@ typedef unsigned int __kernel_gid32_t;
typedef unsigned short __kernel_old_uid_t;
typedef unsigned short __kernel_old_gid_t;
typedef long long __kernel_loff_t;
+typedef __kernel_dev_t __kernel_old_dev_t;
+typedef long __kernel_long_t;
+typedef unsigned long __kernel_ulong_t;
typedef struct {
#ifdef __USE_ALL
diff --git a/libc/sysdeps/linux/frv/bits/stat.h b/libc/sysdeps/linux/frv/bits/stat.h
index 83f5b4726..e6a1944bb 100644
--- a/libc/sysdeps/linux/frv/bits/stat.h
+++ b/libc/sysdeps/linux/frv/bits/stat.h
@@ -70,6 +70,20 @@ struct stat
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
unsigned long int __unused1;
__time_t st_atime; /* Time of last access. */
@@ -78,7 +92,7 @@ struct stat
unsigned long int __unused3;
__time_t st_ctime; /* Time of last status change. */
-
+#endif
unsigned long long __unused4;
};
@@ -103,7 +117,20 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-
+#ifdef __USE_MISC
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
unsigned long int __unused1;
__time_t st_atime; /* Time of last access. */
@@ -112,7 +139,7 @@ struct stat64
unsigned long int __unused3;
__time_t st_ctime; /* Time of last status change. */
-
+#endif
unsigned long long __unused4;
};
#endif
diff --git a/libc/sysdeps/linux/frv/bits/syscalls.h b/libc/sysdeps/linux/frv/bits/syscalls.h
index b1f532040..b03e8dbe0 100644
--- a/libc/sysdeps/linux/frv/bits/syscalls.h
+++ b/libc/sysdeps/linux/frv/bits/syscalls.h
@@ -10,128 +10,71 @@
#define SYS_ify(syscall_name) (__NR_##syscall_name)
-/* 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 (unlikely ((unsigned long)(__sr2) >= (unsigned long)(-4095))) { \
- 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 (unlikely ((unsigned long)(__sr2) >= (unsigned long)(-4095))) { \
- __set_errno (-__sr2); \
- __sr2 = -1; \
- } \
- return (type) (__sr2); \
-} while (0)
-#endif
-
-#ifndef __set_errno
-# define __set_errno(val) ((*__errno_location ()) = (val))
-#endif
-
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
-
-#define _syscall0(type,name) \
-type name(void) \
-{ \
-register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
-register unsigned long __sc0 __asm__ ("gr8"); \
-__asm__ __volatile__ ("tra gr0,gr0" \
- : "=r" (__sc0) \
- : "r" (__scnum)); \
-__syscall_return(type,__sc0); \
-}
-
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
-register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
-register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
-__asm__ __volatile__ ("tra gr0,gr0" \
- : "+r" (__sc0) \
- : "r" (__scnum)); \
-__syscall_return(type,__sc0); \
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1,type2 arg2) \
-{ \
-register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
-register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
-register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
-__asm__ __volatile__ ("tra gr0,gr0" \
- : "+r" (__sc0) \
- : "r" (__scnum), "r" (__sc1)); \
-__syscall_return(type,__sc0); \
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1,type2 arg2,type3 arg3) \
-{ \
-register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
-register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
-register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
-register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \
-__asm__ __volatile__ ("tra gr0,gr0" \
- : "+r" (__sc0) \
- : "r" (__scnum), "r" (__sc1), "r" (__sc2)); \
-__syscall_return(type,__sc0); \
-}
+#define INLINE_SYSCALL_NCS(name, nr, args...) \
+(__extension__ \
+ ({ \
+ unsigned int _inline_sys_result = INTERNAL_SYSCALL_NCS (name, , nr, args);\
+ if (unlikely (INTERNAL_SYSCALL_ERROR_P (_inline_sys_result, ))) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (_inline_sys_result, )); \
+ _inline_sys_result = (unsigned int) -1; \
+ } \
+ (int) _inline_sys_result; \
+ }) \
+)
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
-register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
-register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
-register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
-register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \
-register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \
-__asm__ __volatile__ ("tra gr0,gr0" \
- : "+r" (__sc0) \
- : "r" (__scnum), "r" (__sc1), "r" (__sc2), "r" (__sc3)); \
-__syscall_return(type,__sc0); \
-}
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+(__extension__ \
+ ({unsigned int __internal_sys_result; \
+ { \
+ register int __a1 __asm__ ("gr8"); \
+ register int _nr __asm__ ("gr7"); \
+ LOAD_ARGS_##nr (args) \
+ _nr = (name); \
+ __asm__ __volatile__ ("tra gr0,gr0" \
+ : "=r" (__a1) \
+ : "r" (_nr) ASM_ARGS_##nr \
+ : "memory"); \
+ __internal_sys_result = __a1; \
+ } \
+ (int) __internal_sys_result; }) \
+)
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
-{ \
-register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
-register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
-register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
-register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \
-register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \
-register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5; \
-__asm__ __volatile__ ("tra gr0,gr0" \
- : "+r" (__sc0) \
- : "r" (__scnum), "r" (__sc1), "r" (__sc2), \
- "r" (__sc3), "r" (__sc4)); \
-__syscall_return(type,__sc0); \
-}
+#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((unsigned int) (val) >= 0xfffff001u)
-#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5, type6, arg6) \
-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
-{ \
-register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \
-register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \
-register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \
-register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \
-register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \
-register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5; \
-register unsigned long __sc5 __asm__ ("gr13") = (unsigned long) arg6; \
-__asm__ __volatile__ ("tra gr0,gr0" \
- : "+r" (__sc0) \
- : "r" (__scnum), "r" (__sc1), "r" (__sc2), \
- "r" (__sc3), "r" (__sc4), "r" (__sc5)); \
-__syscall_return(type,__sc0); \
-}
+#define LOAD_ARGS_0()
+#define ASM_ARGS_0
+#define LOAD_ARGS_1(a1) \
+ int __a1tmp = (int) (a1); \
+ LOAD_ARGS_0 () \
+ __a1 = __a1tmp;
+#define ASM_ARGS_1 ASM_ARGS_0, "r" (__a1)
+#define LOAD_ARGS_2(a1, a2) \
+ int __a2tmp = (int) (a2); \
+ LOAD_ARGS_1 (a1) \
+ register int __a2 __asm__ ("gr8") = __a2tmp;
+#define ASM_ARGS_2 ASM_ARGS_1, "r" (__a2)
+#define LOAD_ARGS_3(a1, a2, a3) \
+ int __a3tmp = (int) (a3); \
+ LOAD_ARGS_2 (a1, a2) \
+ register int __a3 __asm__ ("gr9") = __a3tmp;
+#define ASM_ARGS_3 ASM_ARGS_2, "r" (__a3)
+#define LOAD_ARGS_4(a1, a2, a3, a4) \
+ int __a4tmp = (int) (a4); \
+ LOAD_ARGS_3 (a1, a2, a3) \
+ register int __a4 __asm__ ("gr10") = __a4tmp;
+#define ASM_ARGS_4 ASM_ARGS_3, "r" (__a4)
+#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
+ int __v1tmp = (int) (a5); \
+ LOAD_ARGS_4 (a1, a2, a3, a4) \
+ register int __v1 __asm__ ("gr11") = __v1tmp;
+#define ASM_ARGS_5 ASM_ARGS_4, "r" (__v1)
+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
+ int __v2tmp = (int) (a6); \
+ LOAD_ARGS_5 (a1, a2, a3, a4, a5) \
+ register int __v2 __asm__ ("gr12") = __v2tmp;
+#define ASM_ARGS_6 ASM_ARGS_5, "r" (__v2)
#endif /* __ASSEMBLER__ */
#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/frv/bits/uClibc_arch_features.h b/libc/sysdeps/linux/frv/bits/uClibc_arch_features.h
index 293cc9b00..f660fd223 100644
--- a/libc/sysdeps/linux/frv/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/frv/bits/uClibc_arch_features.h
@@ -37,6 +37,6 @@
#define __UCLIBC_HAVE_SIGNED_ZERO__
/* only weird assemblers generally need this */
-#undef __UCLIBC_ASM_LINE_SEP__
+#define __UCLIBC_ASM_LINE_SEP__ !
#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */
diff --git a/libc/sysdeps/linux/frv/crt0.S b/libc/sysdeps/linux/frv/crt1.S
index 59f61f94f..0827feae7 100644
--- a/libc/sysdeps/linux/frv/crt0.S
+++ b/libc/sysdeps/linux/frv/crt1.S
@@ -44,13 +44,10 @@ not, see <http://www.gnu.org/licenses/>. */
.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
+ .type __uClibc_main,%function
+
_start:
/* Make sure the stack pointer is properly aligned. Save the
original value in gr21 such that we can get to arguments and
@@ -104,7 +101,7 @@ _start:
ld.p @(gr11, gr17), gr11
mov gr17, gr15
ld.p @(gr12, gr17), gr12
- call __uClibc_start_main
+ call __uClibc_main
#else
mov.p gr17, gr15
call __uClibc_main
diff --git a/libc/sysdeps/linux/frv/crtreloc.c b/libc/sysdeps/linux/frv/crtreloc.c
index cd07170a8..b1d542395 100644
--- a/libc/sysdeps/linux/frv/crtreloc.c
+++ b/libc/sysdeps/linux/frv/crtreloc.c
@@ -25,6 +25,8 @@ 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, see <http://www.gnu.org/licenses/>. */
+#ifdef __FRV_FDPIC__
+
#include <sys/types.h>
#include <link.h>
@@ -61,7 +63,7 @@ reloc_range_indirect (void ***p, void ***e,
/* 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* attribute_hidden
+attribute_hidden void*
__self_reloc (const struct elf32_fdpic_loadmap *map,
void ***p, void ***e)
{
@@ -72,48 +74,4 @@ __self_reloc (const struct elf32_fdpic_loadmap *map,
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). */
-static __always_inline 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 attribute_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* attribute_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 /* __FRV_FDPIC__ */
diff --git a/libc/sysdeps/linux/frv/jmpbuf-unwind.h b/libc/sysdeps/linux/frv/jmpbuf-unwind.h
index b58f3f0e3..c22ab2409 100644
--- a/libc/sysdeps/linux/frv/jmpbuf-unwind.h
+++ b/libc/sysdeps/linux/frv/jmpbuf-unwind.h
@@ -10,5 +10,3 @@
containing a local variable at ADDRESS. */
#define _JMPBUF_UNWINDS(jmpbuf, address) \
((void *) (address) < (void *) (jmpbuf)->__sp)
-
-#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/linux/frv/syscall.c b/libc/sysdeps/linux/frv/syscall.c
index 68fe55696..a98cf3832 100644
--- a/libc/sysdeps/linux/frv/syscall.c
+++ b/libc/sysdeps/linux/frv/syscall.c
@@ -37,5 +37,5 @@ long syscall(long sysnum, long arg1, long arg2, long arg3,
: "+r" (__sc0)
: "r" (__scnum), "r" (__sc1), "r" (__sc2),
"r" (__sc3), "r" (__sc4), "r" (__sc5));
- __syscall_return(long,__sc0);
+ return (long) __sc0;
}