Index: boot/common/load_elf.c =================================================================== --- boot/common/load_elf.c +++ boot/common/load_elf.c @@ -175,7 +175,11 @@ * Check to see what sort of module we are. */ kfp = file_findfile(NULL, __elfN(kerneltype)); +#if defined(__powerpc__) && __ELF_WORD_SIZE == 64 + if (ehdr->e_type == ET_DYN && ehdr->e_entry == 0) { +#else if (ehdr->e_type == ET_DYN) { +#endif /* Looks like a kld module */ if (multiboot != 0) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module as multiboot\n"); @@ -195,7 +199,12 @@ /* Looks OK, got ahead */ ef.kernel = 0; +#if defined(__powerpc__) && __ELF_WORD_SIZE == 64 + } else if (ehdr->e_type == ET_EXEC || + (ehdr->e_type == ET_DYN && ehdr->e_entry != 0)) { +#else } else if (ehdr->e_type == ET_EXEC) { +#endif /* Looks like a kernel */ if (kfp != NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n"); Index: conf/Makefile.powerpc =================================================================== --- conf/Makefile.powerpc +++ conf/Makefile.powerpc @@ -37,6 +37,11 @@ CFLAGS+= -msoft-float -Wa,-many +.if ${MACHINE_ARCH} == "powerpc64" +CFLAGS+= -fPIC +LDFLAGS+= -pie +.endif + .if !empty(DDB_ENABLED) CFLAGS+= -fno-omit-frame-pointer .endif Index: conf/kmod.mk =================================================================== --- conf/kmod.mk +++ conf/kmod.mk @@ -179,6 +179,9 @@ ${OBJCOPY} --only-keep-debug ${FULLPROG} ${.TARGET} .endif +# Don't add a fake entry point to modules +_LDFLAGS+= -e 0 + .if ${__KLD_SHARED} == yes ${FULLPROG}: ${KMOD}.kld ${LD} -Bshareable ${_LDFLAGS} -o ${.TARGET} ${KMOD}.kld Index: powerpc/aim/machdep.c =================================================================== --- powerpc/aim/machdep.c +++ powerpc/aim/machdep.c @@ -234,7 +234,7 @@ #endif extern void *rstcode, *rstsize; -extern void *trapcode, *trapsize; +extern void *trapcode, *trapsize, *trapcode2; extern void *slbtrap, *slbtrapsize; extern void *alitrap, *alisize; extern void *dsitrap, *dsisize; @@ -495,6 +495,7 @@ generictrap = &trapcode; /* Set TOC base so that the interrupt code can get at it */ + *((void **)TRAP_GENTRAP) = &trapcode2; *((register_t *)TRAP_TOCBASE) = toc; #endif Index: powerpc/aim/trap_subr64.S =================================================================== --- powerpc/aim/trap_subr64.S +++ powerpc/aim/trap_subr64.S @@ -302,8 +302,12 @@ insrdi %r9,%r8,1,0 mtmsrd %r9 isync - - ba cpu_reset + bl 1f + .llong cpu_reset +1: mflr %r9 + ld %r9,0(%r9) + mtlr %r9 + blr CNAME(rstsize) = . - CNAME(rstcode) cpu_reset: @@ -342,16 +346,20 @@ /* * This code gets copied to all the trap vectors - * (except ISI/DSI, ALI, and the interrupts) + * (except ISI/DSI, ALI, and the interrupts). Has to fit in 8 instructions! */ .globl CNAME(trapcode),CNAME(trapsize) + .p2align 3 CNAME(trapcode): mtsprg1 %r1 /* save SP */ mflr %r1 /* Save the old LR in r1 */ mtsprg2 %r1 /* And then in SPRG2 */ + li %r1,TRAP_GENTRAP + ld %r1,0(%r1) + mtlr %r1 li %r1, 0xA0 /* How to get the vector from LR */ - bla generictrap /* LR & SPRG3 is exception # */ + blrl /* Branch to generictrap */ CNAME(trapsize) = .-CNAME(trapcode) /* @@ -361,6 +369,7 @@ * the only time this can be called. */ .globl CNAME(slbtrap),CNAME(slbtrapsize) + .p2align 3 CNAME(slbtrap): mtsprg1 %r1 /* save SP */ GET_CPUINFO(%r1) @@ -369,7 +378,7 @@ std %r2,(PC_SLBSAVE+104)(%r1) mfsrr1 %r2 /* test kernel mode */ mtcr %r2 - bf 17,1f /* branch if PSL_PR is false */ + bf 17,2f /* branch if PSL_PR is false */ /* User mode */ ld %r2,(PC_SLBSAVE+104)(%r1) /* Restore CR */ mtcr %r2 @@ -376,10 +385,24 @@ ld %r2,(PC_SLBSAVE+16)(%r1) /* Restore R2 */ mflr %r1 /* Save the old LR in r1 */ mtsprg2 %r1 /* And then in SPRG2 */ + /* 52 bytes so far */ + bl 1f + .llong generictrap +1: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 li %r1, 0x80 /* How to get the vector from LR */ - bla generictrap /* LR & SPRG3 is exception # */ -1: mflr %r2 /* Save the old LR in r2 */ - bla kern_slbtrap + blrl /* Branch to generictrap */ + /* 84 bytes */ +2: mflr %r2 /* Save the old LR in r2 */ + nop + bl 3f /* Begin dance to jump to kern_slbtrap*/ + .llong kern_slbtrap +3: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 + GET_CPUINFO(%r1) + blrl /* 124 bytes -- 4 to spare */ CNAME(slbtrapsize) = .-CNAME(slbtrap) kern_slbtrap: @@ -518,6 +541,16 @@ mflr %r28 /* save LR */ mfcr %r29 /* save CR */ + /* Begin dance to branch to s_trap in a bit */ + b 1f + .p2align 3 +1: nop + bl 1f + .llong s_trap +1: mflr %r31 + ld %r31,0(%r31) + mtlr %r31 + /* Put our exception vector in SPRG3 */ li %r31, EXC_ALI mtsprg3 %r31 @@ -525,13 +558,12 @@ /* Test whether we already had PR set */ mfsrr1 %r31 mtcr %r31 - bla s_trap + blrl CNAME(alisize) = .-CNAME(alitrap) /* * Similar to the above for DSI - * Has to handle BAT spills - * and standard pagetable spills + * Has to handle standard pagetable spills */ .globl CNAME(dsitrap),CNAME(dsisize) CNAME(dsitrap): @@ -542,7 +574,6 @@ std %r29,(PC_DISISAVE+CPUSAVE_R29)(%r1) std %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) std %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) - mfsprg1 %r1 /* restore SP */ mfcr %r29 /* save CR */ mfxer %r30 /* save XER */ mtsprg2 %r30 /* in SPRG2 */ @@ -549,7 +580,12 @@ mfsrr1 %r31 /* test kernel mode */ mtcr %r31 mflr %r28 /* save LR (SP already saved) */ - bla disitrap + bl 1f /* Begin branching to disitrap */ + .llong disitrap +1: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 + blrl /* Branch to generictrap */ CNAME(dsisize) = .-CNAME(dsitrap) /* @@ -624,7 +660,7 @@ bl restore_kernsrs /* enable kernel mapping */ mfsprg2 %r29 mr %r28,%r27 - ba s_trap + b s_trap /* * generictrap does some standard setup for trap handling to minimize @@ -636,6 +672,8 @@ * SPRG2 - Original LR */ + .globl CNAME(trapcode2) +trapcode2: generictrap: /* Save R1 for computing the exception vector */ mtsprg3 %r1 @@ -657,6 +695,7 @@ mfsprg3 %r31 ori %r31,%r31,0xff00 mflr %r30 + addi %r30,%r30,-4 /* The branch instruction, not the next */ and %r30,%r30,%r31 mtsprg3 %r30 @@ -804,9 +843,16 @@ mfsprg2 %r29 /* ... and r29 */ mflr %r1 /* save LR */ mtsprg2 %r1 /* And then in SPRG2 */ + + nop /* Begin branching to generictrap */ + bl 9f + .llong generictrap +9: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 li %r1, 0 /* How to get the vector from LR */ + blrl /* Branch to generictrap */ - bla generictrap /* and we look like a generic trap */ 1: GET_CPUINFO(%r1) std %r27,(PC_DBSAVE+CPUSAVE_R27)(%r1) /* free r27 */ @@ -816,6 +862,11 @@ std %r30,(PC_DBSAVE+CPUSAVE_R30)(%r1) /* free r30 */ std %r31,(PC_DBSAVE+CPUSAVE_R31)(%r1) /* free r31 */ mflr %r28 /* save LR */ - bla dbtrap + bl 9f /* Begin branch */ + .llong dbtrap +9: mflr %r1 + ld %r1,0(%r1) + mtlr %r1 + blrl /* Branch to generictrap */ CNAME(dbsize) = .-CNAME(dblow) #endif /* KDB */ Index: powerpc/include/trap.h =================================================================== --- powerpc/include/trap.h +++ powerpc/include/trap.h @@ -123,7 +123,8 @@ /* DTrace trap opcode. */ #define EXC_DTRACE 0x7c810808 -/* Magic pointer to store TOC base for trap handlers on ppc64 */ +/* Magic pointer to store TOC base and other info for trap handlers on ppc64 */ +#define TRAP_GENTRAP 0x1f0 #define TRAP_TOCBASE 0x1f8 #ifndef LOCORE