Home | History | Annotate | Download | only in backends
      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 
     43 struct EBLHOOK(siginfo)
     44 {
     45   FIELD (INT, si_signo);
     46   FIELD (INT, si_code);
     47   FIELD (INT, si_errno);
     48 };
     49 
     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 
     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 
     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