[uClibc-cvs] uClibc/ldso/ldso/powerpc elfinterp.c,1.34,1.35

Erik Andersen andersen at uclibc.org
Fri Jan 30 20:34:05 UTC 2004


Update of /var/cvs/uClibc/ldso/ldso/powerpc
In directory nail:/home/andersen/CVS/uClibc/ldso/ldso/powerpc

Modified Files:
	elfinterp.c 
Log Message:
Joakim Tjernlund writes:

> Not there yet, but the interfaces are much closer now...
> Heading to bed though, since its 5:30am.  :-)

This works, but I discovered something "funny". For all
relocs but COPY you can use scope instead of scope->dyn->symbol_scope
and it is much faster to do that. Search for "Funny" in the patch
to see what I mean. Probably I probably broke something, please let me
know if it works for you too.

I think I am done with ldso now. Has been fun and I hope to
actually use uClibc/busybox soon in a project.

Ohh, there is one thing left, double sized PLT entries, but maybe these
aren't needed in uClibc?

 Sweet dreams
              Jocke



Index: elfinterp.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/powerpc/elfinterp.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- elfinterp.c	29 Jan 2004 12:18:54 -0000	1.34
+++ elfinterp.c	30 Jan 2004 20:34:03 -0000	1.35
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2001-2002 David A. Schleef
  * Copyright (C) 2003-2004 Erik Andersen
+ * Copyright (C) 2004 Joakim Tjernlund
  *
  * All rights reserved.
  *
@@ -251,72 +252,7 @@
 	return finaladdr;
 }
 
-static int
-_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
-	  unsigned long rel_addr, unsigned long rel_size,
-	  int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
-			    ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
-{
-	unsigned int i;
-	char *strtab;
-	Elf32_Sym *symtab;
-	ELF_RELOC *rpnt;
-	int symtab_index;
-
-	/* Now parse the relocation information */
-	rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
-	rel_size = rel_size / sizeof(ELF_RELOC);
-
-	symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
-	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
-
-	  for (i = 0; i < rel_size; i++, rpnt++) {
-	        int res;
-
-		symtab_index = ELF32_R_SYM(rpnt->r_info);
-
-		/* When the dynamic linker bootstrapped itself, it resolved some symbols.
-		   Make sure we do not do them again */
-		if (!symtab_index && tpnt->libtype == program_interpreter)
-			continue;
-		if (symtab_index && tpnt->libtype == program_interpreter &&
-		    _dl_symbol(strtab + symtab[symtab_index].st_name))
-			continue;
-
-#if defined (__SUPPORT_LD_DEBUG__)
-		debug_sym(symtab,strtab,symtab_index);
-		debug_reloc(symtab,strtab,rpnt);
-#endif
-
-		res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
-
-		if (res==0) continue;
-
-		_dl_dprintf(2, "\n%s: ",_dl_progname);
-
-		if (symtab_index)
-		  _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
-
-		if (res <0)
-		{
-		        int reloc_type = ELF32_R_TYPE(rpnt->r_info);
-#if defined (__SUPPORT_LD_DEBUG__)
-			_dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
-#else
-			_dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
-#endif
-			_dl_exit(-res);
-		}
-		else if (res >0)
-		{
-			_dl_dprintf(2, "can't resolve symbol\n");
-			return res;
-		}
-	  }
-	  return 0;
-}
-
-static int
+static inline int
 _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
 	      ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
 {
@@ -325,6 +261,7 @@
 	char *symname;
 	Elf32_Addr *reloc_addr;
 	Elf32_Addr finaladdr;
+	struct dyn_elf *sym_scope;
 
 	unsigned long symbol_addr;
 #if defined (__SUPPORT_LD_DEBUG__)
@@ -336,13 +273,22 @@
 		*reloc_addr = tpnt->loadaddr + rpnt->r_addend;
 		return 0;
 	}
-	if (reloc_type == R_PPC_NONE || reloc_type == R_PPC_COPY) /*  R_PPC_COPY is handled later */
+	if (reloc_type == R_PPC_NONE)
 		return 0;
 	symtab_index = ELF32_R_SYM(rpnt->r_info);
 	symname      = strtab + symtab[symtab_index].st_name;
-
-	symbol_addr = (unsigned long) _dl_find_hash(symname, scope,
-						    (reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL), symbolrel);
+#if 0
+	sym_scope = scope->dyn->symbol_scope;
+#else
+	sym_scope = scope;/* Funny, this works too and appears to be much faster. */
+#endif
+	if (reloc_type == R_PPC_COPY) {
+		sym_scope = scope->next;
+		tpnt = NULL; /* To be or not to be ...*/
+	}
+	symbol_addr = (unsigned long) _dl_find_hash(symname, sym_scope,
+						    (reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL),
+						    (reloc_type == R_PPC_COPY ? copyrel : symbolrel));
 	/*
 	 * We want to allow undefined references to weak symbols - this might
 	 * have been intentional.  We should not be linking local symbols
@@ -398,7 +344,6 @@
 		break;
 	}
 	case R_PPC_COPY:
-		/* This does not work yet, R_PPC_COPY is handled later, see if statemet above */
 		if (symbol_addr) {
 #if defined (__SUPPORT_LD_DEBUG__)
 			if(_dl_debug_move)
@@ -423,7 +368,8 @@
 	{
 		Elf32_Sword delta = finaladdr - (Elf32_Word)reloc_addr;
 		if(delta<<6>>6 != delta){
-			_dl_dprintf(2, "%s: symbol '%s' R_PPC_REL24 is out of range.\n\tCompile shared libraries with -fPIC!\n",
+			_dl_dprintf(2, "%s: symbol '%s' R_PPC_REL24 is out of range.\n\t"
+					"Compile shared libraries with -fPIC!\n",
 				    _dl_progname, symname);
 			_dl_exit(1);
 		}
@@ -452,48 +398,6 @@
 	return 0;
 }
 
-/* This is done as a separate step, because there are cases where
-   information is first copied and later initialized.  This results in
-   the wrong information being copied.  Someone at Sun was complaining about
-   a bug in the handling of _COPY by SVr4, and this may in fact be what he
-   was talking about.  Sigh. */
-static int
-_dl_do_copy_reloc (struct elf_resolve *tpnt, struct dyn_elf *scope,
-	     ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab)
-{
-	int reloc_type;
-	int symtab_index;
-	unsigned long *reloc_addr;
-	unsigned long symbol_addr;
-	int goof = 0;
-	char *symname;
-
-	reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
-	reloc_type = ELF32_R_TYPE(rpnt->r_info);
-	if (reloc_type != R_PPC_COPY)
-		return 0;
-	symtab_index = ELF32_R_SYM(rpnt->r_info);
-	symbol_addr = 0;
-	symname      = strtab + symtab[symtab_index].st_name;
-
-	if (symtab_index) {
-		symbol_addr = (unsigned long) _dl_find_hash(symname, scope, NULL, copyrel);
-		if (!symbol_addr) goof++;
-	}
-	if (!goof) {
-#if defined (__SUPPORT_LD_DEBUG__)
-	        if(_dl_debug_move)
-		  _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x",
-			     symname, symtab[symtab_index].st_size,
-			     symbol_addr, symtab[symtab_index].st_value);
-#endif
-			_dl_memcpy((char *) reloc_addr,
-					(char *) (symbol_addr + (unsigned long)rpnt->r_addend), symtab[symtab_index].st_size);
-	}
-
-	return goof;
-}
-
 void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
 	unsigned long rel_addr, unsigned long rel_size, int type)
 {
@@ -538,16 +442,82 @@
 	PPC_ISYNC;
 }
 
+static inline int
+_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
+	  unsigned long rel_addr, unsigned long rel_size,
+	  int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
+			    ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
+{
+	unsigned int i;
+	char *strtab;
+	Elf32_Sym *symtab;
+	ELF_RELOC *rpnt;
+	int symtab_index;
+
+	/* Now parse the relocation information */
+	rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
+	rel_size = rel_size / sizeof(ELF_RELOC);
+
+	symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+	  for (i = 0; i < rel_size; i++, rpnt++) {
+	        int res;
+
+		symtab_index = ELF32_R_SYM(rpnt->r_info);
+
+		/* When the dynamic linker bootstrapped itself, it resolved some symbols.
+		   Make sure we do not do them again */
+		if (!symtab_index && tpnt->libtype == program_interpreter)
+			continue;
+		if (symtab_index && tpnt->libtype == program_interpreter &&
+		    _dl_symbol(strtab + symtab[symtab_index].st_name))
+			continue;
+
+#if defined (__SUPPORT_LD_DEBUG__)
+		debug_sym(symtab,strtab,symtab_index);
+		debug_reloc(symtab,strtab,rpnt);
+#endif
+
+		res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab);
+
+		if (res==0) continue;
+
+		_dl_dprintf(2, "\n%s: ",_dl_progname);
+
+		if (symtab_index)
+		  _dl_dprintf(2, "symbol '%s': ", strtab + symtab[symtab_index].st_name);
+
+		if (res <0)
+		{
+		        int reloc_type = ELF32_R_TYPE(rpnt->r_info);
+#if defined (__SUPPORT_LD_DEBUG__)
+			_dl_dprintf(2, "can't handle reloc type %s\n ", _dl_reltypes(reloc_type));
+#else
+			_dl_dprintf(2, "can't handle reloc type %x\n", reloc_type);
+#endif
+			_dl_exit(-res);
+		}
+		else if (res >0)
+		{
+			_dl_dprintf(2, "can't resolve symbol\n");
+			return res;
+		}
+	  }
+	  return 0;
+}
+
 int _dl_parse_relocation_information(struct dyn_elf *rpnt,
 	unsigned long rel_addr, unsigned long rel_size, int type)
 {
-	return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
+	return _dl_parse(rpnt->dyn, rpnt, rel_addr, rel_size, _dl_do_reloc);
 }
 
+/* Should be a static inline instead, but that conflicts with ld_elf.h */
 int _dl_parse_copy_information(struct dyn_elf *rpnt,
 	unsigned long rel_addr, unsigned long rel_size, int type)
 {
-	return _dl_parse(rpnt->dyn, rpnt->next, rel_addr, rel_size, _dl_do_copy_reloc);
+	/* Not used! */
+	return 0;
 }
 
-




More information about the uClibc-cvs mailing list