2004-04-19 19:29:25 +00:00
|
|
|
#include <u.h>
|
|
|
|
#include <libc.h>
|
|
|
|
#include <mach.h>
|
|
|
|
#include "elf.h"
|
|
|
|
#include "ureg386.h"
|
|
|
|
|
2005-01-11 17:43:53 +00:00
|
|
|
#undef errno
|
|
|
|
#define errno uregerrno
|
|
|
|
|
2004-04-19 19:29:25 +00:00
|
|
|
typedef struct Lreg Lreg;
|
|
|
|
typedef struct Status Status;
|
2004-12-25 22:03:28 +00:00
|
|
|
typedef struct Psinfo Psinfo;
|
2004-04-19 19:29:25 +00:00
|
|
|
|
|
|
|
/*
|
2004-12-25 22:03:28 +00:00
|
|
|
* UregLinux386 is 64-bit aligned within status, so we shouldn't
|
2004-04-19 19:29:25 +00:00
|
|
|
* 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];
|
2004-12-25 22:03:28 +00:00
|
|
|
UregLinux386 reg;
|
2004-04-19 19:29:25 +00:00
|
|
|
u32int fpvalid;
|
|
|
|
};
|
2005-01-23 22:33:04 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
StatusSize = sizeof(Status),
|
|
|
|
};
|
2004-04-19 19:29:25 +00:00
|
|
|
|
2004-12-25 22:03:28 +00:00
|
|
|
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];
|
|
|
|
};
|
2005-01-23 22:33:04 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
PsinfoSize = sizeof(Psinfo),
|
|
|
|
};
|
2004-12-25 22:03:28 +00:00
|
|
|
|
2004-04-19 19:29:25 +00:00
|
|
|
int
|
|
|
|
coreregslinux386(Elf *elf, ElfNote *note, uchar **up)
|
|
|
|
{
|
|
|
|
Status *s;
|
2004-12-25 22:03:28 +00:00
|
|
|
UregLinux386 *l;
|
2004-04-19 19:29:25 +00:00
|
|
|
Ureg *u;
|
|
|
|
|
|
|
|
if(note->descsz < sizeof(Status)){
|
|
|
|
werrstr("elf status note too small");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
s = (Status*)note->desc;
|
|
|
|
l = &s->reg;
|
2005-01-23 22:33:04 +00:00
|
|
|
if((u = malloc(sizeof *u)) == nil)
|
2004-04-19 19:29:25 +00:00
|
|
|
return -1;
|
2005-01-23 22:33:04 +00:00
|
|
|
linux2ureg386(l, u);
|
2004-04-19 19:29:25 +00:00
|
|
|
*up = (uchar*)u;
|
|
|
|
return sizeof(Ureg);
|
|
|
|
}
|
|
|
|
|
2004-12-25 22:03:28 +00:00
|
|
|
int
|
|
|
|
corecmdlinux386(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;
|
2005-01-18 20:49:11 +00:00
|
|
|
// print("elf name %s\nelf args %s\n", p->fname, p->psargs);
|
2004-12-25 22:03:28 +00:00
|
|
|
t = malloc(80+1);
|
|
|
|
if(t == nil)
|
|
|
|
return -1;
|
|
|
|
memmove(t, p->psargs, 80);
|
|
|
|
t[80] = 0;
|
|
|
|
*pp = t;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-01-23 22:33:04 +00:00
|
|
|
#define dprint if(0)print
|
|
|
|
|
|
|
|
void
|
|
|
|
elfcorelinux386(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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|