github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/src/cmd/link/internal/ld/dwarf.go (about)

     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  	"log"
    21  	"os"
    22  	"strings"
    23  )
    24  
    25  const infoprefix = "go.dwarf.info."
    26  
    27  /*
    28   * Offsets and sizes of the debug_* sections in the cout file.
    29   */
    30  var abbrevsym *LSym
    31  var arangessec *LSym
    32  var framesec *LSym
    33  var infosec *LSym
    34  var linesec *LSym
    35  
    36  var gdbscript string
    37  
    38  /*
    39   *  Basic I/O
    40   */
    41  func addrput(s *LSym, addr int64) {
    42  	switch SysArch.PtrSize {
    43  	case 4:
    44  		Adduint32(Ctxt, s, uint32(addr))
    45  
    46  	case 8:
    47  		Adduint64(Ctxt, s, uint64(addr))
    48  	}
    49  }
    50  
    51  func appendUleb128(b []byte, v uint64) []byte {
    52  	for {
    53  		c := uint8(v & 0x7f)
    54  		v >>= 7
    55  		if v != 0 {
    56  			c |= 0x80
    57  		}
    58  		b = append(b, c)
    59  		if c&0x80 == 0 {
    60  			break
    61  		}
    62  	}
    63  	return b
    64  }
    65  
    66  func appendSleb128(b []byte, v int64) []byte {
    67  	for {
    68  		c := uint8(v & 0x7f)
    69  		s := uint8(v & 0x40)
    70  		v >>= 7
    71  		if (v != -1 || s == 0) && (v != 0 || s != 0) {
    72  			c |= 0x80
    73  		}
    74  		b = append(b, c)
    75  		if c&0x80 == 0 {
    76  			break
    77  		}
    78  	}
    79  	return b
    80  }
    81  
    82  var encbuf [10]byte
    83  
    84  func uleb128put(s *LSym, v int64) {
    85  	b := appendUleb128(encbuf[:0], uint64(v))
    86  	Addbytes(Ctxt, s, b)
    87  }
    88  
    89  func sleb128put(s *LSym, v int64) {
    90  	b := appendSleb128(encbuf[:0], v)
    91  	Addbytes(Ctxt, s, b)
    92  }
    93  
    94  /*
    95   * Defining Abbrevs.  This is hardcoded, and there will be
    96   * only a handful of them.  The DWARF spec places no restriction on
    97   * the ordering of attributes in the Abbrevs and DIEs, and we will
    98   * always write them out in the order of declaration in the abbrev.
    99   */
   100  type DWAttrForm struct {
   101  	attr uint16
   102  	form uint8
   103  }
   104  
   105  // Go-specific type attributes.
   106  const (
   107  	DW_AT_go_kind = 0x2900
   108  	DW_AT_go_key  = 0x2901
   109  	DW_AT_go_elem = 0x2902
   110  
   111  	DW_AT_internal_location = 253 // params and locals; not emitted
   112  )
   113  
   114  // Index into the abbrevs table below.
   115  // Keep in sync with ispubname() and ispubtype() below.
   116  // ispubtype considers >= NULLTYPE public
   117  const (
   118  	DW_ABRV_NULL = iota
   119  	DW_ABRV_COMPUNIT
   120  	DW_ABRV_FUNCTION
   121  	DW_ABRV_VARIABLE
   122  	DW_ABRV_AUTO
   123  	DW_ABRV_PARAM
   124  	DW_ABRV_STRUCTFIELD
   125  	DW_ABRV_FUNCTYPEPARAM
   126  	DW_ABRV_DOTDOTDOT
   127  	DW_ABRV_ARRAYRANGE
   128  	DW_ABRV_NULLTYPE
   129  	DW_ABRV_BASETYPE
   130  	DW_ABRV_ARRAYTYPE
   131  	DW_ABRV_CHANTYPE
   132  	DW_ABRV_FUNCTYPE
   133  	DW_ABRV_IFACETYPE
   134  	DW_ABRV_MAPTYPE
   135  	DW_ABRV_PTRTYPE
   136  	DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6.
   137  	DW_ABRV_SLICETYPE
   138  	DW_ABRV_STRINGTYPE
   139  	DW_ABRV_STRUCTTYPE
   140  	DW_ABRV_TYPEDECL
   141  	DW_NABRV
   142  )
   143  
   144  type DWAbbrev struct {
   145  	tag      uint8
   146  	children uint8
   147  	attr     []DWAttrForm
   148  }
   149  
   150  var abbrevs = [DW_NABRV]DWAbbrev{
   151  	/* The mandatory DW_ABRV_NULL entry. */
   152  	{0, 0, []DWAttrForm{}},
   153  
   154  	/* COMPUNIT */
   155  	{
   156  		DW_TAG_compile_unit,
   157  		DW_CHILDREN_yes,
   158  		[]DWAttrForm{
   159  			{DW_AT_name, DW_FORM_string},
   160  			{DW_AT_language, DW_FORM_data1},
   161  			{DW_AT_low_pc, DW_FORM_addr},
   162  			{DW_AT_high_pc, DW_FORM_addr},
   163  			{DW_AT_stmt_list, DW_FORM_data4},
   164  			{DW_AT_comp_dir, DW_FORM_string},
   165  		},
   166  	},
   167  
   168  	/* FUNCTION */
   169  	{
   170  		DW_TAG_subprogram,
   171  		DW_CHILDREN_yes,
   172  		[]DWAttrForm{
   173  			{DW_AT_name, DW_FORM_string},
   174  			{DW_AT_low_pc, DW_FORM_addr},
   175  			{DW_AT_high_pc, DW_FORM_addr},
   176  			{DW_AT_external, DW_FORM_flag},
   177  		},
   178  	},
   179  
   180  	/* VARIABLE */
   181  	{
   182  		DW_TAG_variable,
   183  		DW_CHILDREN_no,
   184  		[]DWAttrForm{
   185  			{DW_AT_name, DW_FORM_string},
   186  			{DW_AT_location, DW_FORM_block1},
   187  			{DW_AT_type, DW_FORM_ref_addr},
   188  			{DW_AT_external, DW_FORM_flag},
   189  		},
   190  	},
   191  
   192  	/* AUTO */
   193  	{
   194  		DW_TAG_variable,
   195  		DW_CHILDREN_no,
   196  		[]DWAttrForm{
   197  			{DW_AT_name, DW_FORM_string},
   198  			{DW_AT_location, DW_FORM_block1},
   199  			{DW_AT_type, DW_FORM_ref_addr},
   200  		},
   201  	},
   202  
   203  	/* PARAM */
   204  	{
   205  		DW_TAG_formal_parameter,
   206  		DW_CHILDREN_no,
   207  		[]DWAttrForm{
   208  			{DW_AT_name, DW_FORM_string},
   209  			{DW_AT_location, DW_FORM_block1},
   210  			{DW_AT_type, DW_FORM_ref_addr},
   211  		},
   212  	},
   213  
   214  	/* STRUCTFIELD */
   215  	{
   216  		DW_TAG_member,
   217  		DW_CHILDREN_no,
   218  		[]DWAttrForm{
   219  			{DW_AT_name, DW_FORM_string},
   220  			{DW_AT_data_member_location, DW_FORM_block1},
   221  			{DW_AT_type, DW_FORM_ref_addr},
   222  		},
   223  	},
   224  
   225  	/* FUNCTYPEPARAM */
   226  	{
   227  		DW_TAG_formal_parameter,
   228  		DW_CHILDREN_no,
   229  
   230  		// No name!
   231  		[]DWAttrForm{
   232  			{DW_AT_type, DW_FORM_ref_addr},
   233  		},
   234  	},
   235  
   236  	/* DOTDOTDOT */
   237  	{
   238  		DW_TAG_unspecified_parameters,
   239  		DW_CHILDREN_no,
   240  		[]DWAttrForm{},
   241  	},
   242  
   243  	/* ARRAYRANGE */
   244  	{
   245  		DW_TAG_subrange_type,
   246  		DW_CHILDREN_no,
   247  
   248  		// No name!
   249  		[]DWAttrForm{
   250  			{DW_AT_type, DW_FORM_ref_addr},
   251  			{DW_AT_count, DW_FORM_udata},
   252  		},
   253  	},
   254  
   255  	// Below here are the types considered public by ispubtype
   256  	/* NULLTYPE */
   257  	{
   258  		DW_TAG_unspecified_type,
   259  		DW_CHILDREN_no,
   260  		[]DWAttrForm{
   261  			{DW_AT_name, DW_FORM_string},
   262  		},
   263  	},
   264  
   265  	/* BASETYPE */
   266  	{
   267  		DW_TAG_base_type,
   268  		DW_CHILDREN_no,
   269  		[]DWAttrForm{
   270  			{DW_AT_name, DW_FORM_string},
   271  			{DW_AT_encoding, DW_FORM_data1},
   272  			{DW_AT_byte_size, DW_FORM_data1},
   273  			{DW_AT_go_kind, DW_FORM_data1},
   274  		},
   275  	},
   276  
   277  	/* ARRAYTYPE */
   278  	// child is subrange with upper bound
   279  	{
   280  		DW_TAG_array_type,
   281  		DW_CHILDREN_yes,
   282  		[]DWAttrForm{
   283  			{DW_AT_name, DW_FORM_string},
   284  			{DW_AT_type, DW_FORM_ref_addr},
   285  			{DW_AT_byte_size, DW_FORM_udata},
   286  			{DW_AT_go_kind, DW_FORM_data1},
   287  		},
   288  	},
   289  
   290  	/* CHANTYPE */
   291  	{
   292  		DW_TAG_typedef,
   293  		DW_CHILDREN_no,
   294  		[]DWAttrForm{
   295  			{DW_AT_name, DW_FORM_string},
   296  			{DW_AT_type, DW_FORM_ref_addr},
   297  			{DW_AT_go_kind, DW_FORM_data1},
   298  			{DW_AT_go_elem, DW_FORM_ref_addr},
   299  		},
   300  	},
   301  
   302  	/* FUNCTYPE */
   303  	{
   304  		DW_TAG_subroutine_type,
   305  		DW_CHILDREN_yes,
   306  		[]DWAttrForm{
   307  			{DW_AT_name, DW_FORM_string},
   308  			// {DW_AT_type,	DW_FORM_ref_addr},
   309  			{DW_AT_go_kind, DW_FORM_data1},
   310  		},
   311  	},
   312  
   313  	/* IFACETYPE */
   314  	{
   315  		DW_TAG_typedef,
   316  		DW_CHILDREN_yes,
   317  		[]DWAttrForm{
   318  			{DW_AT_name, DW_FORM_string},
   319  			{DW_AT_type, DW_FORM_ref_addr},
   320  			{DW_AT_go_kind, DW_FORM_data1},
   321  		},
   322  	},
   323  
   324  	/* MAPTYPE */
   325  	{
   326  		DW_TAG_typedef,
   327  		DW_CHILDREN_no,
   328  		[]DWAttrForm{
   329  			{DW_AT_name, DW_FORM_string},
   330  			{DW_AT_type, DW_FORM_ref_addr},
   331  			{DW_AT_go_kind, DW_FORM_data1},
   332  			{DW_AT_go_key, DW_FORM_ref_addr},
   333  			{DW_AT_go_elem, DW_FORM_ref_addr},
   334  		},
   335  	},
   336  
   337  	/* PTRTYPE */
   338  	{
   339  		DW_TAG_pointer_type,
   340  		DW_CHILDREN_no,
   341  		[]DWAttrForm{
   342  			{DW_AT_name, DW_FORM_string},
   343  			{DW_AT_type, DW_FORM_ref_addr},
   344  			{DW_AT_go_kind, DW_FORM_data1},
   345  		},
   346  	},
   347  
   348  	/* BARE_PTRTYPE */
   349  	{
   350  		DW_TAG_pointer_type,
   351  		DW_CHILDREN_no,
   352  		[]DWAttrForm{
   353  			{DW_AT_name, DW_FORM_string},
   354  		},
   355  	},
   356  
   357  	/* SLICETYPE */
   358  	{
   359  		DW_TAG_structure_type,
   360  		DW_CHILDREN_yes,
   361  		[]DWAttrForm{
   362  			{DW_AT_name, DW_FORM_string},
   363  			{DW_AT_byte_size, DW_FORM_udata},
   364  			{DW_AT_go_kind, DW_FORM_data1},
   365  			{DW_AT_go_elem, DW_FORM_ref_addr},
   366  		},
   367  	},
   368  
   369  	/* STRINGTYPE */
   370  	{
   371  		DW_TAG_structure_type,
   372  		DW_CHILDREN_yes,
   373  		[]DWAttrForm{
   374  			{DW_AT_name, DW_FORM_string},
   375  			{DW_AT_byte_size, DW_FORM_udata},
   376  			{DW_AT_go_kind, DW_FORM_data1},
   377  		},
   378  	},
   379  
   380  	/* STRUCTTYPE */
   381  	{
   382  		DW_TAG_structure_type,
   383  		DW_CHILDREN_yes,
   384  		[]DWAttrForm{
   385  			{DW_AT_name, DW_FORM_string},
   386  			{DW_AT_byte_size, DW_FORM_udata},
   387  			{DW_AT_go_kind, DW_FORM_data1},
   388  		},
   389  	},
   390  
   391  	/* TYPEDECL */
   392  	{
   393  		DW_TAG_typedef,
   394  		DW_CHILDREN_no,
   395  		[]DWAttrForm{
   396  			{DW_AT_name, DW_FORM_string},
   397  			{DW_AT_type, DW_FORM_ref_addr},
   398  		},
   399  	},
   400  }
   401  
   402  var dwarfp *LSym
   403  
   404  func writeabbrev() *LSym {
   405  	s := Linklookup(Ctxt, ".debug_abbrev", 0)
   406  	s.Type = obj.SDWARFSECT
   407  	abbrevsym = s
   408  
   409  	for i := 1; i < DW_NABRV; i++ {
   410  		// See section 7.5.3
   411  		uleb128put(s, int64(i))
   412  
   413  		uleb128put(s, int64(abbrevs[i].tag))
   414  		Adduint8(Ctxt, s, abbrevs[i].children)
   415  		for _, f := range abbrevs[i].attr {
   416  			uleb128put(s, int64(f.attr))
   417  			uleb128put(s, int64(f.form))
   418  		}
   419  		uleb128put(s, 0)
   420  		uleb128put(s, 0)
   421  	}
   422  
   423  	Adduint8(Ctxt, s, 0)
   424  	return s
   425  }
   426  
   427  /*
   428   * Debugging Information Entries and their attributes.
   429   */
   430  
   431  // For DW_CLS_string and _block, value should contain the length, and
   432  // data the data, for _reference, value is 0 and data is a DWDie* to
   433  // the referenced instance, for all others, value is the whole thing
   434  // and data is null.
   435  
   436  type DWAttr struct {
   437  	link  *DWAttr
   438  	atr   uint16 // DW_AT_
   439  	cls   uint8  // DW_CLS_
   440  	value int64
   441  	data  interface{}
   442  }
   443  
   444  type DWDie struct {
   445  	abbrev int
   446  	link   *DWDie
   447  	child  *DWDie
   448  	attr   *DWAttr
   449  	sym    *LSym
   450  }
   451  
   452  /*
   453   * Root DIEs for compilation units, types and global variables.
   454   */
   455  var dwroot DWDie
   456  
   457  var dwtypes DWDie
   458  
   459  var dwglobals DWDie
   460  
   461  func newattr(die *DWDie, attr uint16, cls int, value int64, data interface{}) *DWAttr {
   462  	a := new(DWAttr)
   463  	a.link = die.attr
   464  	die.attr = a
   465  	a.atr = attr
   466  	a.cls = uint8(cls)
   467  	a.value = value
   468  	a.data = data
   469  	return a
   470  }
   471  
   472  // Each DIE (except the root ones) has at least 1 attribute: its
   473  // name. getattr moves the desired one to the front so
   474  // frequently searched ones are found faster.
   475  func getattr(die *DWDie, attr uint16) *DWAttr {
   476  	if die.attr.atr == attr {
   477  		return die.attr
   478  	}
   479  
   480  	a := die.attr
   481  	b := a.link
   482  	for b != nil {
   483  		if b.atr == attr {
   484  			a.link = b.link
   485  			b.link = die.attr
   486  			die.attr = b
   487  			return b
   488  		}
   489  
   490  		a = b
   491  		b = b.link
   492  	}
   493  
   494  	return nil
   495  }
   496  
   497  // Every DIE has at least a DW_AT_name attribute (but it will only be
   498  // written out if it is listed in the abbrev).
   499  func newdie(parent *DWDie, abbrev int, name string, version int) *DWDie {
   500  	die := new(DWDie)
   501  	die.abbrev = abbrev
   502  	die.link = parent.child
   503  	parent.child = die
   504  
   505  	newattr(die, DW_AT_name, DW_CLS_STRING, int64(len(name)), name)
   506  
   507  	if name != "" && (abbrev <= DW_ABRV_VARIABLE || abbrev >= DW_ABRV_NULLTYPE) {
   508  		if abbrev != DW_ABRV_VARIABLE || version == 0 {
   509  			die.sym = Linklookup(Ctxt, infoprefix+name, version)
   510  			die.sym.Attr |= AttrHidden
   511  			die.sym.Type = obj.SDWARFINFO
   512  		}
   513  	}
   514  
   515  	return die
   516  }
   517  
   518  func walktypedef(die *DWDie) *DWDie {
   519  	// Resolve typedef if present.
   520  	if die.abbrev == DW_ABRV_TYPEDECL {
   521  		for attr := die.attr; attr != nil; attr = attr.link {
   522  			if attr.atr == DW_AT_type && attr.cls == DW_CLS_REFERENCE && attr.data != nil {
   523  				return attr.data.(*DWDie)
   524  			}
   525  		}
   526  	}
   527  
   528  	return die
   529  }
   530  
   531  func walksymtypedef(s *LSym) *LSym {
   532  	if t := Linkrlookup(Ctxt, s.Name+"..def", int(s.Version)); t != nil {
   533  		return t
   534  	}
   535  	return s
   536  }
   537  
   538  // Find child by AT_name using hashtable if available or linear scan
   539  // if not.
   540  func findchild(die *DWDie, name string) *DWDie {
   541  	var prev *DWDie
   542  	for ; die != prev; prev, die = die, walktypedef(die) {
   543  		for a := die.child; a != nil; a = a.link {
   544  			if name == getattr(a, DW_AT_name).data {
   545  				return a
   546  			}
   547  		}
   548  		continue
   549  	}
   550  	return nil
   551  }
   552  
   553  // Used to avoid string allocation when looking up dwarf symbols
   554  var prefixBuf = []byte(infoprefix)
   555  
   556  func find(name string) *LSym {
   557  	n := append(prefixBuf, name...)
   558  	// The string allocation below is optimized away because it is only used in a map lookup.
   559  	s := Linkrlookup(Ctxt, string(n), 0)
   560  	prefixBuf = n[:len(infoprefix)]
   561  	return s
   562  }
   563  
   564  func mustFind(name string) *LSym {
   565  	r := find(name)
   566  	if r == nil {
   567  		Exitf("dwarf find: cannot find %s", name)
   568  	}
   569  	return r
   570  }
   571  
   572  func adddwarfref(ctxt *Link, s *LSym, t *LSym, size int) int64 {
   573  	var result int64
   574  	switch size {
   575  	default:
   576  		Diag("invalid size %d in adddwarfref\n", size)
   577  		fallthrough
   578  	case SysArch.PtrSize:
   579  		result = Addaddr(ctxt, s, t)
   580  	case 4:
   581  		result = addaddrplus4(ctxt, s, t, 0)
   582  	}
   583  	r := &s.R[len(s.R)-1]
   584  	r.Type = obj.R_DWARFREF
   585  	return result
   586  }
   587  
   588  func newrefattr(die *DWDie, attr uint16, ref *LSym) *DWAttr {
   589  	if ref == nil {
   590  		return nil
   591  	}
   592  	return newattr(die, attr, DW_CLS_REFERENCE, 0, ref)
   593  }
   594  
   595  func putattr(s *LSym, abbrev int, form int, cls int, value int64, data interface{}) {
   596  	switch form {
   597  	case DW_FORM_addr: // address
   598  		if Linkmode == LinkExternal {
   599  			value -= (data.(*LSym)).Value
   600  			Addaddrplus(Ctxt, s, data.(*LSym), value)
   601  			break
   602  		}
   603  
   604  		addrput(s, value)
   605  
   606  	case DW_FORM_block1: // block
   607  		if cls == DW_CLS_ADDRESS {
   608  			Adduint8(Ctxt, s, uint8(1+SysArch.PtrSize))
   609  			Adduint8(Ctxt, s, DW_OP_addr)
   610  			Addaddr(Ctxt, s, data.(*LSym))
   611  			break
   612  		}
   613  
   614  		value &= 0xff
   615  		Adduint8(Ctxt, s, uint8(value))
   616  		p := data.([]byte)
   617  		for i := 0; int64(i) < value; i++ {
   618  			Adduint8(Ctxt, s, p[i])
   619  		}
   620  
   621  	case DW_FORM_block2: // block
   622  		value &= 0xffff
   623  
   624  		Adduint16(Ctxt, s, uint16(value))
   625  		p := data.([]byte)
   626  		for i := 0; int64(i) < value; i++ {
   627  			Adduint8(Ctxt, s, p[i])
   628  		}
   629  
   630  	case DW_FORM_block4: // block
   631  		value &= 0xffffffff
   632  
   633  		Adduint32(Ctxt, s, uint32(value))
   634  		p := data.([]byte)
   635  		for i := 0; int64(i) < value; i++ {
   636  			Adduint8(Ctxt, s, p[i])
   637  		}
   638  
   639  	case DW_FORM_block: // block
   640  		uleb128put(s, value)
   641  
   642  		p := data.([]byte)
   643  		for i := 0; int64(i) < value; i++ {
   644  			Adduint8(Ctxt, s, p[i])
   645  		}
   646  
   647  	case DW_FORM_data1: // constant
   648  		Adduint8(Ctxt, s, uint8(value))
   649  
   650  	case DW_FORM_data2: // constant
   651  		Adduint16(Ctxt, s, uint16(value))
   652  
   653  	case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr
   654  		if Linkmode == LinkExternal && cls == DW_CLS_PTR {
   655  			adddwarfref(Ctxt, s, linesec, 4)
   656  			break
   657  		}
   658  
   659  		Adduint32(Ctxt, s, uint32(value))
   660  
   661  	case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr
   662  		Adduint64(Ctxt, s, uint64(value))
   663  
   664  	case DW_FORM_sdata: // constant
   665  		sleb128put(s, value)
   666  
   667  	case DW_FORM_udata: // constant
   668  		uleb128put(s, value)
   669  
   670  	case DW_FORM_string: // string
   671  		str := data.(string)
   672  		Addstring(s, str)
   673  		for i := int64(len(str)); i < value; i++ {
   674  			Adduint8(Ctxt, s, 0)
   675  		}
   676  
   677  	case DW_FORM_flag: // flag
   678  		if value != 0 {
   679  			Adduint8(Ctxt, s, 1)
   680  		} else {
   681  			Adduint8(Ctxt, s, 0)
   682  		}
   683  
   684  		// In DWARF 2 (which is what we claim to generate),
   685  	// the ref_addr is the same size as a normal address.
   686  	// In DWARF 3 it is always 32 bits, unless emitting a large
   687  	// (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
   688  	case DW_FORM_ref_addr: // reference to a DIE in the .info section
   689  		if data == nil {
   690  			Diag("dwarf: null reference in %d", abbrev)
   691  			if SysArch.PtrSize == 8 {
   692  				Adduint64(Ctxt, s, 0) // invalid dwarf, gdb will complain.
   693  			} else {
   694  				Adduint32(Ctxt, s, 0) // invalid dwarf, gdb will complain.
   695  			}
   696  		} else {
   697  			dsym := data.(*LSym)
   698  			adddwarfref(Ctxt, s, dsym, SysArch.PtrSize)
   699  		}
   700  
   701  	case DW_FORM_ref1, // reference within the compilation unit
   702  		DW_FORM_ref2,      // reference
   703  		DW_FORM_ref4,      // reference
   704  		DW_FORM_ref8,      // reference
   705  		DW_FORM_ref_udata, // reference
   706  
   707  		DW_FORM_strp,     // string
   708  		DW_FORM_indirect: // (see Section 7.5.3)
   709  		fallthrough
   710  	default:
   711  		Exitf("dwarf: unsupported attribute form %d / class %d", form, cls)
   712  	}
   713  }
   714  
   715  // Note that we can (and do) add arbitrary attributes to a DIE, but
   716  // only the ones actually listed in the Abbrev will be written out.
   717  func putattrs(s *LSym, abbrev int, attr *DWAttr) {
   718  Outer:
   719  	for _, f := range abbrevs[abbrev].attr {
   720  		for ap := attr; ap != nil; ap = ap.link {
   721  			if ap.atr == f.attr {
   722  				putattr(s, abbrev, int(f.form), int(ap.cls), ap.value, ap.data)
   723  				continue Outer
   724  			}
   725  		}
   726  
   727  		putattr(s, abbrev, int(f.form), 0, 0, nil)
   728  	}
   729  }
   730  
   731  func putdies(prev *LSym, die *DWDie) *LSym {
   732  	for ; die != nil; die = die.link {
   733  		prev = putdie(prev, die)
   734  	}
   735  	Adduint8(Ctxt, prev, 0)
   736  	return prev
   737  }
   738  
   739  func putdie(prev *LSym, die *DWDie) *LSym {
   740  	s := die.sym
   741  	if s == nil {
   742  		s = prev
   743  	} else {
   744  		if s.Attr.OnList() {
   745  			log.Fatalf("symbol %s listed multiple times", s.Name)
   746  		}
   747  		s.Attr |= AttrOnList
   748  		prev.Next = s
   749  	}
   750  	uleb128put(s, int64(die.abbrev))
   751  	putattrs(s, die.abbrev, die.attr)
   752  	if abbrevs[die.abbrev].children != 0 {
   753  		return putdies(s, die.child)
   754  	}
   755  	return s
   756  }
   757  
   758  func reverselist(list **DWDie) {
   759  	curr := *list
   760  	var prev *DWDie
   761  	for curr != nil {
   762  		var next *DWDie = curr.link
   763  		curr.link = prev
   764  		prev = curr
   765  		curr = next
   766  	}
   767  
   768  	*list = prev
   769  }
   770  
   771  func reversetree(list **DWDie) {
   772  	reverselist(list)
   773  	for die := *list; die != nil; die = die.link {
   774  		if abbrevs[die.abbrev].children != 0 {
   775  			reversetree(&die.child)
   776  		}
   777  	}
   778  }
   779  
   780  func newmemberoffsetattr(die *DWDie, offs int32) {
   781  	var block [20]byte
   782  	b := append(block[:0], DW_OP_plus_uconst)
   783  	b = appendUleb128(b, uint64(offs))
   784  	newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, int64(len(b)), b)
   785  }
   786  
   787  // GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
   788  // location expression that evals to a const.
   789  func newabslocexprattr(die *DWDie, addr int64, sym *LSym) {
   790  	newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, sym)
   791  	// below
   792  }
   793  
   794  // Lookup predefined types
   795  func lookup_or_diag(n string) *LSym {
   796  	s := Linkrlookup(Ctxt, n, 0)
   797  	if s == nil || s.Size == 0 {
   798  		Exitf("dwarf: missing type: %s", n)
   799  	}
   800  
   801  	return s
   802  }
   803  
   804  func dotypedef(parent *DWDie, name string, def *DWDie) {
   805  	// Only emit typedefs for real names.
   806  	if strings.HasPrefix(name, "map[") {
   807  		return
   808  	}
   809  	if strings.HasPrefix(name, "struct {") {
   810  		return
   811  	}
   812  	if strings.HasPrefix(name, "chan ") {
   813  		return
   814  	}
   815  	if name[0] == '[' || name[0] == '*' {
   816  		return
   817  	}
   818  	if def == nil {
   819  		Diag("dwarf: bad def in dotypedef")
   820  	}
   821  
   822  	def.sym = Linklookup(Ctxt, def.sym.Name+"..def", 0)
   823  	def.sym.Attr |= AttrHidden
   824  	def.sym.Type = obj.SDWARFINFO
   825  
   826  	// The typedef entry must be created after the def,
   827  	// so that future lookups will find the typedef instead
   828  	// of the real definition. This hooks the typedef into any
   829  	// circular definition loops, so that gdb can understand them.
   830  	die := newdie(parent, DW_ABRV_TYPEDECL, name, 0)
   831  
   832  	newrefattr(die, DW_AT_type, def.sym)
   833  }
   834  
   835  // Define gotype, for composite ones recurse into constituents.
   836  func defgotype(gotype *LSym) *LSym {
   837  	if gotype == nil {
   838  		return mustFind("<unspecified>")
   839  	}
   840  
   841  	if !strings.HasPrefix(gotype.Name, "type.") {
   842  		Diag("dwarf: type name doesn't start with \"type.\": %s", gotype.Name)
   843  		return mustFind("<unspecified>")
   844  	}
   845  
   846  	name := gotype.Name[5:] // could also decode from Type.string
   847  
   848  	sdie := find(name)
   849  
   850  	if sdie != nil {
   851  		return sdie
   852  	}
   853  
   854  	return newtype(gotype).sym
   855  }
   856  
   857  func newtype(gotype *LSym) *DWDie {
   858  	name := gotype.Name[5:] // could also decode from Type.string
   859  	kind := decodetype_kind(gotype)
   860  	bytesize := decodetype_size(gotype)
   861  
   862  	var die *DWDie
   863  	switch kind {
   864  	case obj.KindBool:
   865  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0)
   866  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_boolean, 0)
   867  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   868  
   869  	case obj.KindInt,
   870  		obj.KindInt8,
   871  		obj.KindInt16,
   872  		obj.KindInt32,
   873  		obj.KindInt64:
   874  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0)
   875  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_signed, 0)
   876  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   877  
   878  	case obj.KindUint,
   879  		obj.KindUint8,
   880  		obj.KindUint16,
   881  		obj.KindUint32,
   882  		obj.KindUint64,
   883  		obj.KindUintptr:
   884  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0)
   885  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
   886  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   887  
   888  	case obj.KindFloat32,
   889  		obj.KindFloat64:
   890  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0)
   891  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_float, 0)
   892  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   893  
   894  	case obj.KindComplex64,
   895  		obj.KindComplex128:
   896  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name, 0)
   897  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_complex_float, 0)
   898  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   899  
   900  	case obj.KindArray:
   901  		die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name, 0)
   902  		dotypedef(&dwtypes, name, die)
   903  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   904  		s := decodetype_arrayelem(gotype)
   905  		newrefattr(die, DW_AT_type, defgotype(s))
   906  		fld := newdie(die, DW_ABRV_ARRAYRANGE, "range", 0)
   907  
   908  		// use actual length not upper bound; correct for 0-length arrays.
   909  		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0)
   910  
   911  		newrefattr(fld, DW_AT_type, mustFind("uintptr"))
   912  
   913  	case obj.KindChan:
   914  		die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name, 0)
   915  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   916  		s := decodetype_chanelem(gotype)
   917  		newrefattr(die, DW_AT_go_elem, defgotype(s))
   918  		// Save elem type for synthesizechantypes. We could synthesize here
   919  		// but that would change the order of DIEs we output.
   920  		newrefattr(die, DW_AT_type, s)
   921  
   922  	case obj.KindFunc:
   923  		die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name, 0)
   924  		dotypedef(&dwtypes, name, die)
   925  		newrefattr(die, DW_AT_type, mustFind("void"))
   926  		nfields := decodetype_funcincount(gotype)
   927  		var fld *DWDie
   928  		var s *LSym
   929  		for i := 0; i < nfields; i++ {
   930  			s = decodetype_funcintype(gotype, i)
   931  			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
   932  			newrefattr(fld, DW_AT_type, defgotype(s))
   933  		}
   934  
   935  		if decodetype_funcdotdotdot(gotype) {
   936  			newdie(die, DW_ABRV_DOTDOTDOT, "...", 0)
   937  		}
   938  		nfields = decodetype_funcoutcount(gotype)
   939  		for i := 0; i < nfields; i++ {
   940  			s = decodetype_funcouttype(gotype, i)
   941  			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
   942  			newrefattr(fld, DW_AT_type, defptrto(defgotype(s)))
   943  		}
   944  
   945  	case obj.KindInterface:
   946  		die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name, 0)
   947  		dotypedef(&dwtypes, name, die)
   948  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   949  		nfields := int(decodetype_ifacemethodcount(gotype))
   950  		var s *LSym
   951  		if nfields == 0 {
   952  			s = lookup_or_diag("type.runtime.eface")
   953  		} else {
   954  			s = lookup_or_diag("type.runtime.iface")
   955  		}
   956  		newrefattr(die, DW_AT_type, defgotype(s))
   957  
   958  	case obj.KindMap:
   959  		die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name, 0)
   960  		s := decodetype_mapkey(gotype)
   961  		newrefattr(die, DW_AT_go_key, defgotype(s))
   962  		s = decodetype_mapvalue(gotype)
   963  		newrefattr(die, DW_AT_go_elem, defgotype(s))
   964  		// Save gotype for use in synthesizemaptypes. We could synthesize here,
   965  		// but that would change the order of the DIEs.
   966  		newrefattr(die, DW_AT_type, gotype)
   967  
   968  	case obj.KindPtr:
   969  		die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name, 0)
   970  		dotypedef(&dwtypes, name, die)
   971  		s := decodetype_ptrelem(gotype)
   972  		newrefattr(die, DW_AT_type, defgotype(s))
   973  
   974  	case obj.KindSlice:
   975  		die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name, 0)
   976  		dotypedef(&dwtypes, name, die)
   977  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   978  		s := decodetype_arrayelem(gotype)
   979  		elem := defgotype(s)
   980  		newrefattr(die, DW_AT_go_elem, elem)
   981  
   982  	case obj.KindString:
   983  		die = newdie(&dwtypes, DW_ABRV_STRINGTYPE, name, 0)
   984  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   985  
   986  	case obj.KindStruct:
   987  		die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name, 0)
   988  		dotypedef(&dwtypes, name, die)
   989  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   990  		nfields := decodetype_structfieldcount(gotype)
   991  		var f string
   992  		var fld *DWDie
   993  		var s *LSym
   994  		for i := 0; i < nfields; i++ {
   995  			f = decodetype_structfieldname(gotype, i)
   996  			s = decodetype_structfieldtype(gotype, i)
   997  			if f == "" {
   998  				f = s.Name[5:] // skip "type."
   999  			}
  1000  			fld = newdie(die, DW_ABRV_STRUCTFIELD, f, 0)
  1001  			newrefattr(fld, DW_AT_type, defgotype(s))
  1002  			newmemberoffsetattr(fld, int32(decodetype_structfieldoffs(gotype, i)))
  1003  		}
  1004  
  1005  	case obj.KindUnsafePointer:
  1006  		die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name, 0)
  1007  
  1008  	default:
  1009  		Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name)
  1010  		die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name, 0)
  1011  		newrefattr(die, DW_AT_type, mustFind("<unspecified>"))
  1012  	}
  1013  
  1014  	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, int64(kind), 0)
  1015  
  1016  	if _, ok := prototypedies[gotype.Name]; ok {
  1017  		prototypedies[gotype.Name] = die
  1018  	}
  1019  
  1020  	return die
  1021  }
  1022  
  1023  func nameFromDIESym(dwtype *LSym) string {
  1024  	return strings.TrimSuffix(dwtype.Name[len(infoprefix):], "..def")
  1025  }
  1026  
  1027  // Find or construct *T given T.
  1028  func defptrto(dwtype *LSym) *LSym {
  1029  	ptrname := "*" + nameFromDIESym(dwtype)
  1030  	die := find(ptrname)
  1031  	if die == nil {
  1032  		pdie := newdie(&dwtypes, DW_ABRV_PTRTYPE, ptrname, 0)
  1033  		newrefattr(pdie, DW_AT_type, dwtype)
  1034  		return pdie.sym
  1035  	}
  1036  
  1037  	return die
  1038  }
  1039  
  1040  // Copies src's children into dst. Copies attributes by value.
  1041  // DWAttr.data is copied as pointer only. If except is one of
  1042  // the top-level children, it will not be copied.
  1043  func copychildrenexcept(dst *DWDie, src *DWDie, except *DWDie) {
  1044  	for src = src.child; src != nil; src = src.link {
  1045  		if src == except {
  1046  			continue
  1047  		}
  1048  		c := newdie(dst, src.abbrev, getattr(src, DW_AT_name).data.(string), 0)
  1049  		for a := src.attr; a != nil; a = a.link {
  1050  			newattr(c, a.atr, int(a.cls), a.value, a.data)
  1051  		}
  1052  		copychildrenexcept(c, src, nil)
  1053  	}
  1054  
  1055  	reverselist(&dst.child)
  1056  }
  1057  
  1058  func copychildren(dst *DWDie, src *DWDie) {
  1059  	copychildrenexcept(dst, src, nil)
  1060  }
  1061  
  1062  // Search children (assumed to have DW_TAG_member) for the one named
  1063  // field and set its DW_AT_type to dwtype
  1064  func substitutetype(structdie *DWDie, field string, dwtype *LSym) {
  1065  	child := findchild(structdie, field)
  1066  	if child == nil {
  1067  		Exitf("dwarf substitutetype: %s does not have member %s",
  1068  			getattr(structdie, DW_AT_name).data, field)
  1069  		return
  1070  	}
  1071  
  1072  	a := getattr(child, DW_AT_type)
  1073  	if a != nil {
  1074  		a.data = dwtype
  1075  	} else {
  1076  		newrefattr(child, DW_AT_type, dwtype)
  1077  	}
  1078  }
  1079  
  1080  func findprotodie(name string) *DWDie {
  1081  	die, ok := prototypedies[name]
  1082  	if ok && die == nil {
  1083  		defgotype(lookup_or_diag(name))
  1084  		die = prototypedies[name]
  1085  	}
  1086  	return die
  1087  }
  1088  
  1089  func synthesizestringtypes(die *DWDie) {
  1090  	prototype := walktypedef(findprotodie("type.runtime.stringStructDWARF"))
  1091  	if prototype == nil {
  1092  		return
  1093  	}
  1094  
  1095  	for ; die != nil; die = die.link {
  1096  		if die.abbrev != DW_ABRV_STRINGTYPE {
  1097  			continue
  1098  		}
  1099  		copychildren(die, prototype)
  1100  	}
  1101  }
  1102  
  1103  func synthesizeslicetypes(die *DWDie) {
  1104  	prototype := walktypedef(findprotodie("type.runtime.slice"))
  1105  	if prototype == nil {
  1106  		return
  1107  	}
  1108  
  1109  	for ; die != nil; die = die.link {
  1110  		if die.abbrev != DW_ABRV_SLICETYPE {
  1111  			continue
  1112  		}
  1113  		copychildren(die, prototype)
  1114  		elem := getattr(die, DW_AT_go_elem).data.(*LSym)
  1115  		substitutetype(die, "array", defptrto(elem))
  1116  	}
  1117  }
  1118  
  1119  func mkinternaltypename(base string, arg1 string, arg2 string) string {
  1120  	var buf string
  1121  
  1122  	if arg2 == "" {
  1123  		buf = fmt.Sprintf("%s<%s>", base, arg1)
  1124  	} else {
  1125  		buf = fmt.Sprintf("%s<%s,%s>", base, arg1, arg2)
  1126  	}
  1127  	n := buf
  1128  	return n
  1129  }
  1130  
  1131  // synthesizemaptypes is way too closely married to runtime/hashmap.c
  1132  const (
  1133  	MaxKeySize = 128
  1134  	MaxValSize = 128
  1135  	BucketSize = 8
  1136  )
  1137  
  1138  func mkinternaltype(abbrev int, typename, keyname, valname string, f func(*DWDie)) *LSym {
  1139  	name := mkinternaltypename(typename, keyname, valname)
  1140  	symname := infoprefix + name
  1141  	s := Linkrlookup(Ctxt, symname, 0)
  1142  	if s != nil {
  1143  		return s
  1144  	}
  1145  	die := newdie(&dwtypes, abbrev, name, 0)
  1146  	f(die)
  1147  	return die.sym
  1148  }
  1149  
  1150  func synthesizemaptypes(die *DWDie) {
  1151  	hash := walktypedef(findprotodie("type.runtime.hmap"))
  1152  	bucket := walktypedef(findprotodie("type.runtime.bmap"))
  1153  
  1154  	if hash == nil {
  1155  		return
  1156  	}
  1157  
  1158  	for ; die != nil; die = die.link {
  1159  		if die.abbrev != DW_ABRV_MAPTYPE {
  1160  			continue
  1161  		}
  1162  		gotype := getattr(die, DW_AT_type).data.(*LSym)
  1163  		keytype := decodetype_mapkey(gotype)
  1164  		valtype := decodetype_mapvalue(gotype)
  1165  		keysize, valsize := decodetype_size(keytype), decodetype_size(valtype)
  1166  		keytype, valtype = walksymtypedef(defgotype(keytype)), walksymtypedef(defgotype(valtype))
  1167  
  1168  		// compute size info like hashmap.c does.
  1169  		indirect_key, indirect_val := false, false
  1170  		if keysize > MaxKeySize {
  1171  			keysize = int64(SysArch.PtrSize)
  1172  			indirect_key = true
  1173  		}
  1174  		if valsize > MaxValSize {
  1175  			valsize = int64(SysArch.PtrSize)
  1176  			indirect_val = true
  1177  		}
  1178  
  1179  		// Construct type to represent an array of BucketSize keys
  1180  		keyname := nameFromDIESym(keytype)
  1181  		dwhks := mkinternaltype(DW_ABRV_ARRAYTYPE, "[]key", keyname, "", func(dwhk *DWDie) {
  1182  			newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*keysize, 0)
  1183  			t := keytype
  1184  			if indirect_key {
  1185  				t = defptrto(keytype)
  1186  			}
  1187  			newrefattr(dwhk, DW_AT_type, t)
  1188  			fld := newdie(dwhk, DW_ABRV_ARRAYRANGE, "size", 0)
  1189  			newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
  1190  			newrefattr(fld, DW_AT_type, mustFind("uintptr"))
  1191  		})
  1192  
  1193  		// Construct type to represent an array of BucketSize values
  1194  		valname := nameFromDIESym(valtype)
  1195  		dwhvs := mkinternaltype(DW_ABRV_ARRAYTYPE, "[]val", valname, "", func(dwhv *DWDie) {
  1196  			newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*valsize, 0)
  1197  			t := valtype
  1198  			if indirect_val {
  1199  				t = defptrto(valtype)
  1200  			}
  1201  			newrefattr(dwhv, DW_AT_type, t)
  1202  			fld := newdie(dwhv, DW_ABRV_ARRAYRANGE, "size", 0)
  1203  			newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
  1204  			newrefattr(fld, DW_AT_type, mustFind("uintptr"))
  1205  		})
  1206  
  1207  		// Construct bucket<K,V>
  1208  		dwhbs := mkinternaltype(DW_ABRV_STRUCTTYPE, "bucket", keyname, valname, func(dwhb *DWDie) {
  1209  			// Copy over all fields except the field "data" from the generic
  1210  			// bucket. "data" will be replaced with keys/values below.
  1211  			copychildrenexcept(dwhb, bucket, findchild(bucket, "data"))
  1212  
  1213  			fld := newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys", 0)
  1214  			newrefattr(fld, DW_AT_type, dwhks)
  1215  			newmemberoffsetattr(fld, BucketSize)
  1216  			fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values", 0)
  1217  			newrefattr(fld, DW_AT_type, dwhvs)
  1218  			newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize))
  1219  			fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow", 0)
  1220  			newrefattr(fld, DW_AT_type, defptrto(dwhb.sym))
  1221  			newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
  1222  			if SysArch.RegSize > SysArch.PtrSize {
  1223  				fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad", 0)
  1224  				newrefattr(fld, DW_AT_type, mustFind("uintptr"))
  1225  				newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(SysArch.PtrSize))
  1226  			}
  1227  
  1228  			newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize+BucketSize*keysize+BucketSize*valsize+int64(SysArch.RegSize), 0)
  1229  		})
  1230  
  1231  		// Construct hash<K,V>
  1232  		dwhs := mkinternaltype(DW_ABRV_STRUCTTYPE, "hash", keyname, valname, func(dwh *DWDie) {
  1233  			copychildren(dwh, hash)
  1234  			substitutetype(dwh, "buckets", defptrto(dwhbs))
  1235  			substitutetype(dwh, "oldbuckets", defptrto(dwhbs))
  1236  			newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hash, DW_AT_byte_size).value, nil)
  1237  		})
  1238  
  1239  		// make map type a pointer to hash<K,V>
  1240  		newrefattr(die, DW_AT_type, defptrto(dwhs))
  1241  	}
  1242  }
  1243  
  1244  func synthesizechantypes(die *DWDie) {
  1245  	sudog := walktypedef(findprotodie("type.runtime.sudog"))
  1246  	waitq := walktypedef(findprotodie("type.runtime.waitq"))
  1247  	hchan := walktypedef(findprotodie("type.runtime.hchan"))
  1248  	if sudog == nil || waitq == nil || hchan == nil {
  1249  		return
  1250  	}
  1251  
  1252  	sudogsize := int(getattr(sudog, DW_AT_byte_size).value)
  1253  
  1254  	for ; die != nil; die = die.link {
  1255  		if die.abbrev != DW_ABRV_CHANTYPE {
  1256  			continue
  1257  		}
  1258  		elemgotype := getattr(die, DW_AT_type).data.(*LSym)
  1259  		elemsize := decodetype_size(elemgotype)
  1260  		elemname := elemgotype.Name[5:]
  1261  		elemtype := walksymtypedef(defgotype(elemgotype))
  1262  
  1263  		// sudog<T>
  1264  		dwss := mkinternaltype(DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *DWDie) {
  1265  			copychildren(dws, sudog)
  1266  			substitutetype(dws, "elem", elemtype)
  1267  			if elemsize > 8 {
  1268  				elemsize -= 8
  1269  			} else {
  1270  				elemsize = 0
  1271  			}
  1272  			newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT, int64(sudogsize)+elemsize, nil)
  1273  		})
  1274  
  1275  		// waitq<T>
  1276  		dwws := mkinternaltype(DW_ABRV_STRUCTTYPE, "waitq", elemname, "", func(dww *DWDie) {
  1277  
  1278  			copychildren(dww, waitq)
  1279  			substitutetype(dww, "first", defptrto(dwss))
  1280  			substitutetype(dww, "last", defptrto(dwss))
  1281  			newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(waitq, DW_AT_byte_size).value, nil)
  1282  		})
  1283  
  1284  		// hchan<T>
  1285  		dwhs := mkinternaltype(DW_ABRV_STRUCTTYPE, "hchan", elemname, "", func(dwh *DWDie) {
  1286  			copychildren(dwh, hchan)
  1287  			substitutetype(dwh, "recvq", dwws)
  1288  			substitutetype(dwh, "sendq", dwws)
  1289  			newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hchan, DW_AT_byte_size).value, nil)
  1290  		})
  1291  
  1292  		newrefattr(die, DW_AT_type, defptrto(dwhs))
  1293  	}
  1294  }
  1295  
  1296  // For use with pass.c::genasmsym
  1297  func defdwsymb(sym *LSym, s string, t int, v int64, size int64, ver int, gotype *LSym) {
  1298  	if strings.HasPrefix(s, "go.string.") {
  1299  		return
  1300  	}
  1301  	if strings.HasPrefix(s, "runtime.gcbits.") {
  1302  		return
  1303  	}
  1304  
  1305  	if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
  1306  		defgotype(sym)
  1307  		return
  1308  	}
  1309  
  1310  	var dv *DWDie
  1311  
  1312  	var dt *LSym
  1313  	switch t {
  1314  	default:
  1315  		return
  1316  
  1317  	case 'd', 'b', 'D', 'B':
  1318  		dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s, ver)
  1319  		newabslocexprattr(dv, v, sym)
  1320  		if ver == 0 {
  1321  			newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0)
  1322  		}
  1323  		fallthrough
  1324  
  1325  	case 'a', 'p':
  1326  		dt = defgotype(gotype)
  1327  	}
  1328  
  1329  	if dv != nil {
  1330  		newrefattr(dv, DW_AT_type, dt)
  1331  	}
  1332  }
  1333  
  1334  func movetomodule(parent *DWDie) {
  1335  	die := dwroot.child.child
  1336  	for die.link != nil {
  1337  		die = die.link
  1338  	}
  1339  	die.link = parent.child
  1340  }
  1341  
  1342  // If the pcln table contains runtime/runtime.go, use that to set gdbscript path.
  1343  func finddebugruntimepath(s *LSym) {
  1344  	if gdbscript != "" {
  1345  		return
  1346  	}
  1347  
  1348  	for i := range s.FuncInfo.File {
  1349  		f := s.FuncInfo.File[i]
  1350  		if i := strings.Index(f.Name, "runtime/runtime.go"); i >= 0 {
  1351  			gdbscript = f.Name[:i] + "runtime/runtime-gdb.py"
  1352  			break
  1353  		}
  1354  	}
  1355  }
  1356  
  1357  /*
  1358   * Generate short opcodes when possible, long ones when necessary.
  1359   * See section 6.2.5
  1360   */
  1361  const (
  1362  	LINE_BASE   = -1
  1363  	LINE_RANGE  = 4
  1364  	OPCODE_BASE = 10
  1365  )
  1366  
  1367  func putpclcdelta(s *LSym, delta_pc int64, delta_lc int64) {
  1368  	if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE {
  1369  		var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc)
  1370  		if OPCODE_BASE <= opcode && opcode < 256 {
  1371  			Adduint8(Ctxt, s, uint8(opcode))
  1372  			return
  1373  		}
  1374  	}
  1375  
  1376  	if delta_pc != 0 {
  1377  		Adduint8(Ctxt, s, DW_LNS_advance_pc)
  1378  		sleb128put(s, delta_pc)
  1379  	}
  1380  
  1381  	Adduint8(Ctxt, s, DW_LNS_advance_line)
  1382  	sleb128put(s, delta_lc)
  1383  	Adduint8(Ctxt, s, DW_LNS_copy)
  1384  }
  1385  
  1386  func newcfaoffsetattr(die *DWDie, offs int32) {
  1387  	var block [20]byte
  1388  	b := append(block[:0], DW_OP_call_frame_cfa)
  1389  
  1390  	if offs != 0 {
  1391  		b = append(b, DW_OP_consts)
  1392  		b = appendSleb128(b, int64(offs))
  1393  		b = append(b, DW_OP_plus)
  1394  	}
  1395  
  1396  	newattr(die, DW_AT_location, DW_CLS_BLOCK, int64(len(b)), b)
  1397  }
  1398  
  1399  func mkvarname(name string, da int) string {
  1400  	buf := fmt.Sprintf("%s#%d", name, da)
  1401  	n := buf
  1402  	return n
  1403  }
  1404  
  1405  /*
  1406   * Walk prog table, emit line program and build DIE tree.
  1407   */
  1408  
  1409  func getCompilationDir() string {
  1410  	if dir, err := os.Getwd(); err == nil {
  1411  		return dir
  1412  	}
  1413  	return "/"
  1414  }
  1415  
  1416  func writelines(prev *LSym) *LSym {
  1417  	if linesec == nil {
  1418  		linesec = Linklookup(Ctxt, ".debug_line", 0)
  1419  	}
  1420  	linesec.Type = obj.SDWARFSECT
  1421  	linesec.R = linesec.R[:0]
  1422  
  1423  	ls := linesec
  1424  	prev.Next = ls
  1425  
  1426  	unitstart := int64(-1)
  1427  	headerstart := int64(-1)
  1428  	headerend := int64(-1)
  1429  	epc := int64(0)
  1430  	var epcs *LSym
  1431  	var dwinfo *DWDie
  1432  
  1433  	lang := DW_LANG_Go
  1434  
  1435  	s := Ctxt.Textp[0]
  1436  
  1437  	dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, "go", 0)
  1438  	newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(lang), 0)
  1439  	newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, 0, 0)
  1440  	newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
  1441  	// OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
  1442  	compDir := getCompilationDir()
  1443  	newattr(dwinfo, DW_AT_comp_dir, DW_CLS_STRING, int64(len(compDir)), compDir)
  1444  
  1445  	// Write .debug_line Line Number Program Header (sec 6.2.4)
  1446  	// Fields marked with (*) must be changed for 64-bit dwarf
  1447  	unit_length_offset := ls.Size
  1448  	Adduint32(Ctxt, ls, 0) // unit_length (*), filled in at end.
  1449  	unitstart = ls.Size
  1450  	Adduint16(Ctxt, ls, 2) // dwarf version (appendix F)
  1451  	header_length_offset := ls.Size
  1452  	Adduint32(Ctxt, ls, 0) // header_length (*), filled in at end.
  1453  	headerstart = ls.Size
  1454  
  1455  	// cpos == unitstart + 4 + 2 + 4
  1456  	Adduint8(Ctxt, ls, 1)              // minimum_instruction_length
  1457  	Adduint8(Ctxt, ls, 1)              // default_is_stmt
  1458  	Adduint8(Ctxt, ls, LINE_BASE&0xFF) // line_base
  1459  	Adduint8(Ctxt, ls, LINE_RANGE)     // line_range
  1460  	Adduint8(Ctxt, ls, OPCODE_BASE)    // opcode_base
  1461  	Adduint8(Ctxt, ls, 0)              // standard_opcode_lengths[1]
  1462  	Adduint8(Ctxt, ls, 1)              // standard_opcode_lengths[2]
  1463  	Adduint8(Ctxt, ls, 1)              // standard_opcode_lengths[3]
  1464  	Adduint8(Ctxt, ls, 1)              // standard_opcode_lengths[4]
  1465  	Adduint8(Ctxt, ls, 1)              // standard_opcode_lengths[5]
  1466  	Adduint8(Ctxt, ls, 0)              // standard_opcode_lengths[6]
  1467  	Adduint8(Ctxt, ls, 0)              // standard_opcode_lengths[7]
  1468  	Adduint8(Ctxt, ls, 0)              // standard_opcode_lengths[8]
  1469  	Adduint8(Ctxt, ls, 1)              // standard_opcode_lengths[9]
  1470  	Adduint8(Ctxt, ls, 0)              // include_directories  (empty)
  1471  
  1472  	for _, f := range Ctxt.Filesyms {
  1473  		Addstring(ls, f.Name)
  1474  		Adduint8(Ctxt, ls, 0)
  1475  		Adduint8(Ctxt, ls, 0)
  1476  		Adduint8(Ctxt, ls, 0)
  1477  	}
  1478  
  1479  	// 4 zeros: the string termination + 3 fields.
  1480  	Adduint8(Ctxt, ls, 0)
  1481  	// terminate file_names.
  1482  	headerend = ls.Size
  1483  
  1484  	Adduint8(Ctxt, ls, 0) // start extended opcode
  1485  	uleb128put(ls, 1+int64(SysArch.PtrSize))
  1486  	Adduint8(Ctxt, ls, DW_LNE_set_address)
  1487  
  1488  	pc := s.Value
  1489  	line := 1
  1490  	file := 1
  1491  	if Linkmode == LinkExternal {
  1492  		Addaddr(Ctxt, ls, s)
  1493  	} else {
  1494  		addrput(ls, pc)
  1495  	}
  1496  
  1497  	var pcfile Pciter
  1498  	var pcline Pciter
  1499  	for _, Ctxt.Cursym = range Ctxt.Textp {
  1500  		s := Ctxt.Cursym
  1501  
  1502  		dwfunc := newdie(dwinfo, DW_ABRV_FUNCTION, s.Name, int(s.Version))
  1503  		newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
  1504  		epc = s.Value + s.Size
  1505  		epcs = s
  1506  		newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, s)
  1507  		if s.Version == 0 {
  1508  			newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0)
  1509  		}
  1510  
  1511  		if s.FuncInfo == nil {
  1512  			continue
  1513  		}
  1514  
  1515  		finddebugruntimepath(s)
  1516  
  1517  		pciterinit(Ctxt, &pcfile, &s.FuncInfo.Pcfile)
  1518  		pciterinit(Ctxt, &pcline, &s.FuncInfo.Pcline)
  1519  		epc = pc
  1520  		for pcfile.done == 0 && pcline.done == 0 {
  1521  			if epc-s.Value >= int64(pcfile.nextpc) {
  1522  				pciternext(&pcfile)
  1523  				continue
  1524  			}
  1525  
  1526  			if epc-s.Value >= int64(pcline.nextpc) {
  1527  				pciternext(&pcline)
  1528  				continue
  1529  			}
  1530  
  1531  			if int32(file) != pcfile.value {
  1532  				Adduint8(Ctxt, ls, DW_LNS_set_file)
  1533  				uleb128put(ls, int64(pcfile.value))
  1534  				file = int(pcfile.value)
  1535  			}
  1536  
  1537  			putpclcdelta(ls, s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line))
  1538  
  1539  			pc = s.Value + int64(pcline.pc)
  1540  			line = int(pcline.value)
  1541  			if pcfile.nextpc < pcline.nextpc {
  1542  				epc = int64(pcfile.nextpc)
  1543  			} else {
  1544  				epc = int64(pcline.nextpc)
  1545  			}
  1546  			epc += s.Value
  1547  		}
  1548  
  1549  		var (
  1550  			dt, da int
  1551  			offs   int64
  1552  		)
  1553  		for _, a := range s.FuncInfo.Autom {
  1554  			switch a.Name {
  1555  			case obj.A_AUTO:
  1556  				dt = DW_ABRV_AUTO
  1557  				offs = int64(a.Aoffset)
  1558  				if !haslinkregister() {
  1559  					offs -= int64(SysArch.PtrSize)
  1560  				}
  1561  				if obj.Framepointer_enabled(obj.Getgoos(), obj.Getgoarch()) {
  1562  					// The frame pointer is saved
  1563  					// between the CFA and the
  1564  					// autos.
  1565  					offs -= int64(SysArch.PtrSize)
  1566  				}
  1567  
  1568  			case obj.A_PARAM:
  1569  				dt = DW_ABRV_PARAM
  1570  				offs = int64(a.Aoffset) + Ctxt.FixedFrameSize()
  1571  
  1572  			default:
  1573  				continue
  1574  			}
  1575  
  1576  			if strings.Contains(a.Asym.Name, ".autotmp_") {
  1577  				continue
  1578  			}
  1579  			var n string
  1580  			if findchild(dwfunc, a.Asym.Name) != nil {
  1581  				n = mkvarname(a.Asym.Name, da)
  1582  			} else {
  1583  				n = a.Asym.Name
  1584  			}
  1585  
  1586  			// Drop the package prefix from locals and arguments.
  1587  			if i := strings.LastIndex(n, "."); i >= 0 {
  1588  				n = n[i+1:]
  1589  			}
  1590  
  1591  			dwvar := newdie(dwfunc, dt, n, 0)
  1592  			newcfaoffsetattr(dwvar, int32(offs))
  1593  			newrefattr(dwvar, DW_AT_type, defgotype(a.Gotype))
  1594  
  1595  			// push dwvar down dwfunc->child to preserve order
  1596  			newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil)
  1597  
  1598  			dwfunc.child = dwvar.link // take dwvar out from the top of the list
  1599  			dws := &dwfunc.child
  1600  			for ; *dws != nil; dws = &(*dws).link {
  1601  				if offs > getattr(*dws, DW_AT_internal_location).value {
  1602  					break
  1603  				}
  1604  			}
  1605  			dwvar.link = *dws
  1606  			*dws = dwvar
  1607  
  1608  			da++
  1609  		}
  1610  	}
  1611  
  1612  	Adduint8(Ctxt, ls, 0) // start extended opcode
  1613  	uleb128put(ls, 1)
  1614  	Adduint8(Ctxt, ls, DW_LNE_end_sequence)
  1615  
  1616  	newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, epc+1, epcs)
  1617  
  1618  	setuint32(Ctxt, ls, unit_length_offset, uint32(ls.Size-unitstart))
  1619  	setuint32(Ctxt, ls, header_length_offset, uint32(headerend-headerstart))
  1620  
  1621  	return ls
  1622  }
  1623  
  1624  /*
  1625   *  Emit .debug_frame
  1626   */
  1627  const (
  1628  	dataAlignmentFactor = -4
  1629  )
  1630  
  1631  // appendPCDeltaCFA appends per-PC CFA deltas to b and returns the final slice.
  1632  func appendPCDeltaCFA(b []byte, deltapc, cfa int64) []byte {
  1633  	b = append(b, DW_CFA_def_cfa_offset_sf)
  1634  	b = appendSleb128(b, cfa/dataAlignmentFactor)
  1635  
  1636  	switch {
  1637  	case deltapc < 0x40:
  1638  		b = append(b, uint8(DW_CFA_advance_loc+deltapc))
  1639  	case deltapc < 0x100:
  1640  		b = append(b, DW_CFA_advance_loc1)
  1641  		b = append(b, uint8(deltapc))
  1642  	case deltapc < 0x10000:
  1643  		b = append(b, DW_CFA_advance_loc2)
  1644  		b = Thearch.Append16(b, uint16(deltapc))
  1645  	default:
  1646  		b = append(b, DW_CFA_advance_loc4)
  1647  		b = Thearch.Append32(b, uint32(deltapc))
  1648  	}
  1649  	return b
  1650  }
  1651  
  1652  func writeframes(prev *LSym) *LSym {
  1653  	if framesec == nil {
  1654  		framesec = Linklookup(Ctxt, ".debug_frame", 0)
  1655  	}
  1656  	framesec.Type = obj.SDWARFSECT
  1657  	framesec.R = framesec.R[:0]
  1658  	fs := framesec
  1659  	prev.Next = fs
  1660  
  1661  	// Emit the CIE, Section 6.4.1
  1662  	cieReserve := uint32(16)
  1663  	if haslinkregister() {
  1664  		cieReserve = 32
  1665  	}
  1666  	Adduint32(Ctxt, fs, cieReserve)           // initial length, must be multiple of pointer size
  1667  	Adduint32(Ctxt, fs, 0xffffffff)           // cid.
  1668  	Adduint8(Ctxt, fs, 3)                     // dwarf version (appendix F)
  1669  	Adduint8(Ctxt, fs, 0)                     // augmentation ""
  1670  	uleb128put(fs, 1)                         // code_alignment_factor
  1671  	sleb128put(fs, dataAlignmentFactor)       // all CFI offset calculations include multiplication with this factor
  1672  	uleb128put(fs, int64(Thearch.Dwarfreglr)) // return_address_register
  1673  
  1674  	Adduint8(Ctxt, fs, DW_CFA_def_cfa)        // Set the current frame address..
  1675  	uleb128put(fs, int64(Thearch.Dwarfregsp)) // ...to use the value in the platform's SP register (defined in l.go)...
  1676  	if haslinkregister() {
  1677  		uleb128put(fs, int64(0)) // ...plus a 0 offset.
  1678  
  1679  		Adduint8(Ctxt, fs, DW_CFA_same_value) // The platform's link register is unchanged during the prologue.
  1680  		uleb128put(fs, int64(Thearch.Dwarfreglr))
  1681  
  1682  		Adduint8(Ctxt, fs, DW_CFA_val_offset)     // The previous value...
  1683  		uleb128put(fs, int64(Thearch.Dwarfregsp)) // ...of the platform's SP register...
  1684  		uleb128put(fs, int64(0))                  // ...is CFA+0.
  1685  	} else {
  1686  		uleb128put(fs, int64(SysArch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame).
  1687  
  1688  		Adduint8(Ctxt, fs, DW_CFA_offset_extended)                  // The previous value...
  1689  		uleb128put(fs, int64(Thearch.Dwarfreglr))                   // ...of the return address...
  1690  		uleb128put(fs, int64(-SysArch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)].
  1691  	}
  1692  
  1693  	// 4 is to exclude the length field.
  1694  	pad := int64(cieReserve) + 4 - fs.Size
  1695  
  1696  	if pad < 0 {
  1697  		Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
  1698  	}
  1699  
  1700  	Addbytes(Ctxt, fs, zeros[:pad])
  1701  
  1702  	var deltaBuf []byte
  1703  	var pcsp Pciter
  1704  	for _, Ctxt.Cursym = range Ctxt.Textp {
  1705  		s := Ctxt.Cursym
  1706  		if s.FuncInfo == nil {
  1707  			continue
  1708  		}
  1709  
  1710  		// Emit a FDE, Section 6.4.1.
  1711  		// First build the section contents into a byte buffer.
  1712  		deltaBuf = deltaBuf[:0]
  1713  		for pciterinit(Ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
  1714  			nextpc := pcsp.nextpc
  1715  
  1716  			// pciterinit goes up to the end of the function,
  1717  			// but DWARF expects us to stop just before the end.
  1718  			if int64(nextpc) == s.Size {
  1719  				nextpc--
  1720  				if nextpc < pcsp.pc {
  1721  					continue
  1722  				}
  1723  			}
  1724  
  1725  			if haslinkregister() {
  1726  				// TODO(bryanpkc): This is imprecise. In general, the instruction
  1727  				// that stores the return address to the stack frame is not the
  1728  				// same one that allocates the frame.
  1729  				if pcsp.value > 0 {
  1730  					// The return address is preserved at (CFA-frame_size)
  1731  					// after a stack frame has been allocated.
  1732  					deltaBuf = append(deltaBuf, DW_CFA_offset_extended_sf)
  1733  					deltaBuf = appendUleb128(deltaBuf, uint64(Thearch.Dwarfreglr))
  1734  					deltaBuf = appendSleb128(deltaBuf, -int64(pcsp.value)/dataAlignmentFactor)
  1735  				} else {
  1736  					// The return address is restored into the link register
  1737  					// when a stack frame has been de-allocated.
  1738  					deltaBuf = append(deltaBuf, DW_CFA_same_value)
  1739  					deltaBuf = appendUleb128(deltaBuf, uint64(Thearch.Dwarfreglr))
  1740  				}
  1741  				deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
  1742  			} else {
  1743  				deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(SysArch.PtrSize)+int64(pcsp.value))
  1744  			}
  1745  		}
  1746  		pad := int(Rnd(int64(len(deltaBuf)), int64(SysArch.PtrSize))) - len(deltaBuf)
  1747  		deltaBuf = append(deltaBuf, zeros[:pad]...)
  1748  
  1749  		// Emit the FDE header, Section 6.4.1.
  1750  		//	4 bytes: length, must be multiple of thearch.ptrsize
  1751  		//	4 bytes: Pointer to the CIE above, at offset 0
  1752  		//	ptrsize: initial location
  1753  		//	ptrsize: address range
  1754  		Adduint32(Ctxt, fs, uint32(4+2*SysArch.PtrSize+len(deltaBuf))) // length (excludes itself)
  1755  		if Linkmode == LinkExternal {
  1756  			adddwarfref(Ctxt, fs, framesec, 4)
  1757  		} else {
  1758  			Adduint32(Ctxt, fs, 0) // CIE offset
  1759  		}
  1760  		Addaddr(Ctxt, fs, s)
  1761  		addrput(fs, s.Size) // address range
  1762  		Addbytes(Ctxt, fs, deltaBuf)
  1763  	}
  1764  	return fs
  1765  }
  1766  
  1767  /*
  1768   *  Walk DWarfDebugInfoEntries, and emit .debug_info
  1769   */
  1770  const (
  1771  	COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
  1772  )
  1773  
  1774  func writeinfo(prev *LSym) *LSym {
  1775  	if infosec == nil {
  1776  		infosec = Linklookup(Ctxt, ".debug_info", 0)
  1777  	}
  1778  	infosec.R = infosec.R[:0]
  1779  	infosec.Type = obj.SDWARFINFO
  1780  	infosec.Attr |= AttrReachable
  1781  	prev.Next, prev = infosec, infosec
  1782  
  1783  	if arangessec == nil {
  1784  		arangessec = Linklookup(Ctxt, ".dwarfaranges", 0)
  1785  	}
  1786  	arangessec.R = arangessec.R[:0]
  1787  
  1788  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1789  		s := compunit.sym
  1790  		prev.Next, prev = s, s
  1791  
  1792  		// Write .debug_info Compilation Unit Header (sec 7.5.1)
  1793  		// Fields marked with (*) must be changed for 64-bit dwarf
  1794  		// This must match COMPUNITHEADERSIZE above.
  1795  		Adduint32(Ctxt, s, 0) // unit_length (*), will be filled in later.
  1796  		Adduint16(Ctxt, s, 2) // dwarf version (appendix F)
  1797  
  1798  		// debug_abbrev_offset (*)
  1799  		adddwarfref(Ctxt, s, abbrevsym, 4)
  1800  
  1801  		Adduint8(Ctxt, s, uint8(SysArch.PtrSize)) // address_size
  1802  
  1803  		prev = putdie(prev, compunit)
  1804  		cusize := s.Size - 4 // exclude the length field.
  1805  		for child := s.Next; child != nil; child = child.Next {
  1806  			cusize += child.Size
  1807  		}
  1808  
  1809  		setuint32(Ctxt, s, 0, uint32(cusize))
  1810  		newattr(compunit, DW_AT_byte_size, DW_CLS_CONSTANT, cusize, 0)
  1811  	}
  1812  	return prev
  1813  }
  1814  
  1815  /*
  1816   *  Emit .debug_pubnames/_types.  _info must have been written before,
  1817   *  because we need die->offs and infoo/infosize;
  1818   */
  1819  func ispubname(die *DWDie) bool {
  1820  	switch die.abbrev {
  1821  	case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE:
  1822  		a := getattr(die, DW_AT_external)
  1823  		return a != nil && a.value != 0
  1824  	}
  1825  
  1826  	return false
  1827  }
  1828  
  1829  func ispubtype(die *DWDie) bool {
  1830  	return die.abbrev >= DW_ABRV_NULLTYPE
  1831  }
  1832  
  1833  func writepub(sname string, ispub func(*DWDie) bool, prev *LSym) *LSym {
  1834  	s := Linklookup(Ctxt, sname, 0)
  1835  	s.Type = obj.SDWARFSECT
  1836  	prev.Next = s
  1837  
  1838  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1839  		sectionstart := s.Size
  1840  		culength := uint32(getattr(compunit, DW_AT_byte_size).value) + 4
  1841  
  1842  		// Write .debug_pubnames/types	Header (sec 6.1.1)
  1843  		Adduint32(Ctxt, s, 0)                 // unit_length (*), will be filled in later.
  1844  		Adduint16(Ctxt, s, 2)                 // dwarf version (appendix F)
  1845  		adddwarfref(Ctxt, s, compunit.sym, 4) // debug_info_offset (of the Comp unit Header)
  1846  		Adduint32(Ctxt, s, culength)          // debug_info_length
  1847  
  1848  		for die := compunit.child; die != nil; die = die.link {
  1849  			if !ispub(die) {
  1850  				continue
  1851  			}
  1852  			dwa := getattr(die, DW_AT_name)
  1853  			name := dwa.data.(string)
  1854  			if die.sym == nil {
  1855  				fmt.Println("Missing sym for ", name)
  1856  			}
  1857  			adddwarfref(Ctxt, s, die.sym, 4)
  1858  			Addstring(s, name)
  1859  		}
  1860  
  1861  		Adduint32(Ctxt, s, 0)
  1862  
  1863  		setuint32(Ctxt, s, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
  1864  	}
  1865  
  1866  	return s
  1867  }
  1868  
  1869  /*
  1870   *  emit .debug_aranges.  _info must have been written before,
  1871   *  because we need die->offs of dw_globals.
  1872   */
  1873  func writearanges(prev *LSym) *LSym {
  1874  	s := Linklookup(Ctxt, ".debug_aranges", 0)
  1875  	s.Type = obj.SDWARFSECT
  1876  	// The first tuple is aligned to a multiple of the size of a single tuple
  1877  	// (twice the size of an address)
  1878  	headersize := int(Rnd(4+2+4+1+1, int64(SysArch.PtrSize*2))) // don't count unit_length field itself
  1879  
  1880  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1881  		b := getattr(compunit, DW_AT_low_pc)
  1882  		if b == nil {
  1883  			continue
  1884  		}
  1885  		e := getattr(compunit, DW_AT_high_pc)
  1886  		if e == nil {
  1887  			continue
  1888  		}
  1889  
  1890  		// Write .debug_aranges	 Header + entry	 (sec 6.1.2)
  1891  		unitlength := uint32(headersize) + 4*uint32(SysArch.PtrSize) - 4
  1892  		Adduint32(Ctxt, s, unitlength) // unit_length (*)
  1893  		Adduint16(Ctxt, s, 2)          // dwarf version (appendix F)
  1894  
  1895  		adddwarfref(Ctxt, s, compunit.sym, 4)
  1896  
  1897  		Adduint8(Ctxt, s, uint8(SysArch.PtrSize)) // address_size
  1898  		Adduint8(Ctxt, s, 0)                      // segment_size
  1899  		padding := headersize - (4 + 2 + 4 + 1 + 1)
  1900  		for i := 0; i < padding; i++ {
  1901  			Adduint8(Ctxt, s, 0)
  1902  		}
  1903  
  1904  		Addaddrplus(Ctxt, s, b.data.(*LSym), b.value-(b.data.(*LSym)).Value)
  1905  		addrput(s, e.value-b.value)
  1906  		addrput(s, 0)
  1907  		addrput(s, 0)
  1908  	}
  1909  	if s.Size > 0 {
  1910  		prev.Next = s
  1911  		prev = s
  1912  	}
  1913  	return prev
  1914  }
  1915  
  1916  func writegdbscript(prev *LSym) *LSym {
  1917  
  1918  	if gdbscript != "" {
  1919  		s := Linklookup(Ctxt, ".debug_gdb_scripts", 0)
  1920  		s.Type = obj.SDWARFSECT
  1921  		prev.Next = s
  1922  		prev = s
  1923  		Adduint8(Ctxt, s, 1) // magic 1 byte?
  1924  		Addstring(s, gdbscript)
  1925  	}
  1926  
  1927  	return prev
  1928  }
  1929  
  1930  var prototypedies map[string]*DWDie
  1931  
  1932  /*
  1933   * This is the main entry point for generating dwarf.  After emitting
  1934   * the mandatory debug_abbrev section, it calls writelines() to set up
  1935   * the per-compilation unit part of the DIE tree, while simultaneously
  1936   * emitting the debug_line section.  When the final tree contains
  1937   * forward references, it will write the debug_info section in 2
  1938   * passes.
  1939   *
  1940   */
  1941  func dwarfgeneratedebugsyms() {
  1942  	if Debug['w'] != 0 { // disable dwarf
  1943  		return
  1944  	}
  1945  	if Debug['s'] != 0 && HEADTYPE != obj.Hdarwin {
  1946  		return
  1947  	}
  1948  	if HEADTYPE == obj.Hplan9 {
  1949  		return
  1950  	}
  1951  
  1952  	if Linkmode == LinkExternal {
  1953  		if !Iself && HEADTYPE != obj.Hdarwin {
  1954  			return
  1955  		}
  1956  	}
  1957  
  1958  	if Debug['v'] != 0 {
  1959  		fmt.Fprintf(Bso, "%5.2f dwarf\n", obj.Cputime())
  1960  	}
  1961  
  1962  	// For diagnostic messages.
  1963  	newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes")
  1964  
  1965  	// Some types that must exist to define other ones.
  1966  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>", 0)
  1967  
  1968  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "void", 0)
  1969  	newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer", 0)
  1970  
  1971  	die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size
  1972  	newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
  1973  	newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(SysArch.PtrSize), 0)
  1974  	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0)
  1975  
  1976  	// Prototypes needed for type synthesis.
  1977  	prototypedies = map[string]*DWDie{
  1978  		"type.runtime.stringStructDWARF": nil,
  1979  		"type.runtime.slice":             nil,
  1980  		"type.runtime.hmap":              nil,
  1981  		"type.runtime.bmap":              nil,
  1982  		"type.runtime.sudog":             nil,
  1983  		"type.runtime.waitq":             nil,
  1984  		"type.runtime.hchan":             nil,
  1985  	}
  1986  
  1987  	// Needed by the prettyprinter code for interface inspection.
  1988  	defgotype(lookup_or_diag("type.runtime._type"))
  1989  
  1990  	defgotype(lookup_or_diag("type.runtime.interfacetype"))
  1991  	defgotype(lookup_or_diag("type.runtime.itab"))
  1992  
  1993  	genasmsym(defdwsymb)
  1994  
  1995  	dwarfp = writeabbrev()
  1996  	last := dwarfp
  1997  	last = writelines(last)
  1998  	last = writeframes(last)
  1999  
  2000  	synthesizestringtypes(dwtypes.child)
  2001  	synthesizeslicetypes(dwtypes.child)
  2002  	synthesizemaptypes(dwtypes.child)
  2003  	synthesizechantypes(dwtypes.child)
  2004  
  2005  	reversetree(&dwroot.child)
  2006  	reversetree(&dwtypes.child)
  2007  	reversetree(&dwglobals.child)
  2008  
  2009  	movetomodule(&dwtypes)
  2010  	movetomodule(&dwglobals)
  2011  
  2012  	// Need to reorder symbols so SDWARFINFO is after all SDWARFSECT
  2013  	// (but we need to generate dies before writepub)
  2014  	writeinfo(last)
  2015  	infosyms := last.Next
  2016  
  2017  	last = writepub(".debug_pubnames", ispubname, last)
  2018  	last = writepub(".debug_pubtypes", ispubtype, last)
  2019  	last = writearanges(last)
  2020  	last = writegdbscript(last)
  2021  	last.Next = infosyms
  2022  }
  2023  
  2024  /*
  2025   *  Elf.
  2026   */
  2027  func dwarfaddshstrings(shstrtab *LSym) {
  2028  	if Debug['w'] != 0 { // disable dwarf
  2029  		return
  2030  	}
  2031  
  2032  	Addstring(shstrtab, ".debug_abbrev")
  2033  	Addstring(shstrtab, ".debug_aranges")
  2034  	Addstring(shstrtab, ".debug_frame")
  2035  	Addstring(shstrtab, ".debug_info")
  2036  	Addstring(shstrtab, ".debug_line")
  2037  	Addstring(shstrtab, ".debug_pubnames")
  2038  	Addstring(shstrtab, ".debug_pubtypes")
  2039  	Addstring(shstrtab, ".debug_gdb_scripts")
  2040  	if Linkmode == LinkExternal {
  2041  		Addstring(shstrtab, elfRelType+".debug_info")
  2042  		Addstring(shstrtab, elfRelType+".debug_aranges")
  2043  		Addstring(shstrtab, elfRelType+".debug_line")
  2044  		Addstring(shstrtab, elfRelType+".debug_frame")
  2045  		Addstring(shstrtab, elfRelType+".debug_pubnames")
  2046  		Addstring(shstrtab, elfRelType+".debug_pubtypes")
  2047  	}
  2048  }
  2049  
  2050  // Add section symbols for DWARF debug info.  This is called before
  2051  // dwarfaddelfheaders.
  2052  func dwarfaddelfsectionsyms() {
  2053  	if Debug['w'] != 0 { // disable dwarf
  2054  		return
  2055  	}
  2056  	if Linkmode != LinkExternal {
  2057  		return
  2058  	}
  2059  	sym := Linklookup(Ctxt, ".debug_info", 0)
  2060  	putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
  2061  	sym = Linklookup(Ctxt, ".debug_abbrev", 0)
  2062  	putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
  2063  	sym = Linklookup(Ctxt, ".debug_line", 0)
  2064  	putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
  2065  	sym = Linklookup(Ctxt, ".debug_frame", 0)
  2066  	putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
  2067  }
  2068  
  2069  /*
  2070   * Windows PE
  2071   */
  2072  func dwarfaddpeheaders() {
  2073  	if Debug['w'] != 0 { // disable dwarf
  2074  		return
  2075  	}
  2076  	for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
  2077  		h := newPEDWARFSection(sect.Name, int64(sect.Length))
  2078  		fileoff := sect.Vaddr - Segdwarf.Vaddr + Segdwarf.Fileoff
  2079  		if uint64(h.PointerToRawData) != fileoff {
  2080  			Diag("%s.PointerToRawData = %#x, want %#x", sect.Name, h.PointerToRawData, fileoff)
  2081  			errorexit()
  2082  		}
  2083  	}
  2084  }