| #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; | 
 | } | 
 |  |