diff options
| author | Waldemar Brodkorb <wbx@openadk.org> | 2016-02-05 21:07:40 +0100 | 
|---|---|---|
| committer | Waldemar Brodkorb <wbx@uclibc-ng.org> | 2016-02-07 18:23:22 +0100 | 
| commit | c0a2d0b7edacbc6389574821b0231e07431dabb6 (patch) | |
| tree | f2d21c6e2fe8f99ccd820d1d406dc5d51419ba77 | |
| parent | b499fe614ac5b492fc0fdc6e1fbbeeb904674159 (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.
23 files changed, 195 insertions, 293 deletions
@@ -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;  }  | 
