Home | History | Annotate | Download | only in ld
      1 // Copyright 2010 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // TODO/NICETOHAVE:
      6 //   - eliminate DW_CLS_ if not used
      7 //   - package info in compilation units
      8 //   - assign global variables and types to their packages
      9 //   - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg
     10 //     ptype struct '[]uint8' and qualifiers need to be quoted away
     11 //   - lexical scoping is lost, so gdb gets confused as to which 'main.i' you mean.
     12 //   - file:line info for variables
     13 //   - make strings a typedef so prettyprinters can see the underlying string type
     14 
     15 package ld
     16 
     17 import (
     18 	"cmd/internal/obj"
     19 	"fmt"
     20 	"os"
     21 	"strings"
     22 )
     23 
     24 /*
     25  * Offsets and sizes of the debug_* sections in the cout file.
     26  */
     27 var abbrevo int64
     28 
     29 var abbrevsize int64
     30 
     31 var abbrevsym *LSym
     32 
     33 var abbrevsympos int64
     34 
     35 var lineo int64
     36 
     37 var linesize int64
     38 
     39 var linesym *LSym
     40 
     41 var linesympos int64
     42 
     43 var infoo int64 // also the base for DWDie->offs and reference attributes.
     44 
     45 var infosize int64
     46 
     47 var infosym *LSym
     48 
     49 var infosympos int64
     50 
     51 var frameo int64
     52 
     53 var framesize int64
     54 
     55 var framesym *LSym
     56 
     57 var framesympos int64
     58 
     59 var pubnameso int64
     60 
     61 var pubnamessize int64
     62 
     63 var pubtypeso int64
     64 
     65 var pubtypessize int64
     66 
     67 var arangeso int64
     68 
     69 var arangessize int64
     70 
     71 var gdbscripto int64
     72 
     73 var gdbscriptsize int64
     74 
     75 var infosec *LSym
     76 
     77 var inforeloco int64
     78 
     79 var inforelocsize int64
     80 
     81 var arangessec *LSym
     82 
     83 var arangesreloco int64
     84 
     85 var arangesrelocsize int64
     86 
     87 var linesec *LSym
     88 
     89 var linereloco int64
     90 
     91 var linerelocsize int64
     92 
     93 var framesec *LSym
     94 
     95 var framereloco int64
     96 
     97 var framerelocsize int64
     98 
     99 var gdbscript string
    100 
    101 /*
    102  *  Basic I/O
    103  */
    104 func addrput(addr int64) {
    105 	switch Thearch.Ptrsize {
    106 	case 4:
    107 		Thearch.Lput(uint32(addr))
    108 
    109 	case 8:
    110 		Thearch.Vput(uint64(addr))
    111 	}
    112 }
    113 
    114 func uleb128enc(v uint64, dst []byte) int {
    115 	var c uint8
    116 
    117 	length := uint8(0)
    118 	for {
    119 		c = uint8(v & 0x7f)
    120 		v >>= 7
    121 		if v != 0 {
    122 			c |= 0x80
    123 		}
    124 		if dst != nil {
    125 			dst[0] = byte(c)
    126 			dst = dst[1:]
    127 		}
    128 		length++
    129 		if c&0x80 == 0 {
    130 			break
    131 		}
    132 	}
    133 
    134 	return int(length)
    135 }
    136 
    137 func sleb128enc(v int64, dst []byte) int {
    138 	var c uint8
    139 	var s uint8
    140 
    141 	length := uint8(0)
    142 	for {
    143 		c = uint8(v & 0x7f)
    144 		s = uint8(v & 0x40)
    145 		v >>= 7
    146 		if (v != -1 || s == 0) && (v != 0 || s != 0) {
    147 			c |= 0x80
    148 		}
    149 		if dst != nil {
    150 			dst[0] = byte(c)
    151 			dst = dst[1:]
    152 		}
    153 		length++
    154 		if c&0x80 == 0 {
    155 			break
    156 		}
    157 	}
    158 
    159 	return int(length)
    160 }
    161 
    162 var encbuf [10]byte
    163 
    164 func uleb128put(v int64) {
    165 	n := uleb128enc(uint64(v), encbuf[:])
    166 	Cwrite(encbuf[:n])
    167 }
    168 
    169 func sleb128put(v int64) {
    170 	n := sleb128enc(v, encbuf[:])
    171 	Cwrite(encbuf[:n])
    172 }
    173 
    174 /*
    175  * Defining Abbrevs.  This is hardcoded, and there will be
    176  * only a handful of them.  The DWARF spec places no restriction on
    177  * the ordering of attributes in the Abbrevs and DIEs, and we will
    178  * always write them out in the order of declaration in the abbrev.
    179  */
    180 type DWAttrForm struct {
    181 	attr uint16
    182 	form uint8
    183 }
    184 
    185 // Go-specific type attributes.
    186 const (
    187 	DW_AT_go_kind = 0x2900
    188 	DW_AT_go_key  = 0x2901
    189 	DW_AT_go_elem = 0x2902
    190 
    191 	DW_AT_internal_location = 253 // params and locals; not emitted
    192 )
    193 
    194 // Index into the abbrevs table below.
    195 // Keep in sync with ispubname() and ispubtype() below.
    196 // ispubtype considers >= NULLTYPE public
    197 const (
    198 	DW_ABRV_NULL = iota
    199 	DW_ABRV_COMPUNIT
    200 	DW_ABRV_FUNCTION
    201 	DW_ABRV_VARIABLE
    202 	DW_ABRV_AUTO
    203 	DW_ABRV_PARAM
    204 	DW_ABRV_STRUCTFIELD
    205 	DW_ABRV_FUNCTYPEPARAM
    206 	DW_ABRV_DOTDOTDOT
    207 	DW_ABRV_ARRAYRANGE
    208 	DW_ABRV_NULLTYPE
    209 	DW_ABRV_BASETYPE
    210 	DW_ABRV_ARRAYTYPE
    211 	DW_ABRV_CHANTYPE
    212 	DW_ABRV_FUNCTYPE
    213 	DW_ABRV_IFACETYPE
    214 	DW_ABRV_MAPTYPE
    215 	DW_ABRV_PTRTYPE
    216 	DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6.
    217 	DW_ABRV_SLICETYPE
    218 	DW_ABRV_STRINGTYPE
    219 	DW_ABRV_STRUCTTYPE
    220 	DW_ABRV_TYPEDECL
    221 	DW_NABRV
    222 )
    223 
    224 type DWAbbrev struct {
    225 	tag      uint8
    226 	children uint8
    227 	attr     []DWAttrForm
    228 }
    229 
    230 var abbrevs = [DW_NABRV]DWAbbrev{
    231 	/* The mandatory DW_ABRV_NULL entry. */
    232 	{0, 0, []DWAttrForm{}},
    233 
    234 	/* COMPUNIT */
    235 	{
    236 		DW_TAG_compile_unit,
    237 		DW_CHILDREN_yes,
    238 		[]DWAttrForm{
    239 			{DW_AT_name, DW_FORM_string},
    240 			{DW_AT_language, DW_FORM_data1},
    241 			{DW_AT_low_pc, DW_FORM_addr},
    242 			{DW_AT_high_pc, DW_FORM_addr},
    243 			{DW_AT_stmt_list, DW_FORM_data4},
    244 			{DW_AT_comp_dir, DW_FORM_string},
    245 		},
    246 	},
    247 
    248 	/* FUNCTION */
    249 	{
    250 		DW_TAG_subprogram,
    251 		DW_CHILDREN_yes,
    252 		[]DWAttrForm{
    253 			{DW_AT_name, DW_FORM_string},
    254 			{DW_AT_low_pc, DW_FORM_addr},
    255 			{DW_AT_high_pc, DW_FORM_addr},
    256 			{DW_AT_external, DW_FORM_flag},
    257 		},
    258 	},
    259 
    260 	/* VARIABLE */
    261 	{
    262 		DW_TAG_variable,
    263 		DW_CHILDREN_no,
    264 		[]DWAttrForm{
    265 			{DW_AT_name, DW_FORM_string},
    266 			{DW_AT_location, DW_FORM_block1},
    267 			{DW_AT_type, DW_FORM_ref_addr},
    268 			{DW_AT_external, DW_FORM_flag},
    269 		},
    270 	},
    271 
    272 	/* AUTO */
    273 	{
    274 		DW_TAG_variable,
    275 		DW_CHILDREN_no,
    276 		[]DWAttrForm{
    277 			{DW_AT_name, DW_FORM_string},
    278 			{DW_AT_location, DW_FORM_block1},
    279 			{DW_AT_type, DW_FORM_ref_addr},
    280 		},
    281 	},
    282 
    283 	/* PARAM */
    284 	{
    285 		DW_TAG_formal_parameter,
    286 		DW_CHILDREN_no,
    287 		[]DWAttrForm{
    288 			{DW_AT_name, DW_FORM_string},
    289 			{DW_AT_location, DW_FORM_block1},
    290 			{DW_AT_type, DW_FORM_ref_addr},
    291 		},
    292 	},
    293 
    294 	/* STRUCTFIELD */
    295 	{
    296 		DW_TAG_member,
    297 		DW_CHILDREN_no,
    298 		[]DWAttrForm{
    299 			{DW_AT_name, DW_FORM_string},
    300 			{DW_AT_data_member_location, DW_FORM_block1},
    301 			{DW_AT_type, DW_FORM_ref_addr},
    302 		},
    303 	},
    304 
    305 	/* FUNCTYPEPARAM */
    306 	{
    307 		DW_TAG_formal_parameter,
    308 		DW_CHILDREN_no,
    309 
    310 		// No name!
    311 		[]DWAttrForm{
    312 			{DW_AT_type, DW_FORM_ref_addr},
    313 		},
    314 	},
    315 
    316 	/* DOTDOTDOT */
    317 	{
    318 		DW_TAG_unspecified_parameters,
    319 		DW_CHILDREN_no,
    320 		[]DWAttrForm{},
    321 	},
    322 
    323 	/* ARRAYRANGE */
    324 	{
    325 		DW_TAG_subrange_type,
    326 		DW_CHILDREN_no,
    327 
    328 		// No name!
    329 		[]DWAttrForm{
    330 			{DW_AT_type, DW_FORM_ref_addr},
    331 			{DW_AT_count, DW_FORM_udata},
    332 		},
    333 	},
    334 
    335 	// Below here are the types considered public by ispubtype
    336 	/* NULLTYPE */
    337 	{
    338 		DW_TAG_unspecified_type,
    339 		DW_CHILDREN_no,
    340 		[]DWAttrForm{
    341 			{DW_AT_name, DW_FORM_string},
    342 		},
    343 	},
    344 
    345 	/* BASETYPE */
    346 	{
    347 		DW_TAG_base_type,
    348 		DW_CHILDREN_no,
    349 		[]DWAttrForm{
    350 			{DW_AT_name, DW_FORM_string},
    351 			{DW_AT_encoding, DW_FORM_data1},
    352 			{DW_AT_byte_size, DW_FORM_data1},
    353 			{DW_AT_go_kind, DW_FORM_data1},
    354 		},
    355 	},
    356 
    357 	/* ARRAYTYPE */
    358 	// child is subrange with upper bound
    359 	{
    360 		DW_TAG_array_type,
    361 		DW_CHILDREN_yes,
    362 		[]DWAttrForm{
    363 			{DW_AT_name, DW_FORM_string},
    364 			{DW_AT_type, DW_FORM_ref_addr},
    365 			{DW_AT_byte_size, DW_FORM_udata},
    366 			{DW_AT_go_kind, DW_FORM_data1},
    367 		},
    368 	},
    369 
    370 	/* CHANTYPE */
    371 	{
    372 		DW_TAG_typedef,
    373 		DW_CHILDREN_no,
    374 		[]DWAttrForm{
    375 			{DW_AT_name, DW_FORM_string},
    376 			{DW_AT_type, DW_FORM_ref_addr},
    377 			{DW_AT_go_kind, DW_FORM_data1},
    378 			{DW_AT_go_elem, DW_FORM_ref_addr},
    379 		},
    380 	},
    381 
    382 	/* FUNCTYPE */
    383 	{
    384 		DW_TAG_subroutine_type,
    385 		DW_CHILDREN_yes,
    386 		[]DWAttrForm{
    387 			{DW_AT_name, DW_FORM_string},
    388 			// {DW_AT_type,	DW_FORM_ref_addr},
    389 			{DW_AT_go_kind, DW_FORM_data1},
    390 		},
    391 	},
    392 
    393 	/* IFACETYPE */
    394 	{
    395 		DW_TAG_typedef,
    396 		DW_CHILDREN_yes,
    397 		[]DWAttrForm{
    398 			{DW_AT_name, DW_FORM_string},
    399 			{DW_AT_type, DW_FORM_ref_addr},
    400 			{DW_AT_go_kind, DW_FORM_data1},
    401 		},
    402 	},
    403 
    404 	/* MAPTYPE */
    405 	{
    406 		DW_TAG_typedef,
    407 		DW_CHILDREN_no,
    408 		[]DWAttrForm{
    409 			{DW_AT_name, DW_FORM_string},
    410 			{DW_AT_type, DW_FORM_ref_addr},
    411 			{DW_AT_go_kind, DW_FORM_data1},
    412 			{DW_AT_go_key, DW_FORM_ref_addr},
    413 			{DW_AT_go_elem, DW_FORM_ref_addr},
    414 		},
    415 	},
    416 
    417 	/* PTRTYPE */
    418 	{
    419 		DW_TAG_pointer_type,
    420 		DW_CHILDREN_no,
    421 		[]DWAttrForm{
    422 			{DW_AT_name, DW_FORM_string},
    423 			{DW_AT_type, DW_FORM_ref_addr},
    424 			{DW_AT_go_kind, DW_FORM_data1},
    425 		},
    426 	},
    427 
    428 	/* BARE_PTRTYPE */
    429 	{
    430 		DW_TAG_pointer_type,
    431 		DW_CHILDREN_no,
    432 		[]DWAttrForm{
    433 			{DW_AT_name, DW_FORM_string},
    434 		},
    435 	},
    436 
    437 	/* SLICETYPE */
    438 	{
    439 		DW_TAG_structure_type,
    440 		DW_CHILDREN_yes,
    441 		[]DWAttrForm{
    442 			{DW_AT_name, DW_FORM_string},
    443 			{DW_AT_byte_size, DW_FORM_udata},
    444 			{DW_AT_go_kind, DW_FORM_data1},
    445 			{DW_AT_go_elem, DW_FORM_ref_addr},
    446 		},
    447 	},
    448 
    449 	/* STRINGTYPE */
    450 	{
    451 		DW_TAG_structure_type,
    452 		DW_CHILDREN_yes,
    453 		[]DWAttrForm{
    454 			{DW_AT_name, DW_FORM_string},
    455 			{DW_AT_byte_size, DW_FORM_udata},
    456 			{DW_AT_go_kind, DW_FORM_data1},
    457 		},
    458 	},
    459 
    460 	/* STRUCTTYPE */
    461 	{
    462 		DW_TAG_structure_type,
    463 		DW_CHILDREN_yes,
    464 		[]DWAttrForm{
    465 			{DW_AT_name, DW_FORM_string},
    466 			{DW_AT_byte_size, DW_FORM_udata},
    467 			{DW_AT_go_kind, DW_FORM_data1},
    468 		},
    469 	},
    470 
    471 	/* TYPEDECL */
    472 	{
    473 		DW_TAG_typedef,
    474 		DW_CHILDREN_no,
    475 		[]DWAttrForm{
    476 			{DW_AT_name, DW_FORM_string},
    477 			{DW_AT_type, DW_FORM_ref_addr},
    478 		},
    479 	},
    480 }
    481 
    482 func writeabbrev() {
    483 	abbrevo = Cpos()
    484 	for i := 1; i < DW_NABRV; i++ {
    485 		// See section 7.5.3
    486 		uleb128put(int64(i))
    487 
    488 		uleb128put(int64(abbrevs[i].tag))
    489 		Cput(abbrevs[i].children)
    490 		for _, f := range abbrevs[i].attr {
    491 			uleb128put(int64(f.attr))
    492 			uleb128put(int64(f.form))
    493 		}
    494 		uleb128put(0)
    495 		uleb128put(0)
    496 	}
    497 
    498 	Cput(0)
    499 	abbrevsize = Cpos() - abbrevo
    500 }
    501 
    502 /*
    503  * Debugging Information Entries and their attributes.
    504  */
    505 const (
    506 	HASHSIZE = 107
    507 )
    508 
    509 func dwarfhashstr(s string) uint32 {
    510 	h := uint32(0)
    511 	for s != "" {
    512 		h = h + h + h + uint32(s[0])
    513 		s = s[1:]
    514 	}
    515 	return h % HASHSIZE
    516 }
    517 
    518 // For DW_CLS_string and _block, value should contain the length, and
    519 // data the data, for _reference, value is 0 and data is a DWDie* to
    520 // the referenced instance, for all others, value is the whole thing
    521 // and data is null.
    522 
    523 type DWAttr struct {
    524 	link  *DWAttr
    525 	atr   uint16 // DW_AT_
    526 	cls   uint8  // DW_CLS_
    527 	value int64
    528 	data  interface{}
    529 }
    530 
    531 type DWDie struct {
    532 	abbrev int
    533 	link   *DWDie
    534 	child  *DWDie
    535 	attr   *DWAttr
    536 	// offset into .debug_info section, i.e relative to
    537 	// infoo. only valid after call to putdie()
    538 	offs  int64
    539 	hash  []*DWDie // optional index of children by name, enabled by mkindex()
    540 	hlink *DWDie   // bucket chain in parent's index
    541 }
    542 
    543 /*
    544  * Root DIEs for compilation units, types and global variables.
    545  */
    546 var dwroot DWDie
    547 
    548 var dwtypes DWDie
    549 
    550 var dwglobals DWDie
    551 
    552 func newattr(die *DWDie, attr uint16, cls int, value int64, data interface{}) *DWAttr {
    553 	a := new(DWAttr)
    554 	a.link = die.attr
    555 	die.attr = a
    556 	a.atr = attr
    557 	a.cls = uint8(cls)
    558 	a.value = value
    559 	a.data = data
    560 	return a
    561 }
    562 
    563 // Each DIE (except the root ones) has at least 1 attribute: its
    564 // name. getattr moves the desired one to the front so
    565 // frequently searched ones are found faster.
    566 func getattr(die *DWDie, attr uint16) *DWAttr {
    567 	if die.attr.atr == attr {
    568 		return die.attr
    569 	}
    570 
    571 	a := die.attr
    572 	b := a.link
    573 	for b != nil {
    574 		if b.atr == attr {
    575 			a.link = b.link
    576 			b.link = die.attr
    577 			die.attr = b
    578 			return b
    579 		}
    580 
    581 		a = b
    582 		b = b.link
    583 	}
    584 
    585 	return nil
    586 }
    587 
    588 // Every DIE has at least a DW_AT_name attribute (but it will only be
    589 // written out if it is listed in the abbrev).	If its parent is
    590 // keeping an index, the new DIE will be inserted there.
    591 func newdie(parent *DWDie, abbrev int, name string) *DWDie {
    592 	die := new(DWDie)
    593 	die.abbrev = abbrev
    594 	die.link = parent.child
    595 	parent.child = die
    596 
    597 	newattr(die, DW_AT_name, DW_CLS_STRING, int64(len(name)), name)
    598 
    599 	if parent.hash != nil {
    600 		h := int(dwarfhashstr(name))
    601 		die.hlink = parent.hash[h]
    602 		parent.hash[h] = die
    603 	}
    604 
    605 	return die
    606 }
    607 
    608 func mkindex(die *DWDie) {
    609 	die.hash = make([]*DWDie, HASHSIZE)
    610 }
    611 
    612 func walktypedef(die *DWDie) *DWDie {
    613 	// Resolve typedef if present.
    614 	if die.abbrev == DW_ABRV_TYPEDECL {
    615 		for attr := die.attr; attr != nil; attr = attr.link {
    616 			if attr.atr == DW_AT_type && attr.cls == DW_CLS_REFERENCE && attr.data != nil {
    617 				return attr.data.(*DWDie)
    618 			}
    619 		}
    620 	}
    621 
    622 	return die
    623 }
    624 
    625 // Find child by AT_name using hashtable if available or linear scan
    626 // if not.
    627 func find(die *DWDie, name string) *DWDie {
    628 	var a *DWDie
    629 	var b *DWDie
    630 	var die2 *DWDie
    631 	var h int
    632 
    633 top:
    634 	if die.hash == nil {
    635 		for a = die.child; a != nil; a = a.link {
    636 			if name == getattr(a, DW_AT_name).data {
    637 				return a
    638 			}
    639 		}
    640 		goto notfound
    641 	}
    642 
    643 	h = int(dwarfhashstr(name))
    644 	a = die.hash[h]
    645 
    646 	if a == nil {
    647 		goto notfound
    648 	}
    649 
    650 	if name == getattr(a, DW_AT_name).data {
    651 		return a
    652 	}
    653 
    654 	// Move found ones to head of the list.
    655 	b = a.hlink
    656 
    657 	for b != nil {
    658 		if name == getattr(b, DW_AT_name).data {
    659 			a.hlink = b.hlink
    660 			b.hlink = die.hash[h]
    661 			die.hash[h] = b
    662 			return b
    663 		}
    664 
    665 		a = b
    666 		b = b.hlink
    667 	}
    668 
    669 notfound:
    670 	die2 = walktypedef(die)
    671 	if die2 != die {
    672 		die = die2
    673 		goto top
    674 	}
    675 
    676 	return nil
    677 }
    678 
    679 func mustFind(die *DWDie, name string) *DWDie {
    680 	r := find(die, name)
    681 	if r == nil {
    682 		Exitf("dwarf find: %s %p has no %s", getattr(die, DW_AT_name).data, die, name)
    683 	}
    684 	return r
    685 }
    686 
    687 func adddwarfrel(sec *LSym, sym *LSym, offsetbase int64, siz int, addend int64) {
    688 	r := Addrel(sec)
    689 	r.Sym = sym
    690 	r.Xsym = sym
    691 	r.Off = int32(Cpos() - offsetbase)
    692 	r.Siz = uint8(siz)
    693 	r.Type = obj.R_ADDR
    694 	r.Add = addend
    695 	r.Xadd = addend
    696 	if Iself && Thearch.Thechar == '6' {
    697 		addend = 0
    698 	}
    699 	if HEADTYPE == obj.Hdarwin {
    700 		addend += sym.Value
    701 	}
    702 	switch siz {
    703 	case 4:
    704 		Thearch.Lput(uint32(addend))
    705 
    706 	case 8:
    707 		Thearch.Vput(uint64(addend))
    708 
    709 	default:
    710 		Diag("bad size in adddwarfrel")
    711 	}
    712 }
    713 
    714 func newrefattr(die *DWDie, attr uint16, ref *DWDie) *DWAttr {
    715 	if ref == nil {
    716 		return nil
    717 	}
    718 	return newattr(die, attr, DW_CLS_REFERENCE, 0, ref)
    719 }
    720 
    721 var fwdcount int
    722 
    723 func putattr(abbrev int, form int, cls int, value int64, data interface{}) {
    724 	switch form {
    725 	case DW_FORM_addr: // address
    726 		if Linkmode == LinkExternal {
    727 			value -= (data.(*LSym)).Value
    728 			adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value)
    729 			break
    730 		}
    731 
    732 		addrput(value)
    733 
    734 	case DW_FORM_block1: // block
    735 		if cls == DW_CLS_ADDRESS {
    736 			Cput(uint8(1 + Thearch.Ptrsize))
    737 			Cput(DW_OP_addr)
    738 			if Linkmode == LinkExternal {
    739 				value -= (data.(*LSym)).Value
    740 				adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value)
    741 				break
    742 			}
    743 
    744 			addrput(value)
    745 			break
    746 		}
    747 
    748 		value &= 0xff
    749 		Cput(uint8(value))
    750 		p := data.([]byte)
    751 		for i := 0; int64(i) < value; i++ {
    752 			Cput(uint8(p[i]))
    753 		}
    754 
    755 	case DW_FORM_block2: // block
    756 		value &= 0xffff
    757 
    758 		Thearch.Wput(uint16(value))
    759 		p := data.([]byte)
    760 		for i := 0; int64(i) < value; i++ {
    761 			Cput(uint8(p[i]))
    762 		}
    763 
    764 	case DW_FORM_block4: // block
    765 		value &= 0xffffffff
    766 
    767 		Thearch.Lput(uint32(value))
    768 		p := data.([]byte)
    769 		for i := 0; int64(i) < value; i++ {
    770 			Cput(uint8(p[i]))
    771 		}
    772 
    773 	case DW_FORM_block: // block
    774 		uleb128put(value)
    775 
    776 		p := data.([]byte)
    777 		for i := 0; int64(i) < value; i++ {
    778 			Cput(uint8(p[i]))
    779 		}
    780 
    781 	case DW_FORM_data1: // constant
    782 		Cput(uint8(value))
    783 
    784 	case DW_FORM_data2: // constant
    785 		Thearch.Wput(uint16(value))
    786 
    787 	case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr
    788 		if Linkmode == LinkExternal && cls == DW_CLS_PTR {
    789 			adddwarfrel(infosec, linesym, infoo, 4, value)
    790 			break
    791 		}
    792 
    793 		Thearch.Lput(uint32(value))
    794 
    795 	case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr
    796 		Thearch.Vput(uint64(value))
    797 
    798 	case DW_FORM_sdata: // constant
    799 		sleb128put(value)
    800 
    801 	case DW_FORM_udata: // constant
    802 		uleb128put(value)
    803 
    804 	case DW_FORM_string: // string
    805 		strnput(data.(string), int(value+1))
    806 
    807 	case DW_FORM_flag: // flag
    808 		if value != 0 {
    809 			Cput(1)
    810 		} else {
    811 			Cput(0)
    812 		}
    813 
    814 		// In DWARF 2 (which is what we claim to generate),
    815 	// the ref_addr is the same size as a normal address.
    816 	// In DWARF 3 it is always 32 bits, unless emitting a large
    817 	// (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
    818 	case DW_FORM_ref_addr: // reference to a DIE in the .info section
    819 		if data == nil {
    820 			Diag("dwarf: null reference in %d", abbrev)
    821 			if Thearch.Ptrsize == 8 {
    822 				Thearch.Vput(0) // invalid dwarf, gdb will complain.
    823 			} else {
    824 				Thearch.Lput(0) // invalid dwarf, gdb will complain.
    825 			}
    826 		} else {
    827 			off := (data.(*DWDie)).offs
    828 			if off == 0 {
    829 				fwdcount++
    830 			}
    831 			if Linkmode == LinkExternal {
    832 				adddwarfrel(infosec, infosym, infoo, Thearch.Ptrsize, off)
    833 				break
    834 			}
    835 
    836 			addrput(off)
    837 		}
    838 
    839 	case DW_FORM_ref1, // reference within the compilation unit
    840 		DW_FORM_ref2,      // reference
    841 		DW_FORM_ref4,      // reference
    842 		DW_FORM_ref8,      // reference
    843 		DW_FORM_ref_udata, // reference
    844 
    845 		DW_FORM_strp,     // string
    846 		DW_FORM_indirect: // (see Section 7.5.3)
    847 		fallthrough
    848 	default:
    849 		Exitf("dwarf: unsupported attribute form %d / class %d", form, cls)
    850 	}
    851 }
    852 
    853 // Note that we can (and do) add arbitrary attributes to a DIE, but
    854 // only the ones actually listed in the Abbrev will be written out.
    855 func putattrs(abbrev int, attr *DWAttr) {
    856 Outer:
    857 	for _, f := range abbrevs[abbrev].attr {
    858 		for ap := attr; ap != nil; ap = ap.link {
    859 			if ap.atr == f.attr {
    860 				putattr(abbrev, int(f.form), int(ap.cls), ap.value, ap.data)
    861 				continue Outer
    862 			}
    863 		}
    864 
    865 		putattr(abbrev, int(f.form), 0, 0, nil)
    866 	}
    867 }
    868 
    869 func putdies(die *DWDie) {
    870 	for ; die != nil; die = die.link {
    871 		putdie(die)
    872 	}
    873 }
    874 
    875 func putdie(die *DWDie) {
    876 	die.offs = Cpos() - infoo
    877 	uleb128put(int64(die.abbrev))
    878 	putattrs(die.abbrev, die.attr)
    879 	if abbrevs[die.abbrev].children != 0 {
    880 		putdies(die.child)
    881 		Cput(0)
    882 	}
    883 }
    884 
    885 func reverselist(list **DWDie) {
    886 	curr := *list
    887 	var prev *DWDie
    888 	for curr != nil {
    889 		var next *DWDie = curr.link
    890 		curr.link = prev
    891 		prev = curr
    892 		curr = next
    893 	}
    894 
    895 	*list = prev
    896 }
    897 
    898 func reversetree(list **DWDie) {
    899 	reverselist(list)
    900 	for die := *list; die != nil; die = die.link {
    901 		if abbrevs[die.abbrev].children != 0 {
    902 			reversetree(&die.child)
    903 		}
    904 	}
    905 }
    906 
    907 func newmemberoffsetattr(die *DWDie, offs int32) {
    908 	var block [20]byte
    909 
    910 	i := 0
    911 	block[i] = DW_OP_plus_uconst
    912 	i++
    913 	i += uleb128enc(uint64(offs), block[i:])
    914 	newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, int64(i), block[:i])
    915 }
    916 
    917 // GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
    918 // location expression that evals to a const.
    919 func newabslocexprattr(die *DWDie, addr int64, sym *LSym) {
    920 	newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, sym)
    921 	// below
    922 }
    923 
    924 // Lookup predefined types
    925 func lookup_or_diag(n string) *LSym {
    926 	s := Linkrlookup(Ctxt, n, 0)
    927 	if s == nil || s.Size == 0 {
    928 		Exitf("dwarf: missing type: %s", n)
    929 	}
    930 
    931 	return s
    932 }
    933 
    934 func dotypedef(parent *DWDie, name string, def *DWDie) {
    935 	// Only emit typedefs for real names.
    936 	if strings.HasPrefix(name, "map[") {
    937 		return
    938 	}
    939 	if strings.HasPrefix(name, "struct {") {
    940 		return
    941 	}
    942 	if strings.HasPrefix(name, "chan ") {
    943 		return
    944 	}
    945 	if name[0] == '[' || name[0] == '*' {
    946 		return
    947 	}
    948 	if def == nil {
    949 		Diag("dwarf: bad def in dotypedef")
    950 	}
    951 
    952 	// The typedef entry must be created after the def,
    953 	// so that future lookups will find the typedef instead
    954 	// of the real definition. This hooks the typedef into any
    955 	// circular definition loops, so that gdb can understand them.
    956 	die := newdie(parent, DW_ABRV_TYPEDECL, name)
    957 
    958 	newrefattr(die, DW_AT_type, def)
    959 }
    960 
    961 // Define gotype, for composite ones recurse into constituents.
    962 func defgotype(gotype *LSym) *DWDie {
    963 	if gotype == nil {
    964 		return mustFind(&dwtypes, "<unspecified>")
    965 	}
    966 
    967 	if !strings.HasPrefix(gotype.Name, "type.") {
    968 		Diag("dwarf: type name doesn't start with \".type\": %s", gotype.Name)
    969 		return mustFind(&dwtypes, "<unspecified>")
    970 	}
    971 
    972 	name := gotype.Name[5:] // could also decode from Type.string
    973 
    974 	die := find(&dwtypes, name)
    975 
    976 	if die != nil {
    977 		return die
    978 	}
    979 
    980 	if false && Debug['v'] > 2 {
    981 		fmt.Printf("new type: %v\n", gotype)
    982 	}
    983 
    984 	kind := decodetype_kind(gotype)
    985 	bytesize := decodetype_size(gotype)
    986 
    987 	switch kind {
    988 	case obj.KindBool:
    989 		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
    990 		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_boolean, 0)
    991 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
    992 
    993 	case obj.KindInt,
    994 		obj.KindInt8,
    995 		obj.KindInt16,
    996 		obj.KindInt32,
    997 		obj.KindInt64:
    998 		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
    999 		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_signed, 0)
   1000 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1001 
   1002 	case obj.KindUint,
   1003 		obj.KindUint8,
   1004 		obj.KindUint16,
   1005 		obj.KindUint32,
   1006 		obj.KindUint64,
   1007 		obj.KindUintptr:
   1008 		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
   1009 		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
   1010 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1011 
   1012 	case obj.KindFloat32,
   1013 		obj.KindFloat64:
   1014 		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
   1015 		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_float, 0)
   1016 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1017 
   1018 	case obj.KindComplex64,
   1019 		obj.KindComplex128:
   1020 		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
   1021 		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_complex_float, 0)
   1022 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1023 
   1024 	case obj.KindArray:
   1025 		die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name)
   1026 		dotypedef(&dwtypes, name, die)
   1027 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1028 		s := decodetype_arrayelem(gotype)
   1029 		newrefattr(die, DW_AT_type, defgotype(s))
   1030 		fld := newdie(die, DW_ABRV_ARRAYRANGE, "range")
   1031 
   1032 		// use actual length not upper bound; correct for 0-length arrays.
   1033 		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0)
   1034 
   1035 		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
   1036 
   1037 	case obj.KindChan:
   1038 		die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name)
   1039 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1040 		s := decodetype_chanelem(gotype)
   1041 		newrefattr(die, DW_AT_go_elem, defgotype(s))
   1042 
   1043 	case obj.KindFunc:
   1044 		die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name)
   1045 		dotypedef(&dwtypes, name, die)
   1046 		newrefattr(die, DW_AT_type, mustFind(&dwtypes, "void"))
   1047 		nfields := decodetype_funcincount(gotype)
   1048 		var fld *DWDie
   1049 		var s *LSym
   1050 		for i := 0; i < nfields; i++ {
   1051 			s = decodetype_funcintype(gotype, i)
   1052 			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:])
   1053 			newrefattr(fld, DW_AT_type, defgotype(s))
   1054 		}
   1055 
   1056 		if decodetype_funcdotdotdot(gotype) != 0 {
   1057 			newdie(die, DW_ABRV_DOTDOTDOT, "...")
   1058 		}
   1059 		nfields = decodetype_funcoutcount(gotype)
   1060 		for i := 0; i < nfields; i++ {
   1061 			s = decodetype_funcouttype(gotype, i)
   1062 			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:])
   1063 			newrefattr(fld, DW_AT_type, defptrto(defgotype(s)))
   1064 		}
   1065 
   1066 	case obj.KindInterface:
   1067 		die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name)
   1068 		dotypedef(&dwtypes, name, die)
   1069 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1070 		nfields := int(decodetype_ifacemethodcount(gotype))
   1071 		var s *LSym
   1072 		if nfields == 0 {
   1073 			s = lookup_or_diag("type.runtime.eface")
   1074 		} else {
   1075 			s = lookup_or_diag("type.runtime.iface")
   1076 		}
   1077 		newrefattr(die, DW_AT_type, defgotype(s))
   1078 
   1079 	case obj.KindMap:
   1080 		die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name)
   1081 		s := decodetype_mapkey(gotype)
   1082 		newrefattr(die, DW_AT_go_key, defgotype(s))
   1083 		s = decodetype_mapvalue(gotype)
   1084 		newrefattr(die, DW_AT_go_elem, defgotype(s))
   1085 
   1086 	case obj.KindPtr:
   1087 		die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name)
   1088 		dotypedef(&dwtypes, name, die)
   1089 		s := decodetype_ptrelem(gotype)
   1090 		newrefattr(die, DW_AT_type, defgotype(s))
   1091 
   1092 	case obj.KindSlice:
   1093 		die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name)
   1094 		dotypedef(&dwtypes, name, die)
   1095 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1096 		s := decodetype_arrayelem(gotype)
   1097 		newrefattr(die, DW_AT_go_elem, defgotype(s))
   1098 
   1099 	case obj.KindString:
   1100 		die = newdie(&dwtypes, DW_ABRV_STRINGTYPE, name)
   1101 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1102 
   1103 	case obj.KindStruct:
   1104 		die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name)
   1105 		dotypedef(&dwtypes, name, die)
   1106 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   1107 		nfields := decodetype_structfieldcount(gotype)
   1108 		var f string
   1109 		var fld *DWDie
   1110 		var s *LSym
   1111 		for i := 0; i < nfields; i++ {
   1112 			f = decodetype_structfieldname(gotype, i)
   1113 			s = decodetype_structfieldtype(gotype, i)
   1114 			if f == "" {
   1115 				f = s.Name[5:] // skip "type."
   1116 			}
   1117 			fld = newdie(die, DW_ABRV_STRUCTFIELD, f)
   1118 			newrefattr(fld, DW_AT_type, defgotype(s))
   1119 			newmemberoffsetattr(fld, int32(decodetype_structfieldoffs(gotype, i)))
   1120 		}
   1121 
   1122 	case obj.KindUnsafePointer:
   1123 		die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name)
   1124 
   1125 	default:
   1126 		Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name)
   1127 		die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name)
   1128 		newrefattr(die, DW_AT_type, mustFind(&dwtypes, "<unspecified>"))
   1129 	}
   1130 
   1131 	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, int64(kind), 0)
   1132 
   1133 	return die
   1134 }
   1135 
   1136 // Find or construct *T given T.
   1137 func defptrto(dwtype *DWDie) *DWDie {
   1138 	ptrname := fmt.Sprintf("*%s", getattr(dwtype, DW_AT_name).data)
   1139 	die := find(&dwtypes, ptrname)
   1140 	if die == nil {
   1141 		die = newdie(&dwtypes, DW_ABRV_PTRTYPE, ptrname)
   1142 		newrefattr(die, DW_AT_type, dwtype)
   1143 	}
   1144 
   1145 	return die
   1146 }
   1147 
   1148 // Copies src's children into dst. Copies attributes by value.
   1149 // DWAttr.data is copied as pointer only.  If except is one of
   1150 // the top-level children, it will not be copied.
   1151 func copychildrenexcept(dst *DWDie, src *DWDie, except *DWDie) {
   1152 	var c *DWDie
   1153 	var a *DWAttr
   1154 
   1155 	for src = src.child; src != nil; src = src.link {
   1156 		if src == except {
   1157 			continue
   1158 		}
   1159 		c = newdie(dst, src.abbrev, getattr(src, DW_AT_name).data.(string))
   1160 		for a = src.attr; a != nil; a = a.link {
   1161 			newattr(c, a.atr, int(a.cls), a.value, a.data)
   1162 		}
   1163 		copychildrenexcept(c, src, nil)
   1164 	}
   1165 
   1166 	reverselist(&dst.child)
   1167 }
   1168 
   1169 func copychildren(dst *DWDie, src *DWDie) {
   1170 	copychildrenexcept(dst, src, nil)
   1171 }
   1172 
   1173 // Search children (assumed to have DW_TAG_member) for the one named
   1174 // field and set its DW_AT_type to dwtype
   1175 func substitutetype(structdie *DWDie, field string, dwtype *DWDie) {
   1176 	child := mustFind(structdie, field)
   1177 	if child == nil {
   1178 		return
   1179 	}
   1180 
   1181 	a := getattr(child, DW_AT_type)
   1182 	if a != nil {
   1183 		a.data = dwtype
   1184 	} else {
   1185 		newrefattr(child, DW_AT_type, dwtype)
   1186 	}
   1187 }
   1188 
   1189 func synthesizestringtypes(die *DWDie) {
   1190 	prototype := walktypedef(defgotype(lookup_or_diag("type.runtime._string")))
   1191 	if prototype == nil {
   1192 		return
   1193 	}
   1194 
   1195 	for ; die != nil; die = die.link {
   1196 		if die.abbrev != DW_ABRV_STRINGTYPE {
   1197 			continue
   1198 		}
   1199 		copychildren(die, prototype)
   1200 	}
   1201 }
   1202 
   1203 func synthesizeslicetypes(die *DWDie) {
   1204 	prototype := walktypedef(defgotype(lookup_or_diag("type.runtime.slice")))
   1205 	if prototype == nil {
   1206 		return
   1207 	}
   1208 
   1209 	var elem *DWDie
   1210 	for ; die != nil; die = die.link {
   1211 		if die.abbrev != DW_ABRV_SLICETYPE {
   1212 			continue
   1213 		}
   1214 		copychildren(die, prototype)
   1215 		elem = getattr(die, DW_AT_go_elem).data.(*DWDie)
   1216 		substitutetype(die, "array", defptrto(elem))
   1217 	}
   1218 }
   1219 
   1220 func mkinternaltypename(base string, arg1 string, arg2 string) string {
   1221 	var buf string
   1222 
   1223 	if arg2 == "" {
   1224 		buf = fmt.Sprintf("%s<%s>", base, arg1)
   1225 	} else {
   1226 		buf = fmt.Sprintf("%s<%s,%s>", base, arg1, arg2)
   1227 	}
   1228 	n := buf
   1229 	return n
   1230 }
   1231 
   1232 // synthesizemaptypes is way too closely married to runtime/hashmap.c
   1233 const (
   1234 	MaxKeySize = 128
   1235 	MaxValSize = 128
   1236 	BucketSize = 8
   1237 )
   1238 
   1239 func synthesizemaptypes(die *DWDie) {
   1240 	hash := walktypedef(defgotype(lookup_or_diag("type.runtime.hmap")))
   1241 	bucket := walktypedef(defgotype(lookup_or_diag("type.runtime.bmap")))
   1242 
   1243 	if hash == nil {
   1244 		return
   1245 	}
   1246 
   1247 	var a *DWAttr
   1248 	var dwh *DWDie
   1249 	var dwhb *DWDie
   1250 	var dwhk *DWDie
   1251 	var dwhv *DWDie
   1252 	var fld *DWDie
   1253 	var indirect_key int
   1254 	var indirect_val int
   1255 	var keysize int
   1256 	var keytype *DWDie
   1257 	var t *DWDie
   1258 	var valsize int
   1259 	var valtype *DWDie
   1260 	for ; die != nil; die = die.link {
   1261 		if die.abbrev != DW_ABRV_MAPTYPE {
   1262 			continue
   1263 		}
   1264 
   1265 		keytype = walktypedef(getattr(die, DW_AT_go_key).data.(*DWDie))
   1266 		valtype = walktypedef(getattr(die, DW_AT_go_elem).data.(*DWDie))
   1267 
   1268 		// compute size info like hashmap.c does.
   1269 		a = getattr(keytype, DW_AT_byte_size)
   1270 
   1271 		if a != nil {
   1272 			keysize = int(a.value)
   1273 		} else {
   1274 			keysize = Thearch.Ptrsize
   1275 		}
   1276 		a = getattr(valtype, DW_AT_byte_size)
   1277 		if a != nil {
   1278 			valsize = int(a.value)
   1279 		} else {
   1280 			valsize = Thearch.Ptrsize
   1281 		}
   1282 		indirect_key = 0
   1283 		indirect_val = 0
   1284 		if keysize > MaxKeySize {
   1285 			keysize = Thearch.Ptrsize
   1286 			indirect_key = 1
   1287 		}
   1288 
   1289 		if valsize > MaxValSize {
   1290 			valsize = Thearch.Ptrsize
   1291 			indirect_val = 1
   1292 		}
   1293 
   1294 		// Construct type to represent an array of BucketSize keys
   1295 		dwhk = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]key", getattr(keytype, DW_AT_name).data.(string), ""))
   1296 
   1297 		newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(keysize), 0)
   1298 		t = keytype
   1299 		if indirect_key != 0 {
   1300 			t = defptrto(keytype)
   1301 		}
   1302 		newrefattr(dwhk, DW_AT_type, t)
   1303 		fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size")
   1304 		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
   1305 		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
   1306 
   1307 		// Construct type to represent an array of BucketSize values
   1308 		dwhv = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]val", getattr(valtype, DW_AT_name).data.(string), ""))
   1309 
   1310 		newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(valsize), 0)
   1311 		t = valtype
   1312 		if indirect_val != 0 {
   1313 			t = defptrto(valtype)
   1314 		}
   1315 		newrefattr(dwhv, DW_AT_type, t)
   1316 		fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size")
   1317 		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
   1318 		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
   1319 
   1320 		// Construct bucket<K,V>
   1321 		dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("bucket", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string)))
   1322 
   1323 		// Copy over all fields except the field "data" from the generic bucket.
   1324 		// "data" will be replaced with keys/values below.
   1325 		copychildrenexcept(dwhb, bucket, find(bucket, "data"))
   1326 
   1327 		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys")
   1328 		newrefattr(fld, DW_AT_type, dwhk)
   1329 		newmemberoffsetattr(fld, BucketSize)
   1330 		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values")
   1331 		newrefattr(fld, DW_AT_type, dwhv)
   1332 		newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize))
   1333 		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow")
   1334 		newrefattr(fld, DW_AT_type, defptrto(dwhb))
   1335 		newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
   1336 		if Thearch.Regsize > Thearch.Ptrsize {
   1337 			fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad")
   1338 			newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
   1339 			newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(Thearch.Ptrsize))
   1340 		}
   1341 
   1342 		newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize+BucketSize*int64(keysize)+BucketSize*int64(valsize)+int64(Thearch.Regsize), 0)
   1343 
   1344 		// Construct hash<K,V>
   1345 		dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("hash", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string)))
   1346 
   1347 		copychildren(dwh, hash)
   1348 		substitutetype(dwh, "buckets", defptrto(dwhb))
   1349 		substitutetype(dwh, "oldbuckets", defptrto(dwhb))
   1350 		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hash, DW_AT_byte_size).value, nil)
   1351 
   1352 		// make map type a pointer to hash<K,V>
   1353 		newrefattr(die, DW_AT_type, defptrto(dwh))
   1354 	}
   1355 }
   1356 
   1357 func synthesizechantypes(die *DWDie) {
   1358 	sudog := walktypedef(defgotype(lookup_or_diag("type.runtime.sudog")))
   1359 	waitq := walktypedef(defgotype(lookup_or_diag("type.runtime.waitq")))
   1360 	hchan := walktypedef(defgotype(lookup_or_diag("type.runtime.hchan")))
   1361 	if sudog == nil || waitq == nil || hchan == nil {
   1362 		return
   1363 	}
   1364 
   1365 	sudogsize := int(getattr(sudog, DW_AT_byte_size).value)
   1366 
   1367 	var a *DWAttr
   1368 	var dwh *DWDie
   1369 	var dws *DWDie
   1370 	var dww *DWDie
   1371 	var elemsize int
   1372 	var elemtype *DWDie
   1373 	for ; die != nil; die = die.link {
   1374 		if die.abbrev != DW_ABRV_CHANTYPE {
   1375 			continue
   1376 		}
   1377 		elemtype = getattr(die, DW_AT_go_elem).data.(*DWDie)
   1378 		a = getattr(elemtype, DW_AT_byte_size)
   1379 		if a != nil {
   1380 			elemsize = int(a.value)
   1381 		} else {
   1382 			elemsize = Thearch.Ptrsize
   1383 		}
   1384 
   1385 		// sudog<T>
   1386 		dws = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("sudog", getattr(elemtype, DW_AT_name).data.(string), ""))
   1387 
   1388 		copychildren(dws, sudog)
   1389 		substitutetype(dws, "elem", elemtype)
   1390 		if elemsize > 8 {
   1391 			elemsize -= 8
   1392 		} else {
   1393 			elemsize = 0
   1394 		}
   1395 		newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT, int64(sudogsize)+int64(elemsize), nil)
   1396 
   1397 		// waitq<T>
   1398 		dww = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("waitq", getattr(elemtype, DW_AT_name).data.(string), ""))
   1399 
   1400 		copychildren(dww, waitq)
   1401 		substitutetype(dww, "first", defptrto(dws))
   1402 		substitutetype(dww, "last", defptrto(dws))
   1403 		newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(waitq, DW_AT_byte_size).value, nil)
   1404 
   1405 		// hchan<T>
   1406 		dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("hchan", getattr(elemtype, DW_AT_name).data.(string), ""))
   1407 
   1408 		copychildren(dwh, hchan)
   1409 		substitutetype(dwh, "recvq", dww)
   1410 		substitutetype(dwh, "sendq", dww)
   1411 		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hchan, DW_AT_byte_size).value, nil)
   1412 
   1413 		newrefattr(die, DW_AT_type, defptrto(dwh))
   1414 	}
   1415 }
   1416 
   1417 // For use with pass.c::genasmsym
   1418 func defdwsymb(sym *LSym, s string, t int, v int64, size int64, ver int, gotype *LSym) {
   1419 	if strings.HasPrefix(s, "go.string.") {
   1420 		return
   1421 	}
   1422 	if strings.HasPrefix(s, "runtime.gcbits.") {
   1423 		return
   1424 	}
   1425 
   1426 	if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
   1427 		defgotype(sym)
   1428 		return
   1429 	}
   1430 
   1431 	var dv *DWDie
   1432 
   1433 	var dt *DWDie
   1434 	switch t {
   1435 	default:
   1436 		return
   1437 
   1438 	case 'd', 'b', 'D', 'B':
   1439 		dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s)
   1440 		newabslocexprattr(dv, v, sym)
   1441 		if ver == 0 {
   1442 			newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0)
   1443 		}
   1444 		fallthrough
   1445 
   1446 	case 'a', 'p':
   1447 		dt = defgotype(gotype)
   1448 	}
   1449 
   1450 	if dv != nil {
   1451 		newrefattr(dv, DW_AT_type, dt)
   1452 	}
   1453 }
   1454 
   1455 func movetomodule(parent *DWDie) {
   1456 	die := dwroot.child.child
   1457 	for die.link != nil {
   1458 		die = die.link
   1459 	}
   1460 	die.link = parent.child
   1461 }
   1462 
   1463 // If the pcln table contains runtime/runtime.go, use that to set gdbscript path.
   1464 func finddebugruntimepath(s *LSym) {
   1465 	if gdbscript != "" {
   1466 		return
   1467 	}
   1468 
   1469 	var f *LSym
   1470 	var p string
   1471 	for i := 0; i < s.Pcln.Nfile; i++ {
   1472 		f = s.Pcln.File[i]
   1473 		_ = p
   1474 		if i := strings.Index(f.Name, "runtime/runtime.go"); i >= 0 {
   1475 			gdbscript = f.Name[:i] + "runtime/runtime-gdb.py"
   1476 			break
   1477 		}
   1478 	}
   1479 }
   1480 
   1481 /*
   1482  * Generate short opcodes when possible, long ones when necessary.
   1483  * See section 6.2.5
   1484  */
   1485 const (
   1486 	LINE_BASE   = -1
   1487 	LINE_RANGE  = 4
   1488 	OPCODE_BASE = 10
   1489 )
   1490 
   1491 func putpclcdelta(delta_pc int64, delta_lc int64) {
   1492 	if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE {
   1493 		var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc)
   1494 		if OPCODE_BASE <= opcode && opcode < 256 {
   1495 			Cput(uint8(opcode))
   1496 			return
   1497 		}
   1498 	}
   1499 
   1500 	if delta_pc != 0 {
   1501 		Cput(DW_LNS_advance_pc)
   1502 		sleb128put(delta_pc)
   1503 	}
   1504 
   1505 	Cput(DW_LNS_advance_line)
   1506 	sleb128put(delta_lc)
   1507 	Cput(DW_LNS_copy)
   1508 }
   1509 
   1510 func newcfaoffsetattr(die *DWDie, offs int32) {
   1511 	var block [20]byte
   1512 
   1513 	i := 0
   1514 
   1515 	block[i] = DW_OP_call_frame_cfa
   1516 	i++
   1517 	if offs != 0 {
   1518 		block[i] = DW_OP_consts
   1519 		i++
   1520 		i += sleb128enc(int64(offs), block[i:])
   1521 		block[i] = DW_OP_plus
   1522 		i++
   1523 	}
   1524 
   1525 	newattr(die, DW_AT_location, DW_CLS_BLOCK, int64(i), block[:i])
   1526 }
   1527 
   1528 func mkvarname(name string, da int) string {
   1529 	buf := fmt.Sprintf("%s#%d", name, da)
   1530 	n := buf
   1531 	return n
   1532 }
   1533 
   1534 /*
   1535  * Walk prog table, emit line program and build DIE tree.
   1536  */
   1537 
   1538 // flush previous compilation unit.
   1539 func flushunit(dwinfo *DWDie, pc int64, pcsym *LSym, unitstart int64, header_length int32) {
   1540 	if dwinfo != nil && pc != 0 {
   1541 		newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, pcsym)
   1542 	}
   1543 
   1544 	if unitstart >= 0 {
   1545 		Cput(0) // start extended opcode
   1546 		uleb128put(1)
   1547 		Cput(DW_LNE_end_sequence)
   1548 
   1549 		here := Cpos()
   1550 		Cseek(unitstart)
   1551 		Thearch.Lput(uint32(here - unitstart - 4)) // unit_length
   1552 		Thearch.Wput(2)                            // dwarf version
   1553 		Thearch.Lput(uint32(header_length))        // header length starting here
   1554 		Cseek(here)
   1555 	}
   1556 }
   1557 
   1558 func getCompilationDir() string {
   1559 	if dir, err := os.Getwd(); err == nil {
   1560 		return dir
   1561 	}
   1562 	return "/"
   1563 }
   1564 
   1565 func writelines() {
   1566 	if linesec == nil {
   1567 		linesec = Linklookup(Ctxt, ".dwarfline", 0)
   1568 	}
   1569 	linesec.R = linesec.R[:0]
   1570 
   1571 	unitstart := int64(-1)
   1572 	headerend := int64(-1)
   1573 	epc := int64(0)
   1574 	var epcs *LSym
   1575 	lineo = Cpos()
   1576 	var dwinfo *DWDie
   1577 
   1578 	flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10))
   1579 	unitstart = Cpos()
   1580 
   1581 	lang := DW_LANG_Go
   1582 
   1583 	s := Ctxt.Textp
   1584 
   1585 	dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, "go")
   1586 	newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(lang), 0)
   1587 	newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart-lineo, 0)
   1588 	newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
   1589 	// OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
   1590 	compDir := getCompilationDir()
   1591 	newattr(dwinfo, DW_AT_comp_dir, DW_CLS_STRING, int64(len(compDir)), compDir)
   1592 
   1593 	// Write .debug_line Line Number Program Header (sec 6.2.4)
   1594 	// Fields marked with (*) must be changed for 64-bit dwarf
   1595 	Thearch.Lput(0) // unit_length (*), will be filled in by flushunit.
   1596 	Thearch.Wput(2) // dwarf version (appendix F)
   1597 	Thearch.Lput(0) // header_length (*), filled in by flushunit.
   1598 
   1599 	// cpos == unitstart + 4 + 2 + 4
   1600 	Cput(1)                // minimum_instruction_length
   1601 	Cput(1)                // default_is_stmt
   1602 	Cput(LINE_BASE & 0xFF) // line_base
   1603 	Cput(LINE_RANGE)       // line_range
   1604 	Cput(OPCODE_BASE)      // opcode_base
   1605 	Cput(0)                // standard_opcode_lengths[1]
   1606 	Cput(1)                // standard_opcode_lengths[2]
   1607 	Cput(1)                // standard_opcode_lengths[3]
   1608 	Cput(1)                // standard_opcode_lengths[4]
   1609 	Cput(1)                // standard_opcode_lengths[5]
   1610 	Cput(0)                // standard_opcode_lengths[6]
   1611 	Cput(0)                // standard_opcode_lengths[7]
   1612 	Cput(0)                // standard_opcode_lengths[8]
   1613 	Cput(1)                // standard_opcode_lengths[9]
   1614 	Cput(0)                // include_directories  (empty)
   1615 
   1616 	files := make([]*LSym, Ctxt.Nhistfile)
   1617 
   1618 	for f := Ctxt.Filesyms; f != nil; f = f.Next {
   1619 		files[f.Value-1] = f
   1620 	}
   1621 
   1622 	for i := 0; int32(i) < Ctxt.Nhistfile; i++ {
   1623 		strnput(files[i].Name, len(files[i].Name)+4)
   1624 	}
   1625 
   1626 	// 4 zeros: the string termination + 3 fields.
   1627 	Cput(0)
   1628 	// terminate file_names.
   1629 	headerend = Cpos()
   1630 
   1631 	Cput(0) // start extended opcode
   1632 	uleb128put(1 + int64(Thearch.Ptrsize))
   1633 	Cput(DW_LNE_set_address)
   1634 
   1635 	pc := s.Value
   1636 	line := 1
   1637 	file := 1
   1638 	if Linkmode == LinkExternal {
   1639 		adddwarfrel(linesec, s, lineo, Thearch.Ptrsize, 0)
   1640 	} else {
   1641 		addrput(pc)
   1642 	}
   1643 
   1644 	var a *Auto
   1645 	var da int
   1646 	var dt int
   1647 	var dwfunc *DWDie
   1648 	var dws **DWDie
   1649 	var dwvar *DWDie
   1650 	var n string
   1651 	var nn string
   1652 	var offs int64
   1653 	var pcfile Pciter
   1654 	var pcline Pciter
   1655 	var varhash [HASHSIZE]*DWDie
   1656 	for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
   1657 		s = Ctxt.Cursym
   1658 
   1659 		dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s.Name)
   1660 		newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
   1661 		epc = s.Value + s.Size
   1662 		epcs = s
   1663 		newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, s)
   1664 		if s.Version == 0 {
   1665 			newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0)
   1666 		}
   1667 
   1668 		if s.Pcln == nil {
   1669 			continue
   1670 		}
   1671 
   1672 		finddebugruntimepath(s)
   1673 
   1674 		pciterinit(Ctxt, &pcfile, &s.Pcln.Pcfile)
   1675 		pciterinit(Ctxt, &pcline, &s.Pcln.Pcline)
   1676 		epc = pc
   1677 		for pcfile.done == 0 && pcline.done == 0 {
   1678 			if epc-s.Value >= int64(pcfile.nextpc) {
   1679 				pciternext(&pcfile)
   1680 				continue
   1681 			}
   1682 
   1683 			if epc-s.Value >= int64(pcline.nextpc) {
   1684 				pciternext(&pcline)
   1685 				continue
   1686 			}
   1687 
   1688 			if int32(file) != pcfile.value {
   1689 				Cput(DW_LNS_set_file)
   1690 				uleb128put(int64(pcfile.value))
   1691 				file = int(pcfile.value)
   1692 			}
   1693 
   1694 			putpclcdelta(s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line))
   1695 
   1696 			pc = s.Value + int64(pcline.pc)
   1697 			line = int(pcline.value)
   1698 			if pcfile.nextpc < pcline.nextpc {
   1699 				epc = int64(pcfile.nextpc)
   1700 			} else {
   1701 				epc = int64(pcline.nextpc)
   1702 			}
   1703 			epc += s.Value
   1704 		}
   1705 
   1706 		da = 0
   1707 		dwfunc.hash = varhash[:] // enable indexing of children by name
   1708 		varhash = [HASHSIZE]*DWDie{}
   1709 		for a = s.Autom; a != nil; a = a.Link {
   1710 			switch a.Name {
   1711 			case obj.A_AUTO:
   1712 				dt = DW_ABRV_AUTO
   1713 				offs = int64(a.Aoffset)
   1714 				if !haslinkregister() {
   1715 					offs -= int64(Thearch.Ptrsize)
   1716 				}
   1717 
   1718 			case obj.A_PARAM:
   1719 				dt = DW_ABRV_PARAM
   1720 				offs = int64(a.Aoffset)
   1721 				if haslinkregister() {
   1722 					offs += int64(Thearch.Ptrsize)
   1723 				}
   1724 
   1725 			default:
   1726 				continue
   1727 			}
   1728 
   1729 			if strings.Contains(a.Asym.Name, ".autotmp_") {
   1730 				continue
   1731 			}
   1732 			if find(dwfunc, a.Asym.Name) != nil {
   1733 				n = mkvarname(a.Asym.Name, da)
   1734 			} else {
   1735 				n = a.Asym.Name
   1736 			}
   1737 
   1738 			// Drop the package prefix from locals and arguments.
   1739 			_ = nn
   1740 			if i := strings.LastIndex(n, "."); i >= 0 {
   1741 				n = n[i+1:]
   1742 			}
   1743 
   1744 			dwvar = newdie(dwfunc, dt, n)
   1745 			newcfaoffsetattr(dwvar, int32(offs))
   1746 			newrefattr(dwvar, DW_AT_type, defgotype(a.Gotype))
   1747 
   1748 			// push dwvar down dwfunc->child to preserve order
   1749 			newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil)
   1750 
   1751 			dwfunc.child = dwvar.link // take dwvar out from the top of the list
   1752 			for dws = &dwfunc.child; *dws != nil; dws = &(*dws).link {
   1753 				if offs > getattr(*dws, DW_AT_internal_location).value {
   1754 					break
   1755 				}
   1756 			}
   1757 			dwvar.link = *dws
   1758 			*dws = dwvar
   1759 
   1760 			da++
   1761 		}
   1762 
   1763 		dwfunc.hash = nil
   1764 	}
   1765 
   1766 	flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10))
   1767 	linesize = Cpos() - lineo
   1768 }
   1769 
   1770 /*
   1771  *  Emit .debug_frame
   1772  */
   1773 const (
   1774 	CIERESERVE          = 16
   1775 	DATAALIGNMENTFACTOR = -4
   1776 )
   1777 
   1778 func putpccfadelta(deltapc int64, cfa int64) {
   1779 	Cput(DW_CFA_def_cfa_offset_sf)
   1780 	sleb128put(cfa / DATAALIGNMENTFACTOR)
   1781 
   1782 	if deltapc < 0x40 {
   1783 		Cput(uint8(DW_CFA_advance_loc + deltapc))
   1784 	} else if deltapc < 0x100 {
   1785 		Cput(DW_CFA_advance_loc1)
   1786 		Cput(uint8(deltapc))
   1787 	} else if deltapc < 0x10000 {
   1788 		Cput(DW_CFA_advance_loc2)
   1789 		Thearch.Wput(uint16(deltapc))
   1790 	} else {
   1791 		Cput(DW_CFA_advance_loc4)
   1792 		Thearch.Lput(uint32(deltapc))
   1793 	}
   1794 }
   1795 
   1796 func writeframes() {
   1797 	if framesec == nil {
   1798 		framesec = Linklookup(Ctxt, ".dwarfframe", 0)
   1799 	}
   1800 	framesec.R = framesec.R[:0]
   1801 	frameo = Cpos()
   1802 
   1803 	// Emit the CIE, Section 6.4.1
   1804 	Thearch.Lput(CIERESERVE)              // initial length, must be multiple of thearch.ptrsize
   1805 	Thearch.Lput(0xffffffff)              // cid.
   1806 	Cput(3)                               // dwarf version (appendix F)
   1807 	Cput(0)                               // augmentation ""
   1808 	uleb128put(1)                         // code_alignment_factor
   1809 	sleb128put(DATAALIGNMENTFACTOR)       // guess
   1810 	uleb128put(int64(Thearch.Dwarfreglr)) // return_address_register
   1811 
   1812 	Cput(DW_CFA_def_cfa)
   1813 
   1814 	uleb128put(int64(Thearch.Dwarfregsp)) // register SP (**ABI-dependent, defined in l.h)
   1815 	if haslinkregister() {
   1816 		uleb128put(int64(0)) // offset
   1817 	} else {
   1818 		uleb128put(int64(Thearch.Ptrsize)) // offset
   1819 	}
   1820 
   1821 	Cput(DW_CFA_offset_extended)
   1822 	uleb128put(int64(Thearch.Dwarfreglr)) // return address
   1823 	if haslinkregister() {
   1824 		uleb128put(int64(0) / DATAALIGNMENTFACTOR) // at cfa - 0
   1825 	} else {
   1826 		uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4
   1827 	}
   1828 
   1829 	// 4 is to exclude the length field.
   1830 	pad := CIERESERVE + frameo + 4 - Cpos()
   1831 
   1832 	if pad < 0 {
   1833 		Exitf("dwarf: CIERESERVE too small by %d bytes.", -pad)
   1834 	}
   1835 
   1836 	strnput("", int(pad))
   1837 
   1838 	var fdeo int64
   1839 	var fdesize int64
   1840 	var nextpc uint32
   1841 	var pcsp Pciter
   1842 	var s *LSym
   1843 	for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
   1844 		s = Ctxt.Cursym
   1845 		if s.Pcln == nil {
   1846 			continue
   1847 		}
   1848 
   1849 		fdeo = Cpos()
   1850 
   1851 		// Emit a FDE, Section 6.4.1, starting wit a placeholder.
   1852 		Thearch.Lput(0) // length, must be multiple of thearch.ptrsize
   1853 		Thearch.Lput(0) // Pointer to the CIE above, at offset 0
   1854 		addrput(0)      // initial location
   1855 		addrput(0)      // address range
   1856 
   1857 		for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
   1858 			nextpc = pcsp.nextpc
   1859 
   1860 			// pciterinit goes up to the end of the function,
   1861 			// but DWARF expects us to stop just before the end.
   1862 			if int64(nextpc) == s.Size {
   1863 				nextpc--
   1864 				if nextpc < pcsp.pc {
   1865 					continue
   1866 				}
   1867 			}
   1868 
   1869 			if haslinkregister() {
   1870 				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
   1871 			} else {
   1872 				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value))
   1873 			}
   1874 		}
   1875 
   1876 		fdesize = Cpos() - fdeo - 4 // exclude the length field.
   1877 		pad = Rnd(fdesize, int64(Thearch.Ptrsize)) - fdesize
   1878 		strnput("", int(pad))
   1879 		fdesize += pad
   1880 
   1881 		// Emit the FDE header for real, Section 6.4.1.
   1882 		Cseek(fdeo)
   1883 
   1884 		Thearch.Lput(uint32(fdesize))
   1885 		if Linkmode == LinkExternal {
   1886 			adddwarfrel(framesec, framesym, frameo, 4, 0)
   1887 			adddwarfrel(framesec, s, frameo, Thearch.Ptrsize, 0)
   1888 		} else {
   1889 			Thearch.Lput(0)
   1890 			addrput(s.Value)
   1891 		}
   1892 
   1893 		addrput(s.Size)
   1894 		Cseek(fdeo + 4 + fdesize)
   1895 	}
   1896 
   1897 	Cflush()
   1898 	framesize = Cpos() - frameo
   1899 }
   1900 
   1901 /*
   1902  *  Walk DWarfDebugInfoEntries, and emit .debug_info
   1903  */
   1904 const (
   1905 	COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
   1906 )
   1907 
   1908 func writeinfo() {
   1909 	fwdcount = 0
   1910 	if infosec == nil {
   1911 		infosec = Linklookup(Ctxt, ".dwarfinfo", 0)
   1912 	}
   1913 	infosec.R = infosec.R[:0]
   1914 
   1915 	if arangessec == nil {
   1916 		arangessec = Linklookup(Ctxt, ".dwarfaranges", 0)
   1917 	}
   1918 	arangessec.R = arangessec.R[:0]
   1919 
   1920 	var here int64
   1921 	var unitstart int64
   1922 	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
   1923 		unitstart = Cpos()
   1924 
   1925 		// Write .debug_info Compilation Unit Header (sec 7.5.1)
   1926 		// Fields marked with (*) must be changed for 64-bit dwarf
   1927 		// This must match COMPUNITHEADERSIZE above.
   1928 		Thearch.Lput(0) // unit_length (*), will be filled in later.
   1929 		Thearch.Wput(2) // dwarf version (appendix F)
   1930 
   1931 		// debug_abbrev_offset (*)
   1932 		if Linkmode == LinkExternal {
   1933 			adddwarfrel(infosec, abbrevsym, infoo, 4, 0)
   1934 		} else {
   1935 			Thearch.Lput(0)
   1936 		}
   1937 
   1938 		Cput(uint8(Thearch.Ptrsize)) // address_size
   1939 
   1940 		putdie(compunit)
   1941 
   1942 		here = Cpos()
   1943 		Cseek(unitstart)
   1944 		Thearch.Lput(uint32(here - unitstart - 4)) // exclude the length field.
   1945 		Cseek(here)
   1946 	}
   1947 
   1948 	Cflush()
   1949 }
   1950 
   1951 /*
   1952  *  Emit .debug_pubnames/_types.  _info must have been written before,
   1953  *  because we need die->offs and infoo/infosize;
   1954  */
   1955 func ispubname(die *DWDie) bool {
   1956 	switch die.abbrev {
   1957 	case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE:
   1958 		a := getattr(die, DW_AT_external)
   1959 		return a != nil && a.value != 0
   1960 	}
   1961 
   1962 	return false
   1963 }
   1964 
   1965 func ispubtype(die *DWDie) bool {
   1966 	return die.abbrev >= DW_ABRV_NULLTYPE
   1967 }
   1968 
   1969 func writepub(ispub func(*DWDie) bool) int64 {
   1970 	var die *DWDie
   1971 	var dwa *DWAttr
   1972 	var unitstart int64
   1973 	var unitend int64
   1974 	var here int64
   1975 
   1976 	sectionstart := Cpos()
   1977 
   1978 	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
   1979 		unitstart = compunit.offs - COMPUNITHEADERSIZE
   1980 		if compunit.link != nil {
   1981 			unitend = compunit.link.offs - COMPUNITHEADERSIZE
   1982 		} else {
   1983 			unitend = infoo + infosize
   1984 		}
   1985 
   1986 		// Write .debug_pubnames/types	Header (sec 6.1.1)
   1987 		Thearch.Lput(0)                           // unit_length (*), will be filled in later.
   1988 		Thearch.Wput(2)                           // dwarf version (appendix F)
   1989 		Thearch.Lput(uint32(unitstart))           // debug_info_offset (of the Comp unit Header)
   1990 		Thearch.Lput(uint32(unitend - unitstart)) // debug_info_length
   1991 
   1992 		for die = compunit.child; die != nil; die = die.link {
   1993 			if !ispub(die) {
   1994 				continue
   1995 			}
   1996 			Thearch.Lput(uint32(die.offs - unitstart))
   1997 			dwa = getattr(die, DW_AT_name)
   1998 			strnput(dwa.data.(string), int(dwa.value+1))
   1999 		}
   2000 
   2001 		Thearch.Lput(0)
   2002 
   2003 		here = Cpos()
   2004 		Cseek(sectionstart)
   2005 		Thearch.Lput(uint32(here - sectionstart - 4)) // exclude the length field.
   2006 		Cseek(here)
   2007 	}
   2008 
   2009 	return sectionstart
   2010 }
   2011 
   2012 /*
   2013  *  emit .debug_aranges.  _info must have been written before,
   2014  *  because we need die->offs of dw_globals.
   2015  */
   2016 func writearanges() int64 {
   2017 	var b *DWAttr
   2018 	var e *DWAttr
   2019 	var value int64
   2020 
   2021 	sectionstart := Cpos()
   2022 	headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize))) // don't count unit_length field itself
   2023 
   2024 	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
   2025 		b = getattr(compunit, DW_AT_low_pc)
   2026 		if b == nil {
   2027 			continue
   2028 		}
   2029 		e = getattr(compunit, DW_AT_high_pc)
   2030 		if e == nil {
   2031 			continue
   2032 		}
   2033 
   2034 		// Write .debug_aranges	 Header + entry	 (sec 6.1.2)
   2035 		Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*)
   2036 		Thearch.Wput(2)                                                  // dwarf version (appendix F)
   2037 
   2038 		value = compunit.offs - COMPUNITHEADERSIZE // debug_info_offset
   2039 		if Linkmode == LinkExternal {
   2040 			adddwarfrel(arangessec, infosym, sectionstart, 4, value)
   2041 		} else {
   2042 			Thearch.Lput(uint32(value))
   2043 		}
   2044 
   2045 		Cput(uint8(Thearch.Ptrsize))        // address_size
   2046 		Cput(0)                             // segment_size
   2047 		strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize
   2048 
   2049 		if Linkmode == LinkExternal {
   2050 			adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value)
   2051 		} else {
   2052 			addrput(b.value)
   2053 		}
   2054 
   2055 		addrput(e.value - b.value)
   2056 		addrput(0)
   2057 		addrput(0)
   2058 	}
   2059 
   2060 	Cflush()
   2061 	return sectionstart
   2062 }
   2063 
   2064 func writegdbscript() int64 {
   2065 	sectionstart := Cpos()
   2066 
   2067 	if gdbscript != "" {
   2068 		Cput(1) // magic 1 byte?
   2069 		strnput(gdbscript, len(gdbscript)+1)
   2070 		Cflush()
   2071 	}
   2072 
   2073 	return sectionstart
   2074 }
   2075 
   2076 func align(size int64) {
   2077 	if HEADTYPE == obj.Hwindows { // Only Windows PE need section align.
   2078 		strnput("", int(Rnd(size, PEFILEALIGN)-size))
   2079 	}
   2080 }
   2081 
   2082 func writedwarfreloc(s *LSym) int64 {
   2083 	var i int
   2084 	var r *Reloc
   2085 
   2086 	start := Cpos()
   2087 	for ri := 0; ri < len(s.R); ri++ {
   2088 		r = &s.R[ri]
   2089 		if Iself {
   2090 			i = Thearch.Elfreloc1(r, int64(r.Off))
   2091 		} else if HEADTYPE == obj.Hdarwin {
   2092 			i = Thearch.Machoreloc1(r, int64(r.Off))
   2093 		} else {
   2094 			i = -1
   2095 		}
   2096 		if i < 0 {
   2097 			Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
   2098 		}
   2099 	}
   2100 
   2101 	return start
   2102 }
   2103 
   2104 func addmachodwarfsect(prev *Section, name string) *Section {
   2105 	sect := addsection(&Segdwarf, name, 04)
   2106 	sect.Extnum = prev.Extnum + 1
   2107 	sym := Linklookup(Ctxt, name, 0)
   2108 	sym.Sect = sect
   2109 	return sect
   2110 }
   2111 
   2112 /*
   2113  * This is the main entry point for generating dwarf.  After emitting
   2114  * the mandatory debug_abbrev section, it calls writelines() to set up
   2115  * the per-compilation unit part of the DIE tree, while simultaneously
   2116  * emitting the debug_line section.  When the final tree contains
   2117  * forward references, it will write the debug_info section in 2
   2118  * passes.
   2119  *
   2120  */
   2121 func Dwarfemitdebugsections() {
   2122 	if Debug['w'] != 0 { // disable dwarf
   2123 		return
   2124 	}
   2125 
   2126 	if Linkmode == LinkExternal {
   2127 		if !Iself && HEADTYPE != obj.Hdarwin {
   2128 			return
   2129 		}
   2130 		if HEADTYPE == obj.Hdarwin {
   2131 			sect := Segdata.Sect
   2132 			// find the last section.
   2133 			for sect.Next != nil {
   2134 				sect = sect.Next
   2135 			}
   2136 			sect = addmachodwarfsect(sect, ".debug_abbrev")
   2137 			sect = addmachodwarfsect(sect, ".debug_line")
   2138 			sect = addmachodwarfsect(sect, ".debug_frame")
   2139 			sect = addmachodwarfsect(sect, ".debug_info")
   2140 
   2141 			infosym = Linklookup(Ctxt, ".debug_info", 0)
   2142 			infosym.Hide = 1
   2143 
   2144 			abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
   2145 			abbrevsym.Hide = 1
   2146 
   2147 			linesym = Linklookup(Ctxt, ".debug_line", 0)
   2148 			linesym.Hide = 1
   2149 
   2150 			framesym = Linklookup(Ctxt, ".debug_frame", 0)
   2151 			framesym.Hide = 1
   2152 		}
   2153 	}
   2154 
   2155 	// For diagnostic messages.
   2156 	newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes")
   2157 
   2158 	mkindex(&dwroot)
   2159 	mkindex(&dwtypes)
   2160 	mkindex(&dwglobals)
   2161 
   2162 	// Some types that must exist to define other ones.
   2163 	newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>")
   2164 
   2165 	newdie(&dwtypes, DW_ABRV_NULLTYPE, "void")
   2166 	newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer")
   2167 
   2168 	die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr") // needed for array size
   2169 	newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
   2170 	newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0)
   2171 	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0)
   2172 
   2173 	// Needed by the prettyprinter code for interface inspection.
   2174 	defgotype(lookup_or_diag("type.runtime._type"))
   2175 
   2176 	defgotype(lookup_or_diag("type.runtime.interfacetype"))
   2177 	defgotype(lookup_or_diag("type.runtime.itab"))
   2178 
   2179 	genasmsym(defdwsymb)
   2180 
   2181 	writeabbrev()
   2182 	align(abbrevsize)
   2183 	writelines()
   2184 	align(linesize)
   2185 	writeframes()
   2186 	align(framesize)
   2187 
   2188 	synthesizestringtypes(dwtypes.child)
   2189 	synthesizeslicetypes(dwtypes.child)
   2190 	synthesizemaptypes(dwtypes.child)
   2191 	synthesizechantypes(dwtypes.child)
   2192 
   2193 	reversetree(&dwroot.child)
   2194 	reversetree(&dwtypes.child)
   2195 	reversetree(&dwglobals.child)
   2196 
   2197 	movetomodule(&dwtypes)
   2198 	movetomodule(&dwglobals)
   2199 
   2200 	infoo = Cpos()
   2201 	writeinfo()
   2202 	infoe := Cpos()
   2203 	pubnameso = infoe
   2204 	pubtypeso = infoe
   2205 	arangeso = infoe
   2206 	gdbscripto = infoe
   2207 
   2208 	if fwdcount > 0 {
   2209 		if Debug['v'] != 0 {
   2210 			fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime())
   2211 		}
   2212 		Cseek(infoo)
   2213 		writeinfo()
   2214 		if fwdcount > 0 {
   2215 			Exitf("dwarf: unresolved references after first dwarf info pass")
   2216 		}
   2217 
   2218 		if infoe != Cpos() {
   2219 			Exitf("dwarf: inconsistent second dwarf info pass")
   2220 		}
   2221 	}
   2222 
   2223 	infosize = infoe - infoo
   2224 	align(infosize)
   2225 
   2226 	pubnameso = writepub(ispubname)
   2227 	pubnamessize = Cpos() - pubnameso
   2228 	align(pubnamessize)
   2229 
   2230 	pubtypeso = writepub(ispubtype)
   2231 	pubtypessize = Cpos() - pubtypeso
   2232 	align(pubtypessize)
   2233 
   2234 	arangeso = writearanges()
   2235 	arangessize = Cpos() - arangeso
   2236 	align(arangessize)
   2237 
   2238 	gdbscripto = writegdbscript()
   2239 	gdbscriptsize = Cpos() - gdbscripto
   2240 	align(gdbscriptsize)
   2241 
   2242 	for Cpos()&7 != 0 {
   2243 		Cput(0)
   2244 	}
   2245 	if HEADTYPE != obj.Hdarwin {
   2246 		dwarfemitreloc()
   2247 	}
   2248 }
   2249 
   2250 func dwarfemitreloc() {
   2251 	if Debug['w'] != 0 { // disable dwarf
   2252 		return
   2253 	}
   2254 	inforeloco = writedwarfreloc(infosec)
   2255 	inforelocsize = Cpos() - inforeloco
   2256 	align(inforelocsize)
   2257 
   2258 	arangesreloco = writedwarfreloc(arangessec)
   2259 	arangesrelocsize = Cpos() - arangesreloco
   2260 	align(arangesrelocsize)
   2261 
   2262 	linereloco = writedwarfreloc(linesec)
   2263 	linerelocsize = Cpos() - linereloco
   2264 	align(linerelocsize)
   2265 
   2266 	framereloco = writedwarfreloc(framesec)
   2267 	framerelocsize = Cpos() - framereloco
   2268 	align(framerelocsize)
   2269 }
   2270 
   2271 /*
   2272  *  Elf.
   2273  */
   2274 const (
   2275 	ElfStrDebugAbbrev = iota
   2276 	ElfStrDebugAranges
   2277 	ElfStrDebugFrame
   2278 	ElfStrDebugInfo
   2279 	ElfStrDebugLine
   2280 	ElfStrDebugLoc
   2281 	ElfStrDebugMacinfo
   2282 	ElfStrDebugPubNames
   2283 	ElfStrDebugPubTypes
   2284 	ElfStrDebugRanges
   2285 	ElfStrDebugStr
   2286 	ElfStrGDBScripts
   2287 	ElfStrRelDebugInfo
   2288 	ElfStrRelDebugAranges
   2289 	ElfStrRelDebugLine
   2290 	ElfStrRelDebugFrame
   2291 	NElfStrDbg
   2292 )
   2293 
   2294 var elfstrdbg [NElfStrDbg]int64
   2295 
   2296 func dwarfaddshstrings(shstrtab *LSym) {
   2297 	if Debug['w'] != 0 { // disable dwarf
   2298 		return
   2299 	}
   2300 
   2301 	elfstrdbg[ElfStrDebugAbbrev] = Addstring(shstrtab, ".debug_abbrev")
   2302 	elfstrdbg[ElfStrDebugAranges] = Addstring(shstrtab, ".debug_aranges")
   2303 	elfstrdbg[ElfStrDebugFrame] = Addstring(shstrtab, ".debug_frame")
   2304 	elfstrdbg[ElfStrDebugInfo] = Addstring(shstrtab, ".debug_info")
   2305 	elfstrdbg[ElfStrDebugLine] = Addstring(shstrtab, ".debug_line")
   2306 	elfstrdbg[ElfStrDebugLoc] = Addstring(shstrtab, ".debug_loc")
   2307 	elfstrdbg[ElfStrDebugMacinfo] = Addstring(shstrtab, ".debug_macinfo")
   2308 	elfstrdbg[ElfStrDebugPubNames] = Addstring(shstrtab, ".debug_pubnames")
   2309 	elfstrdbg[ElfStrDebugPubTypes] = Addstring(shstrtab, ".debug_pubtypes")
   2310 	elfstrdbg[ElfStrDebugRanges] = Addstring(shstrtab, ".debug_ranges")
   2311 	elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str")
   2312 	elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts")
   2313 	if Linkmode == LinkExternal {
   2314 		switch Thearch.Thechar {
   2315 		case '6', '7', '9':
   2316 			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info")
   2317 			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges")
   2318 			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line")
   2319 			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame")
   2320 		default:
   2321 			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info")
   2322 			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges")
   2323 			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line")
   2324 			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rel.debug_frame")
   2325 		}
   2326 
   2327 		infosym = Linklookup(Ctxt, ".debug_info", 0)
   2328 		infosym.Hide = 1
   2329 
   2330 		abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
   2331 		abbrevsym.Hide = 1
   2332 
   2333 		linesym = Linklookup(Ctxt, ".debug_line", 0)
   2334 		linesym.Hide = 1
   2335 
   2336 		framesym = Linklookup(Ctxt, ".debug_frame", 0)
   2337 		framesym.Hide = 1
   2338 	}
   2339 }
   2340 
   2341 // Add section symbols for DWARF debug info.  This is called before
   2342 // dwarfaddelfheaders.
   2343 func dwarfaddelfsectionsyms() {
   2344 	if infosym != nil {
   2345 		infosympos = Cpos()
   2346 		putelfsectionsym(infosym, 0)
   2347 	}
   2348 
   2349 	if abbrevsym != nil {
   2350 		abbrevsympos = Cpos()
   2351 		putelfsectionsym(abbrevsym, 0)
   2352 	}
   2353 
   2354 	if linesym != nil {
   2355 		linesympos = Cpos()
   2356 		putelfsectionsym(linesym, 0)
   2357 	}
   2358 
   2359 	if framesym != nil {
   2360 		framesympos = Cpos()
   2361 		putelfsectionsym(framesym, 0)
   2362 	}
   2363 }
   2364 
   2365 func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) {
   2366 	sh := newElfShdr(elfstrdbg[elfstr])
   2367 	switch Thearch.Thechar {
   2368 	case '6', '7', '9':
   2369 		sh.type_ = SHT_RELA
   2370 	default:
   2371 		sh.type_ = SHT_REL
   2372 	}
   2373 
   2374 	sh.entsize = uint64(Thearch.Ptrsize) * 2
   2375 	if sh.type_ == SHT_RELA {
   2376 		sh.entsize += uint64(Thearch.Ptrsize)
   2377 	}
   2378 	sh.link = uint32(elfshname(".symtab").shnum)
   2379 	sh.info = uint32(shdata.shnum)
   2380 	sh.off = uint64(off)
   2381 	sh.size = uint64(size)
   2382 	sh.addralign = uint64(Thearch.Ptrsize)
   2383 }
   2384 
   2385 func dwarfaddelfheaders() {
   2386 	if Debug['w'] != 0 { // disable dwarf
   2387 		return
   2388 	}
   2389 
   2390 	sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev])
   2391 	sh.type_ = SHT_PROGBITS
   2392 	sh.off = uint64(abbrevo)
   2393 	sh.size = uint64(abbrevsize)
   2394 	sh.addralign = 1
   2395 	if abbrevsympos > 0 {
   2396 		putelfsymshndx(abbrevsympos, sh.shnum)
   2397 	}
   2398 
   2399 	sh = newElfShdr(elfstrdbg[ElfStrDebugLine])
   2400 	sh.type_ = SHT_PROGBITS
   2401 	sh.off = uint64(lineo)
   2402 	sh.size = uint64(linesize)
   2403 	sh.addralign = 1
   2404 	if linesympos > 0 {
   2405 		putelfsymshndx(linesympos, sh.shnum)
   2406 	}
   2407 	shline := sh
   2408 
   2409 	sh = newElfShdr(elfstrdbg[ElfStrDebugFrame])
   2410 	sh.type_ = SHT_PROGBITS
   2411 	sh.off = uint64(frameo)
   2412 	sh.size = uint64(framesize)
   2413 	sh.addralign = 1
   2414 	if framesympos > 0 {
   2415 		putelfsymshndx(framesympos, sh.shnum)
   2416 	}
   2417 	shframe := sh
   2418 
   2419 	sh = newElfShdr(elfstrdbg[ElfStrDebugInfo])
   2420 	sh.type_ = SHT_PROGBITS
   2421 	sh.off = uint64(infoo)
   2422 	sh.size = uint64(infosize)
   2423 	sh.addralign = 1
   2424 	if infosympos > 0 {
   2425 		putelfsymshndx(infosympos, sh.shnum)
   2426 	}
   2427 	shinfo := sh
   2428 
   2429 	if pubnamessize > 0 {
   2430 		sh := newElfShdr(elfstrdbg[ElfStrDebugPubNames])
   2431 		sh.type_ = SHT_PROGBITS
   2432 		sh.off = uint64(pubnameso)
   2433 		sh.size = uint64(pubnamessize)
   2434 		sh.addralign = 1
   2435 	}
   2436 
   2437 	if pubtypessize > 0 {
   2438 		sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes])
   2439 		sh.type_ = SHT_PROGBITS
   2440 		sh.off = uint64(pubtypeso)
   2441 		sh.size = uint64(pubtypessize)
   2442 		sh.addralign = 1
   2443 	}
   2444 
   2445 	var sharanges *ElfShdr
   2446 	if arangessize != 0 {
   2447 		sh := newElfShdr(elfstrdbg[ElfStrDebugAranges])
   2448 		sh.type_ = SHT_PROGBITS
   2449 		sh.off = uint64(arangeso)
   2450 		sh.size = uint64(arangessize)
   2451 		sh.addralign = 1
   2452 		sharanges = sh
   2453 	}
   2454 
   2455 	if gdbscriptsize != 0 {
   2456 		sh := newElfShdr(elfstrdbg[ElfStrGDBScripts])
   2457 		sh.type_ = SHT_PROGBITS
   2458 		sh.off = uint64(gdbscripto)
   2459 		sh.size = uint64(gdbscriptsize)
   2460 		sh.addralign = 1
   2461 	}
   2462 
   2463 	if inforelocsize != 0 {
   2464 		dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize)
   2465 	}
   2466 
   2467 	if arangesrelocsize != 0 {
   2468 		dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize)
   2469 	}
   2470 
   2471 	if linerelocsize != 0 {
   2472 		dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize)
   2473 	}
   2474 
   2475 	if framerelocsize != 0 {
   2476 		dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize)
   2477 	}
   2478 }
   2479 
   2480 /*
   2481  * Macho
   2482  */
   2483 func dwarfaddmachoheaders(ms *MachoSeg) {
   2484 	if Debug['w'] != 0 { // disable dwarf
   2485 		return
   2486 	}
   2487 
   2488 	// Zero vsize segments won't be loaded in memory, even so they
   2489 	// have to be page aligned in the file.
   2490 	fakestart := Rnd(int64(Segdwarf.Fileoff), 0x1000)
   2491 	addr := Segdata.Vaddr + Segdata.Length
   2492 
   2493 	nsect := 4
   2494 	if pubnamessize > 0 {
   2495 		nsect++
   2496 	}
   2497 	if pubtypessize > 0 {
   2498 		nsect++
   2499 	}
   2500 	if arangessize > 0 {
   2501 		nsect++
   2502 	}
   2503 	if gdbscriptsize > 0 {
   2504 		nsect++
   2505 	}
   2506 
   2507 	if Linkmode != LinkExternal {
   2508 		ms = newMachoSeg("__DWARF", nsect)
   2509 		ms.fileoffset = uint64(fakestart)
   2510 		ms.filesize = Segdwarf.Filelen
   2511 		ms.vaddr = addr
   2512 	}
   2513 
   2514 	msect := newMachoSect(ms, "__debug_abbrev", "__DWARF")
   2515 	msect.off = uint32(abbrevo)
   2516 	msect.size = uint64(abbrevsize)
   2517 	msect.addr = addr
   2518 	addr += msect.size
   2519 	msect.flag = 0x02000000
   2520 	if abbrevsym != nil {
   2521 		abbrevsym.Value = int64(msect.addr)
   2522 	}
   2523 
   2524 	msect = newMachoSect(ms, "__debug_line", "__DWARF")
   2525 	msect.off = uint32(lineo)
   2526 	msect.size = uint64(linesize)
   2527 	msect.addr = addr
   2528 	addr += msect.size
   2529 	msect.flag = 0x02000000
   2530 	if linesym != nil {
   2531 		linesym.Value = int64(msect.addr)
   2532 	}
   2533 	if linerelocsize > 0 {
   2534 		msect.nreloc = uint32(len(linesec.R))
   2535 		msect.reloc = uint32(linereloco)
   2536 	}
   2537 
   2538 	msect = newMachoSect(ms, "__debug_frame", "__DWARF")
   2539 	msect.off = uint32(frameo)
   2540 	msect.size = uint64(framesize)
   2541 	msect.addr = addr
   2542 	addr += msect.size
   2543 	msect.flag = 0x02000000
   2544 	if framesym != nil {
   2545 		framesym.Value = int64(msect.addr)
   2546 	}
   2547 	if framerelocsize > 0 {
   2548 		msect.nreloc = uint32(len(framesec.R))
   2549 		msect.reloc = uint32(framereloco)
   2550 	}
   2551 
   2552 	msect = newMachoSect(ms, "__debug_info", "__DWARF")
   2553 	msect.off = uint32(infoo)
   2554 	msect.size = uint64(infosize)
   2555 	msect.addr = addr
   2556 	addr += msect.size
   2557 	msect.flag = 0x02000000
   2558 	if infosym != nil {
   2559 		infosym.Value = int64(msect.addr)
   2560 	}
   2561 	if inforelocsize > 0 {
   2562 		msect.nreloc = uint32(len(infosec.R))
   2563 		msect.reloc = uint32(inforeloco)
   2564 	}
   2565 
   2566 	if pubnamessize > 0 {
   2567 		msect := newMachoSect(ms, "__debug_pubnames", "__DWARF")
   2568 		msect.off = uint32(pubnameso)
   2569 		msect.size = uint64(pubnamessize)
   2570 		msect.addr = addr
   2571 		addr += msect.size
   2572 		msect.flag = 0x02000000
   2573 	}
   2574 
   2575 	if pubtypessize > 0 {
   2576 		msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF")
   2577 		msect.off = uint32(pubtypeso)
   2578 		msect.size = uint64(pubtypessize)
   2579 		msect.addr = addr
   2580 		addr += msect.size
   2581 		msect.flag = 0x02000000
   2582 	}
   2583 
   2584 	if arangessize > 0 {
   2585 		msect := newMachoSect(ms, "__debug_aranges", "__DWARF")
   2586 		msect.off = uint32(arangeso)
   2587 		msect.size = uint64(arangessize)
   2588 		msect.addr = addr
   2589 		addr += msect.size
   2590 		msect.flag = 0x02000000
   2591 		if arangesrelocsize > 0 {
   2592 			msect.nreloc = uint32(len(arangessec.R))
   2593 			msect.reloc = uint32(arangesreloco)
   2594 		}
   2595 	}
   2596 
   2597 	// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
   2598 	if gdbscriptsize > 0 {
   2599 		msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF")
   2600 		msect.off = uint32(gdbscripto)
   2601 		msect.size = uint64(gdbscriptsize)
   2602 		msect.addr = addr
   2603 		addr += msect.size
   2604 		msect.flag = 0x02000000
   2605 	}
   2606 }
   2607 
   2608 /*
   2609  * Windows PE
   2610  */
   2611 func dwarfaddpeheaders() {
   2612 	if Debug['w'] != 0 { // disable dwarf
   2613 		return
   2614 	}
   2615 
   2616 	newPEDWARFSection(".debug_abbrev", abbrevsize)
   2617 	newPEDWARFSection(".debug_line", linesize)
   2618 	newPEDWARFSection(".debug_frame", framesize)
   2619 	newPEDWARFSection(".debug_info", infosize)
   2620 	newPEDWARFSection(".debug_pubnames", pubnamessize)
   2621 	newPEDWARFSection(".debug_pubtypes", pubtypessize)
   2622 	newPEDWARFSection(".debug_aranges", arangessize)
   2623 	newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize)
   2624 }
   2625