diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/alpha/alpha/elf_machdep.c | 7 | ||||
-rw-r--r-- | sys/amd64/amd64/elf_machdep.c | 8 | ||||
-rw-r--r-- | sys/arm/arm/elf_machdep.c | 8 | ||||
-rw-r--r-- | sys/compat/ia32/ia32_sysvec.c | 8 | ||||
-rw-r--r-- | sys/i386/i386/elf_machdep.c | 8 | ||||
-rw-r--r-- | sys/ia64/ia64/elf_machdep.c | 83 | ||||
-rw-r--r-- | sys/ia64/ia64/machdep.c | 51 | ||||
-rw-r--r-- | sys/ia64/include/md_var.h | 2 | ||||
-rw-r--r-- | sys/kern/imgact_elf.c | 7 | ||||
-rw-r--r-- | sys/powerpc/powerpc/elf_machdep.c | 8 | ||||
-rw-r--r-- | sys/sparc64/sparc64/elf_machdep.c | 8 | ||||
-rw-r--r-- | sys/sys/imgact_elf.h | 3 |
12 files changed, 122 insertions, 79 deletions
diff --git a/sys/alpha/alpha/elf_machdep.c b/sys/alpha/alpha/elf_machdep.c index 25c3ac7..6937e84 100644 --- a/sys/alpha/alpha/elf_machdep.c +++ b/sys/alpha/alpha/elf_machdep.c @@ -106,6 +106,13 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, &freebsd_brand_oinfo); +void +elf64_dump_thread(struct thread *td __unused, void *dst __unused, + size_t *off __unused) +{ +} + + /* Process one elf relocation with addend. */ static int elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index b48e632..11a71a5 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c @@ -102,6 +102,14 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf64_insert_brand_entry, &freebsd_brand_oinfo); + +void +elf64_dump_thread(struct thread *td __unused, void *dst __unused, + size_t *off __unused) +{ +} + + /* Process one elf relocation with addend. */ static int elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c index 303832b..a533df5 100644 --- a/sys/arm/arm/elf_machdep.c +++ b/sys/arm/arm/elf_machdep.c @@ -102,6 +102,14 @@ SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_oinfo); + +void +elf32_dump_thread(struct thread *td __unused, void *dst __unused, + size_t *off __unused) +{ +} + + /* Process one elf relocation with addend. */ static int elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index 4b35148..a2d1435 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c @@ -157,6 +157,14 @@ SYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf32_insert_brand_entry, &ia32_brand_oinfo); + +void +elf32_dump_thread(struct thread *td __unused, void *dst __unused, + size_t *off __unused) +{ +} + + /* XXX may be freebsd32 MI */ static register_t * ia32_copyout_strings(struct image_params *imgp) diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index c6b1ce6..d8756cc 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c @@ -102,6 +102,14 @@ SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_oinfo); + +void +elf32_dump_thread(struct thread *td __unused, void *dst __unused, + size_t *off __unused) +{ +} + + /* Process one elf relocation with addend. */ static int elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c index 92a609f..8588815 100644 --- a/sys/ia64/ia64/elf_machdep.c +++ b/sys/ia64/ia64/elf_machdep.c @@ -49,7 +49,9 @@ #include <machine/md_var.h> #include <machine/unwind.h> -static int ia64_coredump(struct thread *, struct vnode *, off_t); +Elf_Addr link_elf_get_gp(linker_file_t); + +extern Elf_Addr fptr_storage[]; struct sysentvec elf64_freebsd_sysvec = { SYS_MAXSYSCALL, @@ -66,7 +68,7 @@ struct sysentvec elf64_freebsd_sysvec = { NULL, /* &szsigcode */ NULL, "FreeBSD ELF64", - ia64_coredump, + __elfN(coredump), NULL, MINSIGSTKSZ, PAGE_SIZE, @@ -81,67 +83,40 @@ struct sysentvec elf64_freebsd_sysvec = { }; static Elf64_Brandinfo freebsd_brand_info = { - ELFOSABI_FREEBSD, - EM_IA_64, - "FreeBSD", - NULL, - "/libexec/ld-elf.so.1", - &elf64_freebsd_sysvec, - NULL, - }; - + ELFOSABI_FREEBSD, + EM_IA_64, + "FreeBSD", + NULL, + "/libexec/ld-elf.so.1", + &elf64_freebsd_sysvec, + NULL, +}; SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, - (sysinit_cfunc_t) elf64_insert_brand_entry, - &freebsd_brand_info); + (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_info); static Elf64_Brandinfo freebsd_brand_oinfo = { - ELFOSABI_FREEBSD, - EM_IA_64, - "FreeBSD", - NULL, - "/usr/libexec/ld-elf.so.1", - &elf64_freebsd_sysvec, - NULL, - }; - + ELFOSABI_FREEBSD, + EM_IA_64, + "FreeBSD", + NULL, + "/usr/libexec/ld-elf.so.1", + &elf64_freebsd_sysvec, + NULL, +}; SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, - (sysinit_cfunc_t) elf64_insert_brand_entry, - &freebsd_brand_oinfo); + (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_oinfo); -Elf_Addr link_elf_get_gp(linker_file_t); -extern Elf_Addr fptr_storage[]; - -static int -ia64_coredump(struct thread *td, struct vnode *vp, off_t limit) +void +elf64_dump_thread(struct thread *td, void *dst, size_t *off __unused) { - struct trapframe *tf; - uint64_t bspst, kstk, ndirty, rnat; - - tf = td->td_frame; - ndirty = tf->tf_special.ndirty; - if (ndirty != 0) { - kstk = td->td_kstack + (tf->tf_special.bspstore & 0x1ffUL); - __asm __volatile("mov ar.rsc=0;;"); - __asm __volatile("mov %0=ar.bspstore" : "=r"(bspst)); - /* Make sure we have all the user registers written out. */ - if (bspst - kstk < ndirty) { - __asm __volatile("flushrs;;"); - __asm __volatile("mov %0=ar.bspstore" : "=r"(bspst)); - } - __asm __volatile("mov %0=ar.rnat;;" : "=r"(rnat)); - __asm __volatile("mov ar.rsc=3"); - copyout((void*)kstk, (void*)tf->tf_special.bspstore, ndirty); - kstk += ndirty; - tf->tf_special.bspstore += ndirty; - tf->tf_special.ndirty = 0; - tf->tf_special.rnat = - (bspst > kstk && (bspst & 0x1ffUL) < (kstk & 0x1ffUL)) - ? *(uint64_t*)(kstk | 0x1f8UL) : rnat; - } - return (elf64_coredump(td, vp, limit)); + + /* Flush the dirty registers onto the backingstore. */ + if (dst == NULL) + ia64_flush_dirty(td, &td->td_frame->tf_special); } + static Elf_Addr lookup_fdesc(linker_file_t lf, Elf_Word symidx, elf_lookup_fn lookup) { diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 64fc1c0..45cd022 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -1034,36 +1034,41 @@ makectx(struct trapframe *tf, struct pcb *pcb) save_callee_saved_fp(&pcb->pcb_preserved_fp); } +void +ia64_flush_dirty(struct thread *td, struct _special *r) +{ + uint64_t bspst, kstk, rnat; + + if (r->ndirty == 0) + return; + + kstk = td->td_kstack + (r->bspstore & 0x1ffUL); + __asm __volatile("mov ar.rsc=0;;"); + __asm __volatile("mov %0=ar.bspstore" : "=r"(bspst)); + /* Make sure we have all the user registers written out. */ + if (bspst - kstk < r->ndirty) { + __asm __volatile("flushrs;;"); + __asm __volatile("mov %0=ar.bspstore" : "=r"(bspst)); + } + __asm __volatile("mov %0=ar.rnat;;" : "=r"(rnat)); + __asm __volatile("mov ar.rsc=3"); + copyout((void*)kstk, (void*)r->bspstore, r->ndirty); + kstk += r->ndirty; + r->rnat = (bspst > kstk && (bspst & 0x1ffUL) < (kstk & 0x1ffUL)) + ? *(uint64_t*)(kstk | 0x1f8UL) : rnat; + r->bspstore += r->ndirty; + r->ndirty = 0; +} + int get_mcontext(struct thread *td, mcontext_t *mc, int flags) { struct trapframe *tf; - uint64_t bspst, kstk, rnat; tf = td->td_frame; bzero(mc, sizeof(*mc)); - if (tf->tf_special.ndirty != 0) { - kstk = td->td_kstack + (tf->tf_special.bspstore & 0x1ffUL); - __asm __volatile("mov ar.rsc=0;;"); - __asm __volatile("mov %0=ar.bspstore" : "=r"(bspst)); - /* Make sure we have all the user registers written out. */ - if (bspst - kstk < tf->tf_special.ndirty) { - __asm __volatile("flushrs;;"); - __asm __volatile("mov %0=ar.bspstore" : "=r"(bspst)); - } - __asm __volatile("mov %0=ar.rnat;;" : "=r"(rnat)); - __asm __volatile("mov ar.rsc=3"); - copyout((void*)kstk, (void*)tf->tf_special.bspstore, - tf->tf_special.ndirty); - kstk += tf->tf_special.ndirty; - mc->mc_special = tf->tf_special; - mc->mc_special.rnat = - (bspst > kstk && (bspst & 0x1ffUL) < (kstk & 0x1ffUL)) - ? *(uint64_t*)(kstk | 0x1f8UL) : rnat; - mc->mc_special.bspstore += mc->mc_special.ndirty; - mc->mc_special.ndirty = 0; - } else - mc->mc_special = tf->tf_special; + mc->mc_special = tf->tf_special; + ia64_flush_dirty(td, &mc->mc_special); if (tf->tf_flags & FRAME_SYSCALL) { mc->mc_flags |= _MC_FLAGS_SYSCALL_CONTEXT; mc->mc_scratch = tf->tf_scratch; diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h index 99d03dd42..d1a206e 100644 --- a/sys/ia64/include/md_var.h +++ b/sys/ia64/include/md_var.h @@ -65,6 +65,7 @@ extern char esigcode[]; extern int szsigcode; extern long Maxmem; +struct _special; struct fpreg; struct reg; struct thread; @@ -75,6 +76,7 @@ int copyout_regstack(struct thread *, uint64_t *, uint64_t *); void cpu_mp_add(u_int, u_int, u_int); int do_ast(struct trapframe *); int ia64_count_cpus(void); +void ia64_flush_dirty(struct thread *, struct _special *); int ia64_highfp_drop(struct thread *); int ia64_highfp_save(struct thread *); void ia64_init(void); diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 04b88d4..29d6ed8 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1204,8 +1204,11 @@ __elfN(puthdr)(struct thread *td, void *dst, size_t *off, int numsegs) sizeof *status); __elfN(putnote)(dst, off, "FreeBSD", NT_FPREGSET, fpregset, sizeof *fpregset); - - /* XXX allow for MD specific notes. */ + /* + * Allow for MD specific notes, as well as any MD + * specific preparations for writing MI notes. + */ + __elfN(dump_thread)(thr, dst, off); thr = (thr == td) ? TAILQ_FIRST(&p->p_threads) : TAILQ_NEXT(thr, td_plist); diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c index e9481ff..6063e7b 100644 --- a/sys/powerpc/powerpc/elf_machdep.c +++ b/sys/powerpc/powerpc/elf_machdep.c @@ -105,6 +105,14 @@ SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf32_insert_brand_entry, &freebsd_brand_oinfo); + +void +elf32_dump_thread(struct thread *td __unused, void *dst __unused, + size_t *off __unused) +{ +} + + /* Process one elf relocation with addend. */ static int elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c index 2fc98a2..edc18ac 100644 --- a/sys/sparc64/sparc64/elf_machdep.c +++ b/sys/sparc64/sparc64/elf_machdep.c @@ -115,6 +115,14 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t) elf64_insert_brand_entry, &freebsd_brand_oinfo); + +void +elf64_dump_thread(struct thread *td __unused, void *dst __unused, + size_t *off __unused) +{ +} + + /* * The following table holds for each relocation type: * - the width in bits of the memory location the relocation diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h index d69abe6..3454787 100644 --- a/sys/sys/imgact_elf.h +++ b/sys/sys/imgact_elf.h @@ -76,6 +76,9 @@ int __elfN(remove_brand_entry)(Elf_Brandinfo *entry); int __elfN(freebsd_fixup)(register_t **, struct image_params *); int __elfN(coredump)(struct thread *, struct vnode *, off_t); +/* Machine specific function to dump per-thread information. */ +void __elfN(dump_thread)(struct thread *, void *, size_t *); + extern int __elfN(fallback_brand); #endif /* _KERNEL */ |