libmach, acid, db: 64-bit support

This commit is contained in:
Russ Cox 2012-02-19 18:11:39 -05:00
parent 60d96f2e43
commit 443d628838
36 changed files with 2311 additions and 1125 deletions

View file

@ -36,8 +36,8 @@ struct PtraceRegs
int pid;
};
static int ptracesegrw(Map*, Seg*, ulong, void*, uint, int);
static int ptraceregrw(Regs*, char*, ulong*, int);
static int ptracesegrw(Map*, Seg*, u64int, void*, uint, int);
static int ptraceregrw(Regs*, char*, u64int*, int);
static int attachedpids[1000];
static int nattached;
@ -173,7 +173,7 @@ ptraceerr:
}
static int
ptracesegrw(Map *map, Seg *seg, ulong addr, void *v, uint n, int isr)
ptracesegrw(Map *map, Seg *seg, u64int addr, void *v, uint n, int isr)
{
addr += seg->base;
return ptracerw(isr ? PTRACE_PEEKDATA : PTRACE_POKEDATA, PTRACE_PEEKDATA,
@ -212,7 +212,7 @@ reg2linux(char *reg)
}
static int
ptraceregrw(Regs *regs, char *name, ulong *val, int isr)
ptraceregrw(Regs *regs, char *name, u64int *val, int isr)
{
int pid;
ulong addr;

View file

@ -93,7 +93,7 @@ uncrackhdr(Fhdr *hdr)
}
int
mapfile(Fhdr *fp, ulong base, Map *map, Regs **regs)
mapfile(Fhdr *fp, u64int base, Map *map, Regs **regs)
{
if(fp == nil){
werrstr("no file");

View file

@ -4,7 +4,7 @@
#include "elf.h"
#include "dwarf.h"
static int mapelf(Fhdr *fp, ulong base, Map *map, Regs**);
static int mapelf(Fhdr *fp, u64int base, Map *map, Regs**);
static int unpacknote(Elf *elf, uchar *a, uchar *ea, ElfNote *note, uchar **pa);
static struct
@ -21,6 +21,7 @@ static struct
ElfMachArm, MARM, nil, "arm",
ElfMachPower, MPOWER, nil, "powerpc",
ElfMachPower64, MNONE, nil, "powerpc64",
ElfMachAmd64, MAMD64, &machamd64, "amd64",
};
static struct
@ -44,7 +45,8 @@ static struct
{ /* Font Tab 4 */
M386, ALINUX, elfcorelinux386,
M386, ANONE, elfcorelinux386, /* [sic] */
/* M386, AFREEBSD, elfcorefreebsd386, */
// M386, AFREEBSD, elfcorefreebsd386,
MAMD64, AFREEBSD, elfcorefreebsdamd64,
};
int
@ -202,13 +204,13 @@ err:
}
static int
mapelf(Fhdr *fp, ulong base, Map *map, Regs **regs)
mapelf(Fhdr *fp, u64int base, Map *map, Regs **regs)
{
int i;
Elf *elf;
ElfProg *p;
ulong sz;
ulong lim;
u64int sz;
u64int lim;
Seg s;
elf = fp->elf;

View file

@ -3,7 +3,7 @@
#include <mach.h>
#include "macho.h"
static int mapmacho(Fhdr *fp, ulong base, Map *map, Regs**);
static int mapmacho(Fhdr *fp, u64int base, Map *map, Regs**);
static struct
{
@ -136,7 +136,7 @@ err:
}
static int
mapmacho(Fhdr *fp, ulong base, Map *map, Regs **rp)
mapmacho(Fhdr *fp, u64int base, Map *map, Regs **rp)
{
int i, n;
uchar *u;

View file

@ -13,6 +13,11 @@ typedef struct ElfSectBytes ElfSectBytes;
typedef struct ElfProgBytes ElfProgBytes;
typedef struct ElfSymBytes ElfSymBytes;
typedef struct ElfHdrBytes64 ElfHdrBytes64;
typedef struct ElfSectBytes64 ElfSectBytes64;
typedef struct ElfProgBytes64 ElfProgBytes64;
typedef struct ElfSymBytes64 ElfSymBytes64;
struct ElfHdrBytes
{
uchar ident[16];
@ -31,6 +36,24 @@ struct ElfHdrBytes
uchar shstrndx[2];
};
struct ElfHdrBytes64
{
uchar ident[16];
uchar type[2];
uchar machine[2];
uchar version[4];
uchar entry[8];
uchar phoff[8];
uchar shoff[8];
uchar flags[4];
uchar ehsize[2];
uchar phentsize[2];
uchar phnum[2];
uchar shentsize[2];
uchar shnum[2];
uchar shstrndx[2];
};
struct ElfSectBytes
{
uchar name[4];
@ -45,6 +68,20 @@ struct ElfSectBytes
uchar entsize[4];
};
struct ElfSectBytes64
{
uchar name[4];
uchar type[4];
uchar flags[8];
uchar addr[8];
uchar offset[8];
uchar size[8];
uchar link[4];
uchar info[4];
uchar align[8];
uchar entsize[8];
};
struct ElfSymBytes
{
uchar name[4];
@ -55,6 +92,16 @@ struct ElfSymBytes
uchar shndx[2];
};
struct ElfSymBytes64
{
uchar name[4];
uchar info;
uchar other;
uchar shndx[2];
uchar value[8];
uchar size[8];
};
struct ElfProgBytes
{
uchar type[4];
@ -67,11 +114,23 @@ struct ElfProgBytes
uchar align[4];
};
struct ElfProgBytes64
{
uchar type[4];
uchar flags[4];
uchar offset[8];
uchar vaddr[8];
uchar paddr[8];
uchar filesz[8];
uchar memsz[8];
uchar align[8];
};
uchar ElfMagic[4] = { 0x7F, 'E', 'L', 'F' };
static void unpackhdr(ElfHdr*, ElfHdrBytes*);
static void unpackprog(ElfHdr*, ElfProg*, ElfProgBytes*);
static void unpacksect(ElfHdr*, ElfSect*, ElfSectBytes*);
static void unpackhdr(ElfHdr*, void*);
static void unpackprog(ElfHdr*, ElfProg*, void*);
static void unpacksect(ElfHdr*, ElfSect*, void*);
static char *elftypes[] = {
"none",
@ -128,9 +187,11 @@ elfinit(int fd)
int i;
Elf *e;
ElfHdr *h;
ElfHdrBytes hdrb;
ElfProgBytes progb;
ElfSectBytes sectb;
union {
ElfHdrBytes h32;
ElfHdrBytes64 h64;
} hdrb;
void *p;
ElfSect *s;
e = mallocz(sizeof(Elf), 1);
@ -146,17 +207,17 @@ elfinit(int fd)
goto err;
h = &e->hdr;
unpackhdr(h, &hdrb);
if(h->class != ElfClass32){
werrstr("bad ELF class - not 32-bit");
if(h->class != ElfClass32 && h->class != ElfClass64){
werrstr("bad ELF class - not 32-bit, 64-bit");
goto err;
}
if(h->encoding != ElfDataLsb && h->encoding != ElfDataMsb){
werrstr("bad ELF encoding - not LSB, MSB");
goto err;
}
if(hdrb.ident[6] != h->version){
if(hdrb.h32.ident[6] != h->version){
werrstr("bad ELF encoding - version mismatch %02ux and %08ux",
(uint)hdrb.ident[6], (uint)h->version);
(uint)hdrb.h32.ident[6], (uint)h->version);
goto err;
}
@ -165,23 +226,27 @@ elfinit(int fd)
*/
e->nprog = h->phnum;
e->prog = mallocz(sizeof(ElfProg)*e->nprog, 1);
p = mallocz(h->phentsize, 1);
for(i=0; i<e->nprog; i++){
if(seek(fd, h->phoff+i*h->phentsize, 0) < 0
|| readn(fd, &progb, sizeof progb) != sizeof progb)
|| readn(fd, p, h->phentsize) != h->phentsize)
goto err;
unpackprog(h, &e->prog[i], &progb);
unpackprog(h, &e->prog[i], p);
}
free(p);
e->nsect = h->shnum;
if(e->nsect == 0)
goto nosects;
e->sect = mallocz(sizeof(ElfSect)*e->nsect, 1);
p = mallocz(h->shentsize, 1);
for(i=0; i<e->nsect; i++){
if(seek(fd, h->shoff+i*h->shentsize, 0) < 0
|| readn(fd, &sectb, sizeof sectb) != sizeof sectb)
|| readn(fd, p, h->shentsize) != h->shentsize)
goto err;
unpacksect(h, &e->sect[i], &sectb);
unpacksect(h, &e->sect[i], p);
}
free(p);
if(h->shstrndx >= e->nsect){
fprint(2, "warning: bad string section index %d >= %d", h->shstrndx, e->nsect);
@ -243,12 +308,15 @@ elfclose(Elf *elf)
}
static void
unpackhdr(ElfHdr *h, ElfHdrBytes *b)
unpackhdr(ElfHdr *h, void *v)
{
u16int (*e2)(uchar*);
u32int (*e4)(uchar*);
u64int (*e8)(uchar*);
ElfHdrBytes *b;
ElfHdrBytes64 *b64;
b = v;
memmove(h->magic, b->ident, 4);
h->class = b->ident[4];
h->encoding = b->ident[5];
@ -273,6 +341,9 @@ unpackhdr(ElfHdr *h, ElfHdrBytes *b)
h->e4 = e4;
h->e8 = e8;
if(h->class == ElfClass64)
goto b64;
h->type = e2(b->type);
h->machine = e2(b->machine);
h->version = e4(b->version);
@ -286,40 +357,100 @@ unpackhdr(ElfHdr *h, ElfHdrBytes *b)
h->shentsize = e2(b->shentsize);
h->shnum = e2(b->shnum);
h->shstrndx = e2(b->shstrndx);
return;
b64:
b64 = v;
h->type = e2(b64->type);
h->machine = e2(b64->machine);
h->version = e4(b64->version);
h->entry = e8(b64->entry);
h->phoff = e8(b64->phoff);
h->shoff = e8(b64->shoff);
h->flags = e4(b64->flags);
h->ehsize = e2(b64->ehsize);
h->phentsize = e2(b64->phentsize);
h->phnum = e2(b64->phnum);
h->shentsize = e2(b64->shentsize);
h->shnum = e2(b64->shnum);
h->shstrndx = e2(b64->shstrndx);
return;
}
static void
unpackprog(ElfHdr *h, ElfProg *p, ElfProgBytes *b)
unpackprog(ElfHdr *h, ElfProg *p, void *v)
{
u32int (*e4)(uchar*);
u64int (*e8)(uchar*);
e4 = h->e4;
p->type = e4(b->type);
p->offset = e4(b->offset);
p->vaddr = e4(b->vaddr);
p->paddr = e4(b->paddr);
p->filesz = e4(b->filesz);
p->memsz = e4(b->memsz);
p->flags = e4(b->flags);
p->align = e4(b->align);
if(h->class == ElfClass32) {
ElfProgBytes *b;
b = v;
e4 = h->e4;
p->type = e4(b->type);
p->offset = e4(b->offset);
p->vaddr = e4(b->vaddr);
p->paddr = e4(b->paddr);
p->filesz = e4(b->filesz);
p->memsz = e4(b->memsz);
p->flags = e4(b->flags);
p->align = e4(b->align);
} else {
ElfProgBytes64 *b;
b = v;
e4 = h->e4;
e8 = h->e8;
p->type = e4(b->type);
p->offset = e8(b->offset);
p->vaddr = e8(b->vaddr);
p->paddr = e8(b->paddr);
p->filesz = e8(b->filesz);
p->memsz = e8(b->memsz);
p->flags = e4(b->flags);
p->align = e8(b->align);
}
}
static void
unpacksect(ElfHdr *h, ElfSect *s, ElfSectBytes *b)
unpacksect(ElfHdr *h, ElfSect *s, void *v)
{
u32int (*e4)(uchar*);
u64int (*e8)(uchar*);
e4 = h->e4;
s->name = (char*)(uintptr)e4(b->name);
s->type = e4(b->type);
s->flags = e4(b->flags);
s->addr = e4(b->addr);
s->offset = e4(b->offset);
s->size = e4(b->size);
s->link = e4(b->link);
s->info = e4(b->info);
s->align = e4(b->align);
s->entsize = e4(b->entsize);
if(h->class == ElfClass32) {
ElfSectBytes *b;
b = v;
e4 = h->e4;
s->name = (char*)(uintptr)e4(b->name);
s->type = e4(b->type);
s->flags = e4(b->flags);
s->addr = e4(b->addr);
s->offset = e4(b->offset);
s->size = e4(b->size);
s->link = e4(b->link);
s->info = e4(b->info);
s->align = e4(b->align);
s->entsize = e4(b->entsize);
} else {
ElfSectBytes64 *b;
b = v;
e4 = h->e4;
e8 = h->e8;
s->name = (char*)(uintptr)e4(b->name);
s->type = e4(b->type);
s->flags = e8(b->flags);
s->addr = e8(b->addr);
s->offset = e8(b->offset);
s->size = e8(b->size);
s->link = e4(b->link);
s->info = e4(b->info);
s->align = e8(b->align);
s->entsize = e8(b->entsize);
}
}
ElfSect*
@ -374,21 +505,39 @@ elfsym(Elf *elf, int i, ElfSym *sym)
extract:
if(elfmap(elf, symtab) < 0 || elfmap(elf, strtab) < 0)
return -1;
p = symtab->base + i * sizeof(ElfSymBytes);
s = (char*)strtab->base;
x = elf->hdr.e4(p);
if(x >= strtab->size){
werrstr("bad symbol name offset 0x%lux", x);
return -1;
if(elf->hdr.class == ElfClass32) {
p = symtab->base + i * sizeof(ElfSymBytes);
s = (char*)strtab->base;
x = elf->hdr.e4(p);
if(x >= strtab->size){
werrstr("bad symbol name offset 0x%lux", x);
return -1;
}
sym->name = s + x;
sym->value = elf->hdr.e4(p+4);
sym->size = elf->hdr.e4(p+8);
x = p[12];
sym->bind = x>>4;
sym->type = x & 0xF;
sym->other = p[13];
sym->shndx = elf->hdr.e2(p+14);
} else {
p = symtab->base + i * sizeof(ElfSymBytes64);
s = (char*)strtab->base;
x = elf->hdr.e4(p);
if(x >= strtab->size){
werrstr("bad symbol name offset 0x%lux", x);
return -1;
}
sym->name = s + x;
x = p[4];
sym->bind = x>>4;
sym->type = x & 0xF;
sym->other = p[5];
sym->shndx = elf->hdr.e2(p+6);
sym->value = elf->hdr.e8(p+8);
sym->size = elf->hdr.e8(p+16);
}
sym->name = s + x;
sym->value = elf->hdr.e4(p+4);
sym->size = elf->hdr.e4(p+8);
x = p[12];
sym->bind = x>>4;
sym->type = x & 0xF;
sym->other = p[13];
sym->shndx = elf->hdr.e2(p+14);
return 0;
}
i -= elf->nsymtab;

View file

@ -54,6 +54,7 @@ enum
ElfMachAlpha, /* Digital Alpha */
ElfMachSH, /* Hitachi SH */
ElfMachSparc9, /* SPARC V9 */
ElfMachAmd64 = 62, /* x86-64 */
/* and the list goes on... */
ElfAbiNone = 0,
@ -138,9 +139,9 @@ struct ElfHdr
uchar abiversion;
u32int type;
u32int machine;
u32int entry;
u32int phoff;
u32int shoff;
u64int entry;
u64int phoff;
u64int shoff;
u32int flags;
u32int ehsize;
u32int phentsize;
@ -157,27 +158,27 @@ struct ElfSect
{
char *name;
u32int type;
u32int flags;
u32int addr;
u32int offset;
u32int size;
u64int flags;
u64int addr;
u64int offset;
u64int size;
u32int link;
u32int info;
u32int align;
u32int entsize;
u64int align;
u64int entsize;
uchar *base;
};
struct ElfProg
{
u32int type;
u32int offset;
u32int vaddr;
u32int paddr;
u32int filesz;
u32int memsz;
u64int offset;
u64int vaddr;
u64int paddr;
u64int filesz;
u64int memsz;
u32int flags;
u32int align;
u64int align;
};
struct ElfNote
@ -193,8 +194,8 @@ struct ElfNote
struct ElfSym
{
char* name;
u32int value;
u32int size;
u64int value;
u64int size;
uchar bind;
uchar type;
uchar other;
@ -234,4 +235,6 @@ int elfmap(Elf*, ElfSect*);
struct Fhdr;
void elfcorelinux386(struct Fhdr*, Elf*, ElfNote*);
void elfcorefreebsd386(struct Fhdr*, Elf*, ElfNote*);
void elfcorefreebsdamd64(struct Fhdr*, Elf*, ElfNote*);
void elfdl386mapdl(int);

View file

@ -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;
}

View file

@ -9,11 +9,11 @@ struct LocRegs
Regs r;
Regs *oldregs;
Map *map;
ulong *val;
u64int *val;
};
static int
locregrw(Regs *regs, char *name, ulong *val, int isr)
locregrw(Regs *regs, char *name, u64int *val, int isr)
{
int i;
LocRegs *lr;
@ -36,8 +36,8 @@ stacktrace(Map *map, Regs *regs, Tracer trace)
{
char *rname;
int i, ipc, ret;
ulong nextpc, pc, v;
ulong *cur, *next;
u64int nextpc, pc, v;
u64int *cur, *next;
LocRegs lr;
Symbol s, *sp;

View file

@ -4,7 +4,7 @@
#include <mach.h>
char *
_hexify(char *buf, ulong p, int zeros)
_hexify(char *buf, u64int p, int zeros)
{
ulong d;

View file

@ -70,7 +70,7 @@ lget1(Map *map, Regs *regs, Loc loc, uchar *a, uint n)
int
lget2(Map *map, Regs *regs, Loc loc, u16int *u)
{
ulong ul;
u64int ul;
if(locsimplify(map, regs, loc, &loc) < 0)
return -1;
@ -93,7 +93,7 @@ lget2(Map *map, Regs *regs, Loc loc, u16int *u)
int
lget4(Map *map, Regs *regs, Loc loc, u32int *u)
{
ulong ul;
u64int ul;
if(locsimplify(map, regs, loc, &loc) < 0)
return -1;
@ -113,10 +113,23 @@ lget4(Map *map, Regs *regs, Loc loc, u32int *u)
return -1;
}
int
lgeta(Map *map, Regs *regs, Loc loc, u64int *u)
{
u32int v;
if(machcpu == &machamd64)
return lget8(map, regs, loc, u);
if(lget4(map, regs, loc, &v) < 0)
return -1;
*u = v;
return 4;
}
int
lget8(Map *map, Regs *regs, Loc loc, u64int *u)
{
ulong ul;
u64int ul;
if(locsimplify(map, regs, loc, &loc) < 0)
return -1;
@ -190,7 +203,7 @@ lput8(Map *map, Regs *regs, Loc loc, u64int u)
static Loc zl;
Loc
locaddr(ulong addr)
locaddr(u64int addr)
{
Loc l;
@ -214,7 +227,7 @@ locindir(char *reg, long offset)
}
Loc
locconst(ulong con)
locconst(u64int con)
{
Loc l;
@ -248,7 +261,7 @@ locreg(char *reg)
int
locsimplify(Map *map, Regs *regs, Loc loc, Loc *newloc)
{
ulong u;
u64int u;
if(loc.type == LOFFSET){
if(rget(regs, loc.reg, &u) < 0)

View file

@ -18,9 +18,9 @@ static struct {
} rock;
static int
ltrace(Map *map, Regs *regs, ulong pc, ulong nextpc, Symbol *sym, int depth)
ltrace(Map *map, Regs *regs, u64int pc, u64int nextpc, Symbol *sym, int depth)
{
ulong v;
u64int v;
Symbol s1;
USED(pc);
@ -49,7 +49,7 @@ ltrace(Map *map, Regs *regs, ulong pc, ulong nextpc, Symbol *sym, int depth)
}
int
localaddr(Map *map, Regs *regs, char *fn, char *var, ulong *val)
localaddr(Map *map, Regs *regs, char *fn, char *var, u64int *val)
{
Regdesc *rp;

File diff suppressed because it is too large Load diff

197
src/libmach/machamd64.c Normal file
View file

@ -0,0 +1,197 @@
// Inferno libmach/6.c
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/6.c
//
// Copyright © 1994-1999 Lucent Technologies Inc.
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
// Portions Copyright © 1997-1999 Vita Nuova Limited.
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
/*
* amd64 definition
*/
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#include "uregamd64.h"
char *i386excep(Map*, Regs*);
int i386foll(Map*, Regs*, u64int, u64int*);
int i386hexinst(Map*, u64int, char*, int);
int i386das(Map*, u64int, char, char*, int);
int i386instlen(Map*, u64int);
int i386unwind(Map*, Regs*, u64int*, Symbol*);
#define REGOFF(x) offsetof(struct Ureg, x)
#define REGSIZE sizeof(struct Ureg)
#define FP_CTLS(x) (REGSIZE+2*(x))
#define FP_CTL(x) (REGSIZE+4*(x))
#define FP_REG(x) (FP_CTL(8)+16*(x))
#define XM_REG(x) (FP_CTL(8)+8*16+16*(x))
#define FPREGSIZE 512 /* TO DO? currently only 0x1A0 used */
static Regdesc amd64reglist[] = {
{"AX", REGOFF(ax), RINT, 'Y'},
{"BX", REGOFF(bx), RINT, 'Y'},
{"CX", REGOFF(cx), RINT, 'Y'},
{"DX", REGOFF(dx), RINT, 'Y'},
{"SI", REGOFF(si), RINT, 'Y'},
{"DI", REGOFF(di), RINT, 'Y'},
{"BP", REGOFF(bp), RINT, 'Y'},
{"R8", REGOFF(r8), RINT, 'Y'},
{"R9", REGOFF(r9), RINT, 'Y'},
{"R10", REGOFF(r10), RINT, 'Y'},
{"R11", REGOFF(r11), RINT, 'Y'},
{"R12", REGOFF(r12), RINT, 'Y'},
{"R13", REGOFF(r13), RINT, 'Y'},
{"R14", REGOFF(r14), RINT, 'Y'},
{"R15", REGOFF(r15), RINT, 'Y'},
{"DS", REGOFF(ds), RINT, 'x'},
{"ES", REGOFF(es), RINT, 'x'},
{"FS", REGOFF(fs), RINT, 'x'},
{"GS", REGOFF(gs), RINT, 'x'},
{"TYPE", REGOFF(type), RINT, 'Y'},
{"TRAP", REGOFF(type), RINT, 'Y'}, /* alias for acid */
{"ERROR", REGOFF(error), RINT, 'Y'},
{"IP", REGOFF(ip), RINT, 'Y'},
{"PC", REGOFF(ip), RINT, 'Y'}, /* alias for acid */
{"CS", REGOFF(cs), RINT, 'Y'},
{"FLAGS", REGOFF(flags), RINT, 'Y'},
{"SP", REGOFF(sp), RINT, 'Y'},
{"SS", REGOFF(ss), RINT, 'Y'},
{"FCW", FP_CTLS(0), RFLT, 'x'},
{"FSW", FP_CTLS(1), RFLT, 'x'},
{"FTW", FP_CTLS(2), RFLT, 'b'},
{"FOP", FP_CTLS(3), RFLT, 'x'},
{"RIP", FP_CTL(2), RFLT, 'Y'},
{"RDP", FP_CTL(4), RFLT, 'Y'},
{"MXCSR", FP_CTL(6), RFLT, 'X'},
{"MXCSRMASK", FP_CTL(7), RFLT, 'X'},
{"M0", FP_REG(0), RFLT, 'F'}, /* assumes double */
{"M1", FP_REG(1), RFLT, 'F'},
{"M2", FP_REG(2), RFLT, 'F'},
{"M3", FP_REG(3), RFLT, 'F'},
{"M4", FP_REG(4), RFLT, 'F'},
{"M5", FP_REG(5), RFLT, 'F'},
{"M6", FP_REG(6), RFLT, 'F'},
{"M7", FP_REG(7), RFLT, 'F'},
{"X0", XM_REG(0), RFLT, 'F'}, /* assumes double */
{"X1", XM_REG(1), RFLT, 'F'},
{"X2", XM_REG(2), RFLT, 'F'},
{"X3", XM_REG(3), RFLT, 'F'},
{"X4", XM_REG(4), RFLT, 'F'},
{"X5", XM_REG(5), RFLT, 'F'},
{"X6", XM_REG(6), RFLT, 'F'},
{"X7", XM_REG(7), RFLT, 'F'},
{"X8", XM_REG(8), RFLT, 'F'},
{"X9", XM_REG(9), RFLT, 'F'},
{"X10", XM_REG(10), RFLT, 'F'},
{"X11", XM_REG(11), RFLT, 'F'},
{"X12", XM_REG(12), RFLT, 'F'},
{"X13", XM_REG(13), RFLT, 'F'},
{"X14", XM_REG(14), RFLT, 'F'},
{"X15", XM_REG(15), RFLT, 'F'},
{"X16", XM_REG(16), RFLT, 'F'},
/*
{"F0", FP_REG(7), RFLT, '3'},
{"F1", FP_REG(6), RFLT, '3'},
{"F2", FP_REG(5), RFLT, '3'},
{"F3", FP_REG(4), RFLT, '3'},
{"F4", FP_REG(3), RFLT, '3'},
{"F5", FP_REG(2), RFLT, '3'},
{"F6", FP_REG(1), RFLT, '3'},
{"F7", FP_REG(0), RFLT, '3'},
*/
{ 0 }
};
static char *amd64windregs[] = {
"PC",
"SP",
"BP",
"AX",
"CX",
"DX",
"BX",
"SI",
"DI",
"R8",
"R9",
"R10",
"R11",
"R12",
"R13",
"R14",
"R15",
0,
};
Mach machamd64=
{
"amd64",
MAMD64, /* machine type */
amd64reglist, /* register list */
REGSIZE, /* size of registers in bytes */
FPREGSIZE, /* size of fp registers in bytes */
"PC", /* name of PC */
"SP", /* name of SP */
"BP", /* name of FP */
0, /* link register */
"setSB", /* static base register name (bogus anyways) */
0, /* static base register value */
0x1000, /* page size */
0xFFFFFFFF80110000ULL, /* kernel base */
0xFFFF800000000000ULL, /* kernel text mask */
1, /* quantization of pc */
8, /* szaddr */
4, /* szreg */
4, /* szfloat */
8, /* szdouble */
amd64windregs, /* locations unwound in stack trace */
17,
{0xCC, 0, 0, 0}, /* break point: INT 3 */
1, /* break point size */
i386foll, /* following addresses */
i386excep, /* print exception */
i386unwind, /* stack unwind */
leswap2, /* convert short to local byte order */
leswap4, /* convert long to local byte order */
leswap8, /* convert vlong to local byte order */
leieeeftoa32, /* single precision float pointer */
leieeeftoa64, /* double precision float pointer */
leieeeftoa80, /* long double precision floating point */
i386das, /* dissembler */
i386das, /* plan9-format disassembler */
0, /* commercial disassembler */
i386hexinst, /* print instruction */
i386instlen, /* instruction size calculation */
};

View file

@ -14,10 +14,10 @@
*/
static char *powerexcep(Map*, Regs*);
static int powerfoll(Map*, Regs*, ulong, ulong*);
static int powerdas(Map*, ulong, char, char*, int);
static int powerinstlen(Map*, ulong);
static int powerhexinst(Map*, ulong, char*, int);
static int powerfoll(Map*, Regs*, u64int, u64int*);
static int powerdas(Map*, u64int, char, char*, int);
static int powerinstlen(Map*, u64int);
static int powerhexinst(Map*, u64int, char*, int);
static char *excname[] =
{
@ -59,7 +59,7 @@ static char *excname[] =
static char*
powerexcep(Map *map, Regs *regs)
{
ulong c;
u64int c;
static char buf[32];
if(rget(regs, "CAUSE", &c) < 0)
@ -130,7 +130,7 @@ typedef struct {
long immediate;
long w0;
long w1;
ulong addr; /* pc of instruction */
u64int addr; /* pc of instruction */
short target;
char *curr; /* current fill level in output buffer */
char *end; /* end of buffer */
@ -1155,14 +1155,14 @@ printins(Map *map, ulong pc, char *buf, int n)
}
static int
powerdas(Map *map, ulong pc, char modifier, char *buf, int n)
powerdas(Map *map, u64int pc, char modifier, char *buf, int n)
{
USED(modifier);
return printins(map, pc, buf, n);
}
static int
powerhexinst(Map *map, ulong pc, char *buf, int n)
powerhexinst(Map *map, u64int pc, char *buf, int n)
{
Instr instr;
@ -1183,7 +1183,7 @@ powerhexinst(Map *map, ulong pc, char *buf, int n)
}
static int
powerinstlen(Map *map, ulong pc)
powerinstlen(Map *map, u64int pc)
{
Instr i;
@ -1194,7 +1194,7 @@ powerinstlen(Map *map, ulong pc)
}
static int
powerfoll(Map *map, Regs *regs, ulong pc, ulong *foll)
powerfoll(Map *map, Regs *regs, u64int pc, u64int *foll)
{
char *reg;
Instr i;
@ -1337,7 +1337,7 @@ static char *powerwindregs[] =
};
static int
powerunwind(Map *map, Regs *regs, ulong *next, Symbol *sym)
powerunwind(Map *map, Regs *regs, u64int *next, Symbol *sym)
{
/*
* This is tremendously hard. The best we're going to

View file

@ -619,6 +619,9 @@ gccname(char **ps, char **pp)
break;
}
USED(p1);
USED(p0);
out:
*ps = s;
*pp = p;

View file

@ -6,10 +6,10 @@
#include <bio.h>
#include <mach.h>
static int fdrw(Map*, Seg*, ulong, void*, uint, int);
static int zerorw(Map*, Seg*, ulong, void*, uint, int);
static int mrw(Map*, ulong, void*, uint, int);
static int datarw(Map*, Seg*, ulong, void*, uint, int);
static int fdrw(Map*, Seg*, u64int, void*, uint, int);
static int zerorw(Map*, Seg*, u64int, void*, uint, int);
static int mrw(Map*, u64int, void*, uint, int);
static int datarw(Map*, Seg*, u64int, void*, uint, int);
Map*
allocmap(void)
@ -71,7 +71,7 @@ findseg(Map *map, char *name, char *file)
}
int
addrtoseg(Map *map, ulong addr, Seg *sp)
addrtoseg(Map *map, u64int addr, Seg *sp)
{
int i;
Seg *s;
@ -93,7 +93,7 @@ addrtoseg(Map *map, ulong addr, Seg *sp)
}
int
addrtosegafter(Map *map, ulong addr, Seg *sp)
addrtosegafter(Map *map, u64int addr, Seg *sp)
{
int i;
Seg *s, *best;
@ -142,13 +142,13 @@ removeseg(Map *map, int i)
}
int
get1(Map *map, ulong addr, uchar *a, uint n)
get1(Map *map, u64int addr, uchar *a, uint n)
{
return mrw(map, addr, a, n, 1);
}
int
get2(Map *map, ulong addr, u16int *u)
get2(Map *map, u64int addr, u16int *u)
{
u16int v;
@ -159,7 +159,7 @@ get2(Map *map, ulong addr, u16int *u)
}
int
get4(Map *map, ulong addr, u32int *u)
get4(Map *map, u64int addr, u32int *u)
{
u32int v;
@ -170,7 +170,7 @@ get4(Map *map, ulong addr, u32int *u)
}
int
get8(Map *map, ulong addr, u64int *u)
get8(Map *map, u64int addr, u64int *u)
{
u64int v;
@ -181,34 +181,47 @@ get8(Map *map, ulong addr, u64int *u)
}
int
put1(Map *map, ulong addr, uchar *a, uint n)
geta(Map *map, u64int addr, u64int *u)
{
u32int v;
if(machcpu == &machamd64)
return get8(map, addr, u);
if(get4(map, addr, &v) < 0)
return -1;
*u = v;
return 4;
}
int
put1(Map *map, u64int addr, uchar *a, uint n)
{
return mrw(map, addr, a, n, 0);
}
int
put2(Map *map, ulong addr, u16int u)
put2(Map *map, u64int addr, u16int u)
{
u = mach->swap2(u);
return mrw(map, addr, &u, 2, 0);
}
int
put4(Map *map, ulong addr, u32int u)
put4(Map *map, u64int addr, u32int u)
{
u = mach->swap4(u);
return mrw(map, addr, &u, 4, 0);
}
int
put8(Map *map, ulong addr, u64int u)
put8(Map *map, u64int addr, u64int u)
{
u = mach->swap8(u);
return mrw(map, addr, &u, 8, 0);
}
static Seg*
reloc(Map *map, ulong addr, uint n, ulong *off, uint *nn)
reloc(Map *map, u64int addr, uint n, u64int *off, uint *nn)
{
int i;
ulong o;
@ -236,12 +249,12 @@ reloc(Map *map, ulong addr, uint n, ulong *off, uint *nn)
}
static int
mrw(Map *map, ulong addr, void *a, uint n, int r)
mrw(Map *map, u64int addr, void *a, uint n, int r)
{
uint nn;
uint tot;
Seg *s;
ulong off;
u64int off;
for(tot=0; tot<n; tot+=nn){
s = reloc(map, addr+tot, n-tot, &off, &nn);
@ -254,7 +267,7 @@ mrw(Map *map, ulong addr, void *a, uint n, int r)
}
static int
fdrw(Map *map, Seg *seg, ulong addr, void *a, uint n, int r)
fdrw(Map *map, Seg *seg, u64int addr, void *a, uint n, int r)
{
int nn;
uint tot;
@ -279,7 +292,7 @@ fdrw(Map *map, Seg *seg, ulong addr, void *a, uint n, int r)
}
static int
zerorw(Map *map, Seg *seg, ulong addr, void *a, uint n, int r)
zerorw(Map *map, Seg *seg, u64int addr, void *a, uint n, int r)
{
USED(map);
USED(seg);
@ -294,7 +307,7 @@ zerorw(Map *map, Seg *seg, ulong addr, void *a, uint n, int r)
}
static int
datarw(Map *map, Seg *seg, ulong addr, void *a, uint n, int r)
datarw(Map *map, Seg *seg, u64int addr, void *a, uint n, int r)
{
USED(map);

View file

@ -20,6 +20,7 @@ OFILES=\
elf.$O\
elfdl386.$O\
elfcorefreebsd386.$O\
elfcorefreebsdamd64.$O\
elfcorelinux386.$O\
frame.$O\
fpformat.$O\
@ -28,6 +29,7 @@ OFILES=\
loc.$O\
localaddr.$O\
mach386.$O\
machamd64.$O\
macho.$O\
machocorepower.$O\
machpower.$O\

View file

@ -14,7 +14,7 @@ regdesc(char *name)
}
int
rput(Regs *regs, char *name, ulong u)
rput(Regs *regs, char *name, u64int u)
{
if(regs == nil){
werrstr("registers not mapped");
@ -24,7 +24,7 @@ rput(Regs *regs, char *name, ulong u)
}
int
rget(Regs *regs, char *name, ulong *u)
rget(Regs *regs, char *name, u64int *u)
{
if(regs == nil){
*u = ~(ulong)0;
@ -35,7 +35,7 @@ rget(Regs *regs, char *name, ulong *u)
}
int
_uregrw(Regs *regs, char *name, ulong *u, int isr)
_uregrw(Regs *regs, char *name, u64int *u, int isr)
{
Regdesc *r;
uchar *ureg;

View file

@ -69,7 +69,7 @@ findhdr(char *name)
}
int
pc2file(ulong pc, char *file, uint nfile, ulong *line)
pc2file(u64int pc, char *file, uint nfile, ulong *line)
{
Fhdr *p;
@ -81,14 +81,14 @@ pc2file(ulong pc, char *file, uint nfile, ulong *line)
}
int
pc2line(ulong pc, ulong *line)
pc2line(u64int pc, ulong *line)
{
char tmp[10]; /* just in case */
return pc2file(pc, tmp, sizeof tmp, line);
}
int
file2pc(char *file, ulong line, ulong *addr)
file2pc(char *file, ulong line, u64int *addr)
{
Fhdr *p;
@ -102,7 +102,7 @@ file2pc(char *file, ulong line, ulong *addr)
}
int
line2pc(ulong basepc, ulong line, ulong *pc)
line2pc(u64int basepc, ulong line, u64int *pc)
{
Fhdr *p;
@ -116,7 +116,7 @@ line2pc(ulong basepc, ulong line, ulong *pc)
}
int
fnbound(ulong pc, ulong *bounds)
fnbound(u64int pc, u64int *bounds)
{
Fhdr *p;
Loc l;
@ -143,7 +143,7 @@ fnbound(ulong pc, ulong *bounds)
}
int
fileline(ulong pc, char *a, uint n)
fileline(u64int pc, char *a, uint n)
{
ulong line;
@ -408,7 +408,7 @@ findlsym(Symbol *s1, Loc loc, Symbol *s2)
}
int
unwindframe(Map *map, Regs *regs, ulong *next, Symbol *sym)
unwindframe(Map *map, Regs *regs, u64int *next, Symbol *sym)
{
Fhdr *p;
@ -421,7 +421,7 @@ unwindframe(Map *map, Regs *regs, ulong *next, Symbol *sym)
}
int
symoff(char *a, uint n, ulong addr, uint class)
symoff(char *a, uint n, u64int addr, uint class)
{
Loc l;
Symbol s;

View file

@ -6,14 +6,14 @@
#include "dwarf.h"
static void dwarfsymclose(Fhdr*);
static int dwarfpc2file(Fhdr*, ulong, char*, uint, ulong*);
static int dwarfline2pc(Fhdr*, ulong, ulong, ulong*);
static int dwarfpc2file(Fhdr*, u64int, char*, uint, ulong*);
static int dwarfline2pc(Fhdr*, u64int, ulong, u64int*);
static int dwarflookuplsym(Fhdr*, Symbol*, char*, Symbol*);
static int dwarfindexlsym(Fhdr*, Symbol*, uint, Symbol*);
static int dwarffindlsym(Fhdr*, Symbol*, Loc, Symbol*);
static void dwarfsyminit(Fhdr*);
static int dwarftosym(Fhdr*, Dwarf*, DwarfSym*, Symbol*, int);
static int _dwarfunwind(Fhdr *fhdr, Map *map, Regs *regs, ulong *next, Symbol*);
static int _dwarfunwind(Fhdr *fhdr, Map *map, Regs *regs, u64int *next, Symbol*);
int
symdwarf(Fhdr *hdr)
@ -43,7 +43,7 @@ dwarfsymclose(Fhdr *hdr)
}
static int
dwarfpc2file(Fhdr *fhdr, ulong pc, char *buf, uint nbuf, ulong *line)
dwarfpc2file(Fhdr *fhdr, u64int pc, char *buf, uint nbuf, ulong *line)
{
char *cdir, *dir, *file;
@ -61,7 +61,7 @@ dwarfpc2file(Fhdr *fhdr, ulong pc, char *buf, uint nbuf, ulong *line)
}
static int
dwarfline2pc(Fhdr *fhdr, ulong basepc, ulong line, ulong *pc)
dwarfline2pc(Fhdr *fhdr, u64int basepc, ulong line, u64int *pc)
{
werrstr("dwarf line2pc not implemented");
return -1;
@ -323,11 +323,11 @@ dwarftosym(Fhdr *fp, Dwarf *d, DwarfSym *ds, Symbol *s, int infn)
}
static int
dwarfeval(Dwarf *d, Map *map, Regs *regs, ulong cfa, int rno, DwarfExpr e, ulong *u)
dwarfeval(Dwarf *d, Map *map, Regs *regs, ulong cfa, int rno, DwarfExpr e, u64int *u)
{
int i;
u32int u4;
ulong uu;
u64int uu;
switch(e.type){
case RuleUndef:
@ -396,11 +396,11 @@ dwarfexprfmt(Fmt *fmt)
#endif
static int
_dwarfunwind(Fhdr *fhdr, Map *map, Regs *regs, ulong *next, Symbol *sym)
_dwarfunwind(Fhdr *fhdr, Map *map, Regs *regs, u64int *next, Symbol *sym)
{
char *name;
int i, j;
ulong cfa, pc, u;
u64int cfa, pc, u;
Dwarf *d;
DwarfExpr *e, epc, ecfa;

View file

@ -254,6 +254,7 @@ stabssyminit(Fhdr *fp)
break;
}
}
USED(locals);
free(inc);
return 0;
@ -263,7 +264,7 @@ err:
}
static int
stabspc2file(Fhdr *fhdr, ulong pc, char *buf, uint nbuf, ulong *pline)
stabspc2file(Fhdr *fhdr, u64int pc, char *buf, uint nbuf, ulong *pline)
{
int i;
Symbol *s;
@ -298,7 +299,7 @@ stabspc2file(Fhdr *fhdr, ulong pc, char *buf, uint nbuf, ulong *pline)
}
static int
stabsline2pc(Fhdr *fhdr, ulong startpc, ulong line, ulong *pc)
stabsline2pc(Fhdr *fhdr, u64int startpc, ulong line, u64int *pc)
{
int i, trigger;
Symbol *s;

58
src/libmach/uregamd64.h Normal file
View file

@ -0,0 +1,58 @@
// Inferno utils/libmach/ureg6.h
// http://code.google.com/p/inferno-os/source/browse/utils/libmach/ureg6.h
//
// Copyright © 1994-1999 Lucent Technologies Inc.
// Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
// Portions Copyright © 1997-1999 Vita Nuova Limited.
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
// Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
// Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
struct Ureg {
u64int ax;
u64int bx;
u64int cx;
u64int dx;
u64int si;
u64int di;
u64int bp;
u64int r8;
u64int r9;
u64int r10;
u64int r11;
u64int r12;
u64int r13;
u64int r14;
u64int r15;
u16int ds;
u16int es;
u16int fs;
u16int gs;
u64int type;
u64int error; /* error code (or zero) */
u64int ip; /* pc */
u64int cs; /* old context */
u64int flags; /* old flags */
u64int sp; /* sp */
u64int ss; /* old stack segment */
};