/*
 * Dwarf info parse and search.
 */

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

enum
{
	DwarfAttrSibling = 0x01,
	DwarfAttrLocation = 0x02,
	DwarfAttrName = 0x03,
	DwarfAttrOrdering = 0x09,
	DwarfAttrByteSize = 0x0B,
	DwarfAttrBitOffset = 0x0C,
	DwarfAttrBitSize = 0x0D,
	DwarfAttrStmtList = 0x10,
	DwarfAttrLowpc = 0x11,
	DwarfAttrHighpc = 0x12,
	DwarfAttrLanguage = 0x13,
	DwarfAttrDiscr = 0x15,
	DwarfAttrDiscrValue = 0x16,
	DwarfAttrVisibility = 0x17,
	DwarfAttrImport = 0x18,
	DwarfAttrStringLength = 0x19,
	DwarfAttrCommonRef = 0x1A,
	DwarfAttrCompDir = 0x1B,
	DwarfAttrConstValue = 0x1C,
	DwarfAttrContainingType = 0x1D,
	DwarfAttrDefaultValue = 0x1E,
	DwarfAttrInline = 0x20,
	DwarfAttrIsOptional = 0x21,
	DwarfAttrLowerBound = 0x22,
	DwarfAttrProducer = 0x25,
	DwarfAttrPrototyped = 0x27,
	DwarfAttrReturnAddr = 0x2A,
	DwarfAttrStartScope = 0x2C,
	DwarfAttrStrideSize = 0x2E,
	DwarfAttrUpperBound = 0x2F,
	DwarfAttrAbstractOrigin = 0x31,
	DwarfAttrAccessibility = 0x32,
	DwarfAttrAddrClass = 0x33,
	DwarfAttrArtificial = 0x34,
	DwarfAttrBaseTypes = 0x35,
	DwarfAttrCalling = 0x36,
	DwarfAttrCount = 0x37,
	DwarfAttrDataMemberLoc = 0x38,
	DwarfAttrDeclColumn = 0x39,
	DwarfAttrDeclFile = 0x3A,
	DwarfAttrDeclLine = 0x3B,
	DwarfAttrDeclaration = 0x3C,
	DwarfAttrDiscrList = 0x3D,
	DwarfAttrEncoding = 0x3E,
	DwarfAttrExternal = 0x3F,
	DwarfAttrFrameBase = 0x40,
	DwarfAttrFriend = 0x41,
	DwarfAttrIdentifierCase = 0x42,
	DwarfAttrMacroInfo = 0x43,
	DwarfAttrNamelistItem = 0x44,
	DwarfAttrPriority = 0x45,
	DwarfAttrSegment = 0x46,
	DwarfAttrSpecification = 0x47,
	DwarfAttrStaticLink = 0x48,
	DwarfAttrType = 0x49,
	DwarfAttrUseLocation = 0x4A,
	DwarfAttrVarParam = 0x4B,
	DwarfAttrVirtuality = 0x4C,
	DwarfAttrVtableElemLoc = 0x4D,
	DwarfAttrAllocated = 0x4E,
	DwarfAttrAssociated = 0x4F,
	DwarfAttrDataLocation = 0x50,
	DwarfAttrStride = 0x51,
	DwarfAttrEntrypc = 0x52,
	DwarfAttrUseUTF8 = 0x53,
	DwarfAttrExtension = 0x54,
	DwarfAttrRanges = 0x55,
	DwarfAttrTrampoline = 0x56,
	DwarfAttrCallColumn = 0x57,
	DwarfAttrCallFile = 0x58,
	DwarfAttrCallLine = 0x59,
	DwarfAttrDescription = 0x5A,
	DwarfAttrMax,

	FormAddr = 0x01,
	FormDwarfBlock2 = 0x03,
	FormDwarfBlock4 = 0x04,
	FormData2 = 0x05,
	FormData4 = 0x06,
	FormData8 = 0x07,
	FormString = 0x08,
	FormDwarfBlock = 0x09,
	FormDwarfBlock1 = 0x0A,
	FormData1 = 0x0B,
	FormFlag = 0x0C,
	FormSdata = 0x0D,
	FormStrp = 0x0E,
	FormUdata = 0x0F,
	FormRefAddr = 0x10,
	FormRef1 = 0x11,
	FormRef2 = 0x12,
	FormRef4 = 0x13,
	FormRef8 = 0x14,
	FormRefUdata = 0x15,
	FormIndirect = 0x16,
};

static int parseattrs(DwarfBuf*, ulong, DwarfAbbrev*, DwarfAttrs*);
static int getulong(DwarfBuf*, int, ulong, ulong*, int*);
static int getuchar(DwarfBuf*, int, uchar*);
static int getstring(DwarfBuf*, int, char**);
static int getblock(DwarfBuf*, int, DwarfBlock*);
static int skipform(DwarfBuf*, int);
static int constblock(Dwarf*, DwarfBlock*, ulong*);

int
dwarflookupnameinunit(Dwarf *d, ulong unit, char *name, DwarfSym *s)
{
	if(dwarfenumunit(d, unit, s) < 0)
		return -1;

	dwarfnextsymat(d, s, 0);	/* s is now the CompileUnit */
	while(dwarfnextsymat(d, s, 1) == 1)
		if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
			return 0;
	werrstr("symbol '%s' not found", name);
	return -1;
}
	

int
dwarflookupsubname(Dwarf *d, DwarfSym *parent, char *name, DwarfSym *s)
{
	*s = *parent;
	while(dwarfnextsymat(d, s, parent->depth+1))
		if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
			return 0;
	werrstr("symbol '%s' not found", name);
	return -1;
}

int
dwarflookuptag(Dwarf *d, ulong unit, ulong tag, DwarfSym *s)
{
	if(dwarfenumunit(d, unit, s) < 0)
		return -1;

	dwarfnextsymat(d, s, 0);	/* s is now the CompileUnit */
	if(s->attrs.tag == tag)
		return 0;
	while(dwarfnextsymat(d, s, 1) == 1)
		if(s->attrs.tag == tag)
			return 0;
	werrstr("symbol with tag 0x%lux not found", tag);
	return -1;
}

int
dwarfseeksym(Dwarf *d, ulong unit, ulong off, DwarfSym *s)
{
	if(dwarfenumunit(d, unit, s) < 0)
		return -1;
	s->b.p = d->info.data + unit + off;
	if(dwarfnextsymat(d, s, 0) != 1)
		return -1;
	return 0;
}

int
dwarflookupfn(Dwarf *d, ulong unit, ulong pc, DwarfSym *s)
{
	if(dwarfenumunit(d, unit, s) < 0)
		return -1;

	if(dwarfnextsymat(d, s, 0) != 1)
		return -1;
	/* s is now the CompileUnit */

	while(dwarfnextsymat(d, s, 1) == 1){
		if(s->attrs.tag != TagSubprogram)
			continue;
		if(s->attrs.lowpc <= pc && pc < s->attrs.highpc)
			return 0;
	} 
	werrstr("fn containing pc 0x%lux not found", pc);
	return -1;
}

int
dwarfenumunit(Dwarf *d, ulong unit, DwarfSym *s)
{
	int i;
	ulong aoff, len;

	if(unit >= d->info.len){
		werrstr("dwarf unit address 0x%lux >= 0x%lux out of range", unit, d->info.len);
		return -1;
	}
	memset(s, 0, sizeof *s);
	memset(&s->b, 0, sizeof s->b);
	s->b.d = d;
	s->b.p = d->info.data + unit;
	s->b.ep = d->info.data + d->info.len;
	len = dwarfget4(&s->b);
	s->nextunit = unit + 4 + len;

	if(s->b.ep - s->b.p < len){
	badheader:
		werrstr("bad dwarf unit header at unit 0x%lux", unit);
		return -1;
	}
	s->b.ep = s->b.p+len;
	if((i=dwarfget2(&s->b)) != 2)
		goto badheader;
	aoff = dwarfget4(&s->b);
	s->b.addrsize = dwarfget1(&s->b);
	if(d->addrsize == 0)
		d->addrsize = s->b.addrsize;
	if(s->b.p == nil)
		goto badheader;

	s->aoff = aoff;
	s->unit = unit;
	s->depth = 0;
	return 0;
}

int
dwarfenum(Dwarf *d, DwarfSym *s)
{
	if(dwarfenumunit(d, 0, s) < 0)
		return -1;
	s->allunits = 1;
	return 0;
}

int
dwarfnextsym(Dwarf *d, DwarfSym *s)
{
	ulong num;
	DwarfAbbrev *a;

	if(s->attrs.haskids)
		s->depth++;
top:
	if(s->b.p >= s->b.ep){
		if(s->allunits && s->nextunit < d->info.len){
			if(dwarfenumunit(d, s->nextunit, s) < 0)
				return -1;
			s->allunits = 1;
			goto top;
		}
		return 0;
	}

	s->uoff = s->b.p - (d->info.data+s->unit);
	num = dwarfget128(&s->b);
	if(num == 0){
		if(s->depth == 0)
			return 0;
		if(s->depth > 0)
			s->depth--;
		goto top;
	}

	a = dwarfgetabbrev(d, s->aoff, num);
	if(a == nil){
		fprint(2, "getabbrev %ud %ud for %ud,%ud: %r\n", s->aoff, num, s->unit, s->uoff);
		abort();
		return -1;
	}
	if(parseattrs(&s->b, s->unit, a, &s->attrs) < 0)
		return -1;
	return 1;
}

int
dwarfnextsymat(Dwarf *d, DwarfSym *s, int depth)
{
	int r;
	DwarfSym t;
	uint sib;

	if(s->depth == depth && s->attrs.have.sibling){
		sib = s->attrs.sibling;
		if(sib < d->info.len && d->info.data+sib >= s->b.p)
			s->b.p = d->info.data+sib;
		s->attrs.haskids = 0;
	}

	/*
	 * The funny game with t and s make sure that 
	 * if we get to the end of a run of a particular
	 * depth, we leave s so that a call to nextsymat with depth-1
	 * will actually produce the desired guy.  We could change
	 * the interface to dwarfnextsym instead, but I'm scared 
	 * to touch it.
	 */
	t = *s;
	for(;;){
		if((r = dwarfnextsym(d, &t)) != 1)
			return r;
		if(t.depth < depth){
			/* went too far - nothing to see */
			return 0;
		}
		*s = t;
		if(t.depth == depth)
			return 1;
	}
}

typedef struct Parse Parse;
struct Parse {
	int name;
	int off;
	int haveoff;
	int type;
};

#define OFFSET(x) offsetof(DwarfAttrs, x), offsetof(DwarfAttrs, have.x)

static Parse plist[] = {	/* Font Tab 4 */
	DwarfAttrAbstractOrigin,	OFFSET(abstractorigin),		TReference,
	DwarfAttrAccessibility,	OFFSET(accessibility),		TConstant,
	DwarfAttrAddrClass, 		OFFSET(addrclass), 			TConstant,
	DwarfAttrArtificial,		OFFSET(isartificial), 		TFlag,
	DwarfAttrBaseTypes,		OFFSET(basetypes),			TReference,
	DwarfAttrBitOffset,		OFFSET(bitoffset),			TConstant,
	DwarfAttrBitSize,		OFFSET(bitsize),			TConstant,
	DwarfAttrByteSize,		OFFSET(bytesize),			TConstant,
	DwarfAttrCalling,		OFFSET(calling),			TConstant,
	DwarfAttrCommonRef,		OFFSET(commonref),			TReference,
	DwarfAttrCompDir,		OFFSET(compdir),			TString,
	DwarfAttrConstValue,		OFFSET(constvalue),			TString|TConstant|TBlock,
	DwarfAttrContainingType,	OFFSET(containingtype),		TReference,
	DwarfAttrCount,			OFFSET(count),				TConstant|TReference,
	DwarfAttrDataMemberLoc,	OFFSET(datamemberloc),		TBlock|TConstant|TReference,
	DwarfAttrDeclColumn,		OFFSET(declcolumn),			TConstant,
	DwarfAttrDeclFile,		OFFSET(declfile),			TConstant,
	DwarfAttrDeclLine,		OFFSET(declline),			TConstant,
	DwarfAttrDeclaration,	OFFSET(isdeclaration),		TFlag,
	DwarfAttrDefaultValue,	OFFSET(defaultvalue),		TReference,
	DwarfAttrDiscr,			OFFSET(discr),				TReference,
	DwarfAttrDiscrList,		OFFSET(discrlist),			TBlock,
	DwarfAttrDiscrValue,		OFFSET(discrvalue),			TConstant,
	DwarfAttrEncoding,		OFFSET(encoding),			TConstant,
	DwarfAttrExternal,		OFFSET(isexternal),			TFlag,
	DwarfAttrFrameBase,		OFFSET(framebase),			TBlock|TConstant,
	DwarfAttrFriend,			OFFSET(friend),				TReference,
	DwarfAttrHighpc,			OFFSET(highpc),				TAddress,
	DwarfAttrIdentifierCase,	OFFSET(identifiercase),		TConstant,
	DwarfAttrImport,			OFFSET(import),				TReference,
	DwarfAttrInline,			OFFSET(inlined),			TConstant,
	DwarfAttrIsOptional,		OFFSET(isoptional),			TFlag,
	DwarfAttrLanguage,		OFFSET(language),			TConstant,
	DwarfAttrLocation,		OFFSET(location),			TBlock|TConstant,
	DwarfAttrLowerBound,		OFFSET(lowerbound),			TConstant|TReference,
	DwarfAttrLowpc,			OFFSET(lowpc),				TAddress,
	DwarfAttrMacroInfo,		OFFSET(macroinfo),			TConstant,
	DwarfAttrName,			OFFSET(name),				TString,
	DwarfAttrNamelistItem,	OFFSET(namelistitem),		TBlock,
	DwarfAttrOrdering, 		OFFSET(ordering),			TConstant,
	DwarfAttrPriority,		OFFSET(priority),			TReference,
	DwarfAttrProducer,		OFFSET(producer),			TString,
	DwarfAttrPrototyped,		OFFSET(isprototyped),		TFlag,
	DwarfAttrRanges,			OFFSET(ranges),				TReference,
	DwarfAttrReturnAddr,		OFFSET(returnaddr),			TBlock|TConstant,
	DwarfAttrSegment,		OFFSET(segment),			TBlock|TConstant,
	DwarfAttrSibling,		OFFSET(sibling),			TReference,
	DwarfAttrSpecification,	OFFSET(specification),		TReference,
	DwarfAttrStartScope,		OFFSET(startscope),			TConstant,
	DwarfAttrStaticLink,		OFFSET(staticlink),			TBlock|TConstant,
	DwarfAttrStmtList,		OFFSET(stmtlist),			TConstant,
	DwarfAttrStrideSize,		OFFSET(stridesize),			TConstant,
	DwarfAttrStringLength,	OFFSET(stringlength),		TBlock|TConstant,
	DwarfAttrType,			OFFSET(type),				TReference,
	DwarfAttrUpperBound,		OFFSET(upperbound),			TConstant|TReference,
	DwarfAttrUseLocation,	OFFSET(uselocation),		TBlock|TConstant,
	DwarfAttrVarParam,		OFFSET(isvarparam),			TFlag,
	DwarfAttrVirtuality,		OFFSET(virtuality),			TConstant,
	DwarfAttrVisibility,		OFFSET(visibility),			TConstant,
	DwarfAttrVtableElemLoc,	OFFSET(vtableelemloc),		TBlock|TReference,
};

static Parse ptab[DwarfAttrMax];

static int
parseattrs(DwarfBuf *b, ulong unit, DwarfAbbrev *a, DwarfAttrs *attrs)
{
	int i, f, n, got;
	static int nbad;
	void *v;

	/* initialize ptab first time through for quick access */
	if(ptab[DwarfAttrName].name != DwarfAttrName)
		for(i=0; i<nelem(plist); i++)
			ptab[plist[i].name] = plist[i];

	memset(attrs, 0, sizeof *attrs);
	attrs->tag = a->tag;
	attrs->haskids = a->haskids;

	for(i=0; i<a->nattr; i++){
		n = a->attr[i].name;
		f = a->attr[i].form;
		if(n < 0 || n >= nelem(ptab) || ptab[n].name==0){
			if(++nbad == 1)
				fprint(2, "dwarf parse attrs: unexpected attribute name 0x%ux\n", n);
			return -1;
		}
		v = (char*)attrs + ptab[n].off;
		got = 0;
		if(f == FormIndirect)
			f = dwarfget128(b);
		if((ptab[n].type&(TConstant|TReference|TAddress))
		&& getulong(b, f, unit, v, &got) >= 0)
			;
		else if((ptab[n].type&TFlag) && getuchar(b, f, v) >= 0)
			got = TFlag;
		else if((ptab[n].type&TString) && getstring(b, f, v) >= 0)
			got = TString;
		else if((ptab[n].type&TBlock) && getblock(b, f, v) >= 0)
			got = TBlock;
		else{
			if(skipform(b, f) < 0){
				if(++nbad == 1)
					fprint(2, "dwarf parse attrs: cannot skip form %d\n", f);
				return -1;
			}
		}
		if(got == TBlock && (ptab[n].type&TConstant))
			got = constblock(b->d, v, v);
		*((uchar*)attrs+ptab[n].haveoff) = got;
	}
	return 0;
}

static int
getulong(DwarfBuf *b, int form, ulong unit, ulong *u, int *type)
{
	static int nbad;
	uvlong uv;

	switch(form){
	default:
		return -1;

	/* addresses */
	case FormAddr:
		*type = TAddress;
		*u = dwarfgetaddr(b);
		return 0;

	/* references */
	case FormRefAddr:
		/* absolute ref in .debug_info */
		*type = TReference;
		*u = dwarfgetaddr(b);
		return 0;
	case FormRef1:
		*u = dwarfget1(b);
		goto relativeref;
	case FormRef2:
		*u = dwarfget2(b);
		goto relativeref;
	case FormRef4:
		*u = dwarfget4(b);
		goto relativeref;
	case FormRef8:
		*u = dwarfget8(b);
		goto relativeref;
	case FormRefUdata:
		*u = dwarfget128(b);
	relativeref:
		*u += unit;
		*type = TReference;
		return 0;

	/* constants */
	case FormData1:
		*u = dwarfget1(b);
		goto constant;
	case FormData2:
		*u = dwarfget2(b);
		goto constant;
	case FormData4:
		*u = dwarfget4(b);
		goto constant;
	case FormData8:
		uv = dwarfget8(b);
		*u = uv;
		if(uv != *u && ++nbad == 1)
			fprint(2, "dwarf: truncating 64-bit attribute constants\n");
		goto constant;
	case FormSdata:
		*u = dwarfget128s(b);
		goto constant;
	case FormUdata:
		*u = dwarfget128(b);
	constant:
		*type = TConstant;
		return 0;
	}
}

static int
getuchar(DwarfBuf *b, int form, uchar *u)
{
	switch(form){
	default:
		return -1;

	case FormFlag:
		*u = dwarfget1(b);
		return 0;
	}
}

static int
getstring(DwarfBuf *b, int form, char **s)
{
	static int nbad;
	ulong u;

	switch(form){
	default:
		return -1;

	case FormString:
		*s = dwarfgetstring(b);
		return 0;

	case FormStrp:
		u = dwarfget4(b);
		if(u >= b->d->str.len){
			if(++nbad == 1)
				fprint(2, "dwarf: bad string pointer 0x%lux in attribute\n", u);
			/* don't return error - maybe can proceed */
			*s = nil;
		}else
			*s = (char*)b->d->str.data + u;
		return 0;

	}
}

static int
getblock(DwarfBuf *b, int form, DwarfBlock *bl)
{
	ulong n;

	switch(form){
	default:
		return -1;
	case FormDwarfBlock:
		n = dwarfget128(b);
		goto copyn;
	case FormDwarfBlock1:
		n = dwarfget1(b);
		goto copyn;
	case FormDwarfBlock2:
		n = dwarfget2(b);
		goto copyn;
	case FormDwarfBlock4:
		n = dwarfget4(b);
	copyn:
		bl->data = dwarfgetnref(b, n);
		bl->len = n;
		if(bl->data == nil)
			return -1;
		return 0;
	}
}

static int
constblock(Dwarf *d, DwarfBlock *bl, ulong *pval)
{
	DwarfBuf b;

	memset(&b, 0, sizeof b);
	b.p = bl->data;
	b.ep = bl->data+bl->len;
	b.d = d;

	switch(dwarfget1(&b)){
	case OpAddr:
		*pval = dwarfgetaddr(&b);
		return TConstant;
	case OpConst1u:
		*pval = dwarfget1(&b);
		return TConstant;
	case OpConst1s:
		*pval = (schar)dwarfget1(&b);
		return TConstant;
	case OpConst2u:
		*pval = dwarfget2(&b);
		return TConstant;
	case OpConst2s:
		*pval = (s16int)dwarfget2(&b);
		return TConstant;
	case OpConst4u:
		*pval = dwarfget4(&b);
		return TConstant;
	case OpConst4s:
		*pval = (s32int)dwarfget4(&b);
		return TConstant;
	case OpConst8u:
		*pval = (u64int)dwarfget8(&b);
		return TConstant;
	case OpConst8s:
		*pval = (s64int)dwarfget8(&b);
		return TConstant;
	case OpConstu:
		*pval = dwarfget128(&b);
		return TConstant;
	case OpConsts:
		*pval = dwarfget128s(&b);
		return TConstant;
	case OpPlusUconst:
		*pval = dwarfget128(&b);
		return TConstant;
	default:
		return TBlock;
	}
}

/* last resort */
static int
skipform(DwarfBuf *b, int form)
{
	int type;
	DwarfVal val;

	if(getulong(b, form, 0, &val.c, &type) < 0
	&& getuchar(b, form, (uchar*)&val) < 0
	&& getstring(b, form, &val.s) < 0
	&& getblock(b, form, &val.b) < 0)
		return -1;
	return 0;
}
