1 /* $NetBSD: core_machdep.c,v 1.10 2020/11/10 21:38:03 rin Exp $ */
2
3 /*
4 * Copyright (c) 1994-1998 Mark Brinicombe.
5 * Copyright (c) 1994 Brini.
6 * All rights reserved.
7 *
8 * This code is derived from software written for Brini by Mark Brinicombe
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Brini.
21 * 4. The name of the company nor the name of the author may be used to
22 * endorse or promote products derived from this software without specific
23 * prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 */
37
38 #include <sys/param.h>
39
40 __KERNEL_RCSID(0, "$NetBSD: core_machdep.c,v 1.10 2020/11/10 21:38:03 rin Exp $");
41
42 #ifdef _KERNEL_OPT
43 #include "opt_execfmt.h"
44 #else
45 #define EXEC_ELF32 1
46 #endif
47
48 #include <sys/core.h>
49 #include <sys/exec.h>
50 #include <sys/ptrace.h>
51 #include <sys/signalvar.h>
52 #include <sys/systm.h>
53 #include <sys/uio.h>
54 #include <sys/vnode.h>
55 #include <sys/compat_stub.h>
56
57 #include <sys/exec_aout.h> /* for MID_* */
58
59 #include <arm/locore.h>
60
61 #ifdef EXEC_ELF32
62 #include <sys/exec_elf.h>
63 #endif
64
65 #include <machine/reg.h>
66
67
68 /*
69 * Dump the machine specific segment at the start of a core dump.
70 */
71 int
cpu_coredump(struct lwp * l,struct coredump_iostate * iocookie,struct core * chdr)72 cpu_coredump(struct lwp *l, struct coredump_iostate *iocookie,
73 struct core *chdr)
74 {
75 int error;
76 struct {
77 struct reg regs;
78 struct fpreg fpregs;
79 } cpustate;
80 struct coreseg cseg;
81
82 if (iocookie == NULL) {
83 CORE_SETMAGIC(*chdr, COREMAGIC, MID_MACHINE, 0);
84 chdr->c_hdrsize = ALIGN(sizeof(*chdr));
85 chdr->c_seghdrsize = ALIGN(sizeof(cseg));
86 chdr->c_cpusize = sizeof(cpustate);
87 chdr->c_nseg++;
88 return 0;
89 }
90
91 /* Save integer registers. */
92 error = process_read_regs(l, &cpustate.regs);
93 if (error)
94 return error;
95 /* Save floating point registers. */
96 error = process_read_fpregs(l, &cpustate.fpregs, NULL);
97 if (error)
98 return error;
99
100 CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_MACHINE, CORE_CPU);
101 cseg.c_addr = 0;
102 cseg.c_size = chdr->c_cpusize;
103
104 MODULE_HOOK_CALL(coredump_write_hook, (iocookie, UIO_SYSSPACE,
105 &cseg, chdr->c_seghdrsize), ENOSYS, error);
106 if (error)
107 return error;
108
109 MODULE_HOOK_CALL(coredump_write_hook, (iocookie, UIO_SYSSPACE,
110 &cpustate, sizeof(cpustate)), ENOSYS, error);
111
112 return error;
113 }
114
115 #ifdef EXEC_ELF32
116 void
arm_netbsd_elf32_coredump_setup(struct lwp * l,void * arg)117 arm_netbsd_elf32_coredump_setup(struct lwp *l, void *arg)
118 {
119 #if defined(__ARMEB__) || defined(__ARM_EABI__)
120 Elf_Ehdr * const eh = arg;
121 #endif
122 #ifdef __ARM_EABI__
123 struct proc * const p = l->l_proc;
124
125 if (p->p_emul == &emul_netbsd) {
126 eh->e_flags |= EF_ARM_EABI_VER5;
127 }
128 #endif
129 #ifdef __ARMEB__
130 if (CPU_IS_ARMV7_P()
131 || (CPU_IS_ARMV6_P()
132 && (armreg_sctlr_read() & CPU_CONTROL_BEND_ENABLE) == 0)) {
133 eh->e_flags |= EF_ARM_BE8;
134 }
135 #endif
136 }
137 #endif
138