#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#include "elf.h"
#include "dwarf.h"

static void	dwarfsymclose(Fhdr*);
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, u64int *next, Symbol*);

int
symdwarf(Fhdr *hdr)
{
	if(hdr->dwarf == nil){
		werrstr("no dwarf debugging symbols");
		return -1;
	}

	hdr->symclose = dwarfsymclose;
	hdr->pc2file = dwarfpc2file;
	hdr->line2pc = dwarfline2pc;
	hdr->lookuplsym = dwarflookuplsym;
	hdr->indexlsym = dwarfindexlsym;
	hdr->findlsym = dwarffindlsym;
	hdr->unwind = _dwarfunwind;
	dwarfsyminit(hdr);

	return 0;
}

static void
dwarfsymclose(Fhdr *hdr)
{
	dwarfclose(hdr->dwarf);
	hdr->dwarf = nil;
}

static int
dwarfpc2file(Fhdr *fhdr, u64int pc, char *buf, uint nbuf, ulong *line)
{
	char *cdir, *dir, *file;

	if(dwarfpctoline(fhdr->dwarf, pc, &cdir, &dir, &file, line, nil, nil) < 0)
		return -1;

	if(file[0] == '/' || (dir==nil && cdir==nil))
		strecpy(buf, buf+nbuf, file);
	else if((dir && dir[0] == '/') || cdir==nil)
		snprint(buf, nbuf, "%s/%s", dir, file);
	else
		snprint(buf, nbuf, "%s/%s/%s", cdir, dir ? dir : "", file);
	cleanname(buf);
	return 0;;
}

static int
dwarfline2pc(Fhdr *fhdr, u64int basepc, ulong line, u64int *pc)
{
	werrstr("dwarf line2pc not implemented");
	return -1;
}

static uint
typesize(Dwarf *dwarf, ulong unit, ulong tref, char *name)
{
	DwarfSym ds;

top:
	if(dwarfseeksym(dwarf, unit, tref-unit, &ds) < 0){
	cannot:
		fprint(2, "warning: cannot compute size of parameter %s (%lud %lud: %r)\n",
			name, unit, tref);
		return 0;
	}
	
	if(ds.attrs.have.bytesize)
		return ds.attrs.bytesize;

	switch(ds.attrs.tag){
	case TagVolatileType:
	case TagRestrictType:
	case TagTypedef:
		if(ds.attrs.have.type != TReference)
			goto cannot;
		tref = ds.attrs.type;
		goto top;
	}

	goto cannot;
}

static int
roundup(int s, int n)
{
	return (s+n-1)&~(n-1);
}

static int
dwarflenum(Fhdr *fhdr, Symbol *p, char *name, uint j, Loc l, Symbol *s)
{
	int depth, bpoff;
	DwarfSym ds;
	Symbol s1;

	if(p == nil)
		return -1;

	if(p->u.dwarf.unit == 0 && p->u.dwarf.uoff == 0)
		return -1;

	if(dwarfseeksym(fhdr->dwarf, p->u.dwarf.unit, p->u.dwarf.uoff, &ds) < 0)
		return -1;

	ds.depth = 1;
	depth = 1;

	bpoff = 8;
	while(dwarfnextsym(fhdr->dwarf, &ds) == 1 && depth < ds.depth){
		if(ds.attrs.tag != TagVariable){
			if(ds.attrs.tag != TagFormalParameter
			&& ds.attrs.tag != TagUnspecifiedParameters)
				continue;
			if(ds.depth != depth+1)
				continue;
		}
		if(dwarftosym(fhdr, fhdr->dwarf, &ds, &s1, 1) < 0)
			continue;
		/* XXX move this out once there is another architecture */
		/*
		 * gcc tells us the registers where the parameters might be
		 * held for an instruction or two.  use the parameter list to
		 * recompute the actual stack locations.
		 */
		if(fhdr->mtype == M386)
		if(ds.attrs.tag==TagFormalParameter || ds.attrs.tag==TagUnspecifiedParameters){
			if(s1.loc.type==LOFFSET
			&& strcmp(s1.loc.reg, "BP")==0
			&& s1.loc.offset >= 8)
				bpoff = s1.loc.offset;
			else{
				s1.loc.type = LOFFSET;
				s1.loc.reg = "BP";
				s1.loc.offset = bpoff;
			}
			if(ds.attrs.tag == TagFormalParameter){
				if(ds.attrs.have.type)
					bpoff += roundup(typesize(fhdr->dwarf, p->u.dwarf.unit, ds.attrs.type, s1.name), 4);
				else
					fprint(2, "warning: cannot compute size of parameter %s\n", s1.name);
			}
		}
		if(name){
			if(strcmp(ds.attrs.name, name) != 0)
				continue;
		}else if(l.type){
			if(loccmp(&s1.loc, &l) != 0)
				continue;
		}else{
			if(j-- > 0)
				continue;
		}
		*s = s1;
		return 0;
	}
	return -1;
}

static Loc zl;

static int
dwarflookuplsym(Fhdr *fhdr, Symbol *p, char *name, Symbol *s)
{
	return dwarflenum(fhdr, p, name, 0, zl, s);
}

static int
dwarfindexlsym(Fhdr *fhdr, Symbol *p, uint i, Symbol *s)
{
	return dwarflenum(fhdr, p, nil, i, zl, s);
}

static int
dwarffindlsym(Fhdr *fhdr, Symbol *p, Loc l, Symbol *s)
{
	return dwarflenum(fhdr, p, nil, 0, l, s);
}

static void
dwarfsyminit(Fhdr *fp)
{
	Dwarf *d;
	DwarfSym s;
	Symbol sym;

	d = fp->dwarf;
	if(dwarfenum(d, &s) < 0)
		return;

	while(dwarfnextsymat(d, &s, 0) == 1)
	while(dwarfnextsymat(d, &s, 1) == 1){
		if(s.attrs.name == nil)
			continue;
		switch(s.attrs.tag){
		case TagSubprogram:
		case TagVariable:
			if(dwarftosym(fp, d, &s, &sym, 0) < 0)
				continue;
			_addsym(fp, &sym);
		}
	}
}

static char*
regname(Dwarf *d, int i)
{
	if(i < 0 || i >= d->nreg)
		return nil;
	return d->reg[i];
}

static int
dwarftosym(Fhdr *fp, Dwarf *d, DwarfSym *ds, Symbol *s, int infn)
{
	DwarfBuf buf;
	DwarfBlock b;
	
	memset(s, 0, sizeof *s);
	s->u.dwarf.uoff = ds->uoff;
	s->u.dwarf.unit = ds->unit;
	switch(ds->attrs.tag){
	default:
		return -1;
	case TagUnspecifiedParameters:
		ds->attrs.name = "...";
		s->type = 'p';
		goto sym;
	case TagFormalParameter:
		s->type = 'p';
		s->class = CPARAM;
		goto sym;
	case TagSubprogram:
		s->type = 't';
		s->class = CTEXT;
		goto sym;
	case TagVariable:
		if(infn){
			s->type = 'a';
			s->class = CAUTO;
		}else{
			s->type = 'd';
			s->class = CDATA;
		}
	sym:
		s->name = ds->attrs.name;
		if(ds->attrs.have.lowpc){
			s->loc.type = LADDR;
			s->loc.addr = ds->attrs.lowpc;
			if(ds->attrs.have.highpc){
				s->hiloc.type = LADDR;
				s->hiloc.addr = ds->attrs.highpc;
			}
		}else if(ds->attrs.have.location == TConstant){
			s->loc.type = LADDR;
			s->loc.addr = ds->attrs.location.c;
		}else if(ds->attrs.have.location == TBlock){
			b = ds->attrs.location.b;
			if(b.len == 0)
				return -1;
			buf.p = b.data+1;
			buf.ep = b.data+b.len;
			buf.d = d;
			buf.addrsize = 0;
			if(b.data[0]==OpAddr){
				if(b.len != 5)
					return -1;
				s->loc.type = LADDR;
				s->loc.addr = dwarfgetaddr(&buf);
			}else if(OpReg0 <= b.data[0] && b.data[0] < OpReg0+0x20){
				if(b.len != 1 || (s->loc.reg = regname(d, b.data[0]-OpReg0)) == nil)
					return -1;
				s->loc.type = LREG;
			}else if(OpBreg0 <= b.data[0] && b.data[0] < OpBreg0+0x20){
				s->loc.type = LOFFSET;
				s->loc.reg = regname(d, b.data[0]-0x70);
				s->loc.offset = dwarfget128s(&buf);
				if(s->loc.reg == nil)
					return -1;
			}else if(b.data[0] == OpRegx){
				s->loc.type = LREG;
				s->loc.reg = regname(d, dwarfget128(&buf));
				if(s->loc.reg == nil)
					return -1;
			}else if(b.data[0] == OpFbreg){
				s->loc.type = LOFFSET;
				s->loc.reg = mach->fp;
				s->loc.offset = dwarfget128s(&buf);
			}else if(b.data[0] == OpBregx){
				s->loc.type = LOFFSET;
				s->loc.reg = regname(d, dwarfget128(&buf));
				s->loc.offset = dwarfget128s(&buf);
				if(s->loc.reg == nil)
					return -1;
			}else
				s->loc.type = LNONE;
			if(buf.p != buf.ep)
				s->loc.type = LNONE;
		}else
			return -1;
		if(ds->attrs.isexternal)
			s->type += 'A' - 'a';
		if(ds->attrs.tag==TagVariable && s->loc.type==LADDR && s->loc.addr>=fp->dataddr+fp->datsz)
			s->type += 'b' - 'd';
		s->fhdr = fp;
		return 0;
	}
}

static int
dwarfeval(Dwarf *d, Map *map, Regs *regs, ulong cfa, int rno, DwarfExpr e, u64int *u)
{
	int i;
	u32int u4;
	u64int uu;

	switch(e.type){
	case RuleUndef:
		*u = 0;
		return 0;
	case RuleSame:
		if(rno == -1){
			werrstr("pc cannot be `same'");
			return -1;
		}
		return rget(regs, regname(d, rno), u);
	case RuleRegister:
		if((i = windindex(regname(d, e.reg))) < 0)
			return -1;
		return rget(regs, regname(d, i), u);
	case RuleCfaOffset:
		if(cfa == 0){
			werrstr("unknown cfa");
			return -1;
		}
		if(get4(map, cfa + e.offset, &u4) < 0)
			return -1;
		*u = u4;
		return 0;
	case RuleRegOff:
		if(rget(regs, regname(d, e.reg), &uu) < 0)
			return -1;
		if(get4(map, uu+e.offset, &u4) < 0)
			return -1;	
		*u = u4;
		return 0;
	case RuleLocation:
		werrstr("not evaluating dwarf loc expressions");
		return -1;
	}
	werrstr("not reached in dwarfeval");
	return -1;
}

#if 0
static int
dwarfexprfmt(Fmt *fmt)
{
	DwarfExpr *e;

	if((e = va_arg(fmt->args, DwarfExpr*)) == nil)
		return fmtstrcpy(fmt, "<nil>");

	switch(e->type){
	case RuleUndef:
		return fmtstrcpy(fmt, "undef");
	case RuleSame:
		return fmtstrcpy(fmt, "same");
	case RuleCfaOffset:
		return fmtprint(fmt, "%ld(cfa)", e->offset);
	case RuleRegister:
		return fmtprint(fmt, "r%ld", e->reg);
	case RuleRegOff:
		return fmtprint(fmt, "%ld(r%ld)", e->offset, e->reg);
	case RuleLocation:
		return fmtprint(fmt, "l.%.*H", e->loc.len, e->loc.data);
	default:
		return fmtprint(fmt, "?%d", e->type);
	}
}
#endif

static int
_dwarfunwind(Fhdr *fhdr, Map *map, Regs *regs, u64int *next, Symbol *sym)
{
	char *name;
	int i, j;
	u64int cfa, pc, u;
	Dwarf *d;
	DwarfExpr *e, epc, ecfa;


	/*
	 * Use dwarfunwind to tell us what to do.
	 */
	d = fhdr->dwarf;
	e = malloc(d->nreg*sizeof(e[0]));
	if(e == nil)
		return -1;
	if(rget(regs, mach->pc, &pc) < 0)
		goto err;
	if(dwarfunwind(d, pc, &ecfa, &epc, e, d->nreg) < 0)
		goto err;

	/*
	 * Compute CFA.
	 */
	switch(ecfa.type){
	default:
		werrstr("invalid call-frame-address in _dwarfunwind");
		goto err;
	case RuleRegister:
		ecfa.offset = 0;
	case RuleRegOff:
		if((name = regname(d, ecfa.reg)) == nil){
			werrstr("invalid call-frame-address register %d", (int)ecfa.reg);
			goto err;
		}
		if(rget(regs, name, &cfa) < 0){
			werrstr("fetching %s for call-frame-address: %r", name);
			goto err;
		}
		cfa += ecfa.offset;
	}

	/*
	 * Compute registers.
	 */
	for(i=0; i<d->nreg; i++){
		j = windindex(d->reg[i]);
		if(j == -1)
			continue;
		if(dwarfeval(d, map, regs, cfa, i, e[i], &u) < 0)
			u = ~(ulong)0;
		next[j] = u;
	}

	/*
	 * Compute caller pc
	 */
	if(dwarfeval(d, map, regs, cfa, -1, epc, &u) < 0){
		werrstr("computing caller %s: %r", mach->pc);
		goto err;
	}
	next[windindex(mach->pc)] = u;
	free(e);
	return 0;

err:
	free(e);
	return -1;
}

