plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

elfcorelinux386.c (4396B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <mach.h>
      4 #include "elf.h"
      5 #include "ureg386.h"
      6 
      7 #undef errno
      8 #define errno	uregerrno
      9 
     10 typedef struct Lreg Lreg;
     11 typedef struct Status Status;
     12 typedef struct Psinfo Psinfo;
     13 
     14 /*
     15  * UregLinux386 is 64-bit aligned within status, so we shouldn't
     16  * have any packing problems.
     17  */
     18 struct Status
     19 {
     20 	u32int	signo;
     21 	u32int	code;
     22 	u32int	errno;
     23 	u32int	cursig;
     24 	u32int	sigpend;
     25 	u32int	sighold;
     26 	u32int	pid;
     27 	u32int	ppid;
     28 	u32int	pgrp;
     29 	u32int	sid;
     30 	u32int	utime[2];
     31 	u32int	stime[2];
     32 	u32int	cutime[2];
     33 	u32int	cstime[2];
     34 	UregLinux386	reg;
     35 	u32int	fpvalid;
     36 };
     37 enum
     38 {
     39 	StatusSize = sizeof(Status)
     40 };
     41 
     42 struct Psinfo
     43 {
     44 	char state;
     45 	char sname;
     46 	char zomb;
     47 	char nice;
     48 	u32int flag;
     49 	u16int uid;
     50 	u16int gid;
     51 	u32int pid;
     52 	u32int ppid;
     53 	u32int pgrp;
     54 	u32int sid;
     55 	char fname[16];
     56 	char psargs[80];
     57 };
     58 enum
     59 {
     60 	PsinfoSize = sizeof(Psinfo)
     61 };
     62 
     63 int
     64 coreregslinux386(Elf *elf, ElfNote *note, uchar **up)
     65 {
     66 	Status *s;
     67 	UregLinux386 *l;
     68 	Ureg *u;
     69 
     70 	if(note->descsz < sizeof(Status)){
     71 		werrstr("elf status note too small");
     72 		return -1;
     73 	}
     74 	s = (Status*)note->desc;
     75 	l = &s->reg;
     76 	if((u = malloc(sizeof *u)) == nil)
     77 		return -1;
     78 	linux2ureg386(l, u);
     79 	*up = (uchar*)u;
     80 	return sizeof(Ureg);
     81 }
     82 
     83 int
     84 corecmdlinux386(Elf *elf, ElfNote *note, char **pp)
     85 {
     86 	char *t;
     87 	Psinfo *p;
     88 
     89 	*pp = nil;
     90 	if(note->descsz < sizeof(Psinfo)){
     91 		werrstr("elf psinfo note too small");
     92 		return -1;
     93 	}
     94 	p = (Psinfo*)note->desc;
     95 	/* print("elf name %s\nelf args %s\n", p->fname, p->psargs); */
     96 	t = malloc(80+1);
     97 	if(t == nil)
     98 		return -1;
     99 	memmove(t, p->psargs, 80);
    100 	t[80] = 0;
    101 	*pp = t;
    102 	return 0;
    103 }
    104 
    105 #define dprint if(0)print
    106 
    107 void
    108 elfcorelinux386(Fhdr *fp, Elf *elf, ElfNote *note)
    109 {
    110 	int i;
    111 	Psinfo *ps;
    112 	Status *st;
    113 	Mach *m;
    114 	Ureg *u;
    115 
    116 	m = fp->mach;
    117 	dprint("%s ", note->name);
    118 	switch(note->type){
    119 	case ElfNotePrPsinfo:
    120 		ps = (Psinfo*)note->desc;
    121 		dprint("note info\n");
    122 		dprint("state=%d sname=%d zomb=%d nice=%d\n",
    123 			ps->state, ps->sname, ps->zomb, ps->nice);
    124 		dprint("flag=0x%ux uid=%ud gid=%ud pid=%ud ppid=%ud pgrp=%ud sid=%ud\n",
    125 			(uint)m->swap4(ps->flag),
    126 			(uint)m->swap2(ps->uid),
    127 			(uint)m->swap2(ps->gid),
    128 			(uint)m->swap4(ps->pid),
    129 			(uint)m->swap4(ps->ppid),
    130 			(uint)m->swap4(ps->pgrp),
    131 			(uint)m->swap4(ps->sid));
    132 		dprint("fname=%s psargs=%s\n", ps->fname, ps->psargs);
    133 		fp->pid = m->swap4(ps->pid);
    134 		if((fp->prog = strdup(ps->fname)) == nil)
    135 			fprint(2, "warning: out of memory saving core program name\n");
    136 		if((fp->cmdline = strdup(ps->psargs)) == nil)
    137 			fprint(2, "warning: out of memory saving core command line\n");
    138 		break;
    139 	case ElfNotePrTaskstruct:
    140 		dprint("note taskstruct\n");
    141 		break;
    142 	case ElfNotePrAuxv:
    143 		dprint("note auxv\n");
    144 		break;
    145 	case ElfNotePrStatus:
    146 		dprint("note status\n");
    147 		if(note->descsz < StatusSize){
    148 			dprint("too small\n");
    149 			break;
    150 		}
    151 		st = (Status*)note->desc;
    152 		dprint("sig=%ud code=%ud errno=%ud cursig=%ud sigpend=0x%ux sighold=0x%ux\n",
    153 			(uint)m->swap4(st->signo),
    154 			(uint)m->swap4(st->code),
    155 			(uint)m->swap4(st->errno),
    156 			(uint)m->swap4(st->cursig),
    157 			(uint)m->swap4(st->sigpend),
    158 			(uint)m->swap4(st->sighold));
    159 		dprint("pid=%ud ppid=%ud pgrp=%ud sid=%ud\n",
    160 			(uint)m->swap4(st->pid),
    161 			(uint)m->swap4(st->ppid),
    162 			(uint)m->swap4(st->pgrp),
    163 			(uint)m->swap4(st->sid));
    164 		dprint("utime=%ud.%06ud stime=%ud.%06ud cutime=%ud.%06ud cstime=%ud.%06ud\n",
    165 			(uint)m->swap4(st->utime[0]),
    166 			(uint)m->swap4(st->utime[1]),
    167 			(uint)m->swap4(st->stime[0]),
    168 			(uint)m->swap4(st->stime[1]),
    169 			(uint)m->swap4(st->cutime[0]),
    170 			(uint)m->swap4(st->cutime[1]),
    171 			(uint)m->swap4(st->cstime[0]),
    172 			(uint)m->swap4(st->cstime[1]));
    173 		dprint("fpvalid=%ud\n",
    174 			(uint)m->swap4(st->fpvalid));
    175 		if((fp->thread = realloc(fp->thread, (1+fp->nthread)*sizeof(fp->thread[0]))) == nil){
    176 			fprint(2, "warning: out of memory saving thread info\n");
    177 			return;
    178 		}
    179 		i = fp->nthread;
    180 		fp->thread[i].id = m->swap4(st->pid);
    181 		u = malloc(sizeof *u);
    182 		if(u == nil){
    183 			fprint(2, "warning: out of memory saving thread info\n");
    184 			return;
    185 		}
    186 		fp->thread[i].ureg = u;
    187 		linux2ureg386(&st->reg, u);
    188 		fp->nthread++;
    189 		break;
    190 	case ElfNotePrFpreg:
    191 		dprint("note fpreg\n");
    192 		/* XXX maybe record floating-point registers eventually */
    193 		break;
    194 	case ElfNotePrXfpreg:
    195 		dprint("note xfpreg\n");
    196 		/* XXX maybe record floating-point registers eventually */
    197 		break;
    198 	default:
    199 		dprint("note %d\n", note->type);
    200 	}
    201 }