[uClibc-cvs] uClibc/ldso/ldso hash.c,1.14,1.15

Erik Andersen andersen at uclibc.org
Sat Feb 7 12:05:18 UTC 2004


Update of /var/cvs/uClibc/ldso/ldso
In directory nail:/tmp/cvs-serv31632

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

Hi again

All dltest* and test* programs pass for me.
uClibc ld.so resolves according to the OLD weak symbol handling.

I have tried to use the new scheme as well, but that segfaults in all
cases but test3.



Index: hash.c
===================================================================
RCS file: /var/cvs/uClibc/ldso/ldso/hash.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- hash.c	19 Aug 2003 13:11:06 -0000	1.14
+++ hash.c	7 Feb 2004 12:05:16 -0000	1.15
@@ -1,12 +1,12 @@
 /* vi: set sw=4 ts=4: */
-/* Program to load an ELF binary on a linux system, and run it
+/*
+ * Program to load an ELF binary on a linux system, and run it
  * after resolving ELF shared library symbols
  *
- * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, 
+ * Copyright (C) 2004 by Joakim Tjernlund <joakim.tjernlund at lumentis.se>
+ * Copyright (C) 2000-2004 by Erik Andersen <andersen at codpoet.org>
+ * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
  *				David Engel, Hongjiu Lu and Mitch D'Souza
- * Copyright (C) 2001-2002, Erik Andersen
- *
- * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,10 +35,9 @@
 
 /*
  * This is the start of the linked list that describes all of the files present
- * in the system with pointers to all of the symbol, string, and hash tables, 
+ * in the system with pointers to all of the symbol, string, and hash tables,
  * as well as all of the other good stuff in the binary.
  */
-
 struct elf_resolve *_dl_loaded_modules = NULL;
 
 /*
@@ -55,12 +54,9 @@
 struct dyn_elf *_dl_handles = NULL;
 
 
-/*
- * This is the hash function that is used by the ELF linker to generate
- * the hash table that each executable and library is required to
- * have.  We need it to decode the hash table.
- */
-
+/* This is the hash function that is used by the ELF linker to generate the
+ * hash table that each executable and library is required to have.  We need
+ * it to decode the hash table.  */
 unsigned long _dl_elf_hash(const char *name)
 {
 	unsigned long hash = 0;
@@ -75,9 +71,7 @@
 	return hash;
 }
 
-/*
- * Check to see if a library has already been added to the hash chain.
- */
+/* Check to see if a library has already been added to the hash chain.  */
 struct elf_resolve *_dl_check_hashed_files(const char *libname)
 {
 	struct elf_resolve *tpnt;
@@ -97,9 +91,8 @@
  * We add the relevant info to the symbol chain, so that we can resolve all
  * externals properly.
  */
-
-struct elf_resolve *_dl_add_elf_hash_table(const char *libname, 
-	char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr, 
+struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
+	char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr,
 	unsigned long dynamic_size)
 {
 	unsigned long *hash_addr;
@@ -107,8 +100,7 @@
 	int i;
 
 	if (!_dl_loaded_modules) {
-		tpnt = _dl_loaded_modules = 
-		    (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
+		tpnt = _dl_loaded_modules = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
 		_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
 	} else {
 		tpnt = _dl_loaded_modules;
@@ -161,21 +153,18 @@
  * This function resolves externals, and this is either called when we process
  * relocations or when we call an entry in the PLT table for the first time.
  */
-
-char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1, 
+char *_dl_find_hash(const char *name, struct dyn_elf *rpnt1,
 	struct elf_resolve *f_tpnt, enum caller_type caller_type)
 {
 	struct elf_resolve *tpnt;
 	int si;
-	char *pnt;
 	int pass;
 	char *strtab;
 	Elf32_Sym *symtab;
 	unsigned long elf_hash_number, hn;
 	char *weak_result;
-	struct elf_resolve *first_def;
 	struct dyn_elf *rpnt, first;
-	char *data_result = 0;		/* nakao */
+	const ElfW(Sym) *sym;
 
 	weak_result = 0;
 	elf_hash_number = _dl_elf_hash(name);
@@ -185,7 +174,7 @@
 	   that any shared library data symbols referenced in the executable
 	   will be seen at the same address by the executable, shared libraries
 	   and dynamically loaded code. -Rob Ryan (robr at cmu.edu) */
-	if (_dl_symbol_tables && !caller_type && rpnt1) {
+	if (_dl_symbol_tables && rpnt1) {
 		first = (*_dl_symbol_tables);
 		first.next = rpnt1;
 		rpnt1 = (&first);
@@ -222,24 +211,16 @@
 		if (pass != 0) {
 			if (rpnt1 == NULL)
 				break;
-			if ((rpnt1->flags & RTLD_GLOBAL) == 0)
-				continue;
+			//if ((rpnt1->flags & RTLD_GLOBAL) == 0)
+				//continue;
 		}
 
 		for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) {
 			tpnt = rpnt->dyn;
 
-			/*
-			 * The idea here is that if we are using dlsym, we want to
-			 * first search the entire chain loaded from dlopen, and
-			 * return a result from that if we found anything.  If this
-			 * fails, then we continue the search into the stuff loaded
-			 * when the image was activated.  For normal lookups, we start
-			 * with rpnt == NULL, so we should never hit this.  
-			 */
-			if (tpnt->libtype == elf_executable && weak_result != 0) {
-				break;
-			}
+			/* Don't search the executable when resolving a copy reloc. */
+			if (tpnt->libtype == elf_executable && caller_type == copyrel)
+				continue;
 
 			/*
 			 * Avoid calling .urem here.
@@ -247,81 +228,35 @@
 			do_rem(hn, elf_hash_number, tpnt->nbucket);
 			symtab = (Elf32_Sym *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
 			strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
-			/*
-			 * This crap is required because the first instance of a
-			 * symbol on the chain will be used for all symbol references.
-			 * Thus this instance must be resolved to an address that
-			 * contains the actual function, 
-			 */
 
-			first_def = NULL;
-
-			for (si = tpnt->elf_buckets[hn]; si; si = tpnt->chains[si]) {
-				pnt = strtab + symtab[si].st_name;
-
-				if (_dl_strcmp(pnt, name) == 0 &&
-				    symtab[si].st_value != 0)
-				{
-				  if ((ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
-				       ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
-				       ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
-				      symtab[si].st_shndx != SHN_UNDEF) {
-
-					/* Here we make sure that we find a module where the symbol is
-					 * actually defined.
-					 */
+			for (si = tpnt->elf_buckets[hn]; si != STN_UNDEF; si = tpnt->chains[si]) {
+				sym = &symtab[si];
 
-					if (f_tpnt) {
-						if (!first_def)
-							first_def = tpnt;
-						if (first_def == f_tpnt
-							&& symtab[si].st_shndx == 0)
-							continue;
-					}
+				if (sym->st_value == 0)
+					continue;
+				if (ELF32_ST_TYPE(sym->st_info) > STT_FUNC)
+					continue;
+				if (sym->st_shndx == SHN_UNDEF && caller_type != copyrel)
+					continue;
+				if (_dl_strcmp(strtab + sym->st_name, name) != 0)
+					continue;
 
-					switch (ELF32_ST_BIND(symtab[si].st_info)) {
-					case STB_GLOBAL:
-						if (tpnt->libtype != elf_executable && 
-							ELF32_ST_TYPE(symtab[si].st_info) 
-							== STT_NOTYPE) 
-						{	/* nakao */
-							data_result = (char *)tpnt->loadaddr + 
-							    symtab[si].st_value;	/* nakao */
-							break;	/* nakao */
-						} else	/* nakao */
-							return (char*)tpnt->loadaddr + symtab[si].st_value;
-					case STB_WEAK:
-						if (!weak_result)
-							weak_result = (char *)tpnt->loadaddr + symtab[si].st_value;
-						break;
-					default:	/* Do local symbols need to be examined? */
-						break;
-					}
-				  }
-#ifndef __mips__
-				  /*
-				   * References to the address of a function from an executable file and
-				   * the shared objects associated with it might not resolve to the same
-				   * value. To allow comparisons of function addresses we must resolve
-				   * to the address of the plt entry of the executable instead of the
-				   * real function address.
-				   * see "TIS ELF Specification Version 1.2, Book 3, A-11 (Function
-				   * Adresses) 
-				   */				 
-				  if (resolver != caller_type &&
-				      NULL==f_tpnt && /*trick: don't  handle R_??_JMP_SLOT reloc type*/
-				      tpnt->libtype == elf_executable &&
-				      ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC &&
-				      symtab[si].st_shndx == SHN_UNDEF)
-				  {
-				      return (char*)symtab[si].st_value;
-				  }
+				switch (ELF32_ST_BIND(sym->st_info)) {
+				case STB_WEAK:
+//Disable this to match current glibc behavior.  Of course,
+//this doesn't actually work yet and will cause segfaults...
+#if 1
+					if (!weak_result)
+						weak_result = (char *)tpnt->loadaddr + sym->st_value;
+					break;
 #endif
+				case STB_GLOBAL:
+					return (char*)tpnt->loadaddr + sym->st_value;
+				default:	/* Local symbols not handled here */
+					break;
 				}
 			}
 		}
 	}
-	if (data_result)
-		return data_result;		/* nakao */
 	return weak_result;
 }




More information about the uClibc-cvs mailing list