aboutsummaryrefslogtreecommitdiff
path: root/src/libmach/elfcorefreebsdamd64.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmach/elfcorefreebsdamd64.c')
-rw-r--r--src/libmach/elfcorefreebsdamd64.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/libmach/elfcorefreebsdamd64.c b/src/libmach/elfcorefreebsdamd64.c
new file mode 100644
index 00000000..aefed432
--- /dev/null
+++ b/src/libmach/elfcorefreebsdamd64.c
@@ -0,0 +1,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;
+}
+