|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <mach.h> | 
|  | #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; | 
|  | } | 
|  |  |