/*
 * Dwarf abbreviation parsing code.
 *
 * The convention here is that calling dwarfgetabbrevs relinquishes
 * access to any abbrevs returned previously.  Will have to add 
 * explicit reference counting if this turns out not to be acceptable.
 */

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

static int parseabbrevs(Dwarf*, ulong, DwarfAbbrev*, DwarfAttr*, int*, int*);
DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong);

static int
loadabbrevs(Dwarf *d, ulong off, DwarfAbbrev **aa)
{
	int nattr, nabbrev;
	DwarfAbbrev *abbrev;
	DwarfAttr *attr;

	if(d->acache.off == off && d->acache.na){
		*aa = d->acache.a;
		return d->acache.na;
	}

	/* two passes - once to count, then allocate, then a second to copy */
	if(parseabbrevs(d, off, nil, nil, &nabbrev, &nattr) < 0)
		return -1;

	abbrev = malloc(nabbrev*sizeof(DwarfAbbrev) + nattr*sizeof(DwarfAttr));
	attr = (DwarfAttr*)(abbrev+nabbrev);

	if(parseabbrevs(d, off, abbrev, attr, nil, nil) < 0){
		free(abbrev);
		return -1;
	}

	free(d->acache.a);
	d->acache.a = abbrev;
	d->acache.na = nabbrev;
	d->acache.off = off;

	*aa = abbrev;
	return nabbrev;
}

static int
parseabbrevs(Dwarf *d, ulong off, DwarfAbbrev *abbrev, DwarfAttr *attr, int *pnabbrev, int *pnattr)
{
	int i, nabbrev, nattr, haskids;
	ulong num, tag, name, form;
	DwarfBuf b;

	if(off >= d->abbrev.len){
		werrstr("bad abbrev section offset 0x%lux >= 0x%lux\n", off, d->abbrev.len);
		return -1;
	}

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

	nabbrev = 0;
	nattr = 0;
	for(;;){
		if(b.p == nil){
			werrstr("malformed abbrev data");
			return -1;
		}
		num = dwarfget128(&b);
		if(num == 0)
			break;
		tag = dwarfget128(&b);
		haskids = dwarfget1(&b);
		for(i=0;; i++){
			name = dwarfget128(&b);
			form = dwarfget128(&b);
			if(name == 0 && form == 0)
				break;
			if(attr){
				attr[i].name = name;
				attr[i].form = form;
			}
		}
		if(abbrev){
			abbrev->num = num;
			abbrev->tag = tag;
			abbrev->haskids = haskids;
			abbrev->attr = attr;
			abbrev->nattr = i;
			abbrev++;
			attr += i;
		}
		nabbrev++;
		nattr += i;
	}
	if(pnabbrev)
		*pnabbrev = nabbrev;
	if(pnattr)
		*pnattr = nattr;
	return 0;
}

static DwarfAbbrev*
findabbrev(DwarfAbbrev *a, int na, ulong num)
{
	int i;

	for(i=0; i<na; i++)
		if(a[i].num == num)
			return &a[i];
	werrstr("abbrev not found");
	return nil;
}

DwarfAbbrev*
dwarfgetabbrev(Dwarf *d, ulong off, ulong num)
{
	DwarfAbbrev *a;
	int na;

	if((na = loadabbrevs(d, off, &a)) < 0){
		werrstr("loadabbrevs: %r");
		return nil;
	}
	return findabbrev(a, na, num);
}

