PERFORCE change 55052 for review

Peter Wemm peter at FreeBSD.org
Tue Jun 15 23:26:00 GMT 2004


http://perforce.freebsd.org/chv.cgi?CH=55052

Change 55052 by peter at 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)


More information about the p4-projects mailing list