Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 May 2004 12:56:04 -0700 (PDT)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 52942 for review
Message-ID:  <200405171956.i4HJu4I6053259@repoman.freebsd.org>

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

Change 52942 by peter@peter_hammer on 2004/05/17 12:55:57

	load and unload worked, but something trashes the kobj method
	tables still

Affected files ...

.. //depot/projects/hammer/sys/kern/kern_linker.c#13 edit
.. //depot/projects/hammer/sys/kern/link_elf_obj.c#32 edit

Differences ...

==== //depot/projects/hammer/sys/kern/kern_linker.c#13 (text+ko) ====

@@ -1,3 +1,4 @@
+#define KLD_DEBUG
 /*-
  * Copyright (c) 1997-2000 Doug Rabson
  * All rights reserved.
@@ -52,7 +53,7 @@
 #include "linker_if.h"
 
 #ifdef KLD_DEBUG
-int kld_debug = 0;
+int kld_debug = 3;
 #endif
 
 /*

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

@@ -82,6 +82,8 @@
 
 typedef struct elf_file {
 	struct linker_file lf;		/* Common fields */
+
+	char pad0[80];
 	caddr_t		address;	/* Relocation address */
 	vm_object_t	object;		/* VM object to hold file pages */
 	Elf_Shdr	*e_shdr;
@@ -102,6 +104,7 @@
 
 	caddr_t		shstrtab;	/* Section name string table */
 	long		shstrcnt;	/* number of bytes in string table */
+	char pad2[80];
 
 } *elf_file_t;
 
@@ -149,6 +152,38 @@
 
 static int	relocate_file(elf_file_t ef);
 
+static void *
+Malloc(const char *id, unsigned long size, struct malloc_type *type, int flags)
+{
+	void *ret;
+
+	ret = malloc(size, type, flags);
+	printf("Malloc: id %s, size 0x%lx -> ret %p\n", id, size, ret);
+	return ret;
+}
+static void
+Free(const char *id, void *addr, struct malloc_type *type)
+{
+	printf("Free: id %s, addr %p\n", id, addr);
+	free(addr, type);
+}
+
+static int
+Vn_rdwr(enum uio_rw rw, struct vnode *vp, caddr_t base,
+    int len, off_t offset, enum uio_seg segflg, int ioflg,
+    struct ucred *active_cred, struct ucred *file_cred, int *aresid,
+    struct thread *td)
+{
+	int ret;
+
+	printf("vn_rdwr: base %p, len 0x%x, off 0x%lx\n", base, len, offset);
+	ret = vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, active_cred, file_cred, aresid, td);
+	printf("vn_rdwr: returns resid 0x%x, ret %d\n", aresid ? *aresid : 0, ret);
+	return ret;
+}
+#define vn_rdwr Vn_rdwr
+
+
 static void
 link_elf_error(const char *s)
 {
@@ -222,7 +257,7 @@
 #endif
 
 	/* Read the elf header from the file. */
-	hdr = malloc(sizeof(*hdr), M_LINKER, M_WAITOK | M_ZERO);
+	hdr = Malloc("elf header", sizeof(*hdr), M_LINKER, M_WAITOK);
 	if (hdr == NULL) {
 		error = ENOMEM;
 		goto out;
@@ -283,7 +318,7 @@
 		error = ENOEXEC;
 		goto out;
 	}
-	shdr = malloc(nbytes, M_LINKER, M_WAITOK | M_ZERO);
+	shdr = Malloc("shdr", nbytes, M_LINKER, M_WAITOK);
 	if (shdr == NULL) {
 		error = ENOMEM;
 		goto out;
@@ -343,22 +378,26 @@
 
 	/* Allocate space for tracking the load chunks */
 	if (ef->nprogtab != 0)
-		ef->progtab = malloc(ef->nprogtab * sizeof(*ef->progtab),
+		ef->progtab = Malloc("progtab", 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,
+		ef->reltab = Malloc("reltab", 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,
+		ef->relatab = Malloc("relatab", ef->nrela * sizeof(*ef->relatab), M_LINKER,
 		    M_WAITOK | M_ZERO);
-	/* XXX check for failures */
+	if ((ef->nprogtab != 0 && ef->progtab == NULL) ||
+	    (ef->nrel != 0 && ef->reltab == NULL) ||
+	    (ef->nrela != 0 && ef->relatab == NULL)) {
+		error = ENOMEM;
+		goto out;
+	}
 
 	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 | M_ZERO);
+	ef->ddbsymtab = Malloc("ddbsymtab", shdr[symtabindex].sh_size, M_LINKER, M_WAITOK);
 	if (ef->ddbsymtab == NULL) {
 		error = ENOMEM;
 		goto out;
@@ -378,8 +417,7 @@
 		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 | M_ZERO);
+	ef->ddbstrtab = Malloc("ddbstrtab", shdr[symstrindex].sh_size, M_LINKER, M_WAITOK);
 	if (ef->ddbstrtab == NULL) {
 		error = ENOMEM;
 		goto out;
@@ -401,7 +439,7 @@
 	    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,
+		ef->shstrtab = Malloc("shstrtab", shdr[shstrindex].sh_size, M_LINKER,
 		    M_WAITOK);
 		if (ef->shstrtab == NULL) {
 			error = ENOMEM;
@@ -446,8 +484,8 @@
 	}
 	vm_object_reference(ef->object);
 	ef->address = (caddr_t) vm_map_min(kernel_map);
-	error = vm_map_find(kernel_map, ef->object, 0,
-	    &mapbase, mapsize, TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE);
+	error = vm_map_find(kernel_map, ef->object, 0, &mapbase,
+	    round_page(mapsize), TRUE, VM_PROT_ALL, VM_PROT_ALL, FALSE);
 	if (error) {
 		vm_object_deallocate(ef->object);
 		ef->object = 0;
@@ -463,6 +501,7 @@
 	lf->address = ef->address = (caddr_t)mapbase;
 	lf->size = mapsize;
 
+printf("mapbase: 0x%lx, mapsize 0x%lx, end 0x%lx\n", mapbase, mapsize, mapbase + mapsize);
 	/*
 	 * Now load code/data(progbits), zero bss(nobits), allocate space for
 	 * and load relocs
@@ -493,8 +532,8 @@
 					goto out;
 				}
 			} else {
+				ef->progtab[pb].name = "<<NOBITS>>";
 				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;
@@ -502,14 +541,16 @@
 			if (ef->shstrtab && shdr[i].sh_name != 0)
 				ef->progtab[pb].name =
 				    ef->shstrtab + shdr[i].sh_name;
+printf("section %d, pb %d, base %p, name %s\n", i, pb, ef->progtab[pb].addr, ef->progtab[pb].name);
 			mapbase += shdr[i].sh_size;
 			pb++;
 			break;
 		case SHT_REL:
-			ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER,
+			ef->reltab[rl].rel = Malloc("one SHT_REL", 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;
+printf("rel sec %d rl %d addr %p size 0x%lx nrel %d\n", i, rl, ef->reltab[rl].rel, shdr[i].sh_size, ef->reltab[rl].nrel);
 			error = vn_rdwr(UIO_READ, nd.ni_vp,
 			    (void *)ef->reltab[rl].rel,
 			    shdr[i].sh_size, shdr[i].sh_offset,
@@ -524,11 +565,12 @@
 			rl++;
 			break;
 		case SHT_RELA:
-			ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER,
+			ef->relatab[ra].rela = Malloc("one SHT_RELA", 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;
+printf("rela sec %d ra %d addr %p size 0x%lx nrela %d\n", i, ra, ef->relatab[ra].rela, shdr[i].sh_size, ef->relatab[ra].nrela);
 			error = vn_rdwr(UIO_READ, nd.ni_vp,
 			    (void *)ef->relatab[ra].rela,
 			    shdr[i].sh_size, shdr[i].sh_offset,
@@ -574,10 +616,12 @@
 	*result = lf;
 
 out:
-	if (error && lf)
+	if (error && lf) {
+		printf("error: unloading\n");
 		linker_file_unload(lf);
+	}
 	if (hdr)
-		free(hdr, M_LINKER);
+		Free("elf hdr", hdr, M_LINKER);
 	VOP_UNLOCK(nd.ni_vp, 0, td);
 	vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
 
@@ -588,22 +632,39 @@
 link_elf_unload_file(linker_file_t file)
 {
 	elf_file_t ef = (elf_file_t) file;
+	int i;
 
 	/* Notify MD code that a module is being unloaded. */
 	elf_cpu_unload_file(file);
 
+	for (i = 0; i < ef->nrel; i++)
+		if (ef->reltab[i].rel)
+			Free("one reltab", ef->reltab[i].rel, M_LINKER);
+	for (i = 0; i < ef->nrela; i++)
+		if (ef->relatab[i].rela)
+			Free("one relatab", ef->relatab[i].rela, M_LINKER);
+	if (ef->reltab)
+		Free("reltab", ef->reltab, M_LINKER);
+	if (ef->relatab)
+		Free("relatab", ef->relatab, M_LINKER);
+	if (ef->progtab)
+		Free("progtab", ef->progtab, M_LINKER);
+
 	if (ef->object) {
+printf("object: %p, size %ld pages, addr %p, end 0x%lx\n", ef->object, ef->object->size, ef->address, (vm_offset_t) ef->address + (ef->object->size << PAGE_SHIFT));
 		vm_map_remove(kernel_map, (vm_offset_t) ef->address,
 		    (vm_offset_t) ef->address +
 		    (ef->object->size << PAGE_SHIFT));
 		vm_object_deallocate(ef->object);
 	}
 	if (ef->e_shdr)
-		free(ef->e_shdr, M_LINKER);
+		Free("shdr", ef->e_shdr, M_LINKER);
 	if (ef->ddbsymtab)
-		free(ef->ddbsymtab, M_LINKER);
+		Free("ddbsymtab", ef->ddbsymtab, M_LINKER);
 	if (ef->ddbstrtab)
-		free(ef->ddbstrtab, M_LINKER);
+		Free("ddbstrtab", ef->ddbstrtab, M_LINKER);
+	if (ef->shstrtab)
+		Free("shstrtab", ef->shstrtab, M_LINKER);
 }
 
 static const char *
@@ -660,7 +721,7 @@
 				continue;
 			sym = ef->ddbsymtab + symidx;
 			/* Local relocs are already done */
-			if (ELF64_ST_BIND(sym->st_info) == STB_LOCAL)
+			if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
 				continue;
 			if (elf_reloc(&ef->lf, base, rel, ELF_RELOC_REL,
 			    elf_obj_lookup)) {
@@ -685,7 +746,7 @@
 				continue;
 			sym = ef->ddbsymtab + symidx;
 			/* Local relocs are already done */
-			if (ELF64_ST_BIND(sym->st_info) == STB_LOCAL)
+			if (ELF_ST_BIND(sym->st_info) == STB_LOCAL)
 				continue;
 			if (elf_reloc(&ef->lf, base, rela, ELF_RELOC_RELA,
 			    elf_obj_lookup)) {
@@ -802,6 +863,7 @@
 				*stopp = stop;
 			if (countp)
 				*countp = count;
+printf("lookup_set: %s start %p stop %p count 0x%x\n", name, start, stop, count);
 			return (0);
 		}
 	}
@@ -851,7 +913,7 @@
 	sym = ef->ddbsymtab + symidx;
 
 	/* Theoretically we can avoid a lookup for some locals */
-	switch (ELF64_ST_BIND(sym->st_info)) {
+	switch (ELF_ST_BIND(sym->st_info)) {
 	case STB_LOCAL:
 		/* Local, but undefined? huh? */
 		if (sym->st_shndx == SHN_UNDEF)
@@ -885,8 +947,6 @@
 	}
 }
 
-
-
 static void
 link_elf_reloc_local(linker_file_t lf)
 {
@@ -914,7 +974,7 @@
 				continue;
 			sym = ef->ddbsymtab + symidx;
 			/* Only do local relocs */
-			if (ELF64_ST_BIND(sym->st_info) != STB_LOCAL)
+			if (ELF_ST_BIND(sym->st_info) != STB_LOCAL)
 				continue;
 			elf_reloc_local(lf, base, rel, ELF_RELOC_REL,
 			    elf_obj_lookup);
@@ -934,7 +994,7 @@
 				continue;
 			sym = ef->ddbsymtab + symidx;
 			/* Only do local relocs */
-			if (ELF64_ST_BIND(sym->st_info) != STB_LOCAL)
+			if (ELF_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?200405171956.i4HJu4I6053259>