1da0c48c4Sopenharmony_ci/* Common core note type descriptions for Linux. 2da0c48c4Sopenharmony_ci Copyright (C) 2007-2010 Red Hat, Inc. 3da0c48c4Sopenharmony_ci Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015. 4da0c48c4Sopenharmony_ci This file is part of elfutils. 5da0c48c4Sopenharmony_ci 6da0c48c4Sopenharmony_ci This file is free software; you can redistribute it and/or modify 7da0c48c4Sopenharmony_ci it under the terms of either 8da0c48c4Sopenharmony_ci 9da0c48c4Sopenharmony_ci * the GNU Lesser General Public License as published by the Free 10da0c48c4Sopenharmony_ci Software Foundation; either version 3 of the License, or (at 11da0c48c4Sopenharmony_ci your option) any later version 12da0c48c4Sopenharmony_ci 13da0c48c4Sopenharmony_ci or 14da0c48c4Sopenharmony_ci 15da0c48c4Sopenharmony_ci * the GNU General Public License as published by the Free 16da0c48c4Sopenharmony_ci Software Foundation; either version 2 of the License, or (at 17da0c48c4Sopenharmony_ci your option) any later version 18da0c48c4Sopenharmony_ci 19da0c48c4Sopenharmony_ci or both in parallel, as here. 20da0c48c4Sopenharmony_ci 21da0c48c4Sopenharmony_ci elfutils is distributed in the hope that it will be useful, but 22da0c48c4Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 23da0c48c4Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24da0c48c4Sopenharmony_ci General Public License for more details. 25da0c48c4Sopenharmony_ci 26da0c48c4Sopenharmony_ci You should have received copies of the GNU General Public License and 27da0c48c4Sopenharmony_ci the GNU Lesser General Public License along with this program. If 28da0c48c4Sopenharmony_ci not, see <http://www.gnu.org/licenses/>. */ 29da0c48c4Sopenharmony_ci 30da0c48c4Sopenharmony_ci#include <string.h> 31da0c48c4Sopenharmony_ci 32da0c48c4Sopenharmony_ci/* The including CPU_corenote.c file provides prstatus_regs and 33da0c48c4Sopenharmony_ci defines macros ULONG, [PUG]ID_T, and ALIGN_*, TYPE_*. 34da0c48c4Sopenharmony_ci 35da0c48c4Sopenharmony_ci Here we describe the common layout used in <linux/elfcore.h>. */ 36da0c48c4Sopenharmony_ci 37da0c48c4Sopenharmony_ci#define CHAR int8_t 38da0c48c4Sopenharmony_ci#define ALIGN_CHAR 1 39da0c48c4Sopenharmony_ci#define TYPE_CHAR ELF_T_BYTE 40da0c48c4Sopenharmony_ci#define SHORT uint16_t 41da0c48c4Sopenharmony_ci#define ALIGN_SHORT 2 42da0c48c4Sopenharmony_ci#define TYPE_SHORT ELF_T_HALF 43da0c48c4Sopenharmony_ci#define INT int32_t 44da0c48c4Sopenharmony_ci#ifndef ALIGN_INT 45da0c48c4Sopenharmony_ci# define ALIGN_INT 4 46da0c48c4Sopenharmony_ci#endif 47da0c48c4Sopenharmony_ci#define TYPE_INT ELF_T_SWORD 48da0c48c4Sopenharmony_ci#ifndef PR_REG 49da0c48c4Sopenharmony_ci# define PR_REG ULONG 50da0c48c4Sopenharmony_ci#endif 51da0c48c4Sopenharmony_ci#ifndef ALIGN_PR_REG 52da0c48c4Sopenharmony_ci# define ALIGN_PR_REG ALIGN_ULONG 53da0c48c4Sopenharmony_ci#endif 54da0c48c4Sopenharmony_ci#ifndef PRPSINFO_UID_T 55da0c48c4Sopenharmony_ci# define PRPSINFO_UID_T UID_T 56da0c48c4Sopenharmony_ci# define ALIGN_PRPSINFO_UID_T ALIGN_UID_T 57da0c48c4Sopenharmony_ci# define TYPE_PRPSINFO_UID_T TYPE_UID_T 58da0c48c4Sopenharmony_ci#endif 59da0c48c4Sopenharmony_ci#ifndef PRPSINFO_GID_T 60da0c48c4Sopenharmony_ci# define PRPSINFO_GID_T GID_T 61da0c48c4Sopenharmony_ci# define ALIGN_PRPSINFO_GID_T ALIGN_GID_T 62da0c48c4Sopenharmony_ci# define TYPE_PRPSINFO_GID_T TYPE_GID_T 63da0c48c4Sopenharmony_ci#endif 64da0c48c4Sopenharmony_ci 65da0c48c4Sopenharmony_ci#define FIELD(type, name) type name __attribute__ ((aligned (ALIGN_##type))) 66da0c48c4Sopenharmony_ci 67da0c48c4Sopenharmony_cistruct EBLHOOK(siginfo) 68da0c48c4Sopenharmony_ci{ 69da0c48c4Sopenharmony_ci FIELD (INT, si_signo); 70da0c48c4Sopenharmony_ci FIELD (INT, si_code); 71da0c48c4Sopenharmony_ci FIELD (INT, si_errno); 72da0c48c4Sopenharmony_ci}; 73da0c48c4Sopenharmony_ci 74da0c48c4Sopenharmony_cistruct EBLHOOK(timeval) 75da0c48c4Sopenharmony_ci{ 76da0c48c4Sopenharmony_ci FIELD (ULONG, tv_sec); 77da0c48c4Sopenharmony_ci FIELD (ULONG, tv_usec); 78da0c48c4Sopenharmony_ci}; 79da0c48c4Sopenharmony_ci 80da0c48c4Sopenharmony_ci/* On sparc64, tv_usec (suseconds_t) is actually 32 bits with 32 bits padding. 81da0c48c4Sopenharmony_ci The 'T'|0x80 value for .format indicates this as a special kludge. */ 82da0c48c4Sopenharmony_ci#if SUSECONDS_HALF 83da0c48c4Sopenharmony_ci# define TIMEVAL_FIELD(name) FIELD (time, ULONG, name, 'T'|0x80, .count = 2) 84da0c48c4Sopenharmony_ci#else 85da0c48c4Sopenharmony_ci# define TIMEVAL_FIELD(name) FIELD (time, ULONG, name, 'T', .count = 2) 86da0c48c4Sopenharmony_ci#endif 87da0c48c4Sopenharmony_ci 88da0c48c4Sopenharmony_ci 89da0c48c4Sopenharmony_cistruct EBLHOOK(prstatus) 90da0c48c4Sopenharmony_ci{ 91da0c48c4Sopenharmony_ci struct EBLHOOK(siginfo) pr_info; 92da0c48c4Sopenharmony_ci FIELD (SHORT, pr_cursig); 93da0c48c4Sopenharmony_ci FIELD (ULONG, pr_sigpend); 94da0c48c4Sopenharmony_ci FIELD (ULONG, pr_sighold); 95da0c48c4Sopenharmony_ci FIELD (PID_T, pr_pid); 96da0c48c4Sopenharmony_ci FIELD (PID_T, pr_ppid); 97da0c48c4Sopenharmony_ci FIELD (PID_T, pr_pgrp); 98da0c48c4Sopenharmony_ci FIELD (PID_T, pr_sid); 99da0c48c4Sopenharmony_ci struct EBLHOOK(timeval) pr_utime; 100da0c48c4Sopenharmony_ci struct EBLHOOK(timeval) pr_stime; 101da0c48c4Sopenharmony_ci struct EBLHOOK(timeval) pr_cutime; 102da0c48c4Sopenharmony_ci struct EBLHOOK(timeval) pr_cstime; 103da0c48c4Sopenharmony_ci struct 104da0c48c4Sopenharmony_ci { 105da0c48c4Sopenharmony_ci FIELD (PR_REG, pr_reg[PRSTATUS_REGS_SIZE / sizeof (PR_REG)]); 106da0c48c4Sopenharmony_ci } 107da0c48c4Sopenharmony_ci#ifdef ALIGN_PR_REG 108da0c48c4Sopenharmony_ci __attribute__ ((aligned (ALIGN_PR_REG))) 109da0c48c4Sopenharmony_ci#endif 110da0c48c4Sopenharmony_ci ; 111da0c48c4Sopenharmony_ci FIELD (INT, pr_fpvalid); 112da0c48c4Sopenharmony_ci} 113da0c48c4Sopenharmony_ci#ifdef ALIGN_PRSTATUS 114da0c48c4Sopenharmony_ci attribute_packed __attribute__ ((aligned (ALIGN_PRSTATUS))) 115da0c48c4Sopenharmony_ci#endif 116da0c48c4Sopenharmony_ci; 117da0c48c4Sopenharmony_ci 118da0c48c4Sopenharmony_ci#define FNAMESZ 16 119da0c48c4Sopenharmony_ci#define PRARGSZ 80 120da0c48c4Sopenharmony_ci 121da0c48c4Sopenharmony_cistruct EBLHOOK(prpsinfo) 122da0c48c4Sopenharmony_ci{ 123da0c48c4Sopenharmony_ci FIELD (CHAR, pr_state); 124da0c48c4Sopenharmony_ci FIELD (CHAR, pr_sname); 125da0c48c4Sopenharmony_ci FIELD (CHAR, pr_zomb); 126da0c48c4Sopenharmony_ci FIELD (CHAR, pr_nice); 127da0c48c4Sopenharmony_ci FIELD (ULONG, pr_flag); 128da0c48c4Sopenharmony_ci FIELD (PRPSINFO_UID_T, pr_uid); 129da0c48c4Sopenharmony_ci FIELD (PRPSINFO_GID_T, pr_gid); 130da0c48c4Sopenharmony_ci FIELD (PID_T, pr_pid); 131da0c48c4Sopenharmony_ci FIELD (PID_T, pr_ppid); 132da0c48c4Sopenharmony_ci FIELD (PID_T, pr_pgrp); 133da0c48c4Sopenharmony_ci FIELD (PID_T, pr_sid); 134da0c48c4Sopenharmony_ci FIELD (CHAR, pr_fname[FNAMESZ]); 135da0c48c4Sopenharmony_ci FIELD (CHAR, pr_psargs[PRARGSZ]); 136da0c48c4Sopenharmony_ci}; 137da0c48c4Sopenharmony_ci 138da0c48c4Sopenharmony_ci#undef FIELD 139da0c48c4Sopenharmony_ci 140da0c48c4Sopenharmony_ci#define FIELD(igroup, itype, item, fmt, ...) \ 141da0c48c4Sopenharmony_ci { \ 142da0c48c4Sopenharmony_ci .name = #item, \ 143da0c48c4Sopenharmony_ci .group = #igroup, \ 144da0c48c4Sopenharmony_ci .offset = offsetof (struct EBLHOOK(prstatus), pr_##item), \ 145da0c48c4Sopenharmony_ci .type = TYPE_##itype, \ 146da0c48c4Sopenharmony_ci .format = fmt, \ 147da0c48c4Sopenharmony_ci __VA_ARGS__ \ 148da0c48c4Sopenharmony_ci } 149da0c48c4Sopenharmony_ci 150da0c48c4Sopenharmony_cistatic const Ebl_Core_Item prstatus_items[] = 151da0c48c4Sopenharmony_ci { 152da0c48c4Sopenharmony_ci FIELD (signal, INT, info.si_signo, 'd'), 153da0c48c4Sopenharmony_ci FIELD (signal, INT, info.si_code, 'd'), 154da0c48c4Sopenharmony_ci FIELD (signal, INT, info.si_errno, 'd'), 155da0c48c4Sopenharmony_ci FIELD (signal, SHORT, cursig, 'd'), 156da0c48c4Sopenharmony_ci 157da0c48c4Sopenharmony_ci /* Use different group name for a newline delimiter. */ 158da0c48c4Sopenharmony_ci FIELD (signal2, ULONG, sigpend, 'B'), 159da0c48c4Sopenharmony_ci FIELD (signal3, ULONG, sighold, 'B'), 160da0c48c4Sopenharmony_ci FIELD (identity, PID_T, pid, 'd', .thread_identifier = true), 161da0c48c4Sopenharmony_ci FIELD (identity, PID_T, ppid, 'd'), 162da0c48c4Sopenharmony_ci FIELD (identity, PID_T, pgrp, 'd'), 163da0c48c4Sopenharmony_ci FIELD (identity, PID_T, sid, 'd'), 164da0c48c4Sopenharmony_ci TIMEVAL_FIELD (utime), 165da0c48c4Sopenharmony_ci TIMEVAL_FIELD (stime), 166da0c48c4Sopenharmony_ci TIMEVAL_FIELD (cutime), 167da0c48c4Sopenharmony_ci TIMEVAL_FIELD (cstime), 168da0c48c4Sopenharmony_ci#ifdef PRSTATUS_REGSET_ITEMS 169da0c48c4Sopenharmony_ci PRSTATUS_REGSET_ITEMS, 170da0c48c4Sopenharmony_ci#endif 171da0c48c4Sopenharmony_ci FIELD (register, INT, fpvalid, 'd'), 172da0c48c4Sopenharmony_ci }; 173da0c48c4Sopenharmony_ci 174da0c48c4Sopenharmony_ci#undef FIELD 175da0c48c4Sopenharmony_ci 176da0c48c4Sopenharmony_ci#define FIELD(igroup, itype, item, fmt, ...) \ 177da0c48c4Sopenharmony_ci { \ 178da0c48c4Sopenharmony_ci .name = #item, \ 179da0c48c4Sopenharmony_ci .group = #igroup, \ 180da0c48c4Sopenharmony_ci .offset = offsetof (struct EBLHOOK(prpsinfo), pr_##item), \ 181da0c48c4Sopenharmony_ci .type = TYPE_##itype, \ 182da0c48c4Sopenharmony_ci .format = fmt, \ 183da0c48c4Sopenharmony_ci __VA_ARGS__ \ 184da0c48c4Sopenharmony_ci } 185da0c48c4Sopenharmony_ci 186da0c48c4Sopenharmony_cistatic const Ebl_Core_Item prpsinfo_items[] = 187da0c48c4Sopenharmony_ci { 188da0c48c4Sopenharmony_ci FIELD (state, CHAR, state, 'd'), 189da0c48c4Sopenharmony_ci FIELD (state, CHAR, sname, 'c'), 190da0c48c4Sopenharmony_ci FIELD (state, CHAR, zomb, 'd'), 191da0c48c4Sopenharmony_ci FIELD (state, CHAR, nice, 'd'), 192da0c48c4Sopenharmony_ci FIELD (state, ULONG, flag, 'x'), 193da0c48c4Sopenharmony_ci FIELD (identity, PRPSINFO_UID_T, uid, 'd'), 194da0c48c4Sopenharmony_ci FIELD (identity, PRPSINFO_GID_T, gid, 'd'), 195da0c48c4Sopenharmony_ci FIELD (identity, PID_T, pid, 'd'), 196da0c48c4Sopenharmony_ci FIELD (identity, PID_T, ppid, 'd'), 197da0c48c4Sopenharmony_ci FIELD (identity, PID_T, pgrp, 'd'), 198da0c48c4Sopenharmony_ci FIELD (identity, PID_T, sid, 'd'), 199da0c48c4Sopenharmony_ci FIELD (command, CHAR, fname, 's', .count = FNAMESZ), 200da0c48c4Sopenharmony_ci FIELD (command, CHAR, psargs, 's', .count = PRARGSZ), 201da0c48c4Sopenharmony_ci }; 202da0c48c4Sopenharmony_ci 203da0c48c4Sopenharmony_cistatic const Ebl_Core_Item vmcoreinfo_items[] = 204da0c48c4Sopenharmony_ci { 205da0c48c4Sopenharmony_ci { 206da0c48c4Sopenharmony_ci .type = ELF_T_BYTE, .format = '\n' 207da0c48c4Sopenharmony_ci } 208da0c48c4Sopenharmony_ci }; 209da0c48c4Sopenharmony_ci 210da0c48c4Sopenharmony_ci#undef FIELD 211da0c48c4Sopenharmony_ci 212da0c48c4Sopenharmony_ciint 213da0c48c4Sopenharmony_ciEBLHOOK(core_note) (const GElf_Nhdr *nhdr, const char *name, 214da0c48c4Sopenharmony_ci GElf_Word *regs_offset, size_t *nregloc, 215da0c48c4Sopenharmony_ci const Ebl_Register_Location **reglocs, 216da0c48c4Sopenharmony_ci size_t *nitems, const Ebl_Core_Item **items) 217da0c48c4Sopenharmony_ci{ 218da0c48c4Sopenharmony_ci switch (nhdr->n_namesz) 219da0c48c4Sopenharmony_ci { 220da0c48c4Sopenharmony_ci case sizeof "CORE" - 1: /* Buggy old Linux kernels. */ 221da0c48c4Sopenharmony_ci if (memcmp (name, "CORE", nhdr->n_namesz) == 0) 222da0c48c4Sopenharmony_ci break; 223da0c48c4Sopenharmony_ci return 0; 224da0c48c4Sopenharmony_ci 225da0c48c4Sopenharmony_ci case sizeof "CORE": 226da0c48c4Sopenharmony_ci if (memcmp (name, "CORE", nhdr->n_namesz) == 0) 227da0c48c4Sopenharmony_ci break; 228da0c48c4Sopenharmony_ci /* Buggy old Linux kernels didn't terminate "LINUX". */ 229da0c48c4Sopenharmony_ci FALLTHROUGH; 230da0c48c4Sopenharmony_ci 231da0c48c4Sopenharmony_ci case sizeof "LINUX": 232da0c48c4Sopenharmony_ci if (memcmp (name, "LINUX", nhdr->n_namesz) == 0) 233da0c48c4Sopenharmony_ci break; 234da0c48c4Sopenharmony_ci return 0; 235da0c48c4Sopenharmony_ci 236da0c48c4Sopenharmony_ci case sizeof "VMCOREINFO": 237da0c48c4Sopenharmony_ci if (nhdr->n_type != 0 238da0c48c4Sopenharmony_ci || memcmp (name, "VMCOREINFO", sizeof "VMCOREINFO") != 0) 239da0c48c4Sopenharmony_ci return 0; 240da0c48c4Sopenharmony_ci *regs_offset = 0; 241da0c48c4Sopenharmony_ci *nregloc = 0; 242da0c48c4Sopenharmony_ci *nitems = 1; 243da0c48c4Sopenharmony_ci *items = vmcoreinfo_items; 244da0c48c4Sopenharmony_ci return 1; 245da0c48c4Sopenharmony_ci 246da0c48c4Sopenharmony_ci default: 247da0c48c4Sopenharmony_ci return 0; 248da0c48c4Sopenharmony_ci } 249da0c48c4Sopenharmony_ci 250da0c48c4Sopenharmony_ci switch (nhdr->n_type) 251da0c48c4Sopenharmony_ci { 252da0c48c4Sopenharmony_ci case NT_PRSTATUS: 253da0c48c4Sopenharmony_ci if (nhdr->n_descsz != sizeof (struct EBLHOOK(prstatus))) 254da0c48c4Sopenharmony_ci return 0; 255da0c48c4Sopenharmony_ci *regs_offset = offsetof (struct EBLHOOK(prstatus), pr_reg); 256da0c48c4Sopenharmony_ci *nregloc = sizeof prstatus_regs / sizeof prstatus_regs[0]; 257da0c48c4Sopenharmony_ci *reglocs = prstatus_regs; 258da0c48c4Sopenharmony_ci *nitems = sizeof prstatus_items / sizeof prstatus_items[0]; 259da0c48c4Sopenharmony_ci *items = prstatus_items; 260da0c48c4Sopenharmony_ci return 1; 261da0c48c4Sopenharmony_ci 262da0c48c4Sopenharmony_ci case NT_PRPSINFO: 263da0c48c4Sopenharmony_ci if (nhdr->n_descsz != sizeof (struct EBLHOOK(prpsinfo))) 264da0c48c4Sopenharmony_ci return 0; 265da0c48c4Sopenharmony_ci *regs_offset = 0; 266da0c48c4Sopenharmony_ci *nregloc = 0; 267da0c48c4Sopenharmony_ci *reglocs = NULL; 268da0c48c4Sopenharmony_ci *nitems = sizeof prpsinfo_items / sizeof prpsinfo_items[0]; 269da0c48c4Sopenharmony_ci *items = prpsinfo_items; 270da0c48c4Sopenharmony_ci return 1; 271da0c48c4Sopenharmony_ci 272da0c48c4Sopenharmony_ci#define EXTRA_REGSET(type, size, table) \ 273da0c48c4Sopenharmony_ci case type: \ 274da0c48c4Sopenharmony_ci if (nhdr->n_descsz != size) \ 275da0c48c4Sopenharmony_ci return 0; \ 276da0c48c4Sopenharmony_ci *regs_offset = 0; \ 277da0c48c4Sopenharmony_ci *nregloc = sizeof table / sizeof table[0]; \ 278da0c48c4Sopenharmony_ci *reglocs = table; \ 279da0c48c4Sopenharmony_ci *nitems = 0; \ 280da0c48c4Sopenharmony_ci *items = NULL; \ 281da0c48c4Sopenharmony_ci return 1; 282da0c48c4Sopenharmony_ci 283da0c48c4Sopenharmony_ci#define EXTRA_REGSET_ITEMS(type, size, table, extra_items) \ 284da0c48c4Sopenharmony_ci case type: \ 285da0c48c4Sopenharmony_ci if (nhdr->n_descsz != size) \ 286da0c48c4Sopenharmony_ci return 0; \ 287da0c48c4Sopenharmony_ci *regs_offset = 0; \ 288da0c48c4Sopenharmony_ci *nregloc = sizeof table / sizeof table[0]; \ 289da0c48c4Sopenharmony_ci *reglocs = table; \ 290da0c48c4Sopenharmony_ci *nitems = sizeof extra_items / sizeof extra_items[0]; \ 291da0c48c4Sopenharmony_ci *items = extra_items; \ 292da0c48c4Sopenharmony_ci return 1; 293da0c48c4Sopenharmony_ci 294da0c48c4Sopenharmony_ci#define EXTRA_ITEMS(type, size, extra_items) \ 295da0c48c4Sopenharmony_ci case type: \ 296da0c48c4Sopenharmony_ci if (nhdr->n_descsz != size) \ 297da0c48c4Sopenharmony_ci return 0; \ 298da0c48c4Sopenharmony_ci *regs_offset = 0; \ 299da0c48c4Sopenharmony_ci *nregloc = 0; \ 300da0c48c4Sopenharmony_ci *reglocs = NULL; \ 301da0c48c4Sopenharmony_ci *nitems = sizeof extra_items / sizeof extra_items[0]; \ 302da0c48c4Sopenharmony_ci *items = extra_items; \ 303da0c48c4Sopenharmony_ci return 1; 304da0c48c4Sopenharmony_ci 305da0c48c4Sopenharmony_ci#ifdef FPREGSET_SIZE 306da0c48c4Sopenharmony_ci EXTRA_REGSET (NT_FPREGSET, FPREGSET_SIZE, fpregset_regs) 307da0c48c4Sopenharmony_ci#endif 308da0c48c4Sopenharmony_ci 309da0c48c4Sopenharmony_ci#ifdef EXTRA_NOTES 310da0c48c4Sopenharmony_ci EXTRA_NOTES 311da0c48c4Sopenharmony_ci#endif 312da0c48c4Sopenharmony_ci } 313da0c48c4Sopenharmony_ci 314da0c48c4Sopenharmony_ci return 0; 315da0c48c4Sopenharmony_ci} 316