rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 1 | #include <u.h> |
| 2 | #include <libc.h> |
| 3 | #include <mach.h> |
| 4 | #include "elf.h" |
| 5 | #include "ureg386.h" |
| 6 | |
rsc | b8f742d | 2005-01-11 17:43:53 +0000 | [diff] [blame] | 7 | #undef errno |
| 8 | #define errno uregerrno |
| 9 | |
rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 10 | typedef struct Lreg Lreg; |
| 11 | typedef struct Status Status; |
rsc | 1cc215a | 2004-12-25 22:03:28 +0000 | [diff] [blame] | 12 | typedef struct Psinfo Psinfo; |
rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 13 | |
| 14 | /* |
rsc | 1cc215a | 2004-12-25 22:03:28 +0000 | [diff] [blame] | 15 | * UregLinux386 is 64-bit aligned within status, so we shouldn't |
rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 16 | * have any packing problems. |
| 17 | */ |
| 18 | struct 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]; |
rsc | 1cc215a | 2004-12-25 22:03:28 +0000 | [diff] [blame] | 34 | UregLinux386 reg; |
rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 35 | u32int fpvalid; |
| 36 | }; |
rsc | dd944ec | 2005-01-23 22:33:04 +0000 | [diff] [blame] | 37 | enum |
| 38 | { |
rsc | cbeb0b2 | 2006-04-01 19:24:03 +0000 | [diff] [blame] | 39 | StatusSize = sizeof(Status) |
rsc | dd944ec | 2005-01-23 22:33:04 +0000 | [diff] [blame] | 40 | }; |
rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 41 | |
rsc | 1cc215a | 2004-12-25 22:03:28 +0000 | [diff] [blame] | 42 | struct 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 | }; |
rsc | dd944ec | 2005-01-23 22:33:04 +0000 | [diff] [blame] | 58 | enum |
| 59 | { |
rsc | cbeb0b2 | 2006-04-01 19:24:03 +0000 | [diff] [blame] | 60 | PsinfoSize = sizeof(Psinfo) |
rsc | dd944ec | 2005-01-23 22:33:04 +0000 | [diff] [blame] | 61 | }; |
rsc | 1cc215a | 2004-12-25 22:03:28 +0000 | [diff] [blame] | 62 | |
rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 63 | int |
| 64 | coreregslinux386(Elf *elf, ElfNote *note, uchar **up) |
| 65 | { |
| 66 | Status *s; |
rsc | 1cc215a | 2004-12-25 22:03:28 +0000 | [diff] [blame] | 67 | UregLinux386 *l; |
rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 68 | 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; |
rsc | dd944ec | 2005-01-23 22:33:04 +0000 | [diff] [blame] | 76 | if((u = malloc(sizeof *u)) == nil) |
rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 77 | return -1; |
rsc | dd944ec | 2005-01-23 22:33:04 +0000 | [diff] [blame] | 78 | linux2ureg386(l, u); |
rsc | a84cbb2 | 2004-04-19 19:29:25 +0000 | [diff] [blame] | 79 | *up = (uchar*)u; |
| 80 | return sizeof(Ureg); |
| 81 | } |
| 82 | |
rsc | 1cc215a | 2004-12-25 22:03:28 +0000 | [diff] [blame] | 83 | int |
| 84 | corecmdlinux386(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; |
rsc | cbeb0b2 | 2006-04-01 19:24:03 +0000 | [diff] [blame] | 95 | /* print("elf name %s\nelf args %s\n", p->fname, p->psargs); */ |
rsc | 1cc215a | 2004-12-25 22:03:28 +0000 | [diff] [blame] | 96 | 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 | |
rsc | dd944ec | 2005-01-23 22:33:04 +0000 | [diff] [blame] | 105 | #define dprint if(0)print |
| 106 | |
| 107 | void |
| 108 | elfcorelinux386(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 | |