// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// TODO/NICETOHAVE:
//   - eliminate DW_CLS_ if not used
//   - package info in compilation units
//   - assign global variables and types to their packages
//   - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg
//     ptype struct '[]uint8' and qualifiers need to be quoted away
//   - lexical scoping is lost, so gdb gets confused as to which 'main.i' you mean.
//   - file:line info for variables
//   - make strings a typedef so prettyprinters can see the underlying string type
//
#include	"l.h"
#include	"lib.h"
#include	"../ld/dwarf.h"
#include	"../ld/dwarf_defs.h"
#include	"../ld/elf.h"
#include	"../ld/macho.h"
#include	"../ld/pe.h"
#include	"../../pkg/runtime/typekind.h"

/*
 * Offsets and sizes of the debug_* sections in the cout file.
 */

static vlong abbrevo;
static vlong abbrevsize;
static LSym*  abbrevsym;
static vlong abbrevsympos;
static vlong lineo;
static vlong linesize;
static LSym*  linesym;
static vlong linesympos;
static vlong infoo;	// also the base for DWDie->offs and reference attributes.
static vlong infosize;
static LSym*  infosym;
static vlong infosympos;
static vlong frameo;
static vlong framesize;
static LSym*  framesym;
static vlong framesympos;
static vlong pubnameso;
static vlong pubnamessize;
static vlong pubtypeso;
static vlong pubtypessize;
static vlong arangeso;
static vlong arangessize;
static vlong gdbscripto;
static vlong gdbscriptsize;

static LSym *infosec;
static vlong inforeloco;
static vlong inforelocsize;

static LSym *arangessec;
static vlong arangesreloco;
static vlong arangesrelocsize;

static LSym *linesec;
static vlong linereloco;
static vlong linerelocsize;

static LSym *framesec;
static vlong framereloco;
static vlong framerelocsize;

static char  gdbscript[1024];

/*
 *  Basic I/O
 */

static void
addrput(vlong addr)
{
	switch(PtrSize) {
	case 4:
		LPUT(addr);
		break;
	case 8:
		VPUT(addr);
		break;
	}
}

static int
uleb128enc(uvlong v, char* dst)
{
	uint8 c, len;

	len = 0;
	do {
		c = v & 0x7f;
		v >>= 7;
		if (v)
			c |= 0x80;
		if (dst)
			*dst++ = c;
		len++;
	} while (c & 0x80);
	return len;
};

static int
sleb128enc(vlong v, char *dst)
{
	uint8 c, s, len;

	len = 0;
	do {
		c = v & 0x7f;
		s = v & 0x40;
		v >>= 7;
		if ((v != -1 || !s) && (v != 0 || s))
			c |= 0x80;
		if (dst)
			*dst++ = c;
		len++;
	} while(c & 0x80);
	return len;
}

static void
uleb128put(vlong v)
{
	char buf[10];
	strnput(buf, uleb128enc(v, buf));
}

static void
sleb128put(vlong v)
{
	char buf[10];
	strnput(buf, sleb128enc(v, buf));
}

/*
 * Defining Abbrevs.  This is hardcoded, and there will be
 * only a handful of them.  The DWARF spec places no restriction on
 * the ordering of attributes in the Abbrevs and DIEs, and we will
 * always write them out in the order of declaration in the abbrev.
 * This implementation relies on tag, attr < 127, so they serialize as
 * a char.  Higher numbered user-defined tags or attributes can be used
 * for storing internal data but won't be serialized.
 */
typedef struct DWAttrForm DWAttrForm;
struct DWAttrForm {
	uint8 attr;
	uint8 form;
};

// Index into the abbrevs table below.
// Keep in sync with ispubname() and ispubtype() below.
// ispubtype considers >= NULLTYPE public
enum
{
	DW_ABRV_NULL,
	DW_ABRV_COMPUNIT,
	DW_ABRV_FUNCTION,
	DW_ABRV_VARIABLE,
	DW_ABRV_AUTO,
	DW_ABRV_PARAM,
	DW_ABRV_STRUCTFIELD,
	DW_ABRV_FUNCTYPEPARAM,
	DW_ABRV_DOTDOTDOT,
	DW_ABRV_ARRAYRANGE,
	DW_ABRV_NULLTYPE,
	DW_ABRV_BASETYPE,
	DW_ABRV_ARRAYTYPE,
	DW_ABRV_CHANTYPE,
	DW_ABRV_FUNCTYPE,
	DW_ABRV_IFACETYPE,
	DW_ABRV_MAPTYPE,
	DW_ABRV_PTRTYPE,
	DW_ABRV_BARE_PTRTYPE, // only for void*, no DW_AT_type attr to please gdb 6.
	DW_ABRV_SLICETYPE,
	DW_ABRV_STRINGTYPE,
	DW_ABRV_STRUCTTYPE,
	DW_ABRV_TYPEDECL,
	DW_NABRV
};

typedef struct DWAbbrev DWAbbrev;
static struct DWAbbrev {
	uint8 tag;
	uint8 children;
	DWAttrForm attr[30];
} abbrevs[DW_NABRV] = {
	/* The mandatory DW_ABRV_NULL entry. */
	{ 0 },
	/* COMPUNIT */
	{
		DW_TAG_compile_unit, DW_CHILDREN_yes,
		DW_AT_name,	 DW_FORM_string,
		DW_AT_language,	 DW_FORM_data1,
		DW_AT_low_pc,	 DW_FORM_addr,
		DW_AT_high_pc,	 DW_FORM_addr,
		DW_AT_stmt_list, DW_FORM_data4,
		0, 0
	},
	/* FUNCTION */
	{
		DW_TAG_subprogram, DW_CHILDREN_yes,
		DW_AT_name,	 DW_FORM_string,
		DW_AT_low_pc,	 DW_FORM_addr,
		DW_AT_high_pc,	 DW_FORM_addr,
		DW_AT_external,	 DW_FORM_flag,
		0, 0
	},
	/* VARIABLE */
	{
		DW_TAG_variable, DW_CHILDREN_no,
		DW_AT_name,	 DW_FORM_string,
		DW_AT_location,	 DW_FORM_block1,
		DW_AT_type,	 DW_FORM_ref_addr,
		DW_AT_external,	 DW_FORM_flag,
		0, 0
	},
	/* AUTO */
	{
		DW_TAG_variable, DW_CHILDREN_no,
		DW_AT_name,	 DW_FORM_string,
		DW_AT_location,	 DW_FORM_block1,
		DW_AT_type,	 DW_FORM_ref_addr,
		0, 0
	},
	/* PARAM */
	{
		DW_TAG_formal_parameter, DW_CHILDREN_no,
		DW_AT_name,	 DW_FORM_string,
		DW_AT_location,	 DW_FORM_block1,
		DW_AT_type,	 DW_FORM_ref_addr,
		0, 0
	},
	/* STRUCTFIELD */
	{
		DW_TAG_member,	DW_CHILDREN_no,
		DW_AT_name,	DW_FORM_string,
		DW_AT_data_member_location, DW_FORM_block1,
		DW_AT_type,	 DW_FORM_ref_addr,
		0, 0
	},
	/* FUNCTYPEPARAM */
	{
		DW_TAG_formal_parameter, DW_CHILDREN_no,
		// No name!
		DW_AT_type,	 DW_FORM_ref_addr,
		0, 0
	},

	/* DOTDOTDOT */
	{
		DW_TAG_unspecified_parameters, DW_CHILDREN_no,
		0, 0
	},
	/* ARRAYRANGE */
	{
		DW_TAG_subrange_type, DW_CHILDREN_no,
		// No name!
		DW_AT_type,	 DW_FORM_ref_addr,
		DW_AT_upper_bound, DW_FORM_data1,
		0, 0
	},

	// Below here are the types considered public by ispubtype
	/* NULLTYPE */
	{
		DW_TAG_unspecified_type, DW_CHILDREN_no,
		DW_AT_name,	DW_FORM_string,
		0, 0
	},
	/* BASETYPE */
	{
		DW_TAG_base_type, DW_CHILDREN_no,
		DW_AT_name,	 DW_FORM_string,
		DW_AT_encoding,	 DW_FORM_data1,
		DW_AT_byte_size, DW_FORM_data1,
		0, 0
	},
	/* ARRAYTYPE */
	// child is subrange with upper bound
	{
		DW_TAG_array_type, DW_CHILDREN_yes,
		DW_AT_name,	DW_FORM_string,
		DW_AT_type,	DW_FORM_ref_addr,
		DW_AT_byte_size, DW_FORM_udata,
		0, 0
	},

	/* CHANTYPE */
	{
		DW_TAG_typedef, DW_CHILDREN_no,
		DW_AT_name,	DW_FORM_string,
		DW_AT_type,	DW_FORM_ref_addr,
		0, 0
	},

	/* FUNCTYPE */
	{
		DW_TAG_subroutine_type, DW_CHILDREN_yes,
		DW_AT_name,	DW_FORM_string,
//		DW_AT_type,	DW_FORM_ref_addr,
		0, 0
	},

	/* IFACETYPE */
	{
		DW_TAG_typedef, DW_CHILDREN_yes,
		DW_AT_name,	 DW_FORM_string,
		DW_AT_type,	DW_FORM_ref_addr,
		0, 0
	},

	/* MAPTYPE */
	{
		DW_TAG_typedef, DW_CHILDREN_no,
		DW_AT_name,	DW_FORM_string,
		DW_AT_type,	DW_FORM_ref_addr,
		0, 0
	},

	/* PTRTYPE */
	{
		DW_TAG_pointer_type, DW_CHILDREN_no,
		DW_AT_name,	DW_FORM_string,
		DW_AT_type,	DW_FORM_ref_addr,
		0, 0
	},
	/* BARE_PTRTYPE */
	{
		DW_TAG_pointer_type, DW_CHILDREN_no,
		DW_AT_name,	DW_FORM_string,
		0, 0
	},

	/* SLICETYPE */
	{
		DW_TAG_structure_type, DW_CHILDREN_yes,
		DW_AT_name,	DW_FORM_string,
		DW_AT_byte_size, DW_FORM_udata,
		0, 0
	},

	/* STRINGTYPE */
	{
		DW_TAG_structure_type, DW_CHILDREN_yes,
		DW_AT_name,	DW_FORM_string,
		DW_AT_byte_size, DW_FORM_udata,
		0, 0
	},

	/* STRUCTTYPE */
	{
		DW_TAG_structure_type, DW_CHILDREN_yes,
		DW_AT_name,	DW_FORM_string,
		DW_AT_byte_size, DW_FORM_udata,
		0, 0
	},

	/* TYPEDECL */
	{
		DW_TAG_typedef, DW_CHILDREN_no,
		DW_AT_name,	DW_FORM_string,
		DW_AT_type,	DW_FORM_ref_addr,
		0, 0
	},
};

static void
writeabbrev(void)
{
	int i, n;

	abbrevo = cpos();
	for (i = 1; i < DW_NABRV; i++) {
		// See section 7.5.3
		uleb128put(i);
		uleb128put(abbrevs[i].tag);
		cput(abbrevs[i].children);
		// 0 is not a valid attr or form, and DWAbbrev.attr is
		// 0-terminated, so we can treat it as a string
		n = strlen((char*)abbrevs[i].attr) / 2;
		strnput((char*)abbrevs[i].attr,
			(n+1) * sizeof(DWAttrForm));
	}
	cput(0);
	abbrevsize = cpos() - abbrevo;
}

/*
 * Debugging Information Entries and their attributes.
 */

enum
{
	HASHSIZE = 107
};

static uint32
hashstr(char* s)
{
	uint32 h;

	h = 0;
	while (*s)
		h = h+h+h + *s++;
	return h % HASHSIZE;
}

// For DW_CLS_string and _block, value should contain the length, and
// data the data, for _reference, value is 0 and data is a DWDie* to
// the referenced instance, for all others, value is the whole thing
// and data is null.

typedef struct DWAttr DWAttr;
struct DWAttr {
	DWAttr *link;
	uint8 atr;  // DW_AT_
	uint8 cls;  // DW_CLS_
	vlong value;
	char *data;
};

typedef struct DWDie DWDie;
struct DWDie {
	int abbrev;
	DWDie *link;
	DWDie *child;
	DWAttr *attr;
	// offset into .debug_info section, i.e relative to
	// infoo. only valid after call to putdie()
	vlong offs;
	DWDie **hash;  // optional index of children by name, enabled by mkindex()
	DWDie *hlink;  // bucket chain in parent's index
};

/*
 * Root DIEs for compilation units, types and global variables.
 */

static DWDie dwroot;
static DWDie dwtypes;
static DWDie dwglobals;

static DWAttr*
newattr(DWDie *die, uint8 attr, int cls, vlong value, char *data)
{
	DWAttr *a;

	a = mal(sizeof *a);
	a->link = die->attr;
	die->attr = a;
	a->atr = attr;
	a->cls = cls;
	a->value = value;
	a->data = data;
	return a;
}

// Each DIE (except the root ones) has at least 1 attribute: its
// name. getattr moves the desired one to the front so
// frequently searched ones are found faster.
static DWAttr*
getattr(DWDie *die, uint8 attr)
{
	DWAttr *a, *b;

	if (die->attr->atr == attr)
		return die->attr;

	a = die->attr;
	b = a->link;
	while (b != nil) {
		if (b->atr == attr) {
			a->link = b->link;
			b->link = die->attr;
			die->attr = b;
			return b;
		}
		a = b;
		b = b->link;
	}
	return nil;
}

// Every DIE has at least a DW_AT_name attribute (but it will only be
// written out if it is listed in the abbrev).	If its parent is
// keeping an index, the new DIE will be inserted there.
static DWDie*
newdie(DWDie *parent, int abbrev, char *name)
{
	DWDie *die;
	int h;

	die = mal(sizeof *die);
	die->abbrev = abbrev;
	die->link = parent->child;
	parent->child = die;

	newattr(die, DW_AT_name, DW_CLS_STRING, strlen(name), name);

	if (parent->hash) {
		h = hashstr(name);
		die->hlink = parent->hash[h];
		parent->hash[h] = die;
	}

	return die;
}

static void
mkindex(DWDie *die)
{
	die->hash = mal(HASHSIZE * sizeof(DWDie*));
}

static DWDie*
walktypedef(DWDie *die)
{
	DWAttr *attr;

	// Resolve typedef if present.
	if (die->abbrev == DW_ABRV_TYPEDECL) {
		for (attr = die->attr; attr; attr = attr->link) {
			if (attr->atr == DW_AT_type && attr->cls == DW_CLS_REFERENCE && attr->data != nil) {
				return (DWDie*)attr->data;
			}
		}
	}
	return die;
}

// Find child by AT_name using hashtable if available or linear scan
// if not.
static DWDie*
find(DWDie *die, char* name)
{
	DWDie *a, *b, *die2;
	int h;

top:
	if (die->hash == nil) {
		for (a = die->child; a != nil; a = a->link)
			if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
				return a;
		goto notfound;
	}

	h = hashstr(name);
	a = die->hash[h];

	if (a == nil)
		goto notfound;


	if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
		return a;

	// Move found ones to head of the list.
	b = a->hlink;
	while (b != nil) {
		if (strcmp(name, getattr(b, DW_AT_name)->data) == 0) {
			a->hlink = b->hlink;
			b->hlink = die->hash[h];
			die->hash[h] = b;
			return b;
		}
		a = b;
		b = b->hlink;
	}

notfound:
	die2 = walktypedef(die);
	if(die2 != die) {
		die = die2;
		goto top;
	}

	return nil;
}

static DWDie*
find_or_diag(DWDie *die, char* name)
{
	DWDie *r;
	r = find(die, name);
	if (r == nil) {
		diag("dwarf find: %s %p has no %s", getattr(die, DW_AT_name)->data, die, name);
		errorexit();
	}
	return r;
}

static void
adddwarfrel(LSym* sec, LSym* sym, vlong offsetbase, int siz, vlong addend)
{
	Reloc *r;

	r = addrel(sec);
	r->sym = sym;
	r->xsym = sym;
	r->off = cpos() - offsetbase;
	r->siz = siz;
	r->type = R_ADDR;
	r->add = addend;
	r->xadd = addend;
	if(iself && thechar == '6')
		addend = 0;
	switch(siz) {
	case 4:
		LPUT(addend);
		break;
	case 8:
		VPUT(addend);
		break;
	default:
		diag("bad size in adddwarfrel");
		break;
	}
}

static DWAttr*
newrefattr(DWDie *die, uint8 attr, DWDie* ref)
{
	if (ref == nil)
		return nil;
	return newattr(die, attr, DW_CLS_REFERENCE, 0, (char*)ref);
}

static int fwdcount;

static void
putattr(int abbrev, int form, int cls, vlong value, char *data)
{
	vlong off;

	switch(form) {
	case DW_FORM_addr:	// address
		if(linkmode == LinkExternal) {
			value -= ((LSym*)data)->value;
			adddwarfrel(infosec, (LSym*)data, infoo, PtrSize, value);
			break;
		}
		addrput(value);
		break;

	case DW_FORM_block1:	// block
		if(cls == DW_CLS_ADDRESS) {
			cput(1+PtrSize);
			cput(DW_OP_addr);
			if(linkmode == LinkExternal) {
				value -= ((LSym*)data)->value;
				adddwarfrel(infosec, (LSym*)data, infoo, PtrSize, value);
				break;
			}
			addrput(value);
			break;
		}
		value &= 0xff;
		cput(value);
		while(value--)
			cput(*data++);
		break;

	case DW_FORM_block2:	// block
		value &= 0xffff;
		WPUT(value);
		while(value--)
			cput(*data++);
		break;

	case DW_FORM_block4:	// block
		value &= 0xffffffff;
		LPUT(value);
		while(value--)
			cput(*data++);
		break;

	case DW_FORM_block:	// block
		uleb128put(value);
		while(value--)
			cput(*data++);
		break;

	case DW_FORM_data1:	// constant
		cput(value);
		break;

	case DW_FORM_data2:	// constant
		WPUT(value);
		break;

	case DW_FORM_data4:	// constant, {line,loclist,mac,rangelist}ptr
		if(linkmode == LinkExternal && cls == DW_CLS_PTR) {
			adddwarfrel(infosec, linesym, infoo, 4, value);
			break;
		}
		LPUT(value);
		break;

	case DW_FORM_data8:	// constant, {line,loclist,mac,rangelist}ptr
		VPUT(value);
		break;

	case DW_FORM_sdata:	// constant
		sleb128put(value);
		break;

	case DW_FORM_udata:	// constant
		uleb128put(value);
		break;

	case DW_FORM_string:	// string
		strnput(data, value+1);
		break;

	case DW_FORM_flag:	// flag
		cput(value?1:0);
		break;

	case DW_FORM_ref_addr:	// reference to a DIE in the .info section
		// In DWARF 2 (which is what we claim to generate),
		// the ref_addr is the same size as a normal address.
		// In DWARF 3 it is always 32 bits, unless emitting a large
		// (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
		if (data == nil) {
			diag("dwarf: null reference in %d", abbrev);
			if(PtrSize == 8)
				VPUT(0); // invalid dwarf, gdb will complain.
			else
				LPUT(0); // invalid dwarf, gdb will complain.
		} else {
			off = ((DWDie*)data)->offs;
			if (off == 0)
				fwdcount++;
			if(linkmode == LinkExternal) {
				adddwarfrel(infosec, infosym, infoo, PtrSize, off);
				break;
			}
			addrput(off);
		}
		break;

	case DW_FORM_ref1:	// reference within the compilation unit
	case DW_FORM_ref2:	// reference
	case DW_FORM_ref4:	// reference
	case DW_FORM_ref8:	// reference
	case DW_FORM_ref_udata:	// reference

	case DW_FORM_strp:	// string
	case DW_FORM_indirect:	// (see Section 7.5.3)
	default:
		diag("dwarf: unsupported attribute form %d / class %d", form, cls);
		errorexit();
	}
}

// Note that we can (and do) add arbitrary attributes to a DIE, but
// only the ones actually listed in the Abbrev will be written out.
static void
putattrs(int abbrev, DWAttr* attr)
{
	DWAttr *attrs[DW_AT_recursive + 1];
	DWAttrForm* af;

	memset(attrs, 0, sizeof attrs);
	for( ; attr; attr = attr->link)
		if (attr->atr < nelem(attrs))
			attrs[attr->atr] = attr;

	for(af = abbrevs[abbrev].attr; af->attr; af++)
		if (attrs[af->attr])
			putattr(abbrev, af->form,
				attrs[af->attr]->cls,
				attrs[af->attr]->value,
				attrs[af->attr]->data);
		else
			putattr(abbrev, af->form, 0, 0, nil);
}

static void putdie(DWDie* die);

static void
putdies(DWDie* die)
{
	for(; die; die = die->link)
		putdie(die);
}

static void
putdie(DWDie* die)
{
	die->offs = cpos() - infoo;
	uleb128put(die->abbrev);
	putattrs(die->abbrev, die->attr);
	if (abbrevs[die->abbrev].children) {
		putdies(die->child);
		cput(0);
	}
}

static void
reverselist(DWDie** list)
{
	DWDie *curr, *prev;

	curr = *list;
	prev = nil;
	while(curr != nil) {
		DWDie* next = curr->link;
		curr->link = prev;
		prev = curr;
		curr = next;
	}
	*list = prev;
}

static void
reversetree(DWDie** list)
{
	 DWDie *die;

	 reverselist(list);
	 for (die = *list; die != nil; die = die->link)
		 if (abbrevs[die->abbrev].children)
			 reversetree(&die->child);
}

static void
newmemberoffsetattr(DWDie *die, int32 offs)
{
	char block[10];
	int i;

	i = 0;
	if (offs != 0) {
		block[i++] = DW_OP_consts;
		i += sleb128enc(offs, block+i);
		block[i++] = DW_OP_plus;
	}
	newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, i, mal(i));
	memmove(die->attr->data, block, i);
}

// GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
// location expression that evals to a const.
static void
newabslocexprattr(DWDie *die, vlong addr, LSym *sym)
{
	newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, (char*)sym);
}


// Fake attributes for slices, maps and channel
enum {
	DW_AT_internal_elem_type = 250,	 // channels and slices
	DW_AT_internal_key_type = 251,	 // maps
	DW_AT_internal_val_type = 252,	 // maps
	DW_AT_internal_location = 253,	 // params and locals
};

static DWDie* defptrto(DWDie *dwtype);	// below

// Lookup predefined types
static LSym*
lookup_or_diag(char *n)
{
	LSym *s;

	s = linkrlookup(ctxt, n, 0);
	if (s == nil || s->size == 0) {
		diag("dwarf: missing type: %s", n);
		errorexit();
	}
	return s;
}

static void
dotypedef(DWDie *parent, char *name, DWDie *def)
{
	DWDie *die;

	// Only emit typedefs for real names.
	if(strncmp(name, "map[", 4) == 0)
		return;
	if(strncmp(name, "struct {", 8) == 0)
		return;
	if(strncmp(name, "chan ", 5) == 0)
		return;
	if(*name == '[' || *name == '*')
		return;
	if(def == nil)
		diag("dwarf: bad def in dotypedef");

	// The typedef entry must be created after the def,
	// so that future lookups will find the typedef instead
	// of the real definition. This hooks the typedef into any
	// circular definition loops, so that gdb can understand them.
	die = newdie(parent, DW_ABRV_TYPEDECL, name);
	newrefattr(die, DW_AT_type, def);
}

// Define gotype, for composite ones recurse into constituents.
static DWDie*
defgotype(LSym *gotype)
{
	DWDie *die, *fld;
	LSym *s;
	char *name, *f;
	uint8 kind;
	vlong bytesize;
	int i, nfields;

	if (gotype == nil)
		return find_or_diag(&dwtypes, "<unspecified>");

	if (strncmp("type.", gotype->name, 5) != 0) {
		diag("dwarf: type name doesn't start with \".type\": %s", gotype->name);
		return find_or_diag(&dwtypes, "<unspecified>");
	}
	name = gotype->name + 5;  // could also decode from Type.string

	die = find(&dwtypes, name);
	if (die != nil)
		return die;

	if (0 && debug['v'] > 2)
		print("new type: %Y\n", gotype);

	kind = decodetype_kind(gotype);
	bytesize = decodetype_size(gotype);

	switch (kind) {
	case KindBool:
		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_boolean, 0);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		break;

	case KindInt:
	case KindInt8:
	case KindInt16:
	case KindInt32:
	case KindInt64:
		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_signed, 0);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		break;

	case KindUint:
	case KindUint8:
	case KindUint16:
	case KindUint32:
	case KindUint64:
	case KindUintptr:
		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		break;

	case KindFloat32:
	case KindFloat64:
		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_float, 0);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		break;

	case KindComplex64:
	case KindComplex128:
		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
		newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_complex_float, 0);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		break;

	case KindArray:
		die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name);
		dotypedef(&dwtypes, name, die);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		s = decodetype_arrayelem(gotype);
		newrefattr(die, DW_AT_type, defgotype(s));
		fld = newdie(die, DW_ABRV_ARRAYRANGE, "range");
		newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0);
		newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
		break;

	case KindChan:
		die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		s = decodetype_chanelem(gotype);
		newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
		break;

	case KindFunc:
		die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name);
		dotypedef(&dwtypes, name, die);
		newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "void"));
		nfields = decodetype_funcincount(gotype);
		for (i = 0; i < nfields; i++) {
			s = decodetype_funcintype(gotype, i);
			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s->name+5);
			newrefattr(fld, DW_AT_type, defgotype(s));
		}
		if (decodetype_funcdotdotdot(gotype))
			newdie(die, DW_ABRV_DOTDOTDOT, "...");
		nfields = decodetype_funcoutcount(gotype);
		for (i = 0; i < nfields; i++) {
			s = decodetype_funcouttype(gotype, i);
			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s->name+5);
			newrefattr(fld, DW_AT_type, defptrto(defgotype(s)));
		}
		break;

	case KindInterface:
		die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name);
		dotypedef(&dwtypes, name, die);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		nfields = decodetype_ifacemethodcount(gotype);
		if (nfields == 0)
			s = lookup_or_diag("type.runtime.eface");
		else
			s = lookup_or_diag("type.runtime.iface");
		newrefattr(die, DW_AT_type, defgotype(s));
		break;

	case KindMap:
		die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name);
		s = decodetype_mapkey(gotype);
		newrefattr(die, DW_AT_internal_key_type, defgotype(s));
		s = decodetype_mapvalue(gotype);
		newrefattr(die, DW_AT_internal_val_type, defgotype(s));
		break;

	case KindPtr:
		die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
		dotypedef(&dwtypes, name, die);
		s = decodetype_ptrelem(gotype);
		newrefattr(die, DW_AT_type, defgotype(s));
		break;

	case KindSlice:
		die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name);
		dotypedef(&dwtypes, name, die);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		s = decodetype_arrayelem(gotype);
		newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
		break;

	case KindString:
		die = newdie(&dwtypes, DW_ABRV_STRINGTYPE, name);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		break;

	case KindStruct:
		die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name);
		dotypedef(&dwtypes, name, die);
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
		nfields = decodetype_structfieldcount(gotype);
		for (i = 0; i < nfields; i++) {
			f = decodetype_structfieldname(gotype, i);
			s = decodetype_structfieldtype(gotype, i);
			if (f == nil)
				f = s->name + 5;	 // skip "type."
			fld = newdie(die, DW_ABRV_STRUCTFIELD, f);
			newrefattr(fld, DW_AT_type, defgotype(s));
			newmemberoffsetattr(fld, decodetype_structfieldoffs(gotype, i));
		}
		break;

	case KindUnsafePointer:
		die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name);
		break;

	default:
		diag("dwarf: definition of unknown kind %d: %s", kind, gotype->name);
		die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name);
		newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "<unspecified>"));
	 }

	return die;
}

// Find or construct *T given T.
static DWDie*
defptrto(DWDie *dwtype)
{
	char ptrname[1024];
	DWDie *die;

	snprint(ptrname, sizeof ptrname, "*%s", getattr(dwtype, DW_AT_name)->data);
	die = find(&dwtypes, ptrname);
	if (die == nil) {
		die = newdie(&dwtypes, DW_ABRV_PTRTYPE,
			     strcpy(mal(strlen(ptrname)+1), ptrname));
		newrefattr(die, DW_AT_type, dwtype);
	}
	return die;
}

// Copies src's children into dst. Copies attributes by value.
// DWAttr.data is copied as pointer only.  If except is one of
// the top-level children, it will not be copied.
static void
copychildrenexcept(DWDie *dst, DWDie *src, DWDie *except)
{
	DWDie *c;
	DWAttr *a;

	for (src = src->child; src != nil; src = src->link) {
		if(src == except)
			continue;
		c = newdie(dst, src->abbrev, getattr(src, DW_AT_name)->data);
		for (a = src->attr; a != nil; a = a->link)
			newattr(c, a->atr, a->cls, a->value, a->data);
		copychildrenexcept(c, src, nil);
	}
	reverselist(&dst->child);
}
static void
copychildren(DWDie *dst, DWDie *src)
{
	copychildrenexcept(dst, src, nil);
}

// Search children (assumed to have DW_TAG_member) for the one named
// field and set its DW_AT_type to dwtype
static void
substitutetype(DWDie *structdie, char *field, DWDie* dwtype)
{
	DWDie *child;
	DWAttr *a;

	child = find_or_diag(structdie, field);
	if (child == nil)
		return;

	a = getattr(child, DW_AT_type);
	if (a != nil)
		a->data = (char*) dwtype;
	else
		newrefattr(child, DW_AT_type, dwtype);
}

static void
synthesizestringtypes(DWDie* die)
{
	DWDie *prototype;

	prototype = walktypedef(defgotype(lookup_or_diag("type.runtime._string")));
	if (prototype == nil)
		return;

	for (; die != nil; die = die->link) {
		if (die->abbrev != DW_ABRV_STRINGTYPE)
			continue;
		copychildren(die, prototype);
	}
}

static void
synthesizeslicetypes(DWDie *die)
{
	DWDie *prototype, *elem;

	prototype = walktypedef(defgotype(lookup_or_diag("type.runtime.slice")));
	if (prototype == nil)
		return;

	for (; die != nil; die = die->link) {
		if (die->abbrev != DW_ABRV_SLICETYPE)
			continue;
		copychildren(die, prototype);
		elem = (DWDie*) getattr(die, DW_AT_internal_elem_type)->data;
		substitutetype(die, "array", defptrto(elem));
	}
}

static char*
mkinternaltypename(char *base, char *arg1, char *arg2)
{
	char buf[1024];
	char *n;

	if (arg2 == nil)
		snprint(buf, sizeof buf, "%s<%s>", base, arg1);
	else
		snprint(buf, sizeof buf, "%s<%s,%s>", base, arg1, arg2);
	n = mal(strlen(buf) + 1);
	memmove(n, buf, strlen(buf));
	return n;
}

// synthesizemaptypes is way too closely married to runtime/hashmap.c
enum {
	MaxKeySize = 128,
	MaxValSize = 128,
	BucketSize = 8,
};

static void
synthesizemaptypes(DWDie *die)
{

	DWDie *hash, *bucket, *dwh, *dwhk, *dwhv, *dwhb, *keytype, *valtype, *fld;
	int indirect_key, indirect_val;
	int keysize, valsize;
	DWAttr *a;

	hash		= walktypedef(defgotype(lookup_or_diag("type.runtime.hmap")));
	bucket		= walktypedef(defgotype(lookup_or_diag("type.runtime.bucket")));

	if (hash == nil)
		return;

	for (; die != nil; die = die->link) {
		if (die->abbrev != DW_ABRV_MAPTYPE)
			continue;

		keytype = walktypedef((DWDie*) getattr(die, DW_AT_internal_key_type)->data);
		valtype = walktypedef((DWDie*) getattr(die, DW_AT_internal_val_type)->data);

		// compute size info like hashmap.c does.
		a = getattr(keytype, DW_AT_byte_size);
		keysize = a ? a->value : PtrSize;  // We don't store size with Pointers
		a = getattr(valtype, DW_AT_byte_size);
		valsize = a ? a->value : PtrSize;
		indirect_key = 0;
		indirect_val = 0;
		if(keysize > MaxKeySize) {
			keysize = PtrSize;
			indirect_key = 1;
		}
		if(valsize > MaxValSize) {
			valsize = PtrSize;
			indirect_val = 1;
		}

		// Construct type to represent an array of BucketSize keys
		dwhk = newdie(&dwtypes, DW_ABRV_ARRAYTYPE,
			      mkinternaltypename("[]key",
						 getattr(keytype, DW_AT_name)->data, nil));
		newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * keysize, 0);
		newrefattr(dwhk, DW_AT_type, indirect_key ? defptrto(keytype) : keytype);
		fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size");
		newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0);
		newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
		
		// Construct type to represent an array of BucketSize values
		dwhv = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, 
			      mkinternaltypename("[]val",
						 getattr(valtype, DW_AT_name)->data, nil));
		newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * valsize, 0);
		newrefattr(dwhv, DW_AT_type, indirect_val ? defptrto(valtype) : valtype);
		fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size");
		newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0);
		newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));

		// Construct bucket<K,V>
		dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
			      mkinternaltypename("bucket",
						 getattr(keytype, DW_AT_name)->data,
						 getattr(valtype, DW_AT_name)->data));
		// Copy over all fields except the field "data" from the generic bucket.
		// "data" will be replaced with keys/values below.
		copychildrenexcept(dwhb, bucket, find(bucket, "data"));
		
		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys");
		newrefattr(fld, DW_AT_type, dwhk);
		newmemberoffsetattr(fld, BucketSize + PtrSize);
		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values");
		newrefattr(fld, DW_AT_type, dwhv);
		newmemberoffsetattr(fld, BucketSize + PtrSize + BucketSize * keysize);
		newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize + PtrSize + BucketSize * keysize + BucketSize * valsize, 0);
		substitutetype(dwhb, "overflow", defptrto(dwhb));

		// Construct hash<K,V>
		dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
			mkinternaltypename("hash",
				getattr(keytype, DW_AT_name)->data,
				getattr(valtype, DW_AT_name)->data));
		copychildren(dwh, hash);
		substitutetype(dwh, "buckets", defptrto(dwhb));
		substitutetype(dwh, "oldbuckets", defptrto(dwhb));
		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
			getattr(hash, DW_AT_byte_size)->value, nil);

		// make map type a pointer to hash<K,V>
		newrefattr(die, DW_AT_type, defptrto(dwh));
	}
}

static void
synthesizechantypes(DWDie *die)
{
	DWDie *sudog, *waitq, *hchan,
		*dws, *dww, *dwh, *elemtype;
	DWAttr *a;
	int elemsize, sudogsize;

	sudog = walktypedef(defgotype(lookup_or_diag("type.runtime.sudog")));
	waitq = walktypedef(defgotype(lookup_or_diag("type.runtime.waitq")));
	hchan = walktypedef(defgotype(lookup_or_diag("type.runtime.hchan")));
	if (sudog == nil || waitq == nil || hchan == nil)
		return;

	sudogsize = getattr(sudog, DW_AT_byte_size)->value;

	for (; die != nil; die = die->link) {
		if (die->abbrev != DW_ABRV_CHANTYPE)
			continue;
		elemtype = (DWDie*) getattr(die, DW_AT_internal_elem_type)->data;
		a = getattr(elemtype, DW_AT_byte_size);
		elemsize = a ? a->value : PtrSize;

		// sudog<T>
		dws = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
			mkinternaltypename("sudog",
				getattr(elemtype, DW_AT_name)->data, nil));
		copychildren(dws, sudog);
		substitutetype(dws, "elem", elemtype);
		newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT,
			sudogsize + (elemsize > 8 ? elemsize - 8 : 0), nil);

		// waitq<T>
		dww = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
			mkinternaltypename("waitq", getattr(elemtype, DW_AT_name)->data, nil));
		copychildren(dww, waitq);
		substitutetype(dww, "first", defptrto(dws));
		substitutetype(dww, "last",  defptrto(dws));
		newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT,
			getattr(waitq, DW_AT_byte_size)->value, nil);

		// hchan<T>
		dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
			mkinternaltypename("hchan", getattr(elemtype, DW_AT_name)->data, nil));
		copychildren(dwh, hchan);
		substitutetype(dwh, "recvq", dww);
		substitutetype(dwh, "sendq", dww);
		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
			getattr(hchan, DW_AT_byte_size)->value, nil);

		newrefattr(die, DW_AT_type, defptrto(dwh));
	}
}

// For use with pass.c::genasmsym
static void
defdwsymb(LSym* sym, char *s, int t, vlong v, vlong size, int ver, LSym *gotype)
{
	DWDie *dv, *dt;

	USED(size);
	if (strncmp(s, "go.string.", 10) == 0)
		return;

	if (strncmp(s, "type.", 5) == 0 && strcmp(s, "type.*") != 0 && strncmp(s, "type..", 6) != 0) {
		defgotype(sym);
		return;
	}

	dv = nil;

	switch (t) {
	default:
		return;
	case 'd':
	case 'b':
	case 'D':
	case 'B':
		dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s);
		newabslocexprattr(dv, v, sym);
		if (ver == 0)
			newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0);
		// fallthrough
	case 'a':
	case 'p':
		dt = defgotype(gotype);
	}

	if (dv != nil)
		newrefattr(dv, DW_AT_type, dt);
}

static void
movetomodule(DWDie *parent)
{
	DWDie *die;

	die = dwroot.child->child;
	while(die->link != nil)
		die = die->link;
	die->link = parent->child;
}

// If the pcln table contains runtime/string.goc, use that to set gdbscript path.
static void
finddebugruntimepath(LSym *s)
{
	int i;
	char *p;
	LSym *f;
	
	if(gdbscript[0] != '\0')
		return;

	for(i=0; i<s->pcln->nfile; i++) {
		f = s->pcln->file[i];
		if((p = strstr(f->name, "runtime/string.goc")) != nil) {
			*p = '\0';
			snprint(gdbscript, sizeof gdbscript, "%sruntime/runtime-gdb.py", f->name);
			*p = 'r';
			break;
		}
	}
}

/*
 * Generate short opcodes when possible, long ones when necessary.
 * See section 6.2.5
 */

enum {
	LINE_BASE = -1,
	LINE_RANGE = 4,
	OPCODE_BASE = 10
};

static void
putpclcdelta(vlong delta_pc, vlong delta_lc)
{
	if (LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE) {
		vlong opcode = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc);
		if (OPCODE_BASE <= opcode && opcode < 256) {
			cput(opcode);
			return;
		}
	}

	if (delta_pc) {
		cput(DW_LNS_advance_pc);
		sleb128put(delta_pc);
	}

	cput(DW_LNS_advance_line);
	sleb128put(delta_lc);
	cput(DW_LNS_copy);
}

static void
newcfaoffsetattr(DWDie *die, int32 offs)
{
	char block[10];
	int i;

	i = 0;

	block[i++] = DW_OP_call_frame_cfa;
	if (offs != 0) {
		block[i++] = DW_OP_consts;
		i += sleb128enc(offs, block+i);
		block[i++] = DW_OP_plus;
	}
	newattr(die, DW_AT_location, DW_CLS_BLOCK, i, mal(i));
	memmove(die->attr->data, block, i);
}

static char*
mkvarname(char* name, int da)
{
	char buf[1024];
	char *n;

	snprint(buf, sizeof buf, "%s#%d", name, da);
	n = mal(strlen(buf) + 1);
	memmove(n, buf, strlen(buf));
	return n;
}

/*
 * Walk prog table, emit line program and build DIE tree.
 */

// flush previous compilation unit.
static void
flushunit(DWDie *dwinfo, vlong pc, LSym *pcsym, vlong unitstart, int32 header_length)
{
	vlong here;

	if (dwinfo != nil && pc != 0) {
		newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, (char*)pcsym);
	}

	if (unitstart >= 0) {
		cput(0);  // start extended opcode
		uleb128put(1);
		cput(DW_LNE_end_sequence);

		here = cpos();
		cseek(unitstart);
		LPUT(here - unitstart - sizeof(int32));	 // unit_length
		WPUT(2);  // dwarf version
		LPUT(header_length); // header length starting here
		cseek(here);
	}
}

static void
writelines(void)
{
	LSym *s, *epcs;
	Auto *a;
	vlong unitstart, headerend, offs;
	vlong pc, epc;
	int i, lang, da, dt, line, file;
	DWDie *dwinfo, *dwfunc, *dwvar, **dws;
	DWDie *varhash[HASHSIZE];
	char *n, *nn;
	Pciter pcfile, pcline;
	LSym **files, *f;

	if(linesec == S)
		linesec = linklookup(ctxt, ".dwarfline", 0);
	linesec->nr = 0;

	unitstart = -1;
	headerend = -1;
	epc = 0;
	epcs = S;
	lineo = cpos();
	dwinfo = nil;
	
	flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
	unitstart = cpos();
	
	lang = DW_LANG_Go;
	
	s = ctxt->textp;

	dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, estrdup("go"));
	newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT,lang, 0);
	newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
	newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, (char*)s);

	// Write .debug_line Line Number Program Header (sec 6.2.4)
	// Fields marked with (*) must be changed for 64-bit dwarf
	LPUT(0);   // unit_length (*), will be filled in by flushunit.
	WPUT(2);   // dwarf version (appendix F)
	LPUT(0);   // header_length (*), filled in by flushunit.
	// cpos == unitstart + 4 + 2 + 4
	cput(1);   // minimum_instruction_length
	cput(1);   // default_is_stmt
	cput(LINE_BASE);     // line_base
	cput(LINE_RANGE);    // line_range
	cput(OPCODE_BASE);   // opcode_base
	cput(0);   // standard_opcode_lengths[1]
	cput(1);   // standard_opcode_lengths[2]
	cput(1);   // standard_opcode_lengths[3]
	cput(1);   // standard_opcode_lengths[4]
	cput(1);   // standard_opcode_lengths[5]
	cput(0);   // standard_opcode_lengths[6]
	cput(0);   // standard_opcode_lengths[7]
	cput(0);   // standard_opcode_lengths[8]
	cput(1);   // standard_opcode_lengths[9]
	cput(0);   // include_directories  (empty)

	files = emallocz(ctxt->nhistfile*sizeof files[0]);
	for(f = ctxt->filesyms; f != nil; f = f->next)
		files[f->value-1] = f;

	for(i=0; i<ctxt->nhistfile; i++) {
		strnput(files[i]->name, strlen(files[i]->name) + 4);
		// 4 zeros: the string termination + 3 fields.
	}

	cput(0);   // terminate file_names.
	headerend = cpos();

	cput(0);  // start extended opcode
	uleb128put(1 + PtrSize);
	cput(DW_LNE_set_address);

	pc = s->value;
	line = 1;
	file = 1;
	if(linkmode == LinkExternal)
		adddwarfrel(linesec, s, lineo, PtrSize, 0);
	else
		addrput(pc);

	for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
		s = ctxt->cursym;

		dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s->name);
		newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, (char*)s);
		epc = s->value + s->size;
		epcs = s;
		newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, (char*)s);
		if (s->version == 0)
			newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);

		if(s->pcln == nil)
			continue;

		finddebugruntimepath(s);

		pciterinit(ctxt, &pcfile, &s->pcln->pcfile);
		pciterinit(ctxt, &pcline, &s->pcln->pcline);
		epc = pc;
		while(!pcfile.done && !pcline.done) {
			if(epc - s->value >= pcfile.nextpc) {
				pciternext(&pcfile);
				continue;
			}
			if(epc - s->value >= pcline.nextpc) {
				pciternext(&pcline);
				continue;
			}

			if(file != pcfile.value) {
				cput(DW_LNS_set_file);
				uleb128put(pcfile.value);
				file = pcfile.value;
			}
			putpclcdelta(s->value + pcline.pc - pc, pcline.value - line);

			pc = epc;
			if(pcfile.nextpc < pcline.nextpc)
				epc = pcfile.nextpc;
			else
				epc = pcline.nextpc;
			epc += s->value;
			line = pcline.value;
		}

		da = 0;
		dwfunc->hash = varhash;	 // enable indexing of children by name
		memset(varhash, 0, sizeof varhash);
		for(a = s->autom; a; a = a->link) {
			switch (a->type) {
			case A_AUTO:
				dt = DW_ABRV_AUTO;
				offs = a->aoffset - PtrSize;
				break;
			case A_PARAM:
				dt = DW_ABRV_PARAM;
				offs = a->aoffset;
				break;
			default:
				continue;
			}
			if (strstr(a->asym->name, ".autotmp_"))
				continue;
			if (find(dwfunc, a->asym->name) != nil)
				n = mkvarname(a->asym->name, da);
			else
				n = a->asym->name;
			// Drop the package prefix from locals and arguments.
			nn = strrchr(n, '.');
			if (nn)
				n = nn + 1;

			dwvar = newdie(dwfunc, dt, n);
			newcfaoffsetattr(dwvar, offs);
			newrefattr(dwvar, DW_AT_type, defgotype(a->gotype));

			// push dwvar down dwfunc->child to preserve order
			newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil);
			dwfunc->child = dwvar->link;  // take dwvar out from the top of the list
			for (dws = &dwfunc->child; *dws != nil; dws = &(*dws)->link)
				if (offs > getattr(*dws, DW_AT_internal_location)->value)
					break;
			dwvar->link = *dws;
			*dws = dwvar;

			da++;
		}

		dwfunc->hash = nil;
	}

	flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
	linesize = cpos() - lineo;
}

/*
 *  Emit .debug_frame
 */
enum
{
	CIERESERVE = 16,
	DATAALIGNMENTFACTOR = -4,	// TODO -PtrSize?
	FAKERETURNCOLUMN = 16		// TODO gdb6 doesn't like > 15?
};

static void
putpccfadelta(vlong deltapc, vlong cfa)
{
	if (deltapc < 0x40) {
		cput(DW_CFA_advance_loc + deltapc);
	} else if (deltapc < 0x100) {
		cput(DW_CFA_advance_loc1);
		cput(deltapc);
	} else if (deltapc < 0x10000) {
		cput(DW_CFA_advance_loc2);
		WPUT(deltapc);
	} else {
		cput(DW_CFA_advance_loc4);
		LPUT(deltapc);
	}

	cput(DW_CFA_def_cfa_offset_sf);
	sleb128put(cfa / DATAALIGNMENTFACTOR);
}

static void
writeframes(void)
{
	LSym *s;
	vlong fdeo, fdesize, pad;
	Pciter pcsp;

	if(framesec == S)
		framesec = linklookup(ctxt, ".dwarfframe", 0);
	framesec->nr = 0;
	frameo = cpos();

	// Emit the CIE, Section 6.4.1
	LPUT(CIERESERVE);	// initial length, must be multiple of PtrSize
	LPUT(0xffffffff);	// cid.
	cput(3);		// dwarf version (appendix F)
	cput(0);		// augmentation ""
	uleb128put(1);		// code_alignment_factor
	sleb128put(DATAALIGNMENTFACTOR); // guess
	uleb128put(FAKERETURNCOLUMN);	// return_address_register

	cput(DW_CFA_def_cfa);
	uleb128put(DWARFREGSP);	// register SP (**ABI-dependent, defined in l.h)
	uleb128put(PtrSize);	// offset

	cput(DW_CFA_offset + FAKERETURNCOLUMN);	 // return address
	uleb128put(-PtrSize / DATAALIGNMENTFACTOR);  // at cfa - x*4

	// 4 is to exclude the length field.
	pad = CIERESERVE + frameo + 4 - cpos();
	if (pad < 0) {
		diag("dwarf: CIERESERVE too small by %lld bytes.", -pad);
		errorexit();
	}
	strnput("", pad);

	for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
		s = ctxt->cursym;
		if(s->pcln == nil)
			continue;

		fdeo = cpos();
		// Emit a FDE, Section 6.4.1, starting wit a placeholder.
		LPUT(0);	// length, must be multiple of PtrSize
		LPUT(0);	// Pointer to the CIE above, at offset 0
		addrput(0);	// initial location
		addrput(0);	// address range

		for(pciterinit(ctxt, &pcsp, &s->pcln->pcsp); !pcsp.done; pciternext(&pcsp))
			putpccfadelta(pcsp.nextpc - pcsp.pc, PtrSize + pcsp.value);

		fdesize = cpos() - fdeo - 4;	// exclude the length field.
		pad = rnd(fdesize, PtrSize) - fdesize;
		strnput("", pad);
		fdesize += pad;

		// Emit the FDE header for real, Section 6.4.1.
		cseek(fdeo);
		LPUT(fdesize);
		if(linkmode == LinkExternal) {
			adddwarfrel(framesec, framesym, frameo, 4, 0);
			adddwarfrel(framesec, s, frameo, PtrSize, 0);
		}
		else {
			LPUT(0);
			addrput(s->value);
		}
		addrput(s->size);
		cseek(fdeo + 4 + fdesize);
	}

	cflush();
	framesize = cpos() - frameo;
}

/*
 *  Walk DWarfDebugInfoEntries, and emit .debug_info
 */
enum
{
	COMPUNITHEADERSIZE = 4+2+4+1
};

static void
writeinfo(void)
{
	DWDie *compunit;
	vlong unitstart, here;

	fwdcount = 0;
	if (infosec == S)
		infosec = linklookup(ctxt, ".dwarfinfo", 0);
	infosec->nr = 0;

	if(arangessec == S)
		arangessec = linklookup(ctxt, ".dwarfaranges", 0);
	arangessec->nr = 0;

	for (compunit = dwroot.child; compunit; compunit = compunit->link) {
		unitstart = cpos();

		// Write .debug_info Compilation Unit Header (sec 7.5.1)
		// Fields marked with (*) must be changed for 64-bit dwarf
		// This must match COMPUNITHEADERSIZE above.
		LPUT(0);	// unit_length (*), will be filled in later.
		WPUT(2);	// dwarf version (appendix F)

		// debug_abbrev_offset (*)
		if(linkmode == LinkExternal)
			adddwarfrel(infosec, abbrevsym, infoo, 4, 0);
		else
			LPUT(0);

		cput(PtrSize);	// address_size

		putdie(compunit);

		here = cpos();
		cseek(unitstart);
		LPUT(here - unitstart - 4);	// exclude the length field.
		cseek(here);
	}
	cflush();
}

/*
 *  Emit .debug_pubnames/_types.  _info must have been written before,
 *  because we need die->offs and infoo/infosize;
 */
static int
ispubname(DWDie *die)
{
	DWAttr *a;

	switch(die->abbrev) {
	case DW_ABRV_FUNCTION:
	case DW_ABRV_VARIABLE:
		a = getattr(die, DW_AT_external);
		return a && a->value;
	}
	return 0;
}

static int
ispubtype(DWDie *die)
{
	return die->abbrev >= DW_ABRV_NULLTYPE;
}

static vlong
writepub(int (*ispub)(DWDie*))
{
	DWDie *compunit, *die;
	DWAttr *dwa;
	vlong unitstart, unitend, sectionstart, here;

	sectionstart = cpos();

	for (compunit = dwroot.child; compunit != nil; compunit = compunit->link) {
		unitstart = compunit->offs - COMPUNITHEADERSIZE;
		if (compunit->link != nil)
			unitend = compunit->link->offs - COMPUNITHEADERSIZE;
		else
			unitend = infoo + infosize;

		// Write .debug_pubnames/types	Header (sec 6.1.1)
		LPUT(0);			// unit_length (*), will be filled in later.
		WPUT(2);			// dwarf version (appendix F)
		LPUT(unitstart);		// debug_info_offset (of the Comp unit Header)
		LPUT(unitend - unitstart);	// debug_info_length

		for (die = compunit->child; die != nil; die = die->link) {
			if (!ispub(die)) continue;
			LPUT(die->offs - unitstart);
			dwa = getattr(die, DW_AT_name);
			strnput(dwa->data, dwa->value + 1);
		}
		LPUT(0);

		here = cpos();
		cseek(sectionstart);
		LPUT(here - sectionstart - 4);	// exclude the length field.
		cseek(here);

	}

	return sectionstart;
}

/*
 *  emit .debug_aranges.  _info must have been written before,
 *  because we need die->offs of dw_globals.
 */
static vlong
writearanges(void)
{
	DWDie *compunit;
	DWAttr *b, *e;
	int headersize;
	vlong sectionstart;
	vlong value;

	sectionstart = cpos();
	headersize = rnd(4+2+4+1+1, PtrSize);  // don't count unit_length field itself

	for (compunit = dwroot.child; compunit != nil; compunit = compunit->link) {
		b = getattr(compunit,  DW_AT_low_pc);
		if (b == nil)
			continue;
		e = getattr(compunit,  DW_AT_high_pc);
		if (e == nil)
			continue;

		// Write .debug_aranges	 Header + entry	 (sec 6.1.2)
		LPUT(headersize + 4*PtrSize - 4);	// unit_length (*)
		WPUT(2);	// dwarf version (appendix F)

		value = compunit->offs - COMPUNITHEADERSIZE;	// debug_info_offset
		if(linkmode == LinkExternal)
			adddwarfrel(arangessec, infosym, sectionstart, 4, value);
		else
			LPUT(value);

		cput(PtrSize);	// address_size
		cput(0);	// segment_size
		strnput("", headersize - (4+2+4+1+1));	// align to PtrSize

		if(linkmode == LinkExternal)
			adddwarfrel(arangessec, (LSym*)b->data, sectionstart, PtrSize, b->value-((LSym*)b->data)->value);
		else
			addrput(b->value);

		addrput(e->value - b->value);
		addrput(0);
		addrput(0);
	}
	cflush();
	return sectionstart;
}

static vlong
writegdbscript(void)
{
	vlong sectionstart;

	sectionstart = cpos();

	if (gdbscript[0]) {
		cput(1);  // magic 1 byte?
		strnput(gdbscript, strlen(gdbscript)+1);
		cflush();
	}
	return sectionstart;
}

static void
align(vlong size)
{
	if(HEADTYPE == Hwindows) // Only Windows PE need section align.
		strnput("", rnd(size, PEFILEALIGN) - size);
}

static vlong
writedwarfreloc(LSym* s)
{
	int i;
	vlong start;
	Reloc *r;
	
	start = cpos();
	for(r = s->r; r < s->r+s->nr; r++) {
		if(iself)
			i = elfreloc1(r, r->off);
		else if(HEADTYPE == Hdarwin)
			i = machoreloc1(r, r->off);
		else
			i = -1;
		if(i < 0)
			diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name);
	}
	return start;
}

/*
 * This is the main entry point for generating dwarf.  After emitting
 * the mandatory debug_abbrev section, it calls writelines() to set up
 * the per-compilation unit part of the DIE tree, while simultaneously
 * emitting the debug_line section.  When the final tree contains
 * forward references, it will write the debug_info section in 2
 * passes.
 *
 */
void
dwarfemitdebugsections(void)
{
	vlong infoe;
	DWDie* die;

	if(debug['w'])  // disable dwarf
		return;

	if(linkmode == LinkExternal && !iself)
		return;

	// For diagnostic messages.
	newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, strlen("dwtypes"), "dwtypes");

	mkindex(&dwroot);
	mkindex(&dwtypes);
	mkindex(&dwglobals);

	// Some types that must exist to define other ones.
	newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>");
	newdie(&dwtypes, DW_ABRV_NULLTYPE, "void");
	newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer");
	die = newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr");  // needed for array size
	newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
	newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, PtrSize, 0);

	// Needed by the prettyprinter code for interface inspection.
	defgotype(lookup_or_diag("type.runtime.rtype"));
	defgotype(lookup_or_diag("type.runtime.interfaceType"));
	defgotype(lookup_or_diag("type.runtime.itab"));

	genasmsym(defdwsymb);

	writeabbrev();
	align(abbrevsize);
	writelines();
	align(linesize);
	writeframes();
	align(framesize);

	synthesizestringtypes(dwtypes.child);
	synthesizeslicetypes(dwtypes.child);
	synthesizemaptypes(dwtypes.child);
	synthesizechantypes(dwtypes.child);

	reversetree(&dwroot.child);
	reversetree(&dwtypes.child);
	reversetree(&dwglobals.child);

	movetomodule(&dwtypes);
	movetomodule(&dwglobals);

	infoo = cpos();
	writeinfo();
	infoe = cpos();
	pubnameso = infoe;
	pubtypeso = infoe;
	arangeso = infoe;
	gdbscripto = infoe;

	if (fwdcount > 0) {
		if (debug['v'])
			Bprint(&bso, "%5.2f dwarf pass 2.\n", cputime());
		cseek(infoo);
		writeinfo();
		if (fwdcount > 0) {
			diag("dwarf: unresolved references after first dwarf info pass");
			errorexit();
		}
		if (infoe != cpos()) {
			diag("dwarf: inconsistent second dwarf info pass");
			errorexit();
		}
	}
	infosize = infoe - infoo;
	align(infosize);

	pubnameso  = writepub(ispubname);
	pubnamessize  = cpos() - pubnameso;
	align(pubnamessize);

	pubtypeso  = writepub(ispubtype);
	pubtypessize  = cpos() - pubtypeso;
	align(pubtypessize);

	arangeso   = writearanges();
	arangessize   = cpos() - arangeso;
	align(arangessize);

	gdbscripto = writegdbscript();
	gdbscriptsize = cpos() - gdbscripto;
	align(gdbscriptsize);

	while(cpos()&7)
		cput(0);
	inforeloco = writedwarfreloc(infosec);
	inforelocsize = cpos() - inforeloco;
	align(inforelocsize);

	arangesreloco = writedwarfreloc(arangessec);
	arangesrelocsize = cpos() - arangesreloco;
	align(arangesrelocsize);

	linereloco = writedwarfreloc(linesec);
	linerelocsize = cpos() - linereloco;
	align(linerelocsize);

	framereloco = writedwarfreloc(framesec);
	framerelocsize = cpos() - framereloco;
	align(framerelocsize);
}

/*
 *  Elf.
 */
enum
{
	ElfStrDebugAbbrev,
	ElfStrDebugAranges,
	ElfStrDebugFrame,
	ElfStrDebugInfo,
	ElfStrDebugLine,
	ElfStrDebugLoc,
	ElfStrDebugMacinfo,
	ElfStrDebugPubNames,
	ElfStrDebugPubTypes,
	ElfStrDebugRanges,
	ElfStrDebugStr,
	ElfStrGDBScripts,
	ElfStrRelDebugInfo,
	ElfStrRelDebugAranges,
	ElfStrRelDebugLine,
	ElfStrRelDebugFrame,
	NElfStrDbg
};

vlong elfstrdbg[NElfStrDbg];

void
dwarfaddshstrings(LSym *shstrtab)
{
	if(debug['w'])  // disable dwarf
		return;

	elfstrdbg[ElfStrDebugAbbrev]   = addstring(shstrtab, ".debug_abbrev");
	elfstrdbg[ElfStrDebugAranges]  = addstring(shstrtab, ".debug_aranges");
	elfstrdbg[ElfStrDebugFrame]    = addstring(shstrtab, ".debug_frame");
	elfstrdbg[ElfStrDebugInfo]     = addstring(shstrtab, ".debug_info");
	elfstrdbg[ElfStrDebugLine]     = addstring(shstrtab, ".debug_line");
	elfstrdbg[ElfStrDebugLoc]      = addstring(shstrtab, ".debug_loc");
	elfstrdbg[ElfStrDebugMacinfo]  = addstring(shstrtab, ".debug_macinfo");
	elfstrdbg[ElfStrDebugPubNames] = addstring(shstrtab, ".debug_pubnames");
	elfstrdbg[ElfStrDebugPubTypes] = addstring(shstrtab, ".debug_pubtypes");
	elfstrdbg[ElfStrDebugRanges]   = addstring(shstrtab, ".debug_ranges");
	elfstrdbg[ElfStrDebugStr]      = addstring(shstrtab, ".debug_str");
	elfstrdbg[ElfStrGDBScripts]    = addstring(shstrtab, ".debug_gdb_scripts");
	if(linkmode == LinkExternal) {
		if(thechar == '6') {
			elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rela.debug_info");
			elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rela.debug_aranges");
			elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rela.debug_line");
			elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rela.debug_frame");
		} else {
			elfstrdbg[ElfStrRelDebugInfo] = addstring(shstrtab, ".rel.debug_info");
			elfstrdbg[ElfStrRelDebugAranges] = addstring(shstrtab, ".rel.debug_aranges");
			elfstrdbg[ElfStrRelDebugLine] = addstring(shstrtab, ".rel.debug_line");
			elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rel.debug_frame");
		}

		infosym = linklookup(ctxt, ".debug_info", 0);
		infosym->hide = 1;

		abbrevsym = linklookup(ctxt, ".debug_abbrev", 0);
		abbrevsym->hide = 1;

		linesym = linklookup(ctxt, ".debug_line", 0);
		linesym->hide = 1;

		framesym = linklookup(ctxt, ".debug_frame", 0);
		framesym->hide = 1;
	}
}

// Add section symbols for DWARF debug info.  This is called before
// dwarfaddelfheaders.
void
dwarfaddelfsectionsyms()
{
	if(infosym != nil) {
		infosympos = cpos();
		putelfsectionsym(infosym, 0);
	}
	if(abbrevsym != nil) {
		abbrevsympos = cpos();
		putelfsectionsym(abbrevsym, 0);
	}
	if(linesym != nil) {
		linesympos = cpos();
		putelfsectionsym(linesym, 0);
	}
	if(framesym != nil) {
		framesympos = cpos();
		putelfsectionsym(framesym, 0);
	}
}

static void
dwarfaddelfrelocheader(int elfstr, ElfShdr *shdata, vlong off, vlong size)
{
	ElfShdr *sh;

	sh = newElfShdr(elfstrdbg[elfstr]);
	if(thechar == '6') {
		sh->type = SHT_RELA;
	} else {
		sh->type = SHT_REL;
	}
	sh->entsize = PtrSize*(2+(sh->type==SHT_RELA));
	sh->link = elfshname(".symtab")->shnum;
	sh->info = shdata->shnum;
	sh->off = off;
	sh->size = size;
	sh->addralign = PtrSize;
	
}

void
dwarfaddelfheaders(void)
{
	ElfShdr *sh, *shinfo, *sharanges, *shline, *shframe;

	if(debug['w'])  // disable dwarf
		return;

	sh = newElfShdr(elfstrdbg[ElfStrDebugAbbrev]);
	sh->type = SHT_PROGBITS;
	sh->off = abbrevo;
	sh->size = abbrevsize;
	sh->addralign = 1;
	if(abbrevsympos > 0)
		putelfsymshndx(abbrevsympos, sh->shnum);

	sh = newElfShdr(elfstrdbg[ElfStrDebugLine]);
	sh->type = SHT_PROGBITS;
	sh->off = lineo;
	sh->size = linesize;
	sh->addralign = 1;
	if(linesympos > 0)
		putelfsymshndx(linesympos, sh->shnum);
	shline = sh;

	sh = newElfShdr(elfstrdbg[ElfStrDebugFrame]);
	sh->type = SHT_PROGBITS;
	sh->off = frameo;
	sh->size = framesize;
	sh->addralign = 1;
	if(framesympos > 0)
		putelfsymshndx(framesympos, sh->shnum);
	shframe = sh;

	sh = newElfShdr(elfstrdbg[ElfStrDebugInfo]);
	sh->type = SHT_PROGBITS;
	sh->off = infoo;
	sh->size = infosize;
	sh->addralign = 1;
	if(infosympos > 0)
		putelfsymshndx(infosympos, sh->shnum);
	shinfo = sh;

	if (pubnamessize > 0) {
		sh = newElfShdr(elfstrdbg[ElfStrDebugPubNames]);
		sh->type = SHT_PROGBITS;
		sh->off = pubnameso;
		sh->size = pubnamessize;
		sh->addralign = 1;
	}

	if (pubtypessize > 0) {
		sh = newElfShdr(elfstrdbg[ElfStrDebugPubTypes]);
		sh->type = SHT_PROGBITS;
		sh->off = pubtypeso;
		sh->size = pubtypessize;
		sh->addralign = 1;
	}

	sharanges = nil;
	if (arangessize) {
		sh = newElfShdr(elfstrdbg[ElfStrDebugAranges]);
		sh->type = SHT_PROGBITS;
		sh->off = arangeso;
		sh->size = arangessize;
		sh->addralign = 1;
		sharanges = sh;
	}

	if (gdbscriptsize) {
		sh = newElfShdr(elfstrdbg[ElfStrGDBScripts]);
		sh->type = SHT_PROGBITS;
		sh->off = gdbscripto;
		sh->size = gdbscriptsize;
		sh->addralign = 1;
	}

	if(inforelocsize)
		dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize);

	if(arangesrelocsize)
		dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize);

	if(linerelocsize)
		dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize);

	if(framerelocsize)
		dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize);
}

/*
 * Macho
 */
void
dwarfaddmachoheaders(void)
{
	MachoSect *msect;
	MachoSeg *ms;
	vlong fakestart;
	int nsect;

	if(debug['w'])  // disable dwarf
		return;

	// Zero vsize segments won't be loaded in memory, even so they
	// have to be page aligned in the file.
	fakestart = abbrevo & ~0xfff;

	nsect = 4;
	if (pubnamessize  > 0)
		nsect++;
	if (pubtypessize  > 0)
		nsect++;
	if (arangessize	  > 0)
		nsect++;
	if (gdbscriptsize > 0)
		nsect++;

	ms = newMachoSeg("__DWARF", nsect);
	ms->fileoffset = fakestart;
	ms->filesize = abbrevo-fakestart;
	ms->vaddr = ms->fileoffset + segdata.vaddr - segdata.fileoff;

	msect = newMachoSect(ms, "__debug_abbrev", "__DWARF");
	msect->off = abbrevo;
	msect->size = abbrevsize;
	msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
	ms->filesize += msect->size;

	msect = newMachoSect(ms, "__debug_line", "__DWARF");
	msect->off = lineo;
	msect->size = linesize;
	msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
	ms->filesize += msect->size;

	msect = newMachoSect(ms, "__debug_frame", "__DWARF");
	msect->off = frameo;
	msect->size = framesize;
	msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
	ms->filesize += msect->size;

	msect = newMachoSect(ms, "__debug_info", "__DWARF");
	msect->off = infoo;
	msect->size = infosize;
	msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
	ms->filesize += msect->size;

	if (pubnamessize > 0) {
		msect = newMachoSect(ms, "__debug_pubnames", "__DWARF");
		msect->off = pubnameso;
		msect->size = pubnamessize;
		msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
		ms->filesize += msect->size;
	}

	if (pubtypessize > 0) {
		msect = newMachoSect(ms, "__debug_pubtypes", "__DWARF");
		msect->off = pubtypeso;
		msect->size = pubtypessize;
		msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
		ms->filesize += msect->size;
	}

	if (arangessize > 0) {
		msect = newMachoSect(ms, "__debug_aranges", "__DWARF");
		msect->off = arangeso;
		msect->size = arangessize;
		msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
		ms->filesize += msect->size;
	}

	// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
	if (gdbscriptsize > 0) {
		msect = newMachoSect(ms, "__debug_gdb_scripts", "__DWARF");
		msect->off = gdbscripto;
		msect->size = gdbscriptsize;
		msect->addr = msect->off + segdata.vaddr - segdata.fileoff;
		ms->filesize += msect->size;
	}
}

/*
 * Windows PE
 */
void
dwarfaddpeheaders(void)
{
	if(debug['w'])  // disable dwarf
		return;

	newPEDWARFSection(".debug_abbrev", abbrevsize);
	newPEDWARFSection(".debug_line", linesize);
	newPEDWARFSection(".debug_frame", framesize);
	newPEDWARFSection(".debug_info", infosize);
	newPEDWARFSection(".debug_pubnames", pubnamessize);
	newPEDWARFSection(".debug_pubtypes", pubtypessize);
	newPEDWARFSection(".debug_aranges", arangessize);
	newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize);
}
