// Do not edit. Bootstrap copy of /tmp/go/src/cmd/link/internal/ld/dwarf.go

//line /tmp/go/src/cmd/link/internal/ld/dwarf.go:1
// 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

package ld

import (
	"bootstrap/internal/obj"
	"fmt"
	"os"
	"strings"
)

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

var abbrevsize int64

var abbrevsym *LSym

var abbrevsympos int64

var lineo int64

var linesize int64

var linesym *LSym

var linesympos int64

var infoo int64 // also the base for DWDie->offs and reference attributes.

var infosize int64

var infosym *LSym

var infosympos int64

var frameo int64

var framesize int64

var framesym *LSym

var framesympos int64

var pubnameso int64

var pubnamessize int64

var pubtypeso int64

var pubtypessize int64

var arangeso int64

var arangessize int64

var gdbscripto int64

var gdbscriptsize int64

var infosec *LSym

var inforeloco int64

var inforelocsize int64

var arangessec *LSym

var arangesreloco int64

var arangesrelocsize int64

var linesec *LSym

var linereloco int64

var linerelocsize int64

var framesec *LSym

var framereloco int64

var framerelocsize int64

var gdbscript string

/*
 *  Basic I/O
 */
func addrput(addr int64) {
	switch Thearch.Ptrsize {
	case 4:
		Thearch.Lput(uint32(addr))

	case 8:
		Thearch.Vput(uint64(addr))
	}
}

func uleb128enc(v uint64, dst []byte) int {
	var c uint8

	length := uint8(0)
	for {
		c = uint8(v & 0x7f)
		v >>= 7
		if v != 0 {
			c |= 0x80
		}
		if dst != nil {
			dst[0] = byte(c)
			dst = dst[1:]
		}
		length++
		if c&0x80 == 0 {
			break
		}
	}

	return int(length)
}

func sleb128enc(v int64, dst []byte) int {
	var c uint8
	var s uint8

	length := uint8(0)
	for {
		c = uint8(v & 0x7f)
		s = uint8(v & 0x40)
		v >>= 7
		if (v != -1 || s == 0) && (v != 0 || s != 0) {
			c |= 0x80
		}
		if dst != nil {
			dst[0] = byte(c)
			dst = dst[1:]
		}
		length++
		if c&0x80 == 0 {
			break
		}
	}

	return int(length)
}

var encbuf [10]byte

func uleb128put(v int64) {
	n := uleb128enc(uint64(v), encbuf[:])
	Cwrite(encbuf[:n])
}

func sleb128put(v int64) {
	n := sleb128enc(v, encbuf[:])
	Cwrite(encbuf[:n])
}

/*
 * 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.
 */
type DWAttrForm struct {
	attr uint16
	form uint8
}

// Go-specific type attributes.
const (
	DW_AT_go_kind = 0x2900
	DW_AT_go_key  = 0x2901
	DW_AT_go_elem = 0x2902

	DW_AT_internal_location = 253 // params and locals; not emitted
)

// Index into the abbrevs table below.
// Keep in sync with ispubname() and ispubtype() below.
// ispubtype considers >= NULLTYPE public
const (
	DW_ABRV_NULL = iota
	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
)

type DWAbbrev struct {
	tag      uint8
	children uint8
	attr     []DWAttrForm
}

var abbrevs = [DW_NABRV]DWAbbrev{
	/* The mandatory DW_ABRV_NULL entry. */
	{0, 0, []DWAttrForm{}},

	/* COMPUNIT */
	{
		DW_TAG_compile_unit,
		DW_CHILDREN_yes,
		[]DWAttrForm{
			{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},
			{DW_AT_comp_dir, DW_FORM_string},
		},
	},

	/* FUNCTION */
	{
		DW_TAG_subprogram,
		DW_CHILDREN_yes,
		[]DWAttrForm{
			{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},
		},
	},

	/* VARIABLE */
	{
		DW_TAG_variable,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{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},
		},
	},

	/* AUTO */
	{
		DW_TAG_variable,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_location, DW_FORM_block1},
			{DW_AT_type, DW_FORM_ref_addr},
		},
	},

	/* PARAM */
	{
		DW_TAG_formal_parameter,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_location, DW_FORM_block1},
			{DW_AT_type, DW_FORM_ref_addr},
		},
	},

	/* STRUCTFIELD */
	{
		DW_TAG_member,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_data_member_location, DW_FORM_block1},
			{DW_AT_type, DW_FORM_ref_addr},
		},
	},

	/* FUNCTYPEPARAM */
	{
		DW_TAG_formal_parameter,
		DW_CHILDREN_no,

		// No name!
		[]DWAttrForm{
			{DW_AT_type, DW_FORM_ref_addr},
		},
	},

	/* DOTDOTDOT */
	{
		DW_TAG_unspecified_parameters,
		DW_CHILDREN_no,
		[]DWAttrForm{},
	},

	/* ARRAYRANGE */
	{
		DW_TAG_subrange_type,
		DW_CHILDREN_no,

		// No name!
		[]DWAttrForm{
			{DW_AT_type, DW_FORM_ref_addr},
			{DW_AT_count, DW_FORM_udata},
		},
	},

	// Below here are the types considered public by ispubtype
	/* NULLTYPE */
	{
		DW_TAG_unspecified_type,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
		},
	},

	/* BASETYPE */
	{
		DW_TAG_base_type,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_encoding, DW_FORM_data1},
			{DW_AT_byte_size, DW_FORM_data1},
			{DW_AT_go_kind, DW_FORM_data1},
		},
	},

	/* ARRAYTYPE */
	// child is subrange with upper bound
	{
		DW_TAG_array_type,
		DW_CHILDREN_yes,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_type, DW_FORM_ref_addr},
			{DW_AT_byte_size, DW_FORM_udata},
			{DW_AT_go_kind, DW_FORM_data1},
		},
	},

	/* CHANTYPE */
	{
		DW_TAG_typedef,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_type, DW_FORM_ref_addr},
			{DW_AT_go_kind, DW_FORM_data1},
			{DW_AT_go_elem, DW_FORM_ref_addr},
		},
	},

	/* FUNCTYPE */
	{
		DW_TAG_subroutine_type,
		DW_CHILDREN_yes,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			// {DW_AT_type,	DW_FORM_ref_addr},
			{DW_AT_go_kind, DW_FORM_data1},
		},
	},

	/* IFACETYPE */
	{
		DW_TAG_typedef,
		DW_CHILDREN_yes,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_type, DW_FORM_ref_addr},
			{DW_AT_go_kind, DW_FORM_data1},
		},
	},

	/* MAPTYPE */
	{
		DW_TAG_typedef,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_type, DW_FORM_ref_addr},
			{DW_AT_go_kind, DW_FORM_data1},
			{DW_AT_go_key, DW_FORM_ref_addr},
			{DW_AT_go_elem, DW_FORM_ref_addr},
		},
	},

	/* PTRTYPE */
	{
		DW_TAG_pointer_type,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_type, DW_FORM_ref_addr},
			{DW_AT_go_kind, DW_FORM_data1},
		},
	},

	/* BARE_PTRTYPE */
	{
		DW_TAG_pointer_type,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
		},
	},

	/* SLICETYPE */
	{
		DW_TAG_structure_type,
		DW_CHILDREN_yes,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_byte_size, DW_FORM_udata},
			{DW_AT_go_kind, DW_FORM_data1},
			{DW_AT_go_elem, DW_FORM_ref_addr},
		},
	},

	/* STRINGTYPE */
	{
		DW_TAG_structure_type,
		DW_CHILDREN_yes,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_byte_size, DW_FORM_udata},
			{DW_AT_go_kind, DW_FORM_data1},
		},
	},

	/* STRUCTTYPE */
	{
		DW_TAG_structure_type,
		DW_CHILDREN_yes,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_byte_size, DW_FORM_udata},
			{DW_AT_go_kind, DW_FORM_data1},
		},
	},

	/* TYPEDECL */
	{
		DW_TAG_typedef,
		DW_CHILDREN_no,
		[]DWAttrForm{
			{DW_AT_name, DW_FORM_string},
			{DW_AT_type, DW_FORM_ref_addr},
		},
	},
}

func writeabbrev() {
	abbrevo = Cpos()
	for i := 1; i < DW_NABRV; i++ {
		// See section 7.5.3
		uleb128put(int64(i))

		uleb128put(int64(abbrevs[i].tag))
		Cput(abbrevs[i].children)
		for _, f := range abbrevs[i].attr {
			uleb128put(int64(f.attr))
			uleb128put(int64(f.form))
		}
		uleb128put(0)
		uleb128put(0)
	}

	Cput(0)
	abbrevsize = Cpos() - abbrevo
}

/*
 * Debugging Information Entries and their attributes.
 */
const (
	HASHSIZE = 107
)

func dwarfhashstr(s string) uint32 {
	h := uint32(0)
	for s != "" {
		h = h + h + h + uint32(s[0])
		s = s[1:]
	}
	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.

type DWAttr struct {
	link  *DWAttr
	atr   uint16 // DW_AT_
	cls   uint8  // DW_CLS_
	value int64
	data  interface{}
}

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

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

var dwtypes DWDie

var dwglobals DWDie

func newattr(die *DWDie, attr uint16, cls int, value int64, data interface{}) *DWAttr {
	a := new(DWAttr)
	a.link = die.attr
	die.attr = a
	a.atr = attr
	a.cls = uint8(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.
func getattr(die *DWDie, attr uint16) *DWAttr {
	if die.attr.atr == attr {
		return die.attr
	}

	a := die.attr
	b := a.link
	for 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.
func newdie(parent *DWDie, abbrev int, name string) *DWDie {
	die := new(DWDie)
	die.abbrev = abbrev
	die.link = parent.child
	parent.child = die

	newattr(die, DW_AT_name, DW_CLS_STRING, int64(len(name)), name)

	if parent.hash != nil {
		h := int(dwarfhashstr(name))
		die.hlink = parent.hash[h]
		parent.hash[h] = die
	}

	return die
}

func mkindex(die *DWDie) {
	die.hash = make([]*DWDie, HASHSIZE)
}

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

	return die
}

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

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

	h = int(dwarfhashstr(name))
	a = die.hash[h]

	if a == nil {
		goto notfound
	}

	if name == getattr(a, DW_AT_name).data {
		return a
	}

	// Move found ones to head of the list.
	b = a.hlink

	for b != nil {
		if name == getattr(b, DW_AT_name).data {
			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
}

func mustFind(die *DWDie, name string) *DWDie {
	r := find(die, name)
	if r == nil {
		Exitf("dwarf find: %s %p has no %s", getattr(die, DW_AT_name).data, die, name)
	}
	return r
}

func adddwarfrel(sec *LSym, sym *LSym, offsetbase int64, siz int, addend int64) {
	r := Addrel(sec)
	r.Sym = sym
	r.Xsym = sym
	r.Off = int32(Cpos() - offsetbase)
	r.Siz = uint8(siz)
	r.Type = obj.R_ADDR
	r.Add = addend
	r.Xadd = addend
	if Iself && Thearch.Thechar == '6' {
		addend = 0
	}
	if HEADTYPE == obj.Hdarwin {
		addend += sym.Value
	}
	switch siz {
	case 4:
		Thearch.Lput(uint32(addend))

	case 8:
		Thearch.Vput(uint64(addend))

	default:
		Diag("bad size in adddwarfrel")
	}
}

func newrefattr(die *DWDie, attr uint16, ref *DWDie) *DWAttr {
	if ref == nil {
		return nil
	}
	return newattr(die, attr, DW_CLS_REFERENCE, 0, ref)
}

var fwdcount int

func putattr(abbrev int, form int, cls int, value int64, data interface{}) {
	switch form {
	case DW_FORM_addr: // address
		if Linkmode == LinkExternal {
			value -= (data.(*LSym)).Value
			adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value)
			break
		}

		addrput(value)

	case DW_FORM_block1: // block
		if cls == DW_CLS_ADDRESS {
			Cput(uint8(1 + Thearch.Ptrsize))
			Cput(DW_OP_addr)
			if Linkmode == LinkExternal {
				value -= (data.(*LSym)).Value
				adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value)
				break
			}

			addrput(value)
			break
		}

		value &= 0xff
		Cput(uint8(value))
		p := data.([]byte)
		for i := 0; int64(i) < value; i++ {
			Cput(uint8(p[i]))
		}

	case DW_FORM_block2: // block
		value &= 0xffff

		Thearch.Wput(uint16(value))
		p := data.([]byte)
		for i := 0; int64(i) < value; i++ {
			Cput(uint8(p[i]))
		}

	case DW_FORM_block4: // block
		value &= 0xffffffff

		Thearch.Lput(uint32(value))
		p := data.([]byte)
		for i := 0; int64(i) < value; i++ {
			Cput(uint8(p[i]))
		}

	case DW_FORM_block: // block
		uleb128put(value)

		p := data.([]byte)
		for i := 0; int64(i) < value; i++ {
			Cput(uint8(p[i]))
		}

	case DW_FORM_data1: // constant
		Cput(uint8(value))

	case DW_FORM_data2: // constant
		Thearch.Wput(uint16(value))

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

		Thearch.Lput(uint32(value))

	case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr
		Thearch.Vput(uint64(value))

	case DW_FORM_sdata: // constant
		sleb128put(value)

	case DW_FORM_udata: // constant
		uleb128put(value)

	case DW_FORM_string: // string
		strnput(data.(string), int(value+1))

	case DW_FORM_flag: // flag
		if value != 0 {
			Cput(1)
		} else {
			Cput(0)
		}

		// 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.
	case DW_FORM_ref_addr: // reference to a DIE in the .info section
		if data == nil {
			Diag("dwarf: null reference in %d", abbrev)
			if Thearch.Ptrsize == 8 {
				Thearch.Vput(0) // invalid dwarf, gdb will complain.
			} else {
				Thearch.Lput(0) // invalid dwarf, gdb will complain.
			}
		} else {
			off := (data.(*DWDie)).offs
			if off == 0 {
				fwdcount++
			}
			if Linkmode == LinkExternal {
				adddwarfrel(infosec, infosym, infoo, Thearch.Ptrsize, off)
				break
			}

			addrput(off)
		}

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

		DW_FORM_strp,     // string
		DW_FORM_indirect: // (see Section 7.5.3)
		fallthrough
	default:
		Exitf("dwarf: unsupported attribute form %d / class %d", form, cls)
	}
}

// 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.
func putattrs(abbrev int, attr *DWAttr) {
Outer:
	for _, f := range abbrevs[abbrev].attr {
		for ap := attr; ap != nil; ap = ap.link {
			if ap.atr == f.attr {
				putattr(abbrev, int(f.form), int(ap.cls), ap.value, ap.data)
				continue Outer
			}
		}

		putattr(abbrev, int(f.form), 0, 0, nil)
	}
}

func putdies(die *DWDie) {
	for ; die != nil; die = die.link {
		putdie(die)
	}
}

func putdie(die *DWDie) {
	die.offs = Cpos() - infoo
	uleb128put(int64(die.abbrev))
	putattrs(die.abbrev, die.attr)
	if abbrevs[die.abbrev].children != 0 {
		putdies(die.child)
		Cput(0)
	}
}

func reverselist(list **DWDie) {
	curr := *list
	var prev *DWDie
	for curr != nil {
		var next *DWDie = curr.link
		curr.link = prev
		prev = curr
		curr = next
	}

	*list = prev
}

func reversetree(list **DWDie) {
	reverselist(list)
	for die := *list; die != nil; die = die.link {
		if abbrevs[die.abbrev].children != 0 {
			reversetree(&die.child)
		}
	}
}

func newmemberoffsetattr(die *DWDie, offs int32) {
	var block [20]byte

	i := 0
	block[i] = DW_OP_plus_uconst
	i++
	i += uleb128enc(uint64(offs), block[i:])
	newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, int64(i), block[:i])
}

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

// Lookup predefined types
func lookup_or_diag(n string) *LSym {
	s := Linkrlookup(Ctxt, n, 0)
	if s == nil || s.Size == 0 {
		Exitf("dwarf: missing type: %s", n)
	}

	return s
}

func dotypedef(parent *DWDie, name string, def *DWDie) {
	// Only emit typedefs for real names.
	if strings.HasPrefix(name, "map[") {
		return
	}
	if strings.HasPrefix(name, "struct {") {
		return
	}
	if strings.HasPrefix(name, "chan ") {
		return
	}
	if name[0] == '[' || name[0] == '*' {
		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.
func defgotype(gotype *LSym) *DWDie {
	if gotype == nil {
		return mustFind(&dwtypes, "<unspecified>")
	}

	if !strings.HasPrefix(gotype.Name, "type.") {
		Diag("dwarf: type name doesn't start with \".type\": %s", gotype.Name)
		return mustFind(&dwtypes, "<unspecified>")
	}

	name := gotype.Name[5:] // could also decode from Type.string

	die := find(&dwtypes, name)

	if die != nil {
		return die
	}

	if false && Debug['v'] > 2 {
		fmt.Printf("new type: %v\n", gotype)
	}

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

	switch kind {
	case obj.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)

	case obj.KindInt,
		obj.KindInt8,
		obj.KindInt16,
		obj.KindInt32,
		obj.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)

	case obj.KindUint,
		obj.KindUint8,
		obj.KindUint16,
		obj.KindUint32,
		obj.KindUint64,
		obj.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)

	case obj.KindFloat32,
		obj.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)

	case obj.KindComplex64,
		obj.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)

	case obj.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")

		// use actual length not upper bound; correct for 0-length arrays.
		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0)

		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))

	case obj.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_go_elem, defgotype(s))

	case obj.KindFunc:
		die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name)
		dotypedef(&dwtypes, name, die)
		newrefattr(die, DW_AT_type, mustFind(&dwtypes, "void"))
		nfields := decodetype_funcincount(gotype)
		var fld *DWDie
		var s *LSym
		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) != 0 {
			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)))
		}

	case obj.KindInterface:
		die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name)
		dotypedef(&dwtypes, name, die)
		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
		nfields := int(decodetype_ifacemethodcount(gotype))
		var s *LSym
		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))

	case obj.KindMap:
		die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name)
		s := decodetype_mapkey(gotype)
		newrefattr(die, DW_AT_go_key, defgotype(s))
		s = decodetype_mapvalue(gotype)
		newrefattr(die, DW_AT_go_elem, defgotype(s))

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

	case obj.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_go_elem, defgotype(s))

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

	case obj.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)
		var f string
		var fld *DWDie
		var s *LSym
		for i := 0; i < nfields; i++ {
			f = decodetype_structfieldname(gotype, i)
			s = decodetype_structfieldtype(gotype, i)
			if f == "" {
				f = s.Name[5:] // skip "type."
			}
			fld = newdie(die, DW_ABRV_STRUCTFIELD, f)
			newrefattr(fld, DW_AT_type, defgotype(s))
			newmemberoffsetattr(fld, int32(decodetype_structfieldoffs(gotype, i)))
		}

	case obj.KindUnsafePointer:
		die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name)

	default:
		Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name)
		die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name)
		newrefattr(die, DW_AT_type, mustFind(&dwtypes, "<unspecified>"))
	}

	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, int64(kind), 0)

	return die
}

// Find or construct *T given T.
func defptrto(dwtype *DWDie) *DWDie {
	ptrname := fmt.Sprintf("*%s", getattr(dwtype, DW_AT_name).data)
	die := find(&dwtypes, ptrname)
	if die == nil {
		die = newdie(&dwtypes, DW_ABRV_PTRTYPE, 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.
func copychildrenexcept(dst *DWDie, src *DWDie, except *DWDie) {
	var c *DWDie
	var a *DWAttr

	for src = src.child; src != nil; src = src.link {
		if src == except {
			continue
		}
		c = newdie(dst, src.abbrev, getattr(src, DW_AT_name).data.(string))
		for a = src.attr; a != nil; a = a.link {
			newattr(c, a.atr, int(a.cls), a.value, a.data)
		}
		copychildrenexcept(c, src, nil)
	}

	reverselist(&dst.child)
}

func copychildren(dst *DWDie, src *DWDie) {
	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
func substitutetype(structdie *DWDie, field string, dwtype *DWDie) {
	child := mustFind(structdie, field)
	if child == nil {
		return
	}

	a := getattr(child, DW_AT_type)
	if a != nil {
		a.data = dwtype
	} else {
		newrefattr(child, DW_AT_type, dwtype)
	}
}

func synthesizestringtypes(die *DWDie) {
	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)
	}
}

func synthesizeslicetypes(die *DWDie) {
	prototype := walktypedef(defgotype(lookup_or_diag("type.runtime.slice")))
	if prototype == nil {
		return
	}

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

func mkinternaltypename(base string, arg1 string, arg2 string) string {
	var buf string

	if arg2 == "" {
		buf = fmt.Sprintf("%s<%s>", base, arg1)
	} else {
		buf = fmt.Sprintf("%s<%s,%s>", base, arg1, arg2)
	}
	n := buf
	return n
}

// synthesizemaptypes is way too closely married to runtime/hashmap.c
const (
	MaxKeySize = 128
	MaxValSize = 128
	BucketSize = 8
)

func synthesizemaptypes(die *DWDie) {
	hash := walktypedef(defgotype(lookup_or_diag("type.runtime.hmap")))
	bucket := walktypedef(defgotype(lookup_or_diag("type.runtime.bmap")))

	if hash == nil {
		return
	}

	var a *DWAttr
	var dwh *DWDie
	var dwhb *DWDie
	var dwhk *DWDie
	var dwhv *DWDie
	var fld *DWDie
	var indirect_key int
	var indirect_val int
	var keysize int
	var keytype *DWDie
	var t *DWDie
	var valsize int
	var valtype *DWDie
	for ; die != nil; die = die.link {
		if die.abbrev != DW_ABRV_MAPTYPE {
			continue
		}

		keytype = walktypedef(getattr(die, DW_AT_go_key).data.(*DWDie))
		valtype = walktypedef(getattr(die, DW_AT_go_elem).data.(*DWDie))

		// compute size info like hashmap.c does.
		a = getattr(keytype, DW_AT_byte_size)

		if a != nil {
			keysize = int(a.value)
		} else {
			keysize = Thearch.Ptrsize
		}
		a = getattr(valtype, DW_AT_byte_size)
		if a != nil {
			valsize = int(a.value)
		} else {
			valsize = Thearch.Ptrsize
		}
		indirect_key = 0
		indirect_val = 0
		if keysize > MaxKeySize {
			keysize = Thearch.Ptrsize
			indirect_key = 1
		}

		if valsize > MaxValSize {
			valsize = Thearch.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.(string), ""))

		newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(keysize), 0)
		t = keytype
		if indirect_key != 0 {
			t = defptrto(keytype)
		}
		newrefattr(dwhk, DW_AT_type, t)
		fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size")
		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
		newrefattr(fld, DW_AT_type, mustFind(&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.(string), ""))

		newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(valsize), 0)
		t = valtype
		if indirect_val != 0 {
			t = defptrto(valtype)
		}
		newrefattr(dwhv, DW_AT_type, t)
		fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size")
		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))

		// Construct bucket<K,V>
		dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("bucket", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string)))

		// 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)
		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values")
		newrefattr(fld, DW_AT_type, dwhv)
		newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize))
		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow")
		newrefattr(fld, DW_AT_type, defptrto(dwhb))
		newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
		if Thearch.Regsize > Thearch.Ptrsize {
			fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad")
			newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
			newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(Thearch.Ptrsize))
		}

		newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize+BucketSize*int64(keysize)+BucketSize*int64(valsize)+int64(Thearch.Regsize), 0)

		// Construct hash<K,V>
		dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("hash", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string)))

		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))
	}
}

func synthesizechantypes(die *DWDie) {
	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 := int(getattr(sudog, DW_AT_byte_size).value)

	var a *DWAttr
	var dwh *DWDie
	var dws *DWDie
	var dww *DWDie
	var elemsize int
	var elemtype *DWDie
	for ; die != nil; die = die.link {
		if die.abbrev != DW_ABRV_CHANTYPE {
			continue
		}
		elemtype = getattr(die, DW_AT_go_elem).data.(*DWDie)
		a = getattr(elemtype, DW_AT_byte_size)
		if a != nil {
			elemsize = int(a.value)
		} else {
			elemsize = Thearch.Ptrsize
		}

		// sudog<T>
		dws = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("sudog", getattr(elemtype, DW_AT_name).data.(string), ""))

		copychildren(dws, sudog)
		substitutetype(dws, "elem", elemtype)
		if elemsize > 8 {
			elemsize -= 8
		} else {
			elemsize = 0
		}
		newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT, int64(sudogsize)+int64(elemsize), nil)

		// waitq<T>
		dww = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("waitq", getattr(elemtype, DW_AT_name).data.(string), ""))

		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.(string), ""))

		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
func defdwsymb(sym *LSym, s string, t int, v int64, size int64, ver int, gotype *LSym) {
	if strings.HasPrefix(s, "go.string.") {
		return
	}
	if strings.HasPrefix(s, "runtime.gcbits.") {
		return
	}

	if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
		defgotype(sym)
		return
	}

	var dv *DWDie

	var dt *DWDie
	switch t {
	default:
		return

	case 'd', 'b', 'D', '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', 'p':
		dt = defgotype(gotype)
	}

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

func movetomodule(parent *DWDie) {
	die := dwroot.child.child
	for die.link != nil {
		die = die.link
	}
	die.link = parent.child
}

// If the pcln table contains runtime/runtime.go, use that to set gdbscript path.
func finddebugruntimepath(s *LSym) {
	if gdbscript != "" {
		return
	}

	var f *LSym
	var p string
	for i := 0; i < s.Pcln.Nfile; i++ {
		f = s.Pcln.File[i]
		_ = p
		if i := strings.Index(f.Name, "runtime/runtime.go"); i >= 0 {
			gdbscript = f.Name[:i] + "runtime/runtime-gdb.py"
			break
		}
	}
}

/*
 * Generate short opcodes when possible, long ones when necessary.
 * See section 6.2.5
 */
const (
	LINE_BASE   = -1
	LINE_RANGE  = 4
	OPCODE_BASE = 10
)

func putpclcdelta(delta_pc int64, delta_lc int64) {
	if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE {
		var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc)
		if OPCODE_BASE <= opcode && opcode < 256 {
			Cput(uint8(opcode))
			return
		}
	}

	if delta_pc != 0 {
		Cput(DW_LNS_advance_pc)
		sleb128put(delta_pc)
	}

	Cput(DW_LNS_advance_line)
	sleb128put(delta_lc)
	Cput(DW_LNS_copy)
}

func newcfaoffsetattr(die *DWDie, offs int32) {
	var block [20]byte

	i := 0

	block[i] = DW_OP_call_frame_cfa
	i++
	if offs != 0 {
		block[i] = DW_OP_consts
		i++
		i += sleb128enc(int64(offs), block[i:])
		block[i] = DW_OP_plus
		i++
	}

	newattr(die, DW_AT_location, DW_CLS_BLOCK, int64(i), block[:i])
}

func mkvarname(name string, da int) string {
	buf := fmt.Sprintf("%s#%d", name, da)
	n := buf
	return n
}

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

// flush previous compilation unit.
func flushunit(dwinfo *DWDie, pc int64, pcsym *LSym, unitstart int64, header_length int32) {
	if dwinfo != nil && pc != 0 {
		newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, pcsym)
	}

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

		here := Cpos()
		Cseek(unitstart)
		Thearch.Lput(uint32(here - unitstart - 4)) // unit_length
		Thearch.Wput(2)                            // dwarf version
		Thearch.Lput(uint32(header_length))        // header length starting here
		Cseek(here)
	}
}

func getCompilationDir() string {
	if dir, err := os.Getwd(); err == nil {
		return dir
	}
	return "/"
}

func writelines() {
	if linesec == nil {
		linesec = Linklookup(Ctxt, ".dwarfline", 0)
	}
	linesec.R = linesec.R[:0]

	unitstart := int64(-1)
	headerend := int64(-1)
	epc := int64(0)
	var epcs *LSym
	lineo = Cpos()
	var dwinfo *DWDie

	flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10))
	unitstart = Cpos()

	lang := DW_LANG_Go

	s := Ctxt.Textp

	dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, "go")
	newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(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, s)
	// OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
	compDir := getCompilationDir()
	newattr(dwinfo, DW_AT_comp_dir, DW_CLS_STRING, int64(len(compDir)), compDir)

	// Write .debug_line Line Number Program Header (sec 6.2.4)
	// Fields marked with (*) must be changed for 64-bit dwarf
	Thearch.Lput(0) // unit_length (*), will be filled in by flushunit.
	Thearch.Wput(2) // dwarf version (appendix F)
	Thearch.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 & 0xFF) // 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 := make([]*LSym, Ctxt.Nhistfile)

	for f := Ctxt.Filesyms; f != nil; f = f.Next {
		files[f.Value-1] = f
	}

	for i := 0; int32(i) < Ctxt.Nhistfile; i++ {
		strnput(files[i].Name, len(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 + int64(Thearch.Ptrsize))
	Cput(DW_LNE_set_address)

	pc := s.Value
	line := 1
	file := 1
	if Linkmode == LinkExternal {
		adddwarfrel(linesec, s, lineo, Thearch.Ptrsize, 0)
	} else {
		addrput(pc)
	}

	var a *Auto
	var da int
	var dt int
	var dwfunc *DWDie
	var dws **DWDie
	var dwvar *DWDie
	var n string
	var nn string
	var offs int64
	var pcfile Pciter
	var pcline Pciter
	var varhash [HASHSIZE]*DWDie
	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, s)
		epc = s.Value + s.Size
		epcs = s
		newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, 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
		for pcfile.done == 0 && pcline.done == 0 {
			if epc-s.Value >= int64(pcfile.nextpc) {
				pciternext(&pcfile)
				continue
			}

			if epc-s.Value >= int64(pcline.nextpc) {
				pciternext(&pcline)
				continue
			}

			if int32(file) != pcfile.value {
				Cput(DW_LNS_set_file)
				uleb128put(int64(pcfile.value))
				file = int(pcfile.value)
			}

			putpclcdelta(s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line))

			pc = s.Value + int64(pcline.pc)
			line = int(pcline.value)
			if pcfile.nextpc < pcline.nextpc {
				epc = int64(pcfile.nextpc)
			} else {
				epc = int64(pcline.nextpc)
			}
			epc += s.Value
		}

		da = 0
		dwfunc.hash = varhash[:] // enable indexing of children by name
		varhash = [HASHSIZE]*DWDie{}
		for a = s.Autom; a != nil; a = a.Link {
			switch a.Name {
			case obj.A_AUTO:
				dt = DW_ABRV_AUTO
				offs = int64(a.Aoffset)
				if !haslinkregister() {
					offs -= int64(Thearch.Ptrsize)
				}

			case obj.A_PARAM:
				dt = DW_ABRV_PARAM
				offs = int64(a.Aoffset)
				if haslinkregister() {
					offs += int64(Thearch.Ptrsize)
				}

			default:
				continue
			}

			if strings.Contains(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
			if i := strings.LastIndex(n, "."); i >= 0 {
				n = n[i+1:]
			}

			dwvar = newdie(dwfunc, dt, n)
			newcfaoffsetattr(dwvar, int32(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, int32(headerend-unitstart-10))
	linesize = Cpos() - lineo
}

/*
 *  Emit .debug_frame
 */
const (
	CIERESERVE          = 16
	DATAALIGNMENTFACTOR = -4
)

func putpccfadelta(deltapc int64, cfa int64) {
	Cput(DW_CFA_def_cfa_offset_sf)
	sleb128put(cfa / DATAALIGNMENTFACTOR)

	if deltapc < 0x40 {
		Cput(uint8(DW_CFA_advance_loc + deltapc))
	} else if deltapc < 0x100 {
		Cput(DW_CFA_advance_loc1)
		Cput(uint8(deltapc))
	} else if deltapc < 0x10000 {
		Cput(DW_CFA_advance_loc2)
		Thearch.Wput(uint16(deltapc))
	} else {
		Cput(DW_CFA_advance_loc4)
		Thearch.Lput(uint32(deltapc))
	}
}

func writeframes() {
	if framesec == nil {
		framesec = Linklookup(Ctxt, ".dwarfframe", 0)
	}
	framesec.R = framesec.R[:0]
	frameo = Cpos()

	// Emit the CIE, Section 6.4.1
	Thearch.Lput(CIERESERVE)              // initial length, must be multiple of thearch.ptrsize
	Thearch.Lput(0xffffffff)              // cid.
	Cput(3)                               // dwarf version (appendix F)
	Cput(0)                               // augmentation ""
	uleb128put(1)                         // code_alignment_factor
	sleb128put(DATAALIGNMENTFACTOR)       // guess
	uleb128put(int64(Thearch.Dwarfreglr)) // return_address_register

	Cput(DW_CFA_def_cfa)

	uleb128put(int64(Thearch.Dwarfregsp)) // register SP (**ABI-dependent, defined in l.h)
	if haslinkregister() {
		uleb128put(int64(0)) // offset
	} else {
		uleb128put(int64(Thearch.Ptrsize)) // offset
	}

	Cput(DW_CFA_offset_extended)
	uleb128put(int64(Thearch.Dwarfreglr)) // return address
	if haslinkregister() {
		uleb128put(int64(0) / DATAALIGNMENTFACTOR) // at cfa - 0
	} else {
		uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4
	}

	// 4 is to exclude the length field.
	pad := CIERESERVE + frameo + 4 - Cpos()

	if pad < 0 {
		Exitf("dwarf: CIERESERVE too small by %d bytes.", -pad)
	}

	strnput("", int(pad))

	var fdeo int64
	var fdesize int64
	var nextpc uint32
	var pcsp Pciter
	var s *LSym
	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.
		Thearch.Lput(0) // length, must be multiple of thearch.ptrsize
		Thearch.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 == 0; pciternext(&pcsp) {
			nextpc = pcsp.nextpc

			// pciterinit goes up to the end of the function,
			// but DWARF expects us to stop just before the end.
			if int64(nextpc) == s.Size {
				nextpc--
				if nextpc < pcsp.pc {
					continue
				}
			}

			if haslinkregister() {
				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
			} else {
				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value))
			}
		}

		fdesize = Cpos() - fdeo - 4 // exclude the length field.
		pad = Rnd(fdesize, int64(Thearch.Ptrsize)) - fdesize
		strnput("", int(pad))
		fdesize += pad

		// Emit the FDE header for real, Section 6.4.1.
		Cseek(fdeo)

		Thearch.Lput(uint32(fdesize))
		if Linkmode == LinkExternal {
			adddwarfrel(framesec, framesym, frameo, 4, 0)
			adddwarfrel(framesec, s, frameo, Thearch.Ptrsize, 0)
		} else {
			Thearch.Lput(0)
			addrput(s.Value)
		}

		addrput(s.Size)
		Cseek(fdeo + 4 + fdesize)
	}

	Cflush()
	framesize = Cpos() - frameo
}

/*
 *  Walk DWarfDebugInfoEntries, and emit .debug_info
 */
const (
	COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
)

func writeinfo() {
	fwdcount = 0
	if infosec == nil {
		infosec = Linklookup(Ctxt, ".dwarfinfo", 0)
	}
	infosec.R = infosec.R[:0]

	if arangessec == nil {
		arangessec = Linklookup(Ctxt, ".dwarfaranges", 0)
	}
	arangessec.R = arangessec.R[:0]

	var here int64
	var unitstart int64
	for compunit := dwroot.child; compunit != nil; 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.
		Thearch.Lput(0) // unit_length (*), will be filled in later.
		Thearch.Wput(2) // dwarf version (appendix F)

		// debug_abbrev_offset (*)
		if Linkmode == LinkExternal {
			adddwarfrel(infosec, abbrevsym, infoo, 4, 0)
		} else {
			Thearch.Lput(0)
		}

		Cput(uint8(Thearch.Ptrsize)) // address_size

		putdie(compunit)

		here = Cpos()
		Cseek(unitstart)
		Thearch.Lput(uint32(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;
 */
func ispubname(die *DWDie) bool {
	switch die.abbrev {
	case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE:
		a := getattr(die, DW_AT_external)
		return a != nil && a.value != 0
	}

	return false
}

func ispubtype(die *DWDie) bool {
	return die.abbrev >= DW_ABRV_NULLTYPE
}

func writepub(ispub func(*DWDie) bool) int64 {
	var die *DWDie
	var dwa *DWAttr
	var unitstart int64
	var unitend int64
	var here int64

	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)
		Thearch.Lput(0)                           // unit_length (*), will be filled in later.
		Thearch.Wput(2)                           // dwarf version (appendix F)
		Thearch.Lput(uint32(unitstart))           // debug_info_offset (of the Comp unit Header)
		Thearch.Lput(uint32(unitend - unitstart)) // debug_info_length

		for die = compunit.child; die != nil; die = die.link {
			if !ispub(die) {
				continue
			}
			Thearch.Lput(uint32(die.offs - unitstart))
			dwa = getattr(die, DW_AT_name)
			strnput(dwa.data.(string), int(dwa.value+1))
		}

		Thearch.Lput(0)

		here = Cpos()
		Cseek(sectionstart)
		Thearch.Lput(uint32(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.
 */
func writearanges() int64 {
	var b *DWAttr
	var e *DWAttr
	var value int64

	sectionstart := Cpos()
	headersize := int(Rnd(4+2+4+1+1, int64(Thearch.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)
		Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*)
		Thearch.Wput(2)                                                  // dwarf version (appendix F)

		value = compunit.offs - COMPUNITHEADERSIZE // debug_info_offset
		if Linkmode == LinkExternal {
			adddwarfrel(arangessec, infosym, sectionstart, 4, value)
		} else {
			Thearch.Lput(uint32(value))
		}

		Cput(uint8(Thearch.Ptrsize))        // address_size
		Cput(0)                             // segment_size
		strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize

		if Linkmode == LinkExternal {
			adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value)
		} else {
			addrput(b.value)
		}

		addrput(e.value - b.value)
		addrput(0)
		addrput(0)
	}

	Cflush()
	return sectionstart
}

func writegdbscript() int64 {
	sectionstart := Cpos()

	if gdbscript != "" {
		Cput(1) // magic 1 byte?
		strnput(gdbscript, len(gdbscript)+1)
		Cflush()
	}

	return sectionstart
}

func align(size int64) {
	if HEADTYPE == obj.Hwindows { // Only Windows PE need section align.
		strnput("", int(Rnd(size, PEFILEALIGN)-size))
	}
}

func writedwarfreloc(s *LSym) int64 {
	var i int
	var r *Reloc

	start := Cpos()
	for ri := 0; ri < len(s.R); ri++ {
		r = &s.R[ri]
		if Iself {
			i = Thearch.Elfreloc1(r, int64(r.Off))
		} else if HEADTYPE == obj.Hdarwin {
			i = Thearch.Machoreloc1(r, int64(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
}

func addmachodwarfsect(prev *Section, name string) *Section {
	sect := addsection(&Segdwarf, name, 04)
	sect.Extnum = prev.Extnum + 1
	sym := Linklookup(Ctxt, name, 0)
	sym.Sect = sect
	return sect
}

/*
 * 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.
 *
 */
func Dwarfemitdebugsections() {
	if Debug['w'] != 0 { // disable dwarf
		return
	}

	if Linkmode == LinkExternal {
		if !Iself && HEADTYPE != obj.Hdarwin {
			return
		}
		if HEADTYPE == obj.Hdarwin {
			sect := Segdata.Sect
			// find the last section.
			for sect.Next != nil {
				sect = sect.Next
			}
			sect = addmachodwarfsect(sect, ".debug_abbrev")
			sect = addmachodwarfsect(sect, ".debug_line")
			sect = addmachodwarfsect(sect, ".debug_frame")
			sect = addmachodwarfsect(sect, ".debug_info")

			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
		}
	}

	// For diagnostic messages.
	newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("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, int64(Thearch.Ptrsize), 0)
	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0)

	// Needed by the prettyprinter code for interface inspection.
	defgotype(lookup_or_diag("type.runtime._type"))

	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'] != 0 {
			fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime())
		}
		Cseek(infoo)
		writeinfo()
		if fwdcount > 0 {
			Exitf("dwarf: unresolved references after first dwarf info pass")
		}

		if infoe != Cpos() {
			Exitf("dwarf: inconsistent second dwarf info pass")
		}
	}

	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)

	for Cpos()&7 != 0 {
		Cput(0)
	}
	if HEADTYPE != obj.Hdarwin {
		dwarfemitreloc()
	}
}

func dwarfemitreloc() {
	if Debug['w'] != 0 { // disable dwarf
		return
	}
	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.
 */
const (
	ElfStrDebugAbbrev = iota
	ElfStrDebugAranges
	ElfStrDebugFrame
	ElfStrDebugInfo
	ElfStrDebugLine
	ElfStrDebugLoc
	ElfStrDebugMacinfo
	ElfStrDebugPubNames
	ElfStrDebugPubTypes
	ElfStrDebugRanges
	ElfStrDebugStr
	ElfStrGDBScripts
	ElfStrRelDebugInfo
	ElfStrRelDebugAranges
	ElfStrRelDebugLine
	ElfStrRelDebugFrame
	NElfStrDbg
)

var elfstrdbg [NElfStrDbg]int64

func dwarfaddshstrings(shstrtab *LSym) {
	if Debug['w'] != 0 { // 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 {
		switch Thearch.Thechar {
		case '6', '7', '9':
			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")
		default:
			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.
func 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)
	}
}

func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) {
	sh := newElfShdr(elfstrdbg[elfstr])
	switch Thearch.Thechar {
	case '6', '7', '9':
		sh.type_ = SHT_RELA
	default:
		sh.type_ = SHT_REL
	}

	sh.entsize = uint64(Thearch.Ptrsize) * 2
	if sh.type_ == SHT_RELA {
		sh.entsize += uint64(Thearch.Ptrsize)
	}
	sh.link = uint32(elfshname(".symtab").shnum)
	sh.info = uint32(shdata.shnum)
	sh.off = uint64(off)
	sh.size = uint64(size)
	sh.addralign = uint64(Thearch.Ptrsize)
}

func dwarfaddelfheaders() {
	if Debug['w'] != 0 { // disable dwarf
		return
	}

	sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev])
	sh.type_ = SHT_PROGBITS
	sh.off = uint64(abbrevo)
	sh.size = uint64(abbrevsize)
	sh.addralign = 1
	if abbrevsympos > 0 {
		putelfsymshndx(abbrevsympos, sh.shnum)
	}

	sh = newElfShdr(elfstrdbg[ElfStrDebugLine])
	sh.type_ = SHT_PROGBITS
	sh.off = uint64(lineo)
	sh.size = uint64(linesize)
	sh.addralign = 1
	if linesympos > 0 {
		putelfsymshndx(linesympos, sh.shnum)
	}
	shline := sh

	sh = newElfShdr(elfstrdbg[ElfStrDebugFrame])
	sh.type_ = SHT_PROGBITS
	sh.off = uint64(frameo)
	sh.size = uint64(framesize)
	sh.addralign = 1
	if framesympos > 0 {
		putelfsymshndx(framesympos, sh.shnum)
	}
	shframe := sh

	sh = newElfShdr(elfstrdbg[ElfStrDebugInfo])
	sh.type_ = SHT_PROGBITS
	sh.off = uint64(infoo)
	sh.size = uint64(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 = uint64(pubnameso)
		sh.size = uint64(pubnamessize)
		sh.addralign = 1
	}

	if pubtypessize > 0 {
		sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes])
		sh.type_ = SHT_PROGBITS
		sh.off = uint64(pubtypeso)
		sh.size = uint64(pubtypessize)
		sh.addralign = 1
	}

	var sharanges *ElfShdr
	if arangessize != 0 {
		sh := newElfShdr(elfstrdbg[ElfStrDebugAranges])
		sh.type_ = SHT_PROGBITS
		sh.off = uint64(arangeso)
		sh.size = uint64(arangessize)
		sh.addralign = 1
		sharanges = sh
	}

	if gdbscriptsize != 0 {
		sh := newElfShdr(elfstrdbg[ElfStrGDBScripts])
		sh.type_ = SHT_PROGBITS
		sh.off = uint64(gdbscripto)
		sh.size = uint64(gdbscriptsize)
		sh.addralign = 1
	}

	if inforelocsize != 0 {
		dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize)
	}

	if arangesrelocsize != 0 {
		dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize)
	}

	if linerelocsize != 0 {
		dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize)
	}

	if framerelocsize != 0 {
		dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize)
	}
}

/*
 * Macho
 */
func dwarfaddmachoheaders(ms *MachoSeg) {
	if Debug['w'] != 0 { // disable dwarf
		return
	}

	// Zero vsize segments won't be loaded in memory, even so they
	// have to be page aligned in the file.
	fakestart := Rnd(int64(Segdwarf.Fileoff), 0x1000)
	addr := Segdata.Vaddr + Segdata.Length

	nsect := 4
	if pubnamessize > 0 {
		nsect++
	}
	if pubtypessize > 0 {
		nsect++
	}
	if arangessize > 0 {
		nsect++
	}
	if gdbscriptsize > 0 {
		nsect++
	}

	if Linkmode != LinkExternal {
		ms = newMachoSeg("__DWARF", nsect)
		ms.fileoffset = uint64(fakestart)
		ms.filesize = Segdwarf.Filelen
		ms.vaddr = addr
	}

	msect := newMachoSect(ms, "__debug_abbrev", "__DWARF")
	msect.off = uint32(abbrevo)
	msect.size = uint64(abbrevsize)
	msect.addr = addr
	addr += msect.size
	msect.flag = 0x02000000
	if abbrevsym != nil {
		abbrevsym.Value = int64(msect.addr)
	}

	msect = newMachoSect(ms, "__debug_line", "__DWARF")
	msect.off = uint32(lineo)
	msect.size = uint64(linesize)
	msect.addr = addr
	addr += msect.size
	msect.flag = 0x02000000
	if linesym != nil {
		linesym.Value = int64(msect.addr)
	}
	if linerelocsize > 0 {
		msect.nreloc = uint32(len(linesec.R))
		msect.reloc = uint32(linereloco)
	}

	msect = newMachoSect(ms, "__debug_frame", "__DWARF")
	msect.off = uint32(frameo)
	msect.size = uint64(framesize)
	msect.addr = addr
	addr += msect.size
	msect.flag = 0x02000000
	if framesym != nil {
		framesym.Value = int64(msect.addr)
	}
	if framerelocsize > 0 {
		msect.nreloc = uint32(len(framesec.R))
		msect.reloc = uint32(framereloco)
	}

	msect = newMachoSect(ms, "__debug_info", "__DWARF")
	msect.off = uint32(infoo)
	msect.size = uint64(infosize)
	msect.addr = addr
	addr += msect.size
	msect.flag = 0x02000000
	if infosym != nil {
		infosym.Value = int64(msect.addr)
	}
	if inforelocsize > 0 {
		msect.nreloc = uint32(len(infosec.R))
		msect.reloc = uint32(inforeloco)
	}

	if pubnamessize > 0 {
		msect := newMachoSect(ms, "__debug_pubnames", "__DWARF")
		msect.off = uint32(pubnameso)
		msect.size = uint64(pubnamessize)
		msect.addr = addr
		addr += msect.size
		msect.flag = 0x02000000
	}

	if pubtypessize > 0 {
		msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF")
		msect.off = uint32(pubtypeso)
		msect.size = uint64(pubtypessize)
		msect.addr = addr
		addr += msect.size
		msect.flag = 0x02000000
	}

	if arangessize > 0 {
		msect := newMachoSect(ms, "__debug_aranges", "__DWARF")
		msect.off = uint32(arangeso)
		msect.size = uint64(arangessize)
		msect.addr = addr
		addr += msect.size
		msect.flag = 0x02000000
		if arangesrelocsize > 0 {
			msect.nreloc = uint32(len(arangessec.R))
			msect.reloc = uint32(arangesreloco)
		}
	}

	// 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 = uint32(gdbscripto)
		msect.size = uint64(gdbscriptsize)
		msect.addr = addr
		addr += msect.size
		msect.flag = 0x02000000
	}
}

/*
 * Windows PE
 */
func dwarfaddpeheaders() {
	if Debug['w'] != 0 { // 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)
}
