1 #include <u.h>
2 #include <libc.h>
3 #include <mach.h>
4 #include "elf.h"
5 #include "uregamd64.h"
6 
7 typedef struct Ureg Ureg;
8 
9 // See FreeBSD's sys/procfs.h.
10 
11 typedef struct Lreg Lreg;
12 typedef struct Status Status;
13 typedef struct Psinfo Psinfo;
14 
15 struct Lreg
16 {
17 	u64int	r15;
18 	u64int	r14;
19 	u64int	r13;
20 	u64int	r12;
21 	u64int	r11;
22 	u64int	r10;
23 	u64int	r9;
24 	u64int	r8;
25 	u64int	rdi;
26 	u64int	rsi;
27 	u64int	rbp;
28 	u64int	rbx;
29 	u64int	rdx;
30 	u64int	rcx;
31 	u64int	rax;
32 	u32int	trapno;
33 	u16int	fs;
34 	u16int	gs;
35 	u32int	err;
36 	u16int	es;
37 	u16int	ds;
38 	u64int	rip;
39 	u64int	cs;
40 	u64int	rflags;
41 	u64int	rsp;
42 	u64int	ss;
43 };
44 
45 struct Status
46 {
47 	u32int		version;	/* Version number of struct (1) */
48 	u64int		statussz;	/* sizeof(prstatus_t) (1) */
49 	u64int		gregsetsz;	/* sizeof(gregset_t) (1) */
50 	u64int		fpregsetsz;	/* sizeof(fpregset_t) (1) */
51 	u32int		osreldate;	/* Kernel version (1) */
52 	u32int		cursig;	/* Current signal (1) */
53 	u32int		pid;		/* Process ID (1) */
54 	Lreg		reg;		/* General purpose registers (1) */
55 };
56 
57 struct Psinfo
58 {
59 	u32int	version;
60 	u64int	size;
61 	char	name[17];
62 	char	psargs[81];
63 };
64 
65 void
elfcorefreebsdamd64(Fhdr * fp,Elf * elf,ElfNote * note)66 elfcorefreebsdamd64(Fhdr *fp, Elf *elf, ElfNote *note)
67 {
68 	Status *s;
69 	Lreg *l;
70 	Ureg *u;
71 	int i;
72 
73 	switch(note->type) {
74 	case ElfNotePrStatus:
75 		if(note->descsz < sizeof(Status)){
76 			fprint(2, "warning: elf status note too small\n");
77 			break;
78 		}
79 		s = (Status*)note->desc;
80 		if(s->version != 1){
81 			fprint(2, "warning: unknown elf note status version %ud\n", (uint)s->version);
82 			break;
83 		}
84 		l = &s->reg;
85 		u = malloc(sizeof(Ureg));
86 
87 		/* no byte order problems - just copying and rearranging */
88 		u->ax = l->rax;
89 		u->bx = l->rbx;
90 		u->cx = l->rcx;
91 		u->dx = l->rdx;
92 		u->si = l->rsi;
93 		u->di = l->rdi;
94 		u->bp = l->rbp;
95 		u->r8 = l->r8;
96 		u->r9 = l->r9;
97 		u->r10 = l->r10;
98 		u->r11 = l->r11;
99 		u->r12 = l->r12;
100 		u->r13 = l->r13;
101 		u->r14 = l->r14;
102 		u->r15 = l->r15;
103 
104 		u->ds = l->ds;
105 		u->es = l->es;
106 		u->fs = l->fs;
107 		u->gs = l->gs;
108 
109 		u->type = l->trapno;
110 		u->error = l->err;
111 		u->ip = l->rip;
112 		u->cs = l->cs;
113 		u->flags = l->rflags;
114 		u->sp = l->rsp;
115 		u->ss = l->ss;
116 
117 		if((fp->thread = realloc(fp->thread, (1+fp->nthread)*sizeof(fp->thread[0]))) == nil){
118 			fprint(2, "warning: out of memory saving thread info\n");
119 			return;
120 		}
121 		i = fp->nthread;
122 		fp->thread[i].id = s->pid;
123 		fp->thread[i].ureg = u;
124 		fp->nthread++;
125 		break;
126 	}
127 }
128 
129 int
corecmdfreebsd386(Elf * elf,ElfNote * note,char ** pp)130 corecmdfreebsd386(Elf *elf, ElfNote *note, char **pp)
131 {
132 	char *t;
133 	Psinfo *p;
134 
135 	*pp = nil;
136 	if(note->descsz < sizeof(Psinfo)){
137 		werrstr("elf psinfo note too small");
138 		return -1;
139 	}
140 	p = (Psinfo*)note->desc;
141 	/* print("elf name %s\nelf args %s\n", p->name, p->psargs); */
142 	t = malloc(80+1);
143 	if(t == nil)
144 		return -1;
145 	memmove(t, p->psargs, 80);
146 	t[80] = 0;
147 	*pp = t;
148 	return 0;
149 }
150