From c0a2d0b7edacbc6389574821b0231e07431dabb6 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Fri, 5 Feb 2016 21:07:40 +0100 Subject: 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. --- ldso/ldso/bfin/dl-sysdep.h | 2 +- ldso/ldso/dl-hash.c | 4 +-- ldso/ldso/fdpic/dl-inlines.h | 4 +++ ldso/ldso/frv/dl-startup.h | 18 ++++++------ ldso/ldso/frv/dl-sysdep.h | 16 +++++++++-- ldso/ldso/frv/elfinterp.c | 67 ++++++++++++++++++++------------------------ 6 files changed, 60 insertions(+), 51 deletions(-) (limited to 'ldso/ldso') 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 /* __attribute_used__ */ #include /* 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 -- cgit v1.2.3