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>