[PowerPC] Initialize ELFv1 as a secondary sysvec to ELFv2.
In order to enable VDSO timekeeping, it is necessary that there be exactly one primary FreeBSD sysvec for each of the host and (optionally) compat32. So, switch ELFv1 to being a secondary sysvec of ELFv2, so it does not get double-allocated in the shared page. Since secondary sysvecs use the same sigcode allocation as the primary, define both to use the main sigcode64, and adjust the sv_sigcode_base on ELFv2 after initialization to point to the correct offset. This has the desirable side effect of avoiding having a separate copy of the signal trampoline in the shared page. Our sigcode64 was already written to take advantage of trampoline sharing, it was just not being allocated that way until now. Submitted by: jhibbits Sponsored by: Tag1 Consulting, Inc.
This commit is contained in:
parent
016c61beed
commit
3d4217bc0f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=365431
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user