summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/elf_machdep.c7
-rw-r--r--sys/amd64/amd64/elf_machdep.c8
-rw-r--r--sys/arm/arm/elf_machdep.c8
-rw-r--r--sys/compat/ia32/ia32_sysvec.c8
-rw-r--r--sys/i386/i386/elf_machdep.c8
-rw-r--r--sys/ia64/ia64/elf_machdep.c83
-rw-r--r--sys/ia64/ia64/machdep.c51
-rw-r--r--sys/ia64/include/md_var.h2
-rw-r--r--sys/kern/imgact_elf.c7
-rw-r--r--sys/powerpc/powerpc/elf_machdep.c8
-rw-r--r--sys/sparc64/sparc64/elf_machdep.c8
-rw-r--r--sys/sys/imgact_elf.h3
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 */
OpenPOWER on IntegriCloud