[git commit prelink] Add support for DSBT ELF to ld.so

Mark Salter msalter at redhat.com
Wed Apr 6 13:19:49 UTC 2011


commit: http://git.uclibc.org/uClibc/commit/?id=95adc01517efce365da4e40e0d2a081ec4497928
branch: http://git.uclibc.org/uClibc/commit/?id=refs/heads/prelink

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 at redhat.com>
Signed-off-by: Aurelien Jacquiot <a-jacquiot at ti.com>
Signed-off-by: Bernd Schmidt <bernds at codesourcery.com>
---
 include/link.h                  |   13 ++++++++++++-
 ldso/include/dl-defs.h          |    2 +-
 ldso/include/dl-elf.h           |   11 ++++++++++-
 ldso/ldso/dl-elf.c              |   23 ++++++++++++++++++++++-
 ldso/ldso/ldso.c                |   11 ++++++++++-
 libc/misc/elf/dl-iterate-phdr.c |    4 +++-
 6 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/include/link.h b/include/link.h
index cbef616..185ee70 100644
--- a/include/link.h
+++ b/include/link.h
@@ -1,6 +1,6 @@
 /* Data structure for communication from the run-time dynamic linker for
    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.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -83,6 +83,9 @@ extern ElfW(Dyn) _DYNAMIC[];
 #ifdef __FDPIC__
 # include <bits/elf-fdpic.h>
 #endif
+#ifdef __DSBT__
+# include <bits/elf-dsbt.h>
+#endif
 
 /* Structure describing a loaded shared object.  The `l_next' and `l_prev'
    members form a chain of all the shared objects loaded at startup.
@@ -98,8 +101,12 @@ struct link_map
 #ifdef __FDPIC__
     struct elf32_fdpic_loadaddr l_addr;
 #else
+#ifdef __DSBT__
+    struct elf32_dsbt_loadaddr l_addr;
+#else
     ElfW(Addr) l_addr;		/* Base address shared object is loaded at.  */
 #endif
+#endif
     char *l_name;		/* Absolute file name object was found in.  */
     ElfW(Dyn) *l_ld;		/* Dynamic section of the shared object.  */
     struct link_map *l_next, *l_prev; /* Chain of loaded objects.  */
@@ -178,8 +185,12 @@ struct dl_phdr_info
 #ifdef __FDPIC__
     struct elf32_fdpic_loadaddr dlpi_addr;
 #else
+#ifdef __DSBT__
+    struct elf32_dsbt_loadaddr dlpi_addr;
+#else
     ElfW(Addr) dlpi_addr;
 #endif
+#endif
     const char *dlpi_name;
     const ElfW(Phdr) *dlpi_phdr;
     ElfW(Half) dlpi_phnum;
diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h
index 2d6303c..be0a81d 100644
--- a/ldso/include/dl-defs.h
+++ b/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
    matching SYM was found.  */
 #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
 
 /* Unmap all previously-mapped segments accumulated in LOADADDR.
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index 5aec64f..7fbb373 100644
--- a/ldso/include/dl-elf.h
+++ b/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,
 	   we'd have to walk all the loadsegs to find out if it was
 	   actually unnecessary, so skip this optimization.  */
-#ifndef __FDPIC__
+#if !defined __FDPIC__ && !defined __DSBT__
 	if (load_off != 0)
 #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);
 #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
 	return rtld_flags;
 }
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 61d4959..4cbd338 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -188,7 +188,7 @@ unsigned long _dl_error_number;
 unsigned long _dl_internal_error_number;
 
 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;
 	struct elf_resolve *tpnt1;
@@ -806,6 +806,27 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 		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("\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",
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 4d79d46..7ee9257 100644
--- a/ldso/ldso/ldso.c
+++ b/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(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
 		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->dynamic_info,
 					      (unsigned long)tpnt->dynamic_addr,
diff --git a/libc/misc/elf/dl-iterate-phdr.c b/libc/misc/elf/dl-iterate-phdr.c
index a7677f1..f0233ca 100644
--- a/libc/misc/elf/dl-iterate-phdr.c
+++ b/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.  */
       struct dl_phdr_info info;
       int ret;
-#ifdef __FDPIC__
+#if defined(__FDPIC__)
       info.dlpi_addr.map = NULL;
       info.dlpi_addr.got_value = NULL;
+#elif defined(__DSBT__)
+      info.dlpi_addr.map = NULL;
 #else
       info.dlpi_addr = 0;
 #endif
-- 
1.7.3.4



More information about the uClibc-cvs mailing list