202 lines · 4.3 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <mach.h>#include "elf.h"#include "ureg386.h" #undef errno#define errno	uregerrno typedef struct Lreg Lreg;typedef struct Status Status;typedef struct Psinfo Psinfo; /* * UregLinux386 is 64-bit aligned within status, so we shouldn't  * have any packing problems.  */struct Status{	u32int	signo;	u32int	code;	u32int	errno;	u32int	cursig;	u32int	sigpend;	u32int	sighold;	u32int	pid;	u32int	ppid;	u32int	pgrp;	u32int	sid;	u32int	utime[2];	u32int	stime[2];	u32int	cutime[2];	u32int	cstime[2];	UregLinux386	reg;	u32int	fpvalid;};enum{	StatusSize = sizeof(Status)}; struct Psinfo{	char state;	char sname;	char zomb;	char nice;	u32int flag;	u16int uid;	u16int gid;	u32int pid;	u32int ppid;	u32int pgrp;	u32int sid;	char fname[16];	char psargs[80];};enum{	PsinfoSize = sizeof(Psinfo)}; intcoreregslinux386(Elf *elf, ElfNote *note, uchar **up){	Status *s;	UregLinux386 *l;	Ureg *u; 	if(note->descsz < sizeof(Status)){		werrstr("elf status note too small");		return -1;	}	s = (Status*)note->desc;	l = &s->reg;	if((u = malloc(sizeof *u)) == nil)		return -1;	linux2ureg386(l, u);	*up = (uchar*)u;	return sizeof(Ureg);} intcorecmdlinux386(Elf *elf, ElfNote *note, char **pp){	char *t;	Psinfo *p; 	*pp = nil;	if(note->descsz < sizeof(Psinfo)){		werrstr("elf psinfo note too small");		return -1;	}	p = (Psinfo*)note->desc;	/* print("elf name %s\nelf args %s\n", p->fname, p->psargs); */	t = malloc(80+1);	if(t == nil)		return -1;	memmove(t, p->psargs, 80);	t[80] = 0;	*pp = t;	return 0;} #define dprint if(0)print voidelfcorelinux386(Fhdr *fp, Elf *elf, ElfNote *note){	int i;	Psinfo *ps;	Status *st;	Mach *m;	Ureg *u; 	m = fp->mach;	dprint("%s ", note->name);	switch(note->type){	case ElfNotePrPsinfo:		ps = (Psinfo*)note->desc;		dprint("note info\n");		dprint("state=%d sname=%d zomb=%d nice=%d\n",			ps->state, ps->sname, ps->zomb, ps->nice);		dprint("flag=0x%ux uid=%ud gid=%ud pid=%ud ppid=%ud pgrp=%ud sid=%ud\n",			(uint)m->swap4(ps->flag),			(uint)m->swap2(ps->uid),			(uint)m->swap2(ps->gid),			(uint)m->swap4(ps->pid),			(uint)m->swap4(ps->ppid),			(uint)m->swap4(ps->pgrp),			(uint)m->swap4(ps->sid));		dprint("fname=%s psargs=%s\n", ps->fname, ps->psargs);		fp->pid = m->swap4(ps->pid);		if((fp->prog = strdup(ps->fname)) == nil)			fprint(2, "warning: out of memory saving core program name\n");		if((fp->cmdline = strdup(ps->psargs)) == nil)			fprint(2, "warning: out of memory saving core command line\n");		break;	case ElfNotePrTaskstruct:		dprint("note taskstruct\n");		break;	case ElfNotePrAuxv:		dprint("note auxv\n");		break;	case ElfNotePrStatus:		dprint("note status\n");		if(note->descsz < StatusSize){			dprint("too small\n");			break;		}		st = (Status*)note->desc;		dprint("sig=%ud code=%ud errno=%ud cursig=%ud sigpend=0x%ux sighold=0x%ux\n",			(uint)m->swap4(st->signo),			(uint)m->swap4(st->code),			(uint)m->swap4(st->errno),			(uint)m->swap4(st->cursig),			(uint)m->swap4(st->sigpend),			(uint)m->swap4(st->sighold));		dprint("pid=%ud ppid=%ud pgrp=%ud sid=%ud\n",			(uint)m->swap4(st->pid),			(uint)m->swap4(st->ppid),				(uint)m->swap4(st->pgrp),			(uint)m->swap4(st->sid));		dprint("utime=%ud.%06ud stime=%ud.%06ud cutime=%ud.%06ud cstime=%ud.%06ud\n",			(uint)m->swap4(st->utime[0]),			(uint)m->swap4(st->utime[1]),			(uint)m->swap4(st->stime[0]),			(uint)m->swap4(st->stime[1]),			(uint)m->swap4(st->cutime[0]),			(uint)m->swap4(st->cutime[1]),			(uint)m->swap4(st->cstime[0]),			(uint)m->swap4(st->cstime[1]));		dprint("fpvalid=%ud\n",			(uint)m->swap4(st->fpvalid));		if((fp->thread = realloc(fp->thread, (1+fp->nthread)*sizeof(fp->thread[0]))) == nil){			fprint(2, "warning: out of memory saving thread info\n");			return;		}		i = fp->nthread;		fp->thread[i].id = m->swap4(st->pid);		u = malloc(sizeof *u);		if(u == nil){			fprint(2, "warning: out of memory saving thread info\n");			return;		}		fp->thread[i].ureg = u;		linux2ureg386(&st->reg, u);		fp->nthread++;		break;	case ElfNotePrFpreg:		dprint("note fpreg\n");		/* XXX maybe record floating-point registers eventually */		break;	case ElfNotePrXfpreg:		dprint("note xfpreg\n");		/* XXX maybe record floating-point registers eventually */		break;	default:		dprint("note %d\n", note->type);	}}