Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 May 2004 19:52:53 -0700 (PDT)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 52905 for review
Message-ID:  <200405170252.i4H2qr4C097686@repoman.freebsd.org>

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

Change 52905 by peter@peter_hammer on 2004/05/16 19:52:19

	Tidy up a few things.  Track all the progbits/nobits chunks
	in a unified table.  That's one less thing to go wrong.
	De-nest a bunch of heavily nested/indented functions.

Affected files ...

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

Differences ...

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

@@ -60,8 +60,7 @@
 
 typedef struct {
 	void		*addr;
-	Elf_Off		fileoff;
-	Elf_Off		filesz;
+	Elf_Off		size;
 	int		align;
 	int		flags;
 	int		sec;	/* Original section */
@@ -69,25 +68,14 @@
 } Elf_progent;
 
 typedef struct {
-	void		*addr;
-	Elf_Off		memsz;
-	int		align;
-	int		flags;
-	int		sec;	/* Original section */
-	char		*name;
-} Elf_nobitent;
-	
-typedef struct {
 	Elf_Rel		*rel;
-	Elf_Off		fileoff;
-	Elf_Off		filesz;
+	int		nrel;
 	int		sec;
 } Elf_relent;
 
 typedef struct {
 	Elf_Rela	*rela;
-	Elf_Off		fileoff;
-	Elf_Off		filesz;
+	int		nrela;
 	int		sec;
 } Elf_relaent;
 
@@ -101,9 +89,6 @@
 	Elf_progent	*progtab;
 	int		nprogtab;
 
-	Elf_nobitent	*nobittab;
-	int		nnobittab;
-
 	Elf_relaent	*relatab;
 	int		nrela;
 
@@ -203,7 +188,7 @@
 	Elf_Ehdr *hdr;
 	Elf_Shdr *shdr;
 	int nbytes, i;
-	caddr_t mapbase;
+	vm_offset_t mapbase;
 	size_t mapsize;
 	int error = 0;
 	int resid, flags;
@@ -213,7 +198,7 @@
 	int symstrindex;
 	int shstrindex;
 	int nsym;
-	int pb, nb, rl, ra;
+	int pb, rl, ra;
 	int alignmask;
 
 	GIANT_REQUIRED;
@@ -237,7 +222,7 @@
 #endif
 
 	/* Read the elf header from the file. */
-	hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK);
+	hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK | M_ZERO);
 	if (hdr == NULL) {
 		error = ENOMEM;
 		goto out;
@@ -287,7 +272,6 @@
 	}
 	ef = (elf_file_t) lf;
 	ef->nprogtab = 0;
-	ef->nnobittab = 0;
 	ef->e_shdr = 0;
 	ef->nrel = 0;
 	ef->nrela = 0;
@@ -321,11 +305,9 @@
 	for (i = 0; i < hdr->e_shnum; i++) {
 		switch (shdr[i].sh_type) {
 		case SHT_PROGBITS:
+		case SHT_NOBITS:
 			ef->nprogtab++;
 			break;
-		case SHT_NOBITS:
-			ef->nnobittab++;
-			break;
 		case SHT_SYMTAB:
 			nsym++;
 			symtabindex = i;
@@ -341,7 +323,7 @@
 			break;
 		}
 	}
-	if (ef->nprogtab == 0 && ef->nnobittab == 0) {
+	if (ef->nprogtab == 0) {
 		link_elf_error("file has no contents");
 		error = ENOEXEC;
 		goto out;
@@ -360,52 +342,84 @@
 	}
 
 	/* Allocate space for tracking the load chunks */
-	/* XXX - maybe unneeded. might be able to use the shdr directly */
 	if (ef->nprogtab != 0)
-		ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab), M_LINKER, M_WAITOK);
-	if (ef->nnobittab != 0)
-		ef->nobittab = malloc(ef->nnobittab * sizeof(*ef->nobittab), M_LINKER, M_WAITOK);
+		ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab),
+		    M_LINKER, M_WAITOK | M_ZERO);
 	if (ef->nrel != 0)
-		ef->reltab = malloc(ef->nrel * sizeof(*ef->reltab), M_LINKER, M_WAITOK);
+		ef->reltab = malloc(ef->nrel * sizeof(*ef->reltab), M_LINKER,
+		    M_WAITOK | M_ZERO);
 	if (ef->nrela != 0)
-		ef->relatab = malloc(ef->nrela * sizeof(*ef->relatab), M_LINKER, M_WAITOK);
+		ef->relatab = malloc(ef->nrela * sizeof(*ef->relatab), M_LINKER,
+		    M_WAITOK | M_ZERO);
 	/* XXX check for failures */
 
-	/* Space for symbol table */
+	if (symtabindex == -1)
+		panic("lost symbol table index");
+	/* Allocate space for and load the symbol table */
 	ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym);
-	ef->ddbsymtab = malloc(shdr[symtabindex].sh_size, M_LINKER, M_WAITOK);
+	ef->ddbsymtab = malloc(shdr[symtabindex].sh_size, M_LINKER,
+	    M_WAITOK | M_ZERO);
+	if (ef->ddbsymtab == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+	error = vn_rdwr(UIO_READ, nd.ni_vp, (void *)ef->ddbsymtab,
+	    shdr[symtabindex].sh_size, shdr[symtabindex].sh_offset,
+	    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
+	    &resid, td);
+	if (error)
+		goto out;
+	if (resid != 0){
+		error = EINVAL;
+		goto out;
+	}
 
+	if (symstrindex == -1)
+		panic("lost symbol string index");
+	/* Allocate space for and load the symbol strings */
 	ef->ddbstrcnt = shdr[symstrindex].sh_size;
-	ef->ddbstrtab = malloc(shdr[symstrindex].sh_size, M_LINKER, M_WAITOK);
-
-	if (ef->ddbsymtab == NULL || ef->ddbstrtab == NULL) {
+	ef->ddbstrtab = malloc(shdr[symstrindex].sh_size, M_LINKER,
+	    M_WAITOK | M_ZERO);
+	if (ef->ddbstrtab == NULL) {
 		error = ENOMEM;
 		goto out;
 	}
+	error = vn_rdwr(UIO_READ, nd.ni_vp, ef->ddbstrtab,
+	    shdr[symstrindex].sh_size, shdr[symstrindex].sh_offset,
+	    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
+	    &resid, td);
+	if (error)
+		goto out;
+	if (resid != 0){
+		error = EINVAL;
+		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) {
+	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);
+		ef->shstrtab = malloc(shdr[shstrindex].sh_size, M_LINKER,
+		    M_WAITOK);
 		if (ef->shstrtab == NULL) {
 			error = ENOMEM;
 			goto out;
 		}
-		error = vn_rdwr(UIO_READ, nd.ni_vp,
-		    ef->shstrtab, shdr[shstrindex].sh_size, shdr[shstrindex].sh_offset,
+		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;
+		if (resid != 0){
+			error = EINVAL;
+			goto out;
+		}
 	}
 
-	/* Size code/data(progbits) and bss(nobits).  allocate space for relocs */
-	pb = 0;
-	nb = 0;
-	rl = 0;
-	ra = 0;
+	/* Size up code/data(progbits) and bss(nobits). */
 	alignmask = 0;
 	for (i = 0; i < hdr->e_shnum; i++) {
 		switch (shdr[i].sh_type) {
@@ -414,66 +428,18 @@
 			alignmask = shdr[i].sh_addralign - 1;
 			mapsize += alignmask;
 			mapsize &= ~alignmask;
-			break;
-		}
-
-		switch (shdr[i].sh_type) {
-		case SHT_PROGBITS:
-			ef->progtab[pb].addr = (void *)(uintptr_t)mapsize;
-			ef->progtab[pb].fileoff = shdr[i].sh_offset;
-			ef->progtab[pb].filesz = shdr[i].sh_size;
-			ef->progtab[pb].align = shdr[i].sh_addralign;
-			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>>";
 			mapsize += shdr[i].sh_size;
-			pb++;
-			break;
-		case SHT_NOBITS:
-			ef->nobittab[nb].addr = (void *)(uintptr_t)mapsize;
-			ef->nobittab[nb].memsz = shdr[i].sh_size;
-			ef->nobittab[nb].align = shdr[i].sh_addralign;
-			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>>";
-			mapsize += shdr[i].sh_size;
-			nb++;
-			break;
-		case SHT_REL:
-			ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER, M_WAITOK);
-			ef->reltab[rl].fileoff = shdr[i].sh_offset;
-			ef->reltab[rl].filesz = shdr[i].sh_size;
-			ef->reltab[rl].sec = shdr[i].sh_info;
-			rl++;
-			break;
-		case SHT_RELA:
-			ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER, M_WAITOK);
-			ef->relatab[ra].fileoff = shdr[i].sh_offset;
-			ef->relatab[ra].filesz = shdr[i].sh_size;
-			ef->relatab[ra].sec = shdr[i].sh_info;
-			ra++;
 			break;
 		}
 	}
-	if (pb != ef->nprogtab)
-		panic("lots progbits");
-	if (nb != ef->nnobittab)
-		panic("lots nobits");
-	if (rl != ef->nrel)
-		panic("lots rel");
-	if (ra != ef->nrela)
-		panic("lots rela");
 
 	/*
 	 * We know how much space we need for the text/data/bss/etc.
 	 * This stuff needs to be in a single chunk so that profiling etc
 	 * can get the bounds and gdb can associate offsets with modules
 	 */
-	ef->object = vm_object_allocate(OBJT_DEFAULT, round_page(mapsize) >> PAGE_SHIFT);
+	ef->object = vm_object_allocate(OBJT_DEFAULT,
+	    round_page(mapsize) >> PAGE_SHIFT);
 	if (ef->object == NULL) {
 		error = ENOMEM;
 		goto out;
@@ -481,80 +447,111 @@
 	vm_object_reference(ef->object);
 	ef->address = (caddr_t) vm_map_min(kernel_map);
 	error = vm_map_find(kernel_map, ef->object, 0,
-	    (vm_offset_t *) &ef->address, mapsize, TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE);
+	    &mapbase, mapsize, TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE);
 	if (error) {
 		vm_object_deallocate(ef->object);
 		ef->object = 0;
 		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(kernel_map, mapbase,
+	    mapbase + round_page(mapsize),
 	    VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES);
 
-	/* Add the base address to the previously calculated/aligned offsets */
-	for (i = 0; i < ef->nprogtab; i++)
-		ef->progtab[i].addr = mapbase + (uintptr_t)ef->progtab[i].addr;
+	/* Inform the kld system about the situation */
+	lf->address = ef->address = (caddr_t)mapbase;
+	lf->size = mapsize;
 
-	for (i = 0; i < ef->nnobittab; i++)
-		ef->nobittab[i].addr = mapbase + (uintptr_t)ef->nobittab[i].addr;
-	
-
-	/* Load the symbol table. */
-	error = vn_rdwr(UIO_READ, nd.ni_vp,
-	    (void *)ef->ddbsymtab, shdr[symtabindex].sh_size, shdr[symtabindex].sh_offset,
-	    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-	    &resid, td);
-	if (error)
-		goto out;
-	error = vn_rdwr(UIO_READ, nd.ni_vp,
-	    ef->ddbstrtab, shdr[symstrindex].sh_size, shdr[symstrindex].sh_offset,
-	    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-	    &resid, td);
-	if (error)
-		goto out;
-
-	/* Read in the text/data/set/etc sections */
-	for (i = 0; i < ef->nprogtab; i++) {
-		error = vn_rdwr(UIO_READ, nd.ni_vp,
-		    ef->progtab[i].addr,
-		    ef->progtab[i].filesz,
-		    ef->progtab[i].fileoff,
-		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-		    &resid, td);
-		if (error)
-			goto out;
-	}
-
 	/*
-	 * Read in relocation tables.  Platforms use rel or rela, but
-	 * usually not both.
+	 * Now load code/data(progbits), zero bss(nobits), allocate space for
+	 * and load relocs
 	 */
-	for (i = 0; i < ef->nrel; i++) {
-		error = vn_rdwr(UIO_READ, nd.ni_vp,
-		    (void *)ef->reltab[i].rel,
-		    ef->reltab[i].filesz,
-		    ef->reltab[i].fileoff,
-		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-		    &resid, td);
-		if (error)
-			goto out;
+	pb = 0;
+	rl = 0;
+	ra = 0;
+	alignmask = 0;
+	for (i = 0; i < hdr->e_shnum; i++) {
+		switch (shdr[i].sh_type) {
+		case SHT_PROGBITS:
+		case SHT_NOBITS:
+			alignmask = shdr[i].sh_addralign - 1;
+			mapbase += alignmask;
+			mapbase &= ~alignmask;
+			ef->progtab[pb].addr = (void *)(uintptr_t)mapbase;
+			if (shdr[i].sh_type == SHT_PROGBITS) {
+				ef->progtab[pb].name = "<<PROGBITS>>";
+				error = vn_rdwr(UIO_READ, nd.ni_vp,
+				    ef->progtab[pb].addr,
+				    shdr[i].sh_size, shdr[i].sh_offset,
+				    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
+				    NOCRED, &resid, td);
+				if (error)
+					goto out;
+				if (resid != 0){
+					error = EINVAL;
+					goto out;
+				}
+			} else {
+				bzero(ef->progtab[pb].addr, shdr[i].sh_size);
+				ef->progtab[pb].name = "<<NOBITS>>";
+			}
+			ef->progtab[pb].size = shdr[i].sh_size;
+			ef->progtab[pb].align = shdr[i].sh_addralign;
+			ef->progtab[pb].sec = i;
+			if (ef->shstrtab && shdr[i].sh_name != 0)
+				ef->progtab[pb].name =
+				    ef->shstrtab + shdr[i].sh_name;
+			mapsize += shdr[i].sh_size;
+			pb++;
+			break;
+		case SHT_REL:
+			ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER,
+			    M_WAITOK);
+			ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel);
+			ef->reltab[rl].sec = shdr[i].sh_info;
+			error = vn_rdwr(UIO_READ, nd.ni_vp,
+			    (void *)ef->reltab[rl].rel,
+			    shdr[i].sh_size, shdr[i].sh_offset,
+			    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
+			    &resid, td);
+			if (error)
+				goto out;
+			if (resid != 0){
+				error = EINVAL;
+				goto out;
+			}
+			rl++;
+			break;
+		case SHT_RELA:
+			ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER,
+			    M_WAITOK);
+			ef->relatab[ra].nrela =
+			    shdr[i].sh_size / sizeof(Elf_Rela);
+			ef->relatab[ra].sec = shdr[i].sh_info;
+			error = vn_rdwr(UIO_READ, nd.ni_vp,
+			    (void *)ef->relatab[ra].rela,
+			    shdr[i].sh_size, shdr[i].sh_offset,
+			    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
+			    &resid, td);
+			if (error)
+				goto out;
+			if (resid != 0){
+				error = EINVAL;
+				goto out;
+			}
+			ra++;
+			break;
+		}
 	}
-	for (i = 0; i < ef->nrela; i++) {
-		error = vn_rdwr(UIO_READ, nd.ni_vp,
-		    (void *)ef->relatab[i].rela,
-		    ef->relatab[i].filesz,
-		    ef->relatab[i].fileoff,
-		    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
-		    &resid, td);
-		if (error)
-			goto out;
-	}
-
-	/* Inform the kld system about the situation */
-	lf->address = ef->address = mapbase;
-	lf->size = mapsize;
+	if (pb != ef->nprogtab)
+		panic("lost progbits");
+	if (rl != ef->nrel)
+		panic("lost rel");
+	if (ra != ef->nrela)
+		panic("lost rela");
+	if (mapbase != mapsize)
+		printf("mapbase 0x%lx != mapsize 0x%lx\n", mapbase, mapsize);
 
 	/* Local intra-module relocations */
 	link_elf_reloc_local(lf);
@@ -597,7 +594,8 @@
 
 	if (ef->object) {
 		vm_map_remove(kernel_map, (vm_offset_t) ef->address,
-		    (vm_offset_t) ef->address + (ef->object->size << PAGE_SHIFT));
+		    (vm_offset_t) ef->address +
+		    (ef->object->size << PAGE_SHIFT));
 		vm_object_deallocate(ef->object);
 	}
 	if (ef->e_shdr)
@@ -630,12 +628,6 @@
 		if (sec == ef->progtab[i].sec)
 			base = (Elf_Addr)ef->progtab[i].addr;
 	}
-	if (base == 0) {
-		for (i = 0; i < ef->nnobittab; i++) {
-			if (sec == ef->nobittab[i].sec)
-				base = (Elf_Addr)ef->nobittab[i].addr;
-		}
-	}
 	if (base == 0)
 		base = (Elf_Addr)ef->address;
 	return base;
@@ -658,22 +650,24 @@
 	/* Perform relocations without addend if there are any: */
 	for (i = 0; i < ef->nrel; i++) {
 		rel = ef->reltab[i].rel;
-		if (rel) {
-			rellim = (const Elf_Rel *)((const char *)rel + ef->reltab[i].filesz);
-			base = findbase(ef, ef->reltab[i].sec);
-			while (rel < rellim) {
-				symidx = ELF_R_SYM(rel->r_info);
-				if (symidx < ef->ddbsymcnt) {
-					sym = ef->ddbsymtab + symidx;
-					if (ELF64_ST_BIND(sym->st_info) != STB_LOCAL) {
-						if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL, elf_obj_lookup)) {
-							symname = symbol_name(ef, rel->r_info);
-							printf("link_elf: symbol %s undefined\n", symname);
-							return ENOENT;
-						}
-					}
-				}
-				rel++;
+		if (rel == NULL)
+			continue;
+		rellim = rel + ef->reltab[i].nrel;
+		base = findbase(ef, ef->reltab[i].sec);
+		for ( ; rel < rellim; rel++) {
+			symidx = ELF_R_SYM(rel->r_info);
+			if (symidx >= ef->ddbsymcnt)
+				continue;
+			sym = ef->ddbsymtab + symidx;
+			/* Local relocs are already done */
+			if (ELF64_ST_BIND(sym->st_info) == STB_LOCAL)
+				continue;
+			if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL,
+			    elf_obj_lookup)) {
+				symname = symbol_name(ef, rel->r_info);
+				printf("link_elf_obj: symbol %s undefined\n",
+				    symname);
+				return ENOENT;
 			}
 		}
 	}
@@ -681,22 +675,24 @@
 	/* Perform relocations with addend if there are any: */
 	for (i = 0; i < ef->nrela; i++) {
 		rela = ef->relatab[i].rela;
-		if (rela) {
-			relalim = (const Elf_Rela *)((const char *)rela + ef->relatab[i].filesz);
-			base = findbase(ef, ef->relatab[i].sec);
-			while (rela < relalim) {
-				symidx = ELF_R_SYM(rela->r_info);
-				if (symidx < ef->ddbsymcnt) {
-					sym = ef->ddbsymtab + symidx;
-					if (ELF64_ST_BIND(sym->st_info) != STB_LOCAL) {
-						if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA, elf_obj_lookup)) {
-							symname = symbol_name(ef, rela->r_info);
-							printf("link_elf: symbol %s undefined\n", symname);
-							return ENOENT;
-						}
-					}
-				}
-				rela++;
+		if (rela == NULL)
+			continue;
+		relalim = rela + ef->relatab[i].nrela;
+		base = findbase(ef, ef->relatab[i].sec);
+		for ( ; rela < relalim; rela++) {
+			symidx = ELF_R_SYM(rela->r_info);
+			if (symidx >= ef->ddbsymcnt)
+				continue;
+			sym = ef->ddbsymtab + symidx;
+			/* Local relocs are already done */
+			if (ELF64_ST_BIND(sym->st_info) == STB_LOCAL)
+				continue;
+			if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA,
+			    elf_obj_lookup)) {
+				symname = symbol_name(ef, rela->r_info);
+				printf("link_elf_obj: symbol %s undefined\n",
+				    symname);
+				return ENOENT;
 			}
 		}
 	}
@@ -713,13 +709,12 @@
 	int i;
 
 /* XXX search for globals first */
-	/* Exhaustive search */
 	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)) {
+			    ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
 				*sym = (c_linker_sym_t) symp;
 				return 0;
 			} else
@@ -731,7 +726,8 @@
 }
 
 static int
-link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym, linker_symval_t *symval)
+link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
+    linker_symval_t *symval)
 {
 	elf_file_t ef = (elf_file_t) lf;
 	const Elf_Sym *es = (const Elf_Sym*) sym;
@@ -797,7 +793,8 @@
 		if ((strncmp(ef->progtab[i].name, "set_", 4) == 0) &&
 		    strcmp(ef->progtab[i].name + 4, name) == 0) {
 			start  = (void **)ef->progtab[i].addr;
-			stop = (void **)((char *)ef->progtab[i].addr + ef->progtab[i].filesz);
+			stop = (void **)((char *)ef->progtab[i].addr +
+			    ef->progtab[i].size);
 			count = stop - start;
 			if (startp)
 				*startp = start;
@@ -867,14 +864,6 @@
 				break;
 			}
 		}
-		if (ret == 0) {
-			for (i = 0; i < ef->nnobittab; i++) {
-				if (sym->st_shndx == ef->nobittab[i].sec) {
-					ret = (Elf_Addr)ef->nobittab[i].addr;
-					break;
-				}
-			}
-		}
 		return ret + sym->st_value;
 
 	case STB_GLOBAL:
@@ -915,36 +904,40 @@
 	/* Perform relocations without addend if there are any: */
 	for (i = 0; i < ef->nrel; i++) {
 		rel = ef->reltab[i].rel;
-		if (rel) {
-			rellim = (const Elf_Rel *)((const char *)rel + ef->reltab[i].filesz);
-			base = findbase(ef, ef->reltab[i].sec);
-			while (rel < rellim) {
-				symidx = ELF_R_SYM(rel->r_info);
-				if (symidx < ef->ddbsymcnt) {
-					sym = ef->ddbsymtab + symidx;
-					if (ELF64_ST_BIND(sym->st_info) == STB_LOCAL)
-						elf_reloc_local(lf, base, rel, ELF_RELOC_REL, elf_obj_lookup);
-				}
-				rel++;
-			}
+		if (rel == NULL)
+			continue;
+		rellim = rel + ef->reltab[i].nrel;
+		base = findbase(ef, ef->reltab[i].sec);
+		for ( ; rel < rellim; rel++) {
+			symidx = ELF_R_SYM(rel->r_info);
+			if (symidx >= ef->ddbsymcnt)
+				continue;
+			sym = ef->ddbsymtab + symidx;
+			/* Only do local relocs */
+			if (ELF64_ST_BIND(sym->st_info) != STB_LOCAL)
+				continue;
+			elf_reloc_local(lf, base, rel, ELF_RELOC_REL,
+			    elf_obj_lookup);
 		}
 	}
 
 	/* Perform relocations with addend if there are any: */
 	for (i = 0; i < ef->nrela; i++) {
 		rela = ef->relatab[i].rela;
-		if (rela) {
-			relalim = (const Elf_Rela *)((const char *)rela + ef->relatab[i].filesz);
-			base = findbase(ef, ef->relatab[i].sec);
-			while (rela < relalim) {
-				symidx = ELF_R_SYM(rela->r_info);
-				if (symidx < ef->ddbsymcnt) {
-					sym = ef->ddbsymtab + symidx;
-					if (ELF64_ST_BIND(sym->st_info) == STB_LOCAL)
-						elf_reloc_local(lf, base, rela, ELF_RELOC_RELA, elf_obj_lookup);
-				}
-				rela++;
-			}
+		if (rela == NULL)
+			continue;
+		relalim = rela + ef->relatab[i].nrela;
+		base = findbase(ef, ef->relatab[i].sec);
+		for ( ; rela < relalim; rela++) {
+			symidx = ELF_R_SYM(rela->r_info);
+			if (symidx >= ef->ddbsymcnt)
+				continue;
+			sym = ef->ddbsymtab + symidx;
+			/* Only do local relocs */
+			if (ELF64_ST_BIND(sym->st_info) != STB_LOCAL)
+				continue;
+			elf_reloc_local(lf, base, rela, ELF_RELOC_RELA,
+			    elf_obj_lookup);
 		}
 	}
 }



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