1 /* Common core note type descriptions for Linux.
2 Copyright (C) 2007, 2008 Red Hat, Inc.
3 This file is part of Red Hat elfutils.
4
5 Red Hat elfutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by the
7 Free Software Foundation; version 2 of the License.
8
9 Red Hat elfutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with Red Hat elfutils; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
17
18 Red Hat elfutils is an included package of the Open Invention Network.
19 An included package of the Open Invention Network is a package for which
20 Open Invention Network licensees cross-license their patents. No patent
21 license is granted, either expressly or impliedly, by designation as an
22 included package. Should you wish to participate in the Open Invention
23 Network licensing program, please visit www.openinventionnetwork.com
24 <http://www.openinventionnetwork.com>. */
25
26 /* The including CPU_corenote.c file provides prstatus_regs and
27 defines macros ULONG, [PUG]ID_T, and ALIGN_*, TYPE_*.
28
29 Here we describe the common layout used in <linux/elfcore.h>. */
30
31 #define CHAR int8_t
32 #define ALIGN_CHAR 1
33 #define TYPE_CHAR ELF_T_BYTE
34 #define SHORT uint16_t
35 #define ALIGN_SHORT 2
36 #define TYPE_SHORT ELF_T_HALF
37 #define INT int32_t
38 #define ALIGN_INT 4
39 #define TYPE_INT ELF_T_SWORD
40
41 #define FIELD(type, name) type name __attribute__ ((aligned (ALIGN_##type)))
42
EBLHOOK(siginfo)43 struct EBLHOOK(siginfo)
44 {
45 FIELD (INT, si_signo);
46 FIELD (INT, si_code);
47 FIELD (INT, si_errno);
48 };
49
EBLHOOK(timeval)50 struct EBLHOOK(timeval)
51 {
52 FIELD (ULONG, tv_sec);
53 FIELD (ULONG, tv_usec);
54 };
55
56 /* On sparc64, tv_usec (suseconds_t) is actually 32 bits with 32 bits padding.
57 The 'T'|0x80 value for .format indicates this as a special kludge. */
58 #if SUSECONDS_HALF
59 # define TIMEVAL_FIELD(name) FIELD (time, ULONG, name, 'T'|0x80, .count = 2)
60 #else
61 # define TIMEVAL_FIELD(name) FIELD (time, ULONG, name, 'T', .count = 2)
62 #endif
63
64
EBLHOOK(prstatus)65 struct EBLHOOK(prstatus)
66 {
67 struct EBLHOOK(siginfo) pr_info;
68 FIELD (SHORT, pr_cursig);
69 FIELD (ULONG, pr_sigpend);
70 FIELD (ULONG, pr_sighold);
71 FIELD (PID_T, pr_pid);
72 FIELD (PID_T, pr_ppid);
73 FIELD (PID_T, pr_pgrp);
74 FIELD (PID_T, pr_sid);
75 struct EBLHOOK(timeval) pr_utime;
76 struct EBLHOOK(timeval) pr_stime;
77 struct EBLHOOK(timeval) pr_cutime;
78 struct EBLHOOK(timeval) pr_cstime;
79 FIELD (ULONG, pr_reg[PRSTATUS_REGS_SIZE / sizeof (ULONG)]);
80 FIELD (INT, pr_fpvalid);
81 };
82
83 #define FNAMESZ 16
84 #define PRARGSZ 80
85
EBLHOOK(prpsinfo)86 struct EBLHOOK(prpsinfo)
87 {
88 FIELD (CHAR, pr_state);
89 FIELD (CHAR, pr_sname);
90 FIELD (CHAR, pr_zomb);
91 FIELD (CHAR, pr_nice);
92 FIELD (ULONG, pr_flag);
93 FIELD (UID_T, pr_uid);
94 FIELD (GID_T, pr_gid);
95 FIELD (PID_T, pr_pid);
96 FIELD (PID_T, pr_ppid);
97 FIELD (PID_T, pr_pgrp);
98 FIELD (PID_T, pr_sid);
99 FIELD (CHAR, pr_fname[FNAMESZ]);
100 FIELD (CHAR, pr_psargs[PRARGSZ]);
101 };
102
103 #undef FIELD
104
105 #define FIELD(igroup, itype, item, fmt, ...) \
106 { \
107 .name = #item, \
108 .group = #igroup, \
109 .offset = offsetof (struct EBLHOOK(prstatus), pr_##item), \
110 .type = TYPE_##itype, \
111 .format = fmt, \
112 __VA_ARGS__ \
113 }
114
115 static const Ebl_Core_Item prstatus_items[] =
116 {
117 FIELD (signal, INT, info.si_signo, 'd'),
118 FIELD (signal, INT, info.si_code, 'd'),
119 FIELD (signal, INT, info.si_errno, 'd'),
120 FIELD (signal, SHORT, cursig, 'd'),
121 FIELD (signal, ULONG, sigpend, 'B'),
122 FIELD (signal, ULONG, sighold, 'B'),
123 FIELD (identity, PID_T, pid, 'd', .thread_identifier = true),
124 FIELD (identity, PID_T, ppid, 'd'),
125 FIELD (identity, PID_T, pgrp, 'd'),
126 FIELD (identity, PID_T, sid, 'd'),
127 TIMEVAL_FIELD (utime),
128 TIMEVAL_FIELD (stime),
129 TIMEVAL_FIELD (cutime),
130 TIMEVAL_FIELD (cstime),
131 #ifdef PRSTATUS_REGSET_ITEMS
132 PRSTATUS_REGSET_ITEMS,
133 #endif
134 FIELD (register, INT, fpvalid, 'd'),
135 };
136
137 #undef FIELD
138
139 #define FIELD(igroup, itype, item, fmt, ...) \
140 { \
141 .name = #item, \
142 .group = #igroup, \
143 .offset = offsetof (struct EBLHOOK(prpsinfo), pr_##item), \
144 .type = TYPE_##itype, \
145 .format = fmt, \
146 __VA_ARGS__ \
147 }
148
149 static const Ebl_Core_Item prpsinfo_items[] =
150 {
151 FIELD (state, CHAR, state, 'd'),
152 FIELD (state, CHAR, sname, 'c'),
153 FIELD (state, CHAR, zomb, 'd'),
154 FIELD (state, CHAR, nice, 'd'),
155 FIELD (state, ULONG, flag, 'x'),
156 FIELD (identity, UID_T, uid, 'd'),
157 FIELD (identity, GID_T, gid, 'd'),
158 FIELD (identity, PID_T, pid, 'd'),
159 FIELD (identity, PID_T, ppid, 'd'),
160 FIELD (identity, PID_T, pgrp, 'd'),
161 FIELD (identity, PID_T, sid, 'd'),
162 FIELD (command, CHAR, fname, 's', .count = FNAMESZ),
163 FIELD (command, CHAR, psargs, 's', .count = PRARGSZ),
164 };
165
166 #undef FIELD
167
168 int
169 EBLHOOK(core_note) (n_type, descsz,
170 regs_offset, nregloc, reglocs, nitems, items)
171 GElf_Word n_type;
172 GElf_Word descsz;
173 GElf_Word *regs_offset;
174 size_t *nregloc;
175 const Ebl_Register_Location **reglocs;
176 size_t *nitems;
177 const Ebl_Core_Item **items;
178 {
179 switch (n_type)
180 {
181 case NT_PRSTATUS:
182 if (descsz != sizeof (struct EBLHOOK(prstatus)))
183 return 0;
184 *regs_offset = offsetof (struct EBLHOOK(prstatus), pr_reg);
185 *nregloc = sizeof prstatus_regs / sizeof prstatus_regs[0];
186 *reglocs = prstatus_regs;
187 *nitems = sizeof prstatus_items / sizeof prstatus_items[0];
188 *items = prstatus_items;
189 return 1;
190
191 case NT_PRPSINFO:
192 if (descsz != sizeof (struct EBLHOOK(prpsinfo)))
193 return 0;
194 *regs_offset = 0;
195 *nregloc = 0;
196 *reglocs = NULL;
197 *nitems = sizeof prpsinfo_items / sizeof prpsinfo_items[0];
198 *items = prpsinfo_items;
199 return 1;
200
201 #define EXTRA_REGSET(type, size, table) \
202 case type: \
203 if (descsz != size) \
204 return 0; \
205 *regs_offset = 0; \
206 *nregloc = sizeof table / sizeof table[0]; \
207 *reglocs = table; \
208 *nitems = 0; \
209 *items = NULL; \
210 return 1;
211
212 #ifdef FPREGSET_SIZE
213 EXTRA_REGSET (NT_FPREGSET, FPREGSET_SIZE, fpregset_regs)
214 #endif
215
216 #ifdef EXTRA_NOTES
217 EXTRA_NOTES
218 #endif
219 }
220
221 return 0;
222 }
223