PERFORCE change 52942 for review
Peter Wemm
peter at FreeBSD.org
Mon May 17 12:56:10 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=52942
Change 52942 by peter at 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);
More information about the p4-projects
mailing list