1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
#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;
}
|