Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Apr 2004 19:58:15 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 50162 for review
Message-ID:  <200404020358.i323wFBo045752@repoman.freebsd.org>

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

Change 50162 by peter@peter_hammer on 2004/04/01 19:57:17

	checkpoint.  close, but still no cigar.  The STT_* types are only
	relevant for STB_LOCAL binding, it seems.  STB_GLOBAL would always be
	a fallthrough.  Or something.  Hmmm.

Affected files ...

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

Differences ...

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

@@ -64,6 +64,8 @@
 	Elf_Off		filesz;
 	int		align;
 	int		flags;
+	int		sec;	/* Original section */
+	char		*name;
 } Elf_progent;
 
 typedef struct {
@@ -71,6 +73,8 @@
 	Elf_Off		memsz;
 	int		align;
 	int		flags;
+	int		sec;	/* Original section */
+	char		*name;
 } Elf_nobitent;
 	
 typedef struct {
@@ -90,6 +94,7 @@
 	struct linker_file lf;		/* Common fields */
 	caddr_t		address;	/* Relocation address */
 	vm_object_t	object;		/* VM object to hold file pages */
+	Elf_Shdr	*e_shdr;
 
 	Elf_progent	*progtab;
 	int		nprogtab;
@@ -108,6 +113,9 @@
 	caddr_t		ddbstrtab;	/* String table */
 	long		ddbstrcnt;	/* number of bytes in string table */
 
+	caddr_t		shstrtab;	/* Section name string table */
+	long		shstrcnt;	/* number of bytes in string table */
+
 #if 0
 	caddr_t		symbase;	/* malloc'ed symbol base */
 	caddr_t		strbase;	/* malloc'ed string base */
@@ -195,6 +203,7 @@
 	struct nameidata nd;
 	struct thread *td = curthread;	/* XXX */
 	Elf_Ehdr *hdr;
+	Elf_Shdr *shdr;
 	int nbytes, i;
 	caddr_t mapbase;
 	size_t mapsize;
@@ -202,9 +211,9 @@
 	int resid, flags;
 	elf_file_t ef;
 	linker_file_t lf;
-	Elf_Shdr *shdr;
 	int symtabindex;
 	int symstrindex;
+	int shstrindex;
 	int nsym;
 	int pb, nb, rl, ra;
 	int alignmask;
@@ -281,6 +290,19 @@
 
 printf("elf_load_obj: initial checks look ok!\n");
 
+printf("section table read in ok\n");
+	lf = linker_make_file(filename, &link_elf_class);
+	if (!lf) {
+		error = ENOMEM;
+		goto out;
+	}
+	ef = (elf_file_t) lf;
+	ef->nprogtab = 0;
+	ef->nnobittab = 0;
+	ef->e_shdr = 0;
+	ef->nrel = 0;
+	ef->nrela = 0;
+
 	/* Allocate and read in the section header */
 	nbytes = hdr->e_shnum * hdr->e_shentsize;
 	if (nbytes == 0 || hdr->e_shoff == 0 ||
@@ -294,6 +316,7 @@
 		error = ENOMEM;
 		goto out;
 	}
+	ef->e_shdr = shdr;
 	error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)shdr, nbytes, hdr->e_shoff,
 	    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED, &resid, td);
 	if (error)
@@ -303,21 +326,9 @@
 		goto out;
 	}
 
-printf("section table read in ok\n");
-	lf = linker_make_file(filename, &link_elf_class);
-	if (!lf) {
-		error = ENOMEM;
-		goto out;
-	}
-	ef = (elf_file_t) lf;
-
 printf("scan header1\n");
 	/* Scan the section header for information and table sizing. */
-	ef->nprogtab = 0;
-	ef->nnobittab = 0;
 	nsym = 0;
-	ef->nrel = 0;
-	ef->nrela = 0;
 	symtabindex = -1;
 	symstrindex = -1;
 	for (i = 0; i < hdr->e_shnum; i++) {
@@ -395,6 +406,18 @@
 		goto out;
 	}
 
+	/* Do we have a string table for the section names?  */
+	shstrindex = -1;
+	if (hdr->e_shstrndx != 0 && shdr[hdr->e_shstrndx].sh_type == SHT_STRTAB) {
+		shstrindex = hdr->e_shstrndx;
+		ef->shstrcnt = shdr[shstrindex].sh_size;
+		ef->shstrtab = malloc(shdr[shstrindex].sh_size, M_LINKER, M_WAITOK);
+		if (ef->shstrtab == NULL) {
+			error = ENOMEM;
+			goto out;
+		}
+	}
+
 	/* Size code/data(progbits) and bss(nobits).  allocate space for relocs */
 	pb = 0;
 	nb = 0;
@@ -420,7 +443,12 @@
 			ef->progtab[pb].fileoff = shdr[i].sh_offset;
 			ef->progtab[pb].filesz = shdr[i].sh_size;
 			ef->progtab[pb].align = shdr[i].sh_addralign;
-printf("progbits at %ld\n", mapsize);
+			ef->progtab[pb].sec = i;
+			if (ef->shstrtab && shdr[i].sh_name != 0)
+				ef->progtab[pb].name = ef->shstrtab + shdr[i].sh_name;
+			else
+				ef->progtab[pb].name = "<<PROGBITS>>";
+printf("progbits at %ld, sec %d, name %s\n", mapsize, ef->progtab[pb].sec, ef->progtab[pb].name);
 			mapsize += shdr[i].sh_size;
 			pb++;
 			break;
@@ -428,7 +456,12 @@
 			ef->nobittab[nb].addr = (void *)(uintptr_t)mapsize;
 			ef->nobittab[nb].memsz = shdr[i].sh_size;
 			ef->nobittab[nb].align = shdr[i].sh_addralign;
-printf("nobits at %ld\n", mapsize);
+			ef->nobittab[nb].sec = i;
+			if (ef->shstrtab && shdr[i].sh_name != 0) 
+				ef->nobittab[nb].name = ef->shstrtab + shdr[i].sh_name;
+			else
+				ef->nobittab[nb].name = "<<NOBITS>>";
+printf("nobits at %ld, sec %d name %s\n", mapsize, ef->nobittab[nb].sec, ef->nobittab[nb].name);
 			mapsize += shdr[i].sh_size;
 			nb++;
 			break;
@@ -505,6 +538,15 @@
 	    &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 */
@@ -586,8 +628,6 @@
 printf("link_elf_obj: finishing up! error = %d\n", error);
 	if (error && lf)
 		linker_file_unload(lf);
-	if (shdr)
-		free(shdr, M_LINKER);
 	if (hdr)
 		free(hdr, M_LINKER);
 	VOP_UNLOCK(nd.ni_vp, 0, td);
@@ -611,6 +651,8 @@
 	}
 	if (ef->address)
 		free(ef->address, M_LINKER);
+	if (ef->e_shdr)
+		free(ef->e_shdr, M_LINKER);
 	if (ef->ddbsymtab)
 		free(ef->ddbsymtab, M_LINKER);
 	if (ef->ddbstrtab)
@@ -881,7 +923,8 @@
 	elf_file_t ef = (elf_file_t)lf;
 	const Elf_Sym *sym;
 	const char *symbol;
-	Elf_addr ret;
+	Elf_Addr ret;
+	int i;
 
 printf("elf_obj_lookup: symidx %ld (< %ld?)\n", symidx, ef->ddbsymcnt);
 
@@ -914,12 +957,32 @@
 
 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 %p\n", ret);
+printf("linker_file_lookup_symbol returns 0x%lx\n", ret);
 		return ret;
 
 	case STT_SECTION:
 		/* Relative to section number */
-		XXX
+		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;
+			}
+		}
+		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;
+printf("returning base 0x%lx\n", ret);
+				return ret;
+			}
+		}
+printf("STT_SECTION index %d not found!\n", sym->st_shndx);
+		return (0);
+	default:
+printf("Unknown symbol type! %d\n", ELF64_ST_TYPE(sym->st_info));
+		return (0);
 	}
 }
 



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