Sfoglia il codice sorgente

Add support for DSBT ELF to ld.so

This adds support for DSBT ELF to ld.so.  This uses loadmaps like FD-PIC.
Some code is added in ld.so to initialize the DSBT tables, and there's
also a new target macro FINISH_BOOTSTRAP_RELOC.

Signed-off-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Aurelien Jacquiot <a-jacquiot@ti.com>
Signed-off-by: Bernd Schmidt <bernds@codesourcery.com>
Mark Salter 14 anni fa
parent
commit
95adc01517

+ 12 - 1
include/link.h

@@ -1,6 +1,6 @@
 /* Data structure for communication from the run-time dynamic linker for
 /* Data structure for communication from the run-time dynamic linker for
    loaded ELF shared objects.
    loaded ELF shared objects.
-   Copyright (C) 1995-2001, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1995-2001, 2004, 2005, 2006, 2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    This file is part of the GNU C Library.
 
 
    The GNU C Library is free software; you can redistribute it and/or
    The GNU C Library is free software; you can redistribute it and/or
@@ -83,6 +83,9 @@ extern ElfW(Dyn) _DYNAMIC[];
 #ifdef __FDPIC__
 #ifdef __FDPIC__
 # include <bits/elf-fdpic.h>
 # include <bits/elf-fdpic.h>
 #endif
 #endif
+#ifdef __DSBT__
+# include <bits/elf-dsbt.h>
+#endif
 
 
 /* Structure describing a loaded shared object.  The `l_next' and `l_prev'
 /* Structure describing a loaded shared object.  The `l_next' and `l_prev'
    members form a chain of all the shared objects loaded at startup.
    members form a chain of all the shared objects loaded at startup.
@@ -97,8 +100,12 @@ struct link_map
 
 
 #ifdef __FDPIC__
 #ifdef __FDPIC__
     struct elf32_fdpic_loadaddr l_addr;
     struct elf32_fdpic_loadaddr l_addr;
+#else
+#ifdef __DSBT__
+    struct elf32_dsbt_loadaddr l_addr;
 #else
 #else
     ElfW(Addr) l_addr;		/* Base address shared object is loaded at.  */
     ElfW(Addr) l_addr;		/* Base address shared object is loaded at.  */
+#endif
 #endif
 #endif
     char *l_name;		/* Absolute file name object was found in.  */
     char *l_name;		/* Absolute file name object was found in.  */
     ElfW(Dyn) *l_ld;		/* Dynamic section of the shared object.  */
     ElfW(Dyn) *l_ld;		/* Dynamic section of the shared object.  */
@@ -177,8 +184,12 @@ struct dl_phdr_info
   {
   {
 #ifdef __FDPIC__
 #ifdef __FDPIC__
     struct elf32_fdpic_loadaddr dlpi_addr;
     struct elf32_fdpic_loadaddr dlpi_addr;
+#else
+#ifdef __DSBT__
+    struct elf32_dsbt_loadaddr dlpi_addr;
 #else
 #else
     ElfW(Addr) dlpi_addr;
     ElfW(Addr) dlpi_addr;
+#endif
 #endif
 #endif
     const char *dlpi_name;
     const char *dlpi_name;
     const ElfW(Phdr) *dlpi_phdr;
     const ElfW(Phdr) *dlpi_phdr;

+ 1 - 1
ldso/include/dl-defs.h

@@ -212,7 +212,7 @@ typedef struct {
    _dl_find_hash for this reloc TYPE.  TPNT is the module in which the
    _dl_find_hash for this reloc TYPE.  TPNT is the module in which the
    matching SYM was found.  */
    matching SYM was found.  */
 #ifndef DL_FIND_HASH_VALUE
 #ifndef DL_FIND_HASH_VALUE
-# define DL_FIND_HASH_VALUE(TPNT, TYPE, SYM) (DL_RELOC_ADDR ((SYM)->st_value, (TPNT)->loadaddr))
+# define DL_FIND_HASH_VALUE(TPNT, TYPE, SYM) (DL_RELOC_ADDR ((TPNT)->loadaddr, (SYM)->st_value))
 #endif
 #endif
 
 
 /* Unmap all previously-mapped segments accumulated in LOADADDR.
 /* Unmap all previously-mapped segments accumulated in LOADADDR.

+ 10 - 1
ldso/include/dl-elf.h

@@ -165,7 +165,7 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info
 	/* Don't adjust .dynamic unnecessarily.  For FDPIC targets,
 	/* Don't adjust .dynamic unnecessarily.  For FDPIC targets,
 	   we'd have to walk all the loadsegs to find out if it was
 	   we'd have to walk all the loadsegs to find out if it was
 	   actually unnecessary, so skip this optimization.  */
 	   actually unnecessary, so skip this optimization.  */
-#ifndef __FDPIC__
+#if !defined __FDPIC__ && !defined __DSBT__
 	if (load_off != 0)
 	if (load_off != 0)
 #endif
 #endif
 	{
 	{
@@ -179,6 +179,15 @@ unsigned int __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info
 		ADJUST_DYN_INFO(DT_GNU_HASH_IDX, load_off);
 		ADJUST_DYN_INFO(DT_GNU_HASH_IDX, load_off);
 #endif
 #endif
 	}
 	}
+#ifdef __DSBT__
+	/* Get the mapped address of the DSBT base.  */
+	ADJUST_DYN_INFO(DT_DSBT_BASE_IDX, load_off);
+
+	/* Initialize loadmap dsbt info.  */
+	load_off.map->dsbt_table = dynamic_info[DT_DSBT_BASE_IDX];
+	load_off.map->dsbt_size = dynamic_info[DT_DSBT_SIZE_IDX];
+	load_off.map->dsbt_index = dynamic_info[DT_DSBT_INDEX_IDX];
+#endif
 #undef ADJUST_DYN_INFO
 #undef ADJUST_DYN_INFO
 	return rtld_flags;
 	return rtld_flags;
 }
 }

+ 22 - 1
ldso/ldso/dl-elf.c

@@ -188,7 +188,7 @@ unsigned long _dl_error_number;
 unsigned long _dl_internal_error_number;
 unsigned long _dl_internal_error_number;
 
 
 struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
 struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
-	struct elf_resolve *tpnt, char *full_libname, int __attribute__((unused)) trace_loaded_objects)
+	struct elf_resolve *tpnt, char *full_libname, int attribute_unused trace_loaded_objects)
 {
 {
 	char *pnt;
 	char *pnt;
 	struct elf_resolve *tpnt1;
 	struct elf_resolve *tpnt1;
@@ -806,6 +806,27 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 		INIT_GOT(lpnt, tpnt);
 		INIT_GOT(lpnt, tpnt);
 	}
 	}
 
 
+#ifdef __DSBT__
+	/* Handle DSBT initialization */
+	{
+		struct elf_resolve *t, *ref = NULL;
+		int idx = tpnt->loadaddr.map->dsbt_index;
+		unsigned *dsbt = tpnt->loadaddr.map->dsbt_table;
+
+		/*
+		 * Setup dsbt slot for this module in dsbt of all modules.
+		 */
+		for (t = _dl_loaded_modules; t; t = t->next) {
+			/* find a dsbt table from another module */
+			if (ref == NULL && t != tpnt)
+				ref = t;
+			t->loadaddr.map->dsbt_table[idx] = (unsigned)dsbt;
+		}
+		if (ref)
+			_dl_memcpy(dsbt, ref->loadaddr.map->dsbt_table,
+				   tpnt->loadaddr.map->dsbt_size * sizeof(unsigned *));
+	}
+#endif
 	_dl_if_debug_dprint("\n\tfile='%s';  generating link map\n", libname);
 	_dl_if_debug_dprint("\n\tfile='%s';  generating link map\n", libname);
 	_dl_if_debug_dprint("\t\tdynamic: %x  base: %x\n", dynamic_addr, DL_LOADADDR_BASE(lib_loadaddr));
 	_dl_if_debug_dprint("\t\tdynamic: %x  base: %x\n", dynamic_addr, DL_LOADADDR_BASE(lib_loadaddr));
 	_dl_if_debug_dprint("\t\t  entry: %x  phdr: %x  phnum: %x\n\n",
 	_dl_if_debug_dprint("\t\t  entry: %x  phdr: %x  phnum: %x\n\n",

+ 10 - 1
ldso/ldso/ldso.c

@@ -868,7 +868,16 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 		ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
 		ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
 		ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
 		ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
 		int j;
 		int j;
-
+#ifdef __DSBT__
+		struct elf_resolve *ref = _dl_loaded_modules;
+		_dl_if_debug_dprint("ref is %x, dsbt %x, ref-dsbt %x size %x\n",
+				    ref, tpnt->loadaddr.map->dsbt_table,
+				    ref->loadaddr.map->dsbt_table,
+				    tpnt->loadaddr.map->dsbt_size);
+
+		_dl_memcpy(tpnt->loadaddr.map->dsbt_table, ref->loadaddr.map->dsbt_table,
+			   tpnt->loadaddr.map->dsbt_size * sizeof(unsigned *));
+#endif
 		tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
 		tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
 					      tpnt->dynamic_info,
 					      tpnt->dynamic_info,
 					      (unsigned long)tpnt->dynamic_addr,
 					      (unsigned long)tpnt->dynamic_addr,

+ 3 - 1
libc/misc/elf/dl-iterate-phdr.c

@@ -62,9 +62,11 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
       /* This entry describes this statically-linked program itself.  */
       /* This entry describes this statically-linked program itself.  */
       struct dl_phdr_info info;
       struct dl_phdr_info info;
       int ret;
       int ret;
-#ifdef __FDPIC__
+#if defined(__FDPIC__)
       info.dlpi_addr.map = NULL;
       info.dlpi_addr.map = NULL;
       info.dlpi_addr.got_value = NULL;
       info.dlpi_addr.got_value = NULL;
+#elif defined(__DSBT__)
+      info.dlpi_addr.map = NULL;
 #else
 #else
       info.dlpi_addr = 0;
       info.dlpi_addr = 0;
 #endif
 #endif