Index: sys/alpha/alpha/elf_machdep.c =========================================================================== --- sys/alpha/alpha/elf_machdep.c 2004/04/30 09:10:56 #11 +++ sys/alpha/alpha/elf_machdep.c 2004/04/30 09:10:56 @@ -108,9 +108,9 @@ /* Process one elf relocation with addend. */ static int -elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) +elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, int local, elf_lookup_fn lookup) { - Elf_Addr relocbase = (Elf_Addr) lf->address; Elf_Addr *where; Elf_Addr addr; Elf_Addr addend; @@ -152,7 +152,7 @@ break; case R_ALPHA_REFQUAD: - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend; @@ -161,7 +161,7 @@ break; case R_ALPHA_GLOB_DAT: - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend; @@ -171,7 +171,7 @@ case R_ALPHA_JMP_SLOT: /* No point in lazy binding for kernel modules. */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; if (*where != addr) @@ -198,17 +198,19 @@ } int -elf_reloc(linker_file_t lf, const void *data, int type) +elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, + elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 0)); + return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); } int -elf_reloc_local(linker_file_t lf, const void *data, int type) +elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 1)); + return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); } int Index: sys/amd64/amd64/elf_machdep.c =========================================================================== --- sys/amd64/amd64/elf_machdep.c 2004/04/30 09:10:56 #7 +++ sys/amd64/amd64/elf_machdep.c 2004/04/30 09:10:56 @@ -104,10 +104,11 @@ /* Process one elf relocation with addend. */ static int -elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) +elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, int local, elf_lookup_fn lookup) { - Elf_Addr relocbase = (Elf_Addr) lf->address; - Elf_Addr *where; + Elf64_Addr *where, val; + Elf32_Addr *where32, val32; Elf_Addr addr; Elf_Addr addend; Elf_Word rtype, symidx; @@ -133,37 +134,39 @@ panic("unknown reloc type %d\n", type); } - if (local) { - if (rtype == R_X86_64_RELATIVE) { /* A + B */ - addr = relocbase + addend; - if (*where != addr) - *where = addr; - } - return (0); - } + switch (rtype) { - switch (rtype) { case R_X86_64_NONE: /* none */ break; case R_X86_64_64: /* S + A */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); + val = addr + addend; if (addr == 0) return -1; - addr += addend; - if (*where != addr) - *where = addr; + if (*where != val) + *where = val; break; case R_X86_64_PC32: /* S + A - P */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); + where32 = (Elf32_Addr *)where; + val32 = (Elf32_Addr)(addr + addend - (Elf_Addr)where); + if (addr == 0) + return -1; + if (*where32 != val32) + *where32 = val32; + break; + + case R_X86_64_32S: /* S + A sign extend */ + addr = lookup(lf, symidx, 1); + val32 = (Elf32_Addr)(addr + addend); + where32 = (Elf32_Addr *)where; if (addr == 0) return -1; - addr += addend - (Elf_Addr)where; - /* XXX needs to be 32 bit *where, not 64 bit */ - if (*where != addr) - *where = addr; + if (*where32 != val32) + *where32 = val32; break; case R_X86_64_COPY: /* none */ @@ -176,7 +179,7 @@ break; case R_X86_64_GLOB_DAT: /* S */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; if (*where != addr) @@ -184,6 +187,10 @@ break; case R_X86_64_RELATIVE: /* B + A */ + addr = relocbase + addend; + val = addr; + if (*where != val) + *where = val; break; default: @@ -195,17 +202,19 @@ } int -elf_reloc(linker_file_t lf, const void *data, int type) +elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, + elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 0)); + return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); } int -elf_reloc_local(linker_file_t lf, const void *data, int type) +elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 1)); + return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); } int Index: sys/conf/files =========================================================================== --- sys/conf/files 2004/04/30 09:10:56 #331 +++ sys/conf/files 2004/04/30 09:10:56 @@ -1083,6 +1083,7 @@ kern/kern_uuid.c standard kern/kern_xxx.c standard kern/link_elf.c standard +kern/link_elf_obj.c standard kern/md4c.c optional netsmb kern/md5c.c standard kern/sched_4bsd.c optional sched_4bsd Index: sys/conf/kmod.mk =========================================================================== --- sys/conf/kmod.mk 2004/04/30 09:10:56 #53 +++ sys/conf/kmod.mk 2004/04/30 09:10:56 @@ -137,18 +137,12 @@ ${OBJCOPY} --strip-debug ${FULLPROG} ${PROG} .endif -${FULLPROG}: ${KMOD}.kld - ${LD} -Bshareable ${LDFLAGS} -o ${.TARGET} ${KMOD}.kld -.if !defined(DEBUG_FLAGS) - ${OBJCOPY} --strip-debug ${.TARGET} -.endif - EXPORT_SYMS?= NO .if ${EXPORT_SYMS} != YES CLEANFILES+= ${.OBJDIR}/export_syms .endif -${KMOD}.kld: ${OBJS} +${FULLPROG}: ${OBJS} ${LD} ${LDFLAGS} -r -d -o ${.TARGET} ${OBJS} .if defined(EXPORT_SYMS) .if ${EXPORT_SYMS} != YES @@ -164,6 +158,9 @@ xargs -J% ${OBJCOPY} % ${.TARGET} .endif .endif +.if !defined(DEBUG_FLAGS) + ${OBJCOPY} --strip-debug ${.TARGET} +.endif _ILINKS=@ machine Index: sys/i386/i386/elf_machdep.c =========================================================================== --- sys/i386/i386/elf_machdep.c 2004/04/30 09:10:56 #11 +++ sys/i386/i386/elf_machdep.c 2004/04/30 09:10:56 @@ -104,9 +104,9 @@ /* Process one elf relocation with addend. */ static int -elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) +elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, int local, elf_lookup_fn lookup) { - Elf_Addr relocbase = (Elf_Addr) lf->address; Elf_Addr *where; Elf_Addr addr; Elf_Addr addend; @@ -148,7 +148,7 @@ break; case R_386_32: /* S + A */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend; @@ -157,7 +157,7 @@ break; case R_386_PC32: /* S + A - P */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend - (Elf_Addr)where; @@ -175,7 +175,7 @@ break; case R_386_GLOB_DAT: /* S */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; if (*where != addr) @@ -194,17 +194,19 @@ } int -elf_reloc(linker_file_t lf, const void *data, int type) +elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, + elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 0)); + return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); } int -elf_reloc_local(linker_file_t lf, const void *data, int type) +elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 1)); + return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); } int Index: sys/ia64/ia64/elf_machdep.c =========================================================================== --- sys/ia64/ia64/elf_machdep.c 2004/04/30 09:10:56 #16 +++ sys/ia64/ia64/elf_machdep.c 2004/04/30 09:10:56 @@ -143,7 +143,7 @@ } static Elf_Addr -lookup_fdesc(linker_file_t lf, Elf_Word symidx) +lookup_fdesc(linker_file_t lf, Elf_Word symidx, elf_lookup_fn lookup) { linker_file_t top; Elf_Addr addr; @@ -151,7 +151,7 @@ int i; static int eot = 0; - addr = elf_lookup(lf, symidx, 0); + addr = lookup(lf, symidx, 0); if (addr == 0) { top = lf; symname = elf_get_symname(top, symidx); @@ -191,7 +191,8 @@ /* Process one elf relocation with addend. */ static int -elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) +elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, int local, elf_lookup_fn lookup) { Elf_Addr relocbase = (Elf_Addr)lf->address; Elf_Addr *where; @@ -238,7 +239,7 @@ case R_IA64_NONE: break; case R_IA64_DIR64LSB: /* word64 LSB S + A */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return (-1); *where = addr + addend; @@ -248,7 +249,7 @@ printf("%s: addend ignored for OPD relocation\n", __func__); } - addr = lookup_fdesc(lf, symidx); + addr = lookup_fdesc(lf, symidx, lookup); if (addr == 0) return (-1); *where = addr; @@ -256,7 +257,7 @@ case R_IA64_REL64LSB: /* word64 LSB BD + A */ break; case R_IA64_IPLTLSB: - addr = lookup_fdesc(lf, symidx); + addr = lookup_fdesc(lf, symidx, lookup); if (addr == 0) return (-1); where[0] = *((Elf_Addr*)addr) + addend; @@ -272,17 +273,19 @@ } int -elf_reloc(linker_file_t lf, const void *data, int type) +elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, + elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 0)); + return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); } int -elf_reloc_local(linker_file_t lf, const void *data, int type) +elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 1)); + return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); } int Index: sys/kern/link_elf.c =========================================================================== --- sys/kern/link_elf.c 2004/04/30 09:10:56 #36 +++ sys/kern/link_elf.c 2004/04/30 09:10:56 @@ -118,6 +118,7 @@ int (*)(const char *, void *), void *); static void link_elf_reloc_local(linker_file_t); +static Elf_Addr elf_lookup(linker_file_t lf, Elf_Word symidx, int deps); static kobj_method_t link_elf_methods[] = { KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), @@ -928,7 +929,7 @@ if (rel) { rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize); while (rel < rellim) { - if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { + if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL, elf_lookup)) { symname = symbol_name(ef, rel->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; @@ -942,7 +943,7 @@ if (rela) { relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize); while (rela < relalim) { - if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { + if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA, elf_lookup)) { symname = symbol_name(ef, rela->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; @@ -956,7 +957,7 @@ if (rel) { rellim = (const Elf_Rel *)((const char *)ef->pltrel + ef->pltrelsize); while (rel < rellim) { - if (elf_reloc(&ef->lf, rel, ELF_RELOC_REL)) { + if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL, elf_lookup)) { symname = symbol_name(ef, rel->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; @@ -970,7 +971,7 @@ if (rela) { relalim = (const Elf_Rela *)((const char *)ef->pltrela + ef->pltrelasize); while (rela < relalim) { - if (elf_reloc(&ef->lf, rela, ELF_RELOC_RELA)) { + if (elf_reloc(&ef->lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA, elf_lookup)) { symname = symbol_name(ef, rela->r_info); printf("link_elf: symbol %s undefined\n", symname); return ENOENT; @@ -1244,7 +1245,7 @@ * This is not only more efficient, it's also more correct. It's not always * the case that the symbol can be found through the hash table. */ -Elf_Addr +static Elf_Addr elf_lookup(linker_file_t lf, Elf_Word symidx, int deps) { elf_file_t ef = (elf_file_t)lf; @@ -1297,7 +1298,7 @@ if ((rel = ef->rel) != NULL) { rellim = (const Elf_Rel *)((const char *)ef->rel + ef->relsize); while (rel < rellim) { - elf_reloc_local(lf, rel, ELF_RELOC_REL); + elf_reloc_local(lf, (Elf_Addr)ef->address, rel, ELF_RELOC_REL, elf_lookup); rel++; } } @@ -1306,7 +1307,7 @@ if ((rela = ef->rela) != NULL) { relalim = (const Elf_Rela *)((const char *)ef->rela + ef->relasize); while (rela < relalim) { - elf_reloc_local(lf, rela, ELF_RELOC_RELA); + elf_reloc_local(lf, (Elf_Addr)ef->address, rela, ELF_RELOC_RELA, elf_lookup); rela++; } } Index: sys/modules/test/Makefile =========================================================================== *** /dev/null Fri Apr 30 09:10:17 2004 --- sys/modules/test/Makefile Fri Apr 30 09:11:18 2004 *************** *** 0 **** --- 1,6 ---- + # $FreeBSD: src/sys/modules/accf_data/Makefile,v 1.2 2001/01/06 13:59:38 obrien Exp $ + + KMOD= testmod + SRCS= testmod.c + + .include Index: sys/modules/test/testmod.c =========================================================================== *** /dev/null Fri Apr 30 09:10:17 2004 --- sys/modules/test/testmod.c Fri Apr 30 09:11:18 2004 *************** *** 0 **** --- 1,31 ---- + #include + #include + #include + #include + + int foo; + int bar = 1; + + static int + testmodevent(module_t mod, int type, void *data) + { + + switch (type) { + case MOD_LOAD: + printf("testmod: mod_load called! foo=%d bar=%d\n", foo, bar); + break; + case MOD_UNLOAD: + printf("testmod: mod_unload called! foo=%d bar=%d\n", foo, bar); + break; + } + foo++; + return 0; + } + + static moduledata_t test_mod = { + "testmod", + testmodevent, + NULL + }; + + DECLARE_MODULE(testmod, test_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); Index: sys/powerpc/powerpc/elf_machdep.c =========================================================================== --- sys/powerpc/powerpc/elf_machdep.c 2004/04/30 09:10:56 #9 +++ sys/powerpc/powerpc/elf_machdep.c 2004/04/30 09:10:56 @@ -106,9 +106,9 @@ /* Process one elf relocation with addend. */ static int -elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) +elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, int local, elf_lookup_fn lookup) { - Elf_Addr relocbase = (Elf_Addr) lf->address; Elf_Addr *where; Elf_Addr addr; Elf_Addr addend; @@ -141,7 +141,7 @@ break; case R_PPC_GLOB_DAT: - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend; @@ -151,7 +151,7 @@ case R_PPC_JMP_SLOT: /* No point in lazy binding for kernel modules. */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; if (*where != addr) @@ -181,17 +181,19 @@ } int -elf_reloc(linker_file_t lf, const void *data, int type) +elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, + elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 0)); + return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); } int -elf_reloc_local(linker_file_t lf, const void *data, int type) +elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 1)); + return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); } int Index: sys/sparc64/sparc64/elf_machdep.c =========================================================================== --- sys/sparc64/sparc64/elf_machdep.c 2004/04/30 09:10:56 #15 +++ sys/sparc64/sparc64/elf_machdep.c 2004/04/30 09:10:56 @@ -252,7 +252,8 @@ #define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t]) int -elf_reloc_local(linker_file_t lf, const void *data, int type) +elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, elf_lookup_fn lookup) { const Elf_Rela *rela; Elf_Addr value; @@ -275,7 +276,8 @@ /* Process one elf relocation with addend. */ int -elf_reloc(linker_file_t lf, const void *data, int type) +elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, + elf_lookup_fn lookup) { const Elf_Rela *rela; Elf_Addr relocbase; @@ -289,7 +291,6 @@ if (type != ELF_RELOC_RELA) return (-1); - relocbase = (Elf_Addr)lf->address; rela = (const Elf_Rela *)data; where = (Elf_Addr *)(relocbase + rela->r_offset); where32 = (Elf_Half *)where; @@ -309,7 +310,7 @@ value = rela->r_addend; if (RELOC_RESOLVE_SYMBOL(rtype)) { - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return (-1); value += addr; Index: sys/sys/linker.h =========================================================================== --- sys/sys/linker.h 2004/04/30 09:10:56 #12 +++ sys/sys/linker.h 2004/04/30 09:10:56 @@ -241,10 +241,11 @@ #endif +typedef Elf_Addr elf_lookup_fn(linker_file_t, Elf_Word, int); + /* Support functions */ -int elf_reloc(linker_file_t _lf, const void *_rel, int _type); -int elf_reloc_local(linker_file_t _lf, const void *_rel, int _type); -Elf_Addr elf_lookup(linker_file_t, Elf_Word, int); +int elf_reloc(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu); +int elf_reloc_local(linker_file_t _lf, Elf_Addr base, const void *_rel, int _type, elf_lookup_fn _lu); const Elf_Sym *elf_get_sym(linker_file_t _lf, Elf_Word _symidx); const char *elf_get_symname(linker_file_t _lf, Elf_Word _symidx);