diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c index c9ba70dceea..d8f1278872b 100644 --- a/sys/powerpc/powerpc/elf64_machdep.c +++ b/sys/powerpc/powerpc/elf64_machdep.c @@ -95,7 +95,6 @@ struct sysentvec elf64_freebsd_sysvec_v1 = { .sv_hwcap = &cpu_features, .sv_hwcap2 = &cpu_features2, }; -INIT_SYSENTVEC(elf64_sysvec_v1, &elf64_freebsd_sysvec_v1); struct sysentvec elf64_freebsd_sysvec_v2 = { .sv_size = SYS_MAXSYSCALL, @@ -105,8 +104,8 @@ struct sysentvec elf64_freebsd_sysvec_v2 = { .sv_transtrap = NULL, .sv_fixup = __elfN(freebsd_fixup), .sv_sendsig = sendsig, - .sv_sigcode = sigcode64_elfv2, - .sv_szsigcode = &szsigcode64_elfv2, + .sv_sigcode = sigcode64, /* Fixed up in ppc64_init_sysvecs(). */ + .sv_szsigcode = &szsigcode64, .sv_name = "FreeBSD ELF64 V2", .sv_coredump = __elfN(coredump), .sv_imgact_try = NULL, @@ -133,7 +132,6 @@ struct sysentvec elf64_freebsd_sysvec_v2 = { .sv_hwcap = &cpu_features, .sv_hwcap2 = &cpu_features2, }; -INIT_SYSENTVEC(elf64_sysvec_v2, &elf64_freebsd_sysvec_v2); static boolean_t ppc64_elfv1_header_match(struct image_params *params, int32_t *, uint32_t *); @@ -193,6 +191,26 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, void elf_reloc_self(Elf_Dyn *dynp, Elf_Addr relocbase); +static void +ppc64_init_sysvecs(void *arg) +{ + exec_sysvec_init(&elf64_freebsd_sysvec_v2); + exec_sysvec_init_secondary(&elf64_freebsd_sysvec_v2, + &elf64_freebsd_sysvec_v1); + /* + * Adjust elfv2 sigcode after elfv1 sysvec is initialized. + * exec_sysvec_init_secondary() assumes secondary sysvecs use + * identical signal code, and skips allocating a second copy. + * Since the ELFv2 trampoline is a strict subset of the ELFv1 code, + * we can work around this by adjusting the base address. This also + * avoids two copies of the trampoline code being allocated! + */ + elf64_freebsd_sysvec_v2.sv_sigcode_base += + (uintptr_t)sigcode64_elfv2 - (uintptr_t)&sigcode64; + elf64_freebsd_sysvec_v2.sv_szsigcode = &szsigcode64_elfv2; +} +SYSINIT(elf64_sysvec, SI_SUB_EXEC, SI_ORDER_ANY, ppc64_init_sysvecs, NULL); + static boolean_t ppc64_elfv1_header_match(struct image_params *params, int32_t *osrel __unused, uint32_t *fctl0 __unused)