Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jun 2004 23:25:58 GMT
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 55052 for review
Message-ID:  <200406152325.i5FNPwet008656@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=55052

Change 55052 by peter@peter_daintree on 2004/06/15 23:25:10

	Use Ian Dowse's idea of adjusting the symbol table once
	at load time rather than constantly trying to figure out which section
	each symbol is in and finding its base address.  Incidently, this
	makes the internal look/feel of the after-load state more consistent
	with the non-obj loader.

Affected files ...

.. //depot/projects/hammer/sys/kern/link_elf_obj.c#43 edit

Differences ...

==== //depot/projects/hammer/sys/kern/link_elf_obj.c#43 (text+ko) ====

@@ -187,7 +187,8 @@
 	struct thread *td = curthread;	/* XXX */
 	Elf_Ehdr *hdr;
 	Elf_Shdr *shdr;
-	int nbytes, i;
+	Elf_Sym *es;
+	int nbytes, i, j;
 	vm_offset_t mapbase;
 	size_t mapsize;
 	int error = 0;
@@ -504,6 +505,14 @@
 			if (ef->shstrtab && shdr[i].sh_name != 0)
 				ef->progtab[pb].name =
 				    ef->shstrtab + shdr[i].sh_name;
+
+			/* Update all symbol values with the offset. */
+			for (j = 0; j < ef->ddbsymcnt; j++) {
+				es = &ef->ddbsymtab[j];
+				if (es->st_shndx != i)
+					continue;
+				es->st_value += (Elf_Addr)ef->progtab[pb].addr;
+			}
 			mapbase += shdr[i].sh_size;
 			pb++;
 			break;
@@ -643,11 +652,11 @@
 	Elf_Addr base = 0;
 
 	for (i = 0; i < ef->nprogtab; i++) {
-		if (sec == ef->progtab[i].sec)
+		if (sec == ef->progtab[i].sec) {
 			base = (Elf_Addr)ef->progtab[i].addr;
+			break;
+		}
 	}
-	if (base == 0)
-		base = (Elf_Addr)ef->address;
 	return base;
 }
 
@@ -672,6 +681,8 @@
 			panic("lost a reltab!");
 		rellim = rel + ef->reltab[i].nrel;
 		base = findbase(ef, ef->reltab[i].sec);
+		if (base == 0)
+			panic("lost base for reltab");
 		for ( ; rel < rellim; rel++) {
 			symidx = ELF_R_SYM(rel->r_info);
 			if (symidx >= ef->ddbsymcnt)
@@ -697,6 +708,8 @@
 			panic("lost a relatab!");
 		relalim = rela + ef->relatab[i].nrela;
 		base = findbase(ef, ef->relatab[i].sec);
+		if (base == 0)
+			panic("lost base for relatab");
 		for ( ; rela < relalim; rela++) {
 			symidx = ELF_R_SYM(rela->r_info);
 			if (symidx >= ef->ddbsymcnt)
@@ -726,20 +739,13 @@
 	const char *strp;
 	int i;
 
-/* XXX search for globals first */
 	for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
 		strp = ef->ddbstrtab + symp->st_name;
-		if (strcmp(name, strp) == 0) {
-			if (symp->st_shndx != SHN_UNDEF ||
-			    (symp->st_value != 0 &&
-			    ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
-				*sym = (c_linker_sym_t) symp;
-				return 0;
-			} else
-				return ENOENT;
+		if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) {
+			*sym = (c_linker_sym_t) symp;
+			return 0;
 		}
 	}
-
 	return ENOENT;
 }
 
@@ -747,16 +753,12 @@
 link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
     linker_symval_t *symval)
 {
-	Elf_Addr base;
 	elf_file_t ef = (elf_file_t) lf;
 	const Elf_Sym *es = (const Elf_Sym*) sym;
 
 	if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
-		base = findbase(ef, es->st_shndx);
-		if (base == 0)
-			base = (Elf_Addr)ef->address;
 		symval->name = ef->ddbstrtab + es->st_name;
-		symval->value = (caddr_t)base + es->st_value;
+		symval->value = (caddr_t)es->st_value;
 		symval->size = es->st_size;
 		return 0;
 	}
@@ -771,7 +773,6 @@
 	u_long off = (uintptr_t) (void *) value;
 	u_long diff = off;
 	u_long st_value;
-	Elf_Addr base;
 	const Elf_Sym *es;
 	const Elf_Sym *best = 0;
 	int i;
@@ -779,10 +780,7 @@
 	for (i = 0, es = ef->ddbsymtab; i < ef->ddbsymcnt; i++, es++) {
 		if (es->st_name == 0)
 			continue;
-		base = findbase(ef, es->st_shndx);
-		if (base == 0)
-			base = (Elf_Addr)ef->address;
-		st_value = es->st_value + base;
+		st_value = es->st_value;
 		if (off >= st_value) {
 			if (off - st_value < diff) {
 				diff = off - st_value;
@@ -868,7 +866,6 @@
 	const Elf_Sym *sym;
 	const char *symbol;
 	Elf_Addr ret;
-	int i;
 
 	/* Don't even try to lookup the symbol if the index is bogus. */
 	if (symidx >= ef->ddbsymcnt)
@@ -877,19 +874,8 @@
 	sym = ef->ddbsymtab + symidx;
 
 	/* Quick answer if there is a definition included. */
-	if (sym->st_shndx != SHN_UNDEF) {
-		ret = 0;
-		/* Relative to section number */
-		for (i = 0; i < ef->nprogtab; i++) {
-			if (sym->st_shndx == ef->progtab[i].sec) {
-				ret = (Elf_Addr)ef->progtab[i].addr;
-				break;
-			}
-		}
-		if (ret == 0)
-			return (0);
-		return ret + sym->st_value;
-	}
+	if (sym->st_shndx != SHN_UNDEF)
+		return (sym->st_value);
 
 	/* If we get here, then it is undefined and needs a lookup. */
 	switch (ELF_ST_BIND(sym->st_info)) {
@@ -937,6 +923,8 @@
 			panic("lost a reltab!");
 		rellim = rel + ef->reltab[i].nrel;
 		base = findbase(ef, ef->reltab[i].sec);
+		if (base == 0)
+			panic("lost base for reltab");
 		for ( ; rel < rellim; rel++) {
 			symidx = ELF_R_SYM(rel->r_info);
 			if (symidx >= ef->ddbsymcnt)
@@ -957,6 +945,8 @@
 			panic("lost a relatab!");
 		relalim = rela + ef->relatab[i].nrela;
 		base = findbase(ef, ef->relatab[i].sec);
+		if (base == 0)
+			panic("lost base for relatab");
 		for ( ; rela < relalim; rela++) {
 			symidx = ELF_R_SYM(rela->r_info);
 			if (symidx >= ef->ddbsymcnt)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406152325.i5FNPwet008656>