#include #include #include #include "elf.h" #include "uregamd64.h" typedef struct Ureg Ureg; // See FreeBSD's sys/procfs.h. typedef struct Lreg Lreg; typedef struct Status Status; typedef struct Psinfo Psinfo; struct Lreg { u64int r15; u64int r14; u64int r13; u64int r12; u64int r11; u64int r10; u64int r9; u64int r8; u64int rdi; u64int rsi; u64int rbp; u64int rbx; u64int rdx; u64int rcx; u64int rax; u32int trapno; u16int fs; u16int gs; u32int err; u16int es; u16int ds; u64int rip; u64int cs; u64int rflags; u64int rsp; u64int ss; }; struct Status { u32int version; /* Version number of struct (1) */ u64int statussz; /* sizeof(prstatus_t) (1) */ u64int gregsetsz; /* sizeof(gregset_t) (1) */ u64int fpregsetsz; /* sizeof(fpregset_t) (1) */ u32int osreldate; /* Kernel version (1) */ u32int cursig; /* Current signal (1) */ u32int pid; /* Process ID (1) */ Lreg reg; /* General purpose registers (1) */ }; struct Psinfo { u32int version; u64int size; char name[17]; char psargs[81]; }; void elfcorefreebsdamd64(Fhdr *fp, Elf *elf, ElfNote *note) { Status *s; Lreg *l; Ureg *u; int i; switch(note->type) { case ElfNotePrStatus: if(note->descsz < sizeof(Status)){ fprint(2, "warning: elf status note too small\n"); break; } s = (Status*)note->desc; if(s->version != 1){ fprint(2, "warning: unknown elf note status version %ud\n", (uint)s->version); break; } l = &s->reg; u = malloc(sizeof(Ureg)); /* no byte order problems - just copying and rearranging */ u->ax = l->rax; u->bx = l->rbx; u->cx = l->rcx; u->dx = l->rdx; u->si = l->rsi; u->di = l->rdi; u->bp = l->rbp; u->r8 = l->r8; u->r9 = l->r9; u->r10 = l->r10; u->r11 = l->r11; u->r12 = l->r12; u->r13 = l->r13; u->r14 = l->r14; u->r15 = l->r15; u->ds = l->ds; u->es = l->es; u->fs = l->fs; u->gs = l->gs; u->type = l->trapno; u->error = l->err; u->ip = l->rip; u->cs = l->cs; u->flags = l->rflags; u->sp = l->rsp; u->ss = l->ss; 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 = s->pid; fp->thread[i].ureg = u; fp->nthread++; break; } } int corecmdfreebsd386(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->name, p->psargs); */ t = malloc(80+1); if(t == nil) return -1; memmove(t, p->psargs, 80); t[80] = 0; *pp = t; return 0; }