Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Apr 2004 21:28:21 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 50165 for review
Message-ID:  <200404020528.i325SLQG071732@repoman.freebsd.org>

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

Change 50165 by peter@peter_hammer on 2004/04/01 21:27:27

	read shstrtab earlier so we can use it for debug output
	really fix the local symbol relocator (I hope)

Affected files ...

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

Differences ...

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

@@ -416,6 +416,13 @@
 			error = ENOMEM;
 			goto out;
 		}
+printf("reading shstrtab\n");
+		error = vn_rdwr(UIO_READ, nd.ni_vp,
+		    ef->shstrtab, shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset,
+		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
+		    &resid, td);
+		if (error)
+			goto out;
 	}
 
 	/* Size code/data(progbits) and bss(nobits).  allocate space for relocs */
@@ -510,6 +517,10 @@
 		goto out;
 	}
 	mapbase = ef->address;
+	/* Wire the pages */
+	vm_map_wire(kernel_map, (vm_offset_t)mapbase,
+	    (vm_offset_t)mapbase + round_page(mapsize),
+	    VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES);
 printf("final mapbase %p, final mapsize %ld\n", mapbase, mapsize);
 
 	/* Add the base address to the previously calculated/aligned offsets */
@@ -538,15 +549,6 @@
 	    &resid, td);
 	if (error)
 		goto out;
-	if (ef->shstrtab) {
-printf("reading shstrtab\n");
-		error = vn_rdwr(UIO_READ, nd.ni_vp,
-		    ef->shstrtab, shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset,
-		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-		    &resid, td);
-		if (error)
-			goto out;
-	}
 
 printf("reading progbits\n");
 	/* Read in the text/data/set/etc sections */
@@ -560,10 +562,6 @@
 		    &resid, td);
 		if (error)
 			goto out;
-		/* Wire the pages */
-		vm_map_wire(kernel_map, (vm_offset_t)ef->progtab[i].addr,
-		    (vm_offset_t)ef->progtab[i].addr + ef->progtab[i].filesz,
-		    VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES);
 	}
 
 	/*
@@ -935,53 +933,47 @@
 	sym = ef->ddbsymtab + symidx;
 printf("sym: %p (base %p)\n", sym, ef->ddbsymtab);
 
-#if 0
 	/* Theoretically we can avoid a lookup for some locals */
 	switch (ELF64_ST_BIND(sym->st_info)) {
 	case STB_LOCAL:
-	case STB_GLOBAL:
-	case STB_WEAK:
-	}
-#endif
-	switch (ELF64_ST_TYPE(sym->st_info)) {
-	case STT_OBJECT:
-	case STT_FUNC:
-		/* Relative to Data or Function name */
-		symbol = ef->ddbstrtab + sym->st_name;
-printf("strtab %p, st_name %d\n", ef->ddbstrtab, sym->st_name);
-printf("symbol = %p (%s)\n", symbol, symbol);
-
-		/* Force a lookup failure if the symbol name is bogus. */
-		if (*symbol == 0)
+		/* Local, but undefined? huh? */
+		if (sym->st_shndx == SHN_UNDEF)
 			return (0);
-
-printf("calling linker_file_lookup_symbol, deps %d\n", deps);
-		ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
-printf("linker_file_lookup_symbol returns 0x%lx\n", ret);
-		return ret;
-
-	case STT_SECTION:
+		ret = 0;
 		/* Relative to section number */
 		for (i = 0; i < ef->nprogtab; i++) {
 			if (sym->st_shndx == ef->progtab[i].sec) {
 printf("FOUND PROGBITS SECTION RELOC, name %s\n", ef->progtab[i].name);
 				ret = (Elf_Addr)ef->progtab[i].addr;
 printf("returning base 0x%lx\n", ret);
-				return ret;
+				break;
 			}
 		}
-		for (i = 0; i < ef->nnobittab; i++) {
-			if (sym->st_shndx == ef->nobittab[i].sec) {
+		if (ret == 0) {
+			for (i = 0; i < ef->nnobittab; i++) {
+				if (sym->st_shndx == ef->nobittab[i].sec) {
 printf("FOUND NOBITS SECTION RELOC, name %s\n", ef->nobittab[i].name);
-				ret = (Elf_Addr)ef->nobittab[i].addr;
+					ret = (Elf_Addr)ef->nobittab[i].addr;
 printf("returning base 0x%lx\n", ret);
-				return ret;
+					break;
+				}
 			}
 		}
-printf("STT_SECTION index %d not found!\n", sym->st_shndx);
-		return (0);
+		return ret + sym->st_value;
+
+	case STB_GLOBAL:
+		/* Relative to Data or Function name */
+		symbol = ef->ddbstrtab + sym->st_name;
+
+		/* Force a lookup failure if the symbol name is bogus. */
+		if (*symbol == 0)
+			return (0);
+printf("calling linker_file_lookup_symbol, deps %d\n", deps);
+		ret = ((Elf_Addr)linker_file_lookup_symbol(lf, symbol, deps));
+printf("linker_file_lookup_symbol returns 0x%lx\n", ret);
+		return ret;
 	default:
-printf("Unknown symbol type! %d\n", ELF64_ST_TYPE(sym->st_info));
+printf("UNKNOWN BINDING %d\n", ELF64_ST_BIND(sym->st_info));
 		return (0);
 	}
 }



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