/*
 * 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;
}
