blob: 6cd0a5f99a9d08f160ae103c0d3f53cad7bcb755 [file] [log] [blame]
rsca84cbb22004-04-19 19:29:25 +00001#include <u.h>
2#include <libc.h>
3#include <mach.h>
4#include "elf.h"
5#include "ureg386.h"
6
rscb8f742d2005-01-11 17:43:53 +00007#undef errno
8#define errno uregerrno
9
rsca84cbb22004-04-19 19:29:25 +000010typedef struct Lreg Lreg;
11typedef struct Status Status;
rsc1cc215a2004-12-25 22:03:28 +000012typedef struct Psinfo Psinfo;
rsca84cbb22004-04-19 19:29:25 +000013
14/*
rsc1cc215a2004-12-25 22:03:28 +000015 * UregLinux386 is 64-bit aligned within status, so we shouldn't
rsca84cbb22004-04-19 19:29:25 +000016 * have any packing problems.
17 */
18struct Status
19{
20 u32int signo;
21 u32int code;
22 u32int errno;
23 u32int cursig;
24 u32int sigpend;
25 u32int sighold;
26 u32int pid;
27 u32int ppid;
28 u32int pgrp;
29 u32int sid;
30 u32int utime[2];
31 u32int stime[2];
32 u32int cutime[2];
33 u32int cstime[2];
rsc1cc215a2004-12-25 22:03:28 +000034 UregLinux386 reg;
rsca84cbb22004-04-19 19:29:25 +000035 u32int fpvalid;
36};
rscdd944ec2005-01-23 22:33:04 +000037enum
38{
rsccbeb0b22006-04-01 19:24:03 +000039 StatusSize = sizeof(Status)
rscdd944ec2005-01-23 22:33:04 +000040};
rsca84cbb22004-04-19 19:29:25 +000041
rsc1cc215a2004-12-25 22:03:28 +000042struct Psinfo
43{
44 char state;
45 char sname;
46 char zomb;
47 char nice;
48 u32int flag;
49 u16int uid;
50 u16int gid;
51 u32int pid;
52 u32int ppid;
53 u32int pgrp;
54 u32int sid;
55 char fname[16];
56 char psargs[80];
57};
rscdd944ec2005-01-23 22:33:04 +000058enum
59{
rsccbeb0b22006-04-01 19:24:03 +000060 PsinfoSize = sizeof(Psinfo)
rscdd944ec2005-01-23 22:33:04 +000061};
rsc1cc215a2004-12-25 22:03:28 +000062
rsca84cbb22004-04-19 19:29:25 +000063int
64coreregslinux386(Elf *elf, ElfNote *note, uchar **up)
65{
66 Status *s;
rsc1cc215a2004-12-25 22:03:28 +000067 UregLinux386 *l;
rsca84cbb22004-04-19 19:29:25 +000068 Ureg *u;
69
70 if(note->descsz < sizeof(Status)){
71 werrstr("elf status note too small");
72 return -1;
73 }
74 s = (Status*)note->desc;
75 l = &s->reg;
rscdd944ec2005-01-23 22:33:04 +000076 if((u = malloc(sizeof *u)) == nil)
rsca84cbb22004-04-19 19:29:25 +000077 return -1;
rscdd944ec2005-01-23 22:33:04 +000078 linux2ureg386(l, u);
rsca84cbb22004-04-19 19:29:25 +000079 *up = (uchar*)u;
80 return sizeof(Ureg);
81}
82
rsc1cc215a2004-12-25 22:03:28 +000083int
84corecmdlinux386(Elf *elf, ElfNote *note, char **pp)
85{
86 char *t;
87 Psinfo *p;
88
89 *pp = nil;
90 if(note->descsz < sizeof(Psinfo)){
91 werrstr("elf psinfo note too small");
92 return -1;
93 }
94 p = (Psinfo*)note->desc;
rsccbeb0b22006-04-01 19:24:03 +000095 /* print("elf name %s\nelf args %s\n", p->fname, p->psargs); */
rsc1cc215a2004-12-25 22:03:28 +000096 t = malloc(80+1);
97 if(t == nil)
98 return -1;
99 memmove(t, p->psargs, 80);
100 t[80] = 0;
101 *pp = t;
102 return 0;
103}
104
rscdd944ec2005-01-23 22:33:04 +0000105#define dprint if(0)print
106
107void
108elfcorelinux386(Fhdr *fp, Elf *elf, ElfNote *note)
109{
110 int i;
111 Psinfo *ps;
112 Status *st;
113 Mach *m;
114 Ureg *u;
115
116 m = fp->mach;
117 dprint("%s ", note->name);
118 switch(note->type){
119 case ElfNotePrPsinfo:
120 ps = (Psinfo*)note->desc;
121 dprint("note info\n");
122 dprint("state=%d sname=%d zomb=%d nice=%d\n",
123 ps->state, ps->sname, ps->zomb, ps->nice);
124 dprint("flag=0x%ux uid=%ud gid=%ud pid=%ud ppid=%ud pgrp=%ud sid=%ud\n",
125 (uint)m->swap4(ps->flag),
126 (uint)m->swap2(ps->uid),
127 (uint)m->swap2(ps->gid),
128 (uint)m->swap4(ps->pid),
129 (uint)m->swap4(ps->ppid),
130 (uint)m->swap4(ps->pgrp),
131 (uint)m->swap4(ps->sid));
132 dprint("fname=%s psargs=%s\n", ps->fname, ps->psargs);
133 fp->pid = m->swap4(ps->pid);
134 if((fp->prog = strdup(ps->fname)) == nil)
135 fprint(2, "warning: out of memory saving core program name\n");
136 if((fp->cmdline = strdup(ps->psargs)) == nil)
137 fprint(2, "warning: out of memory saving core command line\n");
138 break;
139 case ElfNotePrTaskstruct:
140 dprint("note taskstruct\n");
141 break;
142 case ElfNotePrAuxv:
143 dprint("note auxv\n");
144 break;
145 case ElfNotePrStatus:
146 dprint("note status\n");
147 if(note->descsz < StatusSize){
148 dprint("too small\n");
149 break;
150 }
151 st = (Status*)note->desc;
152 dprint("sig=%ud code=%ud errno=%ud cursig=%ud sigpend=0x%ux sighold=0x%ux\n",
153 (uint)m->swap4(st->signo),
154 (uint)m->swap4(st->code),
155 (uint)m->swap4(st->errno),
156 (uint)m->swap4(st->cursig),
157 (uint)m->swap4(st->sigpend),
158 (uint)m->swap4(st->sighold));
159 dprint("pid=%ud ppid=%ud pgrp=%ud sid=%ud\n",
160 (uint)m->swap4(st->pid),
161 (uint)m->swap4(st->ppid),
162 (uint)m->swap4(st->pgrp),
163 (uint)m->swap4(st->sid));
164 dprint("utime=%ud.%06ud stime=%ud.%06ud cutime=%ud.%06ud cstime=%ud.%06ud\n",
165 (uint)m->swap4(st->utime[0]),
166 (uint)m->swap4(st->utime[1]),
167 (uint)m->swap4(st->stime[0]),
168 (uint)m->swap4(st->stime[1]),
169 (uint)m->swap4(st->cutime[0]),
170 (uint)m->swap4(st->cutime[1]),
171 (uint)m->swap4(st->cstime[0]),
172 (uint)m->swap4(st->cstime[1]));
173 dprint("fpvalid=%ud\n",
174 (uint)m->swap4(st->fpvalid));
175 if((fp->thread = realloc(fp->thread, (1+fp->nthread)*sizeof(fp->thread[0]))) == nil){
176 fprint(2, "warning: out of memory saving thread info\n");
177 return;
178 }
179 i = fp->nthread;
180 fp->thread[i].id = m->swap4(st->pid);
181 u = malloc(sizeof *u);
182 if(u == nil){
183 fprint(2, "warning: out of memory saving thread info\n");
184 return;
185 }
186 fp->thread[i].ureg = u;
187 linux2ureg386(&st->reg, u);
188 fp->nthread++;
189 break;
190 case ElfNotePrFpreg:
191 dprint("note fpreg\n");
192 /* XXX maybe record floating-point registers eventually */
193 break;
194 case ElfNotePrXfpreg:
195 dprint("note xfpreg\n");
196 /* XXX maybe record floating-point registers eventually */
197 break;
198 default:
199 dprint("note %d\n", note->type);
200 }
201}
202