summaryrefslogtreecommitdiff
path: root/ldso
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 /ldso
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.
Diffstat (limited to 'ldso')
-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
8 files changed, 62 insertions, 53 deletions
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