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

	dwarfnextsym(d, s, 1);	/* s is now the CompileUnit */
	if(dwarfnextsym(d, s, 1) == 1){	/* s is now the first child of the compile unit */
		do{
			if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
				return 0;
		}while(dwarfnextsym(d, s, 0) == 1);
	} 
	werrstr("symbol '%s' not found", name);
	return -1;
}
	

int
dwarflookupsubname(Dwarf *d, DwarfSym *parent, char *name, DwarfSym *s)
{
	*s = *parent;
	dwarfnextsym(d, s, 1);
	if(s->depth == parent->depth+1)
		do{
			if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
				return 0;
		}while(dwarfnextsym(d, s, 0) == 1);
	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;

	dwarfnextsym(d, s, 1);	/* s is now the CompileUnit */
	if(s->attrs.tag == tag)
		return 0;

	if(dwarfnextsym(d, s, 1) == 1){	/* s is now the first child of the compile unit */
		do{
			if(s->attrs.tag == tag)
				return 0;
		}while(dwarfnextsym(d, s, 0) == 1);
	} 
	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(dwarfnextsym(d, s, 1) != 1)
		return -1;
	return 0;
}

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

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

	if(dwarfnextsym(d, s, 1) == 1){	/* s is now the first child of the compile unit */
		do{
			if(s->attrs.tag != TagSubprogram)
				continue;
			if(s->attrs.lowpc <= pc && pc < s->attrs.highpc)
				return 0;
		}while(dwarfnextsym(d, s, 0) == 1);
	} 
	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;
}

static 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: %r\n", num);
		return -1;
	}
	if(parseattrs(&s->b, s->unit, a, &s->attrs) < 0)
		return -1;
	return 1;
}

int
dwarfnextsym(Dwarf *d, DwarfSym *s, int recurse)
{
	int r;
	int depth;
	ulong sib;

	if(recurse)
		return _dwarfnextsym(d, s);

	depth = s->depth;
	if(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;
	}

	do{
		r = _dwarfnextsym(d, s);
		if(r <= 0)
			return r;
	}while(s->depth != depth);
	if(s->depth < depth)
		return 0;
	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 = 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;
}
