/*
 * Dwarf data format parsing routines.
 */

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

ulong
dwarfget1(DwarfBuf *b)
{
	if(b->p==nil || b->p+1 > b->ep){
		b->p = nil;
		return 0;
	}
	return *b->p++;
}

int
dwarfgetn(DwarfBuf *b, uchar *a, int n)
{
	if(b->p==nil || b->p+n > b->ep){
		b->p = nil;
		memset(a, 0, n);
		return -1;
	}
	memmove(a, b->p, n);
	b->p += n;
	return 0;
}

uchar*
dwarfgetnref(DwarfBuf *b, ulong n)
{
	uchar *p;

	if(b->p==nil || b->p+n > b->ep){
		b->p = nil;
		return nil;
	}
	p = b->p;
	b->p += n;
	return p;
}

char*
dwarfgetstring(DwarfBuf *b)
{
	char *s;

	if(b->p == nil)
		return nil;
	s = (char*)b->p;
	while(b->p < b->ep && *b->p)
		b->p++;
	if(b->p >= b->ep){
		b->p = nil;
		return nil;
	}
	b->p++;
	return s;
}

void
dwarfskip(DwarfBuf *b, int n)
{
	if(b->p==nil || b->p+n > b->ep)
		b->p = nil;
	else
		b->p += n;
}

ulong
dwarfget2(DwarfBuf *b)
{
	ulong v;

	if(b->p==nil || b->p+2 > b->ep){
		b->p = nil;
		return 0;
	}
	v = b->d->elf->hdr.e2(b->p);
	b->p += 2;
	return v;
}

ulong
dwarfget4(DwarfBuf *b)
{
	ulong v;

	if(b->p==nil || b->p+4 > b->ep){
		b->p = nil;
		return 0;
	}
	v = b->d->elf->hdr.e4(b->p);
	b->p += 4;
	return v;
}

uvlong
dwarfget8(DwarfBuf *b)
{
	uvlong v;

	if(b->p==nil || b->p+8 > b->ep){
		b->p = nil;
		return 0;
	}
	v = b->d->elf->hdr.e8(b->p);
	b->p += 8;
	return v;
}

ulong
dwarfgetaddr(DwarfBuf *b)
{
	static int nbad;

	if(b->addrsize == 0)
		b->addrsize = b->d->addrsize;

	switch(b->addrsize){
	case 1:
		return dwarfget1(b);
	case 2:
		return dwarfget2(b);
	case 4:
		return dwarfget4(b);
	case 8:
		return dwarfget8(b);
	default:
		if(++nbad == 1)
			fprint(2, "dwarf: unexpected address size %lud in dwarfgetaddr\n", b->addrsize);
		b->p = nil;
		return 0;
	}
}

int n1, n2, n3, n4, n5;

/* An inline function picks off the calls to dwarfget128 for 1-byte encodings,
 * more than by far the common case (99.999% on most binaries!). */
ulong
dwarfget128(DwarfBuf *b)
{
	static int nbad;
	ulong c, d;

	if(b->p == nil)
		return 0;
	c = *b->p++;
	if(!(c&0x80))
{n1++;
		return c;
}
	d = *b->p++;
	c |= (d&0x7F)<<7;
	if(!(d&0x80))
{n2++;
		return c;
}
	d = *b->p++;
	c |= (d&0x7F)<<14;
	if(!(d&0x80))
{n3++;
		return c;
}
	d = *b->p++;
	c |= (d&0x7F)<<21;
	if(!(d&0x80))
{n4++;
		return c;
}
	d = *b->p++;
	c |= (d&0x7F)<<28;
	if(!(d&0x80))
{n5++;
		return c;
}
	while(b->p<b->ep && *b->p&0x80)
		b->p++;
	if(++nbad == 1)
		fprint(2, "dwarf: overflow during parsing of uleb128 integer\n");
	return c;
}

long
dwarfget128s(DwarfBuf *b)
{
	int nb, c;
	ulong v;
	static int nbad;

	v = 0;
	nb = 0;
	if(b->p==nil)
		return 0;
	while(b->p<b->ep){
		c = *b->p++;
		v |= (c & 0x7F)<<nb;
		nb += 7;
		if(!(c&0x80))
			break;
	}
	if(v&(1<<(nb-1)))
		v |= ~(((ulong)1<<nb)-1);
	if(nb > 8*sizeof(ulong)){
		if(0)
		if(++nbad == 1)
			fprint(2, "dwarf: overflow during parsing of sleb128 integer: got %d bits\n", nb);
	}
	return v;
}

