Browse Source

patch from Bernd Schmidt to abstract away initializing of relocation addresses

Mike Frysinger 18 years ago
parent
commit
47319595bd
7 changed files with 84 additions and 46 deletions
  1. 33 0
      ldso/include/dl-defs.h
  2. 1 1
      ldso/include/dl-elf.h
  3. 13 10
      ldso/ldso/dl-elf.c
  4. 3 3
      ldso/ldso/dl-hash.c
  5. 5 5
      ldso/ldso/dl-startup.c
  6. 23 21
      ldso/ldso/ldso.c
  7. 6 6
      ldso/libdl/libdl.c

+ 33 - 0
ldso/include/dl-defs.h

@@ -75,6 +75,14 @@ typedef struct {
 # define DL_LOADADDR_TYPE ElfW(Addr)
 # define DL_LOADADDR_TYPE ElfW(Addr)
 #endif
 #endif
 
 
+/* When DL_LOADADDR_TYPE is not a scalar value, or some different
+ * computation is needed to relocate an address, define this.
+ */
+#ifndef DL_RELOC_ADDR
+# define DL_RELOC_ADDR(LOADADDR, ADDR) \
+	((LOADADDR) + (ADDR))
+#endif
+
 /* Initialize a LOADADDR representing the loader itself.  It's only
 /* Initialize a LOADADDR representing the loader itself.  It's only
  * called from DL_BOOT, so additional arguments passed to it may be
  * called from DL_BOOT, so additional arguments passed to it may be
  * referenced.
  * referenced.
@@ -84,6 +92,24 @@ typedef struct {
 	((LOADADDR) = (BASEADDR))
 	((LOADADDR) = (BASEADDR))
 #endif
 #endif
 
 
+/* Define if any declarations/definitions of local variables are
+ * needed in a function that calls DT_INIT_LOADADDR or
+ * DL_INIT_LOADADDR_HDR.  Declarations must be properly terminated
+ * with a semicolon, and non-declaration statements are forbidden.
+ */
+#ifndef DL_INIT_LOADADDR_EXTRA_DECLS
+# define DL_INIT_LOADADDR_EXTRA_DECLS /* int i; */
+#endif
+
+/* Prepare a DL_LOADADDR_TYPE data structure for incremental
+ * initialization with DL_INIT_LOADADDR_HDR, given pointers to a base
+ * load address and to program headers.
+ */
+#ifndef DL_INIT_LOADADDR
+# define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
+	((LOADADDR) = (BASEADDR))
+#endif
+
 /* Initialize a LOADADDR representing the program.  It's called from
 /* Initialize a LOADADDR representing the program.  It's called from
  * DL_BOOT only.
  * DL_BOOT only.
  */
  */
@@ -92,6 +118,13 @@ typedef struct {
 	((LOADADDR) = (DL_LOADADDR_TYPE)(BASEADDR))
 	((LOADADDR) = (DL_LOADADDR_TYPE)(BASEADDR))
 #endif
 #endif
 
 
+/* Convert a DL_LOADADDR_TYPE to an identifying pointer.  Used mostly
+ * for debugging.
+ */
+#ifndef DL_LOADADDR_BASE
+# define DL_LOADADDR_BASE(LOADADDR) (LOADADDR)
+#endif
+
 /* Test whether a given ADDR is more likely to be within the memory
 /* Test whether a given ADDR is more likely to be within the memory
  * region mapped to TPNT (a struct elf_resolve *) than to TFROM.
  * region mapped to TPNT (a struct elf_resolve *) than to TFROM.
  * Everywhere that this is used, TFROM is initially NULL, and whenever
  * Everywhere that this is used, TFROM is initially NULL, and whenever

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

@@ -141,7 +141,7 @@ void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[],
 #define ADJUST_DYN_INFO(tag, load_off) \
 #define ADJUST_DYN_INFO(tag, load_off) \
 	do { \
 	do { \
 		if (dynamic_info[tag]) \
 		if (dynamic_info[tag]) \
-			dynamic_info[tag] += load_off; \
+			dynamic_info[tag] = (unsigned long) DL_RELOC_ADDR(load_off, dynamic_info[tag]); \
 	} while(0)
 	} while(0)
 	ADJUST_DYN_INFO(DT_HASH, load_off);
 	ADJUST_DYN_INFO(DT_HASH, load_off);
 	ADJUST_DYN_INFO(DT_PLTGOT, load_off);
 	ADJUST_DYN_INFO(DT_PLTGOT, load_off);

+ 13 - 10
ldso/ldso/dl-elf.c

@@ -118,9 +118,9 @@ int _dl_unmap_cache(void)
 void
 void
 _dl_protect_relro (struct elf_resolve *l)
 _dl_protect_relro (struct elf_resolve *l)
 {
 {
-	ElfW(Addr) start = ((l->loadaddr + l->relro_addr)
+	ElfW(Addr) start = (DL_RELOC_ADDR(l->loadaddr, l->relro_addr)
 			    & ~(_dl_pagesize - 1));
 			    & ~(_dl_pagesize - 1));
-	ElfW(Addr) end = ((l->loadaddr + l->relro_addr + l->relro_size)
+	ElfW(Addr) end = ((DL_RELOC_ADDR(l->loadaddr, l->relro_addr) + l->relro_size)
 			  & ~(_dl_pagesize - 1));
 			  & ~(_dl_pagesize - 1));
 	_dl_if_debug_dprint("RELRO protecting %s:  start:%x, end:%x\n", l->libname, start, end);
 	_dl_if_debug_dprint("RELRO protecting %s:  start:%x, end:%x\n", l->libname, start, end);
 	if (start != end &&
 	if (start != end &&
@@ -352,8 +352,9 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	ElfW(Addr) relro_addr = 0;
 	ElfW(Addr) relro_addr = 0;
 	size_t relro_size = 0;
 	size_t relro_size = 0;
 	struct stat st;
 	struct stat st;
+	DL_LOADADDR_TYPE lib_loadaddr;
+	DL_INIT_LOADADDR_EXTRA_DECLS
 
 
-	libaddr = 0;
 	infile = _dl_open(libname, O_RDONLY, 0);
 	infile = _dl_open(libname, O_RDONLY, 0);
 	if (infile < 0) {
 	if (infile < 0) {
 		_dl_internal_error_number = LD_ERROR_NOFILE;
 		_dl_internal_error_number = LD_ERROR_NOFILE;
@@ -471,6 +472,8 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	/* Get the memory to store the library */
 	/* Get the memory to store the library */
 	ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
 	ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];
 
 
+	DL_INIT_LOADADDR(lib_loadaddr, libaddr, ppnt, epnt->e_phnum);
+
 	for (i = 0; i < epnt->e_phnum; i++) {
 	for (i = 0; i < epnt->e_phnum; i++) {
 		if (ppnt->p_type == PT_GNU_RELRO) {
 		if (ppnt->p_type == PT_GNU_RELRO) {
 			relro_addr = ppnt->p_vaddr;
 			relro_addr = ppnt->p_vaddr;
@@ -547,7 +550,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 
 	/* For a non-PIC library, the addresses are all absolute */
 	/* For a non-PIC library, the addresses are all absolute */
 	if (piclib) {
 	if (piclib) {
-		dynamic_addr += (unsigned long) libaddr;
+		dynamic_addr = (unsigned long) DL_RELOC_ADDR(lib_loadaddr, dynamic_addr);
 	}
 	}
 
 
 	/*
 	/*
@@ -567,7 +570,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 
 	dpnt = (ElfW(Dyn) *) dynamic_addr;
 	dpnt = (ElfW(Dyn) *) dynamic_addr;
 	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
 	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
-	_dl_parse_dynamic_info(dpnt, dynamic_info, NULL, libaddr);
+	_dl_parse_dynamic_info(dpnt, dynamic_info, NULL, lib_loadaddr);
 	/* If the TEXTREL is set, this means that we need to make the pages
 	/* If the TEXTREL is set, this means that we need to make the pages
 	   writable before we perform relocations.  Do this now. They get set
 	   writable before we perform relocations.  Do this now. They get set
 	   back again later. */
 	   back again later. */
@@ -588,13 +591,13 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 #endif
 #endif
 	}
 	}
 
 
-	tpnt = _dl_add_elf_hash_table(libname, libaddr, dynamic_info,
+	tpnt = _dl_add_elf_hash_table(libname, lib_loadaddr, dynamic_info,
 			dynamic_addr, 0);
 			dynamic_addr, 0);
 	tpnt->relro_addr = relro_addr;
 	tpnt->relro_addr = relro_addr;
 	tpnt->relro_size = relro_size;
 	tpnt->relro_size = relro_size;
 	tpnt->st_dev = st.st_dev;
 	tpnt->st_dev = st.st_dev;
 	tpnt->st_ino = st.st_ino;
 	tpnt->st_ino = st.st_ino;
-	tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);
+	tpnt->ppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(tpnt->loadaddr, epnt->e_phoff);
 	tpnt->n_phent = epnt->e_phnum;
 	tpnt->n_phent = epnt->e_phnum;
 
 
 	/*
 	/*
@@ -625,9 +628,9 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 	}
 	}
 
 
 	_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, libaddr);
+	_dl_if_debug_dprint("\t\tdynamic: %x  base: %x\n", dynamic_addr, DL_LOADADDR_BASE(libaddr));
 	_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",
-			epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent);
+			DL_RELOC_ADDR(lib_loadaddr, epnt->e_entry), tpnt->ppnt, tpnt->n_phent);
 
 
 	_dl_munmap(header, _dl_pagesize);
 	_dl_munmap(header, _dl_pagesize);
 
 
@@ -819,7 +822,7 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void
 	int ret = 0;
 	int ret = 0;
 
 
 	for (l = _dl_loaded_modules; l != NULL; l = l->next) {
 	for (l = _dl_loaded_modules; l != NULL; l = l->next) {
-		info.dlpi_addr = l->loadaddr;
+		info.dlpi_addr = DL_LOADADDR_BASE(l->loadaddr);
 		info.dlpi_name = l->libname;
 		info.dlpi_name = l->libname;
 		info.dlpi_phdr = l->ppnt;
 		info.dlpi_phdr = l->ppnt;
 		info.dlpi_phnum = l->n_phent;
 		info.dlpi_phnum = l->n_phent;

+ 3 - 3
ldso/ldso/dl-hash.c

@@ -163,7 +163,7 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *
 
 
 		/* Avoid calling .urem here. */
 		/* Avoid calling .urem here. */
 		do_rem(hn, elf_hash_number, tpnt->nbucket);
 		do_rem(hn, elf_hash_number, tpnt->nbucket);
-		symtab = (ElfW(Sym) *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB]);
+		symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB];
 		strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]);
 		strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]);
 
 
 		for (si = tpnt->elf_buckets[hn]; si != STN_UNDEF; si = tpnt->chains[si]) {
 		for (si = tpnt->elf_buckets[hn]; si != STN_UNDEF; si = tpnt->chains[si]) {
@@ -184,11 +184,11 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *
 /* Perhaps we should support old style weak symbol handling
 /* Perhaps we should support old style weak symbol handling
  * per what glibc does when you export LD_DYNAMIC_WEAK */
  * per what glibc does when you export LD_DYNAMIC_WEAK */
 				if (!weak_result)
 				if (!weak_result)
-					weak_result = (char *)tpnt->loadaddr + sym->st_value;
+					weak_result = (char *) DL_RELOC_ADDR(tpnt->loadaddr, sym->st_value);
 				break;
 				break;
 #endif
 #endif
 			case STB_GLOBAL:
 			case STB_GLOBAL:
-				return (char*)tpnt->loadaddr + sym->st_value;
+				return (char*) DL_RELOC_ADDR(tpnt->loadaddr, sym->st_value);
 			default:	/* Local symbols not handled here */
 			default:	/* Local symbols not handled here */
 				break;
 				break;
 			}
 			}

+ 5 - 5
ldso/ldso/dl-startup.c

@@ -186,14 +186,14 @@ static void * __attribute_used__ _dl_start(unsigned long args)
 		_dl_exit(0);
 		_dl_exit(0);
 	}
 	}
 	SEND_STDERR_DEBUG("ELF header=");
 	SEND_STDERR_DEBUG("ELF header=");
-	SEND_ADDRESS_STDERR_DEBUG(load_addr, 1);
+	SEND_ADDRESS_STDERR_DEBUG(DL_LOADADDR_BASE(load_addr), 1);
 
 
 	/* Locate the global offset table.  Since this code must be PIC
 	/* Locate the global offset table.  Since this code must be PIC
 	 * we can take advantage of the magic offset register, if we
 	 * we can take advantage of the magic offset register, if we
 	 * happen to know what that is for this architecture.  If not,
 	 * happen to know what that is for this architecture.  If not,
 	 * we can always read stuff out of the ELF file to find it... */
 	 * we can always read stuff out of the ELF file to find it... */
 	got = elf_machine_dynamic();
 	got = elf_machine_dynamic();
-	dpnt = (ElfW(Dyn) *) (got + load_addr);
+	dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(load_addr, got);
 	SEND_STDERR_DEBUG("First Dynamic section entry=");
 	SEND_STDERR_DEBUG("First Dynamic section entry=");
 	SEND_ADDRESS_STDERR_DEBUG(dpnt, 1);
 	SEND_ADDRESS_STDERR_DEBUG(dpnt, 1);
 	_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
 	_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
@@ -259,9 +259,9 @@ static void * __attribute_used__ _dl_start(unsigned long args)
 				rel_addr += relative_count * sizeof(ELF_RELOC);
 				rel_addr += relative_count * sizeof(ELF_RELOC);
 			}
 			}
 
 
-			rpnt = (ELF_RELOC *) (rel_addr + load_addr);
+			rpnt = (ELF_RELOC *) DL_RELOC_ADDR(load_addr, rel_addr);
 			for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
 			for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
-				reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
+				reloc_addr = (unsigned long *) DL_RELOC_ADDR(load_addr, (unsigned long)rpnt->r_offset);
 				symtab_index = ELF_R_SYM(rpnt->r_info);
 				symtab_index = ELF_R_SYM(rpnt->r_info);
 				symbol_addr = 0;
 				symbol_addr = 0;
 				sym = NULL;
 				sym = NULL;
@@ -272,7 +272,7 @@ static void * __attribute_used__ _dl_start(unsigned long args)
 					symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB];
 					symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB];
 					strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
 					strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
 					sym = &symtab[symtab_index];
 					sym = &symtab[symtab_index];
-					symbol_addr = load_addr + sym->st_value;
+					symbol_addr = (unsigned long) DL_RELOC_ADDR(load_addr, sym->st_value);
 
 
 					SEND_STDERR_DEBUG("relocating symbol: ");
 					SEND_STDERR_DEBUG("relocating symbol: ");
 					SEND_STDERR_DEBUG(strtab + sym->st_name);
 					SEND_STDERR_DEBUG(strtab + sym->st_name);

+ 23 - 21
ldso/ldso/ldso.c

@@ -109,7 +109,7 @@ static void _dl_run_array_forward(unsigned long array, unsigned long size,
 		unsigned int jm;
 		unsigned int jm;
 		ElfW(Addr) *addrs;
 		ElfW(Addr) *addrs;
 		jm = size / sizeof (ElfW(Addr));
 		jm = size / sizeof (ElfW(Addr));
-		addrs = (ElfW(Addr) *) (array + loadaddr);
+		addrs = (ElfW(Addr) *) DL_RELOC_ADDR(loadaddr, array);
 		for (j = 0; j < jm; ++j) {
 		for (j = 0; j < jm; ++j) {
 			void (*dl_elf_func) (void);
 			void (*dl_elf_func) (void);
 			dl_elf_func = (void (*)(void)) (intptr_t) addrs[j];
 			dl_elf_func = (void (*)(void)) (intptr_t) addrs[j];
@@ -136,7 +136,7 @@ void _dl_run_fini_array(struct elf_resolve *tpnt);
 void _dl_run_fini_array(struct elf_resolve *tpnt)
 void _dl_run_fini_array(struct elf_resolve *tpnt)
 {
 {
 	if (tpnt->dynamic_info[DT_FINI_ARRAY]) {
 	if (tpnt->dynamic_info[DT_FINI_ARRAY]) {
-		ElfW(Addr) *array = (ElfW(Addr) *) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI_ARRAY]);
+		ElfW(Addr) *array = (ElfW(Addr) *) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI_ARRAY]);
 		unsigned int i = (tpnt->dynamic_info[DT_FINI_ARRAYSZ] / sizeof(ElfW(Addr)));
 		unsigned int i = (tpnt->dynamic_info[DT_FINI_ARRAYSZ] / sizeof(ElfW(Addr)));
 		while (i-- > 0) {
 		while (i-- > 0) {
 			void (*dl_elf_func) (void);
 			void (*dl_elf_func) (void);
@@ -166,7 +166,7 @@ static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
 		if (tpnt->dynamic_info[DT_FINI]) {
 		if (tpnt->dynamic_info[DT_FINI]) {
 			void (*dl_elf_func) (void);
 			void (*dl_elf_func) (void);
 
 
-			dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+			dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
 			_dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
 			_dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
 			(*dl_elf_func) ();
 			(*dl_elf_func) ();
 		}
 		}
@@ -299,9 +299,9 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 				break;
 				break;
 			}
 			}
 
 
-		if (app_tpnt->loadaddr)
+		if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
 			_dl_debug_early("Position Independent Executable: "
 			_dl_debug_early("Position Independent Executable: "
-					"app_tpnt->loadaddr=%x\n", app_tpnt->loadaddr);
+					"app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
 	}
 	}
 
 
 	/*
 	/*
@@ -318,7 +318,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 			relro_size = ppnt->p_memsz;
 			relro_size = ppnt->p_memsz;
 		}
 		}
 		if (ppnt->p_type == PT_DYNAMIC) {
 		if (ppnt->p_type == PT_DYNAMIC) {
-			dpnt = (ElfW(Dyn) *) (ppnt->p_vaddr + app_tpnt->loadaddr);
+			dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
 			_dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
 			_dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
 			/* Ugly, ugly.  We need to call mprotect to change the
 			/* Ugly, ugly.  We need to call mprotect to change the
@@ -332,7 +332,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 				ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
 				ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
 				for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
 				for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
 					if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
 					if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
-						_dl_mprotect((void *) ((ppnt->p_vaddr + app_tpnt->loadaddr) & PAGE_ALIGN),
+						_dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
 							     ((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) +
 							     ((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) +
 							     (unsigned long) ppnt->p_filesz,
 							     (unsigned long) ppnt->p_filesz,
 							     PROT_READ | PROT_WRITE | PROT_EXEC);
 							     PROT_READ | PROT_WRITE | PROT_EXEC);
@@ -347,7 +347,9 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 #endif
 #endif
 			/* OK, we have what we need - slip this one into the list. */
 			/* OK, we have what we need - slip this one into the list. */
 			app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
 			app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
-					app_tpnt->dynamic_info, ppnt->p_vaddr + app_tpnt->loadaddr, ppnt->p_filesz);
+					app_tpnt->dynamic_info,
+					DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
+					ppnt->p_filesz);
 			_dl_loaded_modules->libtype = elf_executable;
 			_dl_loaded_modules->libtype = elf_executable;
 			_dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
 			_dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
 			_dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
 			_dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
@@ -368,7 +370,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 		if (ppnt->p_type == PT_INTERP) {
 		if (ppnt->p_type == PT_INTERP) {
 			char *ptmp;
 			char *ptmp;
 
 
-			tpnt->libname = (char *) ppnt->p_vaddr + app_tpnt->loadaddr;
+			tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
 
 
 			/* Store the path where the shared lib loader was found
 			/* Store the path where the shared lib loader was found
 			 * for later use
 			 * for later use
@@ -378,7 +380,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 			if (ptmp != _dl_ldsopath)
 			if (ptmp != _dl_ldsopath)
 				*ptmp = '\0';
 				*ptmp = '\0';
 
 
-			_dl_debug_early("Lib Loader: (%x) %s\n", tpnt->loadaddr, tpnt->libname);
+			_dl_debug_early("Lib Loader: (%x) %s\n", DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
 		}
 		}
 	}
 	}
 	app_tpnt->relro_addr = relro_addr;
 	app_tpnt->relro_addr = relro_addr;
@@ -450,7 +452,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 	 */
 	 */
 	debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
 	debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
 	debug_addr->r_version = 1;
 	debug_addr->r_version = 1;
-	debug_addr->r_ldbase = load_addr;
+	debug_addr->r_ldbase = DL_LOADADDR_BASE(load_addr);
 	debug_addr->r_brk = (unsigned long) &_dl_debug_state;
 	debug_addr->r_brk = (unsigned long) &_dl_debug_state;
 	_dl_debug_addr = debug_addr;
 	_dl_debug_addr = debug_addr;
 
 
@@ -497,7 +499,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 				} else {
 				} else {
 					tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
 					tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
 
 
-					_dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
+					_dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
 
 
 #ifdef __LDSO_LDD_SUPPORT__
 #ifdef __LDSO_LDD_SUPPORT__
 					if (trace_loaded_objects &&
 					if (trace_loaded_objects &&
@@ -509,7 +511,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 						 */
 						 */
 						if (_dl_strcmp(_dl_progname, str) != 0)
 						if (_dl_strcmp(_dl_progname, str) != 0)
 							_dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
 							_dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
-								    tpnt1->loadaddr);
+								    DL_LOADADDR_BASE(tpnt1->loadaddr));
 					}
 					}
 #endif
 #endif
 				}
 				}
@@ -588,14 +590,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 			} else {
 			} else {
 				tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
 				tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
 
 
-				_dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
+				_dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
 
 
 #ifdef __LDSO_LDD_SUPPORT__
 #ifdef __LDSO_LDD_SUPPORT__
 				if (trace_loaded_objects &&
 				if (trace_loaded_objects &&
 				    tpnt1->usage_count == 1) {
 				    tpnt1->usage_count == 1) {
 					_dl_dprintf(1, "\t%s => %s (%x)\n",
 					_dl_dprintf(1, "\t%s => %s (%x)\n",
 						    cp2, tpnt1->libname,
 						    cp2, tpnt1->libname,
-						    (unsigned)tpnt1->loadaddr);
+						    DL_LOADADDR_BASE(tpnt1->loadaddr));
 				}
 				}
 #endif
 #endif
 			}
 			}
@@ -647,14 +649,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 
 
 				tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
 				tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
 
 
-				_dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
+				_dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
 
 
 #ifdef __LDSO_LDD_SUPPORT__
 #ifdef __LDSO_LDD_SUPPORT__
 				if (trace_loaded_objects &&
 				if (trace_loaded_objects &&
 				    tpnt1->usage_count == 1) {
 				    tpnt1->usage_count == 1) {
 					_dl_dprintf(1, "\t%s => %s (%x)\n",
 					_dl_dprintf(1, "\t%s => %s (%x)\n",
 						    lpntstr, tpnt1->libname,
 						    lpntstr, tpnt1->libname,
-						    (unsigned)tpnt1->loadaddr);
+						    DL_LOADADDR_BASE(tpnt1->loadaddr));
 				}
 				}
 #endif
 #endif
 			}
 			}
@@ -715,7 +717,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 	 */
 	 */
 	if (tpnt) {
 	if (tpnt) {
 		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) *) (load_addr + epnt->e_phoff);
+		ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
 		int j;
 		int j;
 
 
 		tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
 		tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
@@ -765,7 +767,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 	if (trace_loaded_objects) {
 	if (trace_loaded_objects) {
 		_dl_dprintf(1, "\t%s => %s (%x)\n",
 		_dl_dprintf(1, "\t%s => %s (%x)\n",
 			    rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
 			    rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
-			    rpnt->dyn->libname, rpnt->dyn->loadaddr);
+			    rpnt->dyn->libname, DL_LOADADDR_BASE(rpnt->dyn->loadaddr));
 		_dl_exit(0);
 		_dl_exit(0);
 	}
 	}
 #endif
 #endif
@@ -817,7 +819,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 		for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
 		for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
 			for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
 			for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
 				if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
 				if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
-					_dl_mprotect((void *) (tpnt->loadaddr + (myppnt->p_vaddr & PAGE_ALIGN)),
+					_dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
 							(myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
 							(myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
 				}
 				}
 			}
 			}
@@ -846,7 +848,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
 		if (tpnt->dynamic_info[DT_INIT]) {
 		if (tpnt->dynamic_info[DT_INIT]) {
 			void (*dl_elf_func) (void);
 			void (*dl_elf_func) (void);
 
 
-			dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
+			dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
 
 
 			_dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
 			_dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
 
 

+ 6 - 6
ldso/libdl/libdl.c

@@ -377,7 +377,7 @@ void *dlopen(const char *libname, int flag)
 
 
 		if (tpnt->dynamic_info[DT_INIT]) {
 		if (tpnt->dynamic_info[DT_INIT]) {
 			void (*dl_elf_func) (void);
 			void (*dl_elf_func) (void);
-			dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
+			dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
 			if (dl_elf_func && *dl_elf_func != NULL) {
 			if (dl_elf_func && *dl_elf_func != NULL) {
 				_dl_if_debug_print("running ctors for library %s at '%p'\n",
 				_dl_if_debug_print("running ctors for library %s at '%p'\n",
 						tpnt->libname, dl_elf_func);
 						tpnt->libname, dl_elf_func);
@@ -510,7 +510,7 @@ static int do_dlclose(void *vhandle, int need_fini)
 #endif
 #endif
 
 
 				if (tpnt->dynamic_info[DT_FINI]) {
 				if (tpnt->dynamic_info[DT_FINI]) {
-					dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+					dl_elf_fini = (int (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
 					_dl_if_debug_print("running dtors for library %s at '%p'\n",
 					_dl_if_debug_print("running dtors for library %s at '%p'\n",
 							tpnt->libname, dl_elf_fini);
 							tpnt->libname, dl_elf_fini);
 					(*dl_elf_fini) ();
 					(*dl_elf_fini) ();
@@ -620,7 +620,7 @@ int dlinfo(void)
 	/* First start with a complete list of all of the loaded files. */
 	/* First start with a complete list of all of the loaded files. */
 	for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
 	for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
 		fprintf(stderr, "\t%p %p %p %s %d %s\n",
 		fprintf(stderr, "\t%p %p %p %s %d %s\n",
-		        tpnt->loadaddr, tpnt, tpnt->symbol_scope,
+		        DL_LOADADDR_BASE(tpnt->loadaddr), tpnt, tpnt->symbol_scope,
 		        type[tpnt->libtype],
 		        type[tpnt->libtype],
 		        tpnt->usage_count, tpnt->libname);
 		        tpnt->usage_count, tpnt->libname);
 	}
 	}
@@ -658,7 +658,7 @@ int dladdr(const void *__address, Dl_info * __info)
 		tpnt = rpnt;
 		tpnt = rpnt;
 
 
 		_dl_if_debug_print("Module \"%s\" at %p\n",
 		_dl_if_debug_print("Module \"%s\" at %p\n",
-		                   tpnt->libname, tpnt->loadaddr);
+		                   tpnt->libname, DL_LOADADDR_BASE(tpnt->loadaddr));
 
 
 		if (DL_ADDR_IN_LOADADDR((ElfW(Addr)) __address,  tpnt, pelf))
 		if (DL_ADDR_IN_LOADADDR((ElfW(Addr)) __address,  tpnt, pelf))
 			pelf = tpnt;
 			pelf = tpnt;
@@ -687,7 +687,7 @@ int dladdr(const void *__address, Dl_info * __info)
 			for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) {
 			for (si = pelf->elf_buckets[hn]; si; si = pelf->chains[si]) {
 				ElfW(Addr) symbol_addr;
 				ElfW(Addr) symbol_addr;
 
 
-				symbol_addr = pelf->loadaddr + symtab[si].st_value;
+				symbol_addr = (ElfW(Addr)) DL_RELOC_ADDR(pelf->loadaddr, symtab[si].st_value);
 				if (symbol_addr <= (ElfW(Addr))__address && (!sf || sa < symbol_addr)) {
 				if (symbol_addr <= (ElfW(Addr))__address && (!sf || sa < symbol_addr)) {
 					sa = symbol_addr;
 					sa = symbol_addr;
 					sn = si;
 					sn = si;
@@ -701,7 +701,7 @@ int dladdr(const void *__address, Dl_info * __info)
 
 
 		if (sf) {
 		if (sf) {
 			__info->dli_fname = pelf->libname;
 			__info->dli_fname = pelf->libname;
-			__info->dli_fbase = (void *)pelf->loadaddr;
+			__info->dli_fbase = (void *) DL_LOADADDR_BASE(pelf->loadaddr);
 			__info->dli_sname = strtab + symtab[sn].st_name;
 			__info->dli_sname = strtab + symtab[sn].st_name;
 			__info->dli_saddr = (void *)sa;
 			__info->dli_saddr = (void *)sa;
 		}
 		}