github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/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  	"strings"
    21  )
    22  
    23  /*
    24   * Offsets and sizes of the debug_* sections in the cout file.
    25   */
    26  var abbrevo int64
    27  
    28  var abbrevsize int64
    29  
    30  var abbrevsym *LSym
    31  
    32  var abbrevsympos int64
    33  
    34  var lineo int64
    35  
    36  var linesize int64
    37  
    38  var linesym *LSym
    39  
    40  var linesympos int64
    41  
    42  var infoo int64 // also the base for DWDie->offs and reference attributes.
    43  
    44  var infosize int64
    45  
    46  var infosym *LSym
    47  
    48  var infosympos int64
    49  
    50  var frameo int64
    51  
    52  var framesize int64
    53  
    54  var framesym *LSym
    55  
    56  var framesympos int64
    57  
    58  var pubnameso int64
    59  
    60  var pubnamessize int64
    61  
    62  var pubtypeso int64
    63  
    64  var pubtypessize int64
    65  
    66  var arangeso int64
    67  
    68  var arangessize int64
    69  
    70  var gdbscripto int64
    71  
    72  var gdbscriptsize int64
    73  
    74  var infosec *LSym
    75  
    76  var inforeloco int64
    77  
    78  var inforelocsize int64
    79  
    80  var arangessec *LSym
    81  
    82  var arangesreloco int64
    83  
    84  var arangesrelocsize int64
    85  
    86  var linesec *LSym
    87  
    88  var linereloco int64
    89  
    90  var linerelocsize int64
    91  
    92  var framesec *LSym
    93  
    94  var framereloco int64
    95  
    96  var framerelocsize int64
    97  
    98  var gdbscript string
    99  
   100  /*
   101   *  Basic I/O
   102   */
   103  func addrput(addr int64) {
   104  	switch Thearch.Ptrsize {
   105  	case 4:
   106  		Thearch.Lput(uint32(addr))
   107  
   108  	case 8:
   109  		Thearch.Vput(uint64(addr))
   110  	}
   111  }
   112  
   113  func uleb128enc(v uint64, dst []byte) int {
   114  	var c uint8
   115  
   116  	length := uint8(0)
   117  	for {
   118  		c = uint8(v & 0x7f)
   119  		v >>= 7
   120  		if v != 0 {
   121  			c |= 0x80
   122  		}
   123  		if dst != nil {
   124  			dst[0] = byte(c)
   125  			dst = dst[1:]
   126  		}
   127  		length++
   128  		if c&0x80 == 0 {
   129  			break
   130  		}
   131  	}
   132  
   133  	return int(length)
   134  }
   135  
   136  func sleb128enc(v int64, dst []byte) int {
   137  	var c uint8
   138  	var s uint8
   139  
   140  	length := uint8(0)
   141  	for {
   142  		c = uint8(v & 0x7f)
   143  		s = uint8(v & 0x40)
   144  		v >>= 7
   145  		if (v != -1 || s == 0) && (v != 0 || s != 0) {
   146  			c |= 0x80
   147  		}
   148  		if dst != nil {
   149  			dst[0] = byte(c)
   150  			dst = dst[1:]
   151  		}
   152  		length++
   153  		if c&0x80 == 0 {
   154  			break
   155  		}
   156  	}
   157  
   158  	return int(length)
   159  }
   160  
   161  func uleb128put(v int64) {
   162  	var buf [10]byte
   163  	n := uleb128enc(uint64(v), buf[:])
   164  	Cwrite(buf[:n])
   165  }
   166  
   167  func sleb128put(v int64) {
   168  	var buf [10]byte
   169  	n := sleb128enc(v, buf[:])
   170  	Cwrite(buf[:n])
   171  }
   172  
   173  /*
   174   * Defining Abbrevs.  This is hardcoded, and there will be
   175   * only a handful of them.  The DWARF spec places no restriction on
   176   * the ordering of attributes in the Abbrevs and DIEs, and we will
   177   * always write them out in the order of declaration in the abbrev.
   178   */
   179  type DWAttrForm struct {
   180  	attr uint16
   181  	form uint8
   182  }
   183  
   184  // Go-specific type attributes.
   185  const (
   186  	DW_AT_go_kind = 0x2900
   187  	DW_AT_go_key  = 0x2901
   188  	DW_AT_go_elem = 0x2902
   189  
   190  	DW_AT_internal_location = 253 // params and locals; not emitted
   191  )
   192  
   193  // Index into the abbrevs table below.
   194  // Keep in sync with ispubname() and ispubtype() below.
   195  // ispubtype considers >= NULLTYPE public
   196  const (
   197  	DW_ABRV_NULL = iota
   198  	DW_ABRV_COMPUNIT
   199  	DW_ABRV_FUNCTION
   200  	DW_ABRV_VARIABLE
   201  	DW_ABRV_AUTO
   202  	DW_ABRV_PARAM
   203  	DW_ABRV_STRUCTFIELD
   204  	DW_ABRV_FUNCTYPEPARAM
   205  	DW_ABRV_DOTDOTDOT
   206  	DW_ABRV_ARRAYRANGE
   207  	DW_ABRV_NULLTYPE
   208  	DW_ABRV_BASETYPE
   209  	DW_ABRV_ARRAYTYPE
   210  	DW_ABRV_CHANTYPE
   211  	DW_ABRV_FUNCTYPE
   212  	DW_ABRV_IFACETYPE
   213  	DW_ABRV_MAPTYPE
   214  	DW_ABRV_PTRTYPE
   215  	DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6.
   216  	DW_ABRV_SLICETYPE
   217  	DW_ABRV_STRINGTYPE
   218  	DW_ABRV_STRUCTTYPE
   219  	DW_ABRV_TYPEDECL
   220  	DW_NABRV
   221  )
   222  
   223  type DWAbbrev struct {
   224  	tag      uint8
   225  	children uint8
   226  	attr     []DWAttrForm
   227  }
   228  
   229  var abbrevs = [DW_NABRV]DWAbbrev{
   230  	/* The mandatory DW_ABRV_NULL entry. */
   231  	{0, 0, []DWAttrForm{}},
   232  
   233  	/* COMPUNIT */
   234  	{
   235  		DW_TAG_compile_unit,
   236  		DW_CHILDREN_yes,
   237  		[]DWAttrForm{
   238  			{DW_AT_name, DW_FORM_string},
   239  			{DW_AT_language, DW_FORM_data1},
   240  			{DW_AT_low_pc, DW_FORM_addr},
   241  			{DW_AT_high_pc, DW_FORM_addr},
   242  			{DW_AT_stmt_list, DW_FORM_data4},
   243  		},
   244  	},
   245  
   246  	/* FUNCTION */
   247  	{
   248  		DW_TAG_subprogram,
   249  		DW_CHILDREN_yes,
   250  		[]DWAttrForm{
   251  			{DW_AT_name, DW_FORM_string},
   252  			{DW_AT_low_pc, DW_FORM_addr},
   253  			{DW_AT_high_pc, DW_FORM_addr},
   254  			{DW_AT_external, DW_FORM_flag},
   255  		},
   256  	},
   257  
   258  	/* VARIABLE */
   259  	{
   260  		DW_TAG_variable,
   261  		DW_CHILDREN_no,
   262  		[]DWAttrForm{
   263  			{DW_AT_name, DW_FORM_string},
   264  			{DW_AT_location, DW_FORM_block1},
   265  			{DW_AT_type, DW_FORM_ref_addr},
   266  			{DW_AT_external, DW_FORM_flag},
   267  		},
   268  	},
   269  
   270  	/* AUTO */
   271  	{
   272  		DW_TAG_variable,
   273  		DW_CHILDREN_no,
   274  		[]DWAttrForm{
   275  			{DW_AT_name, DW_FORM_string},
   276  			{DW_AT_location, DW_FORM_block1},
   277  			{DW_AT_type, DW_FORM_ref_addr},
   278  		},
   279  	},
   280  
   281  	/* PARAM */
   282  	{
   283  		DW_TAG_formal_parameter,
   284  		DW_CHILDREN_no,
   285  		[]DWAttrForm{
   286  			{DW_AT_name, DW_FORM_string},
   287  			{DW_AT_location, DW_FORM_block1},
   288  			{DW_AT_type, DW_FORM_ref_addr},
   289  		},
   290  	},
   291  
   292  	/* STRUCTFIELD */
   293  	{
   294  		DW_TAG_member,
   295  		DW_CHILDREN_no,
   296  		[]DWAttrForm{
   297  			{DW_AT_name, DW_FORM_string},
   298  			{DW_AT_data_member_location, DW_FORM_block1},
   299  			{DW_AT_type, DW_FORM_ref_addr},
   300  		},
   301  	},
   302  
   303  	/* FUNCTYPEPARAM */
   304  	{
   305  		DW_TAG_formal_parameter,
   306  		DW_CHILDREN_no,
   307  
   308  		// No name!
   309  		[]DWAttrForm{
   310  			{DW_AT_type, DW_FORM_ref_addr},
   311  		},
   312  	},
   313  
   314  	/* DOTDOTDOT */
   315  	{
   316  		DW_TAG_unspecified_parameters,
   317  		DW_CHILDREN_no,
   318  		[]DWAttrForm{},
   319  	},
   320  
   321  	/* ARRAYRANGE */
   322  	{
   323  		DW_TAG_subrange_type,
   324  		DW_CHILDREN_no,
   325  
   326  		// No name!
   327  		[]DWAttrForm{
   328  			{DW_AT_type, DW_FORM_ref_addr},
   329  			{DW_AT_count, DW_FORM_udata},
   330  		},
   331  	},
   332  
   333  	// Below here are the types considered public by ispubtype
   334  	/* NULLTYPE */
   335  	{
   336  		DW_TAG_unspecified_type,
   337  		DW_CHILDREN_no,
   338  		[]DWAttrForm{
   339  			{DW_AT_name, DW_FORM_string},
   340  		},
   341  	},
   342  
   343  	/* BASETYPE */
   344  	{
   345  		DW_TAG_base_type,
   346  		DW_CHILDREN_no,
   347  		[]DWAttrForm{
   348  			{DW_AT_name, DW_FORM_string},
   349  			{DW_AT_encoding, DW_FORM_data1},
   350  			{DW_AT_byte_size, DW_FORM_data1},
   351  			{DW_AT_go_kind, DW_FORM_data1},
   352  		},
   353  	},
   354  
   355  	/* ARRAYTYPE */
   356  	// child is subrange with upper bound
   357  	{
   358  		DW_TAG_array_type,
   359  		DW_CHILDREN_yes,
   360  		[]DWAttrForm{
   361  			{DW_AT_name, DW_FORM_string},
   362  			{DW_AT_type, DW_FORM_ref_addr},
   363  			{DW_AT_byte_size, DW_FORM_udata},
   364  			{DW_AT_go_kind, DW_FORM_data1},
   365  		},
   366  	},
   367  
   368  	/* CHANTYPE */
   369  	{
   370  		DW_TAG_typedef,
   371  		DW_CHILDREN_no,
   372  		[]DWAttrForm{
   373  			{DW_AT_name, DW_FORM_string},
   374  			{DW_AT_type, DW_FORM_ref_addr},
   375  			{DW_AT_go_kind, DW_FORM_data1},
   376  			{DW_AT_go_elem, DW_FORM_ref_addr},
   377  		},
   378  	},
   379  
   380  	/* FUNCTYPE */
   381  	{
   382  		DW_TAG_subroutine_type,
   383  		DW_CHILDREN_yes,
   384  		[]DWAttrForm{
   385  			{DW_AT_name, DW_FORM_string},
   386  			// {DW_AT_type,	DW_FORM_ref_addr},
   387  			{DW_AT_go_kind, DW_FORM_data1},
   388  		},
   389  	},
   390  
   391  	/* IFACETYPE */
   392  	{
   393  		DW_TAG_typedef,
   394  		DW_CHILDREN_yes,
   395  		[]DWAttrForm{
   396  			{DW_AT_name, DW_FORM_string},
   397  			{DW_AT_type, DW_FORM_ref_addr},
   398  			{DW_AT_go_kind, DW_FORM_data1},
   399  		},
   400  	},
   401  
   402  	/* MAPTYPE */
   403  	{
   404  		DW_TAG_typedef,
   405  		DW_CHILDREN_no,
   406  		[]DWAttrForm{
   407  			{DW_AT_name, DW_FORM_string},
   408  			{DW_AT_type, DW_FORM_ref_addr},
   409  			{DW_AT_go_kind, DW_FORM_data1},
   410  			{DW_AT_go_key, DW_FORM_ref_addr},
   411  			{DW_AT_go_elem, DW_FORM_ref_addr},
   412  		},
   413  	},
   414  
   415  	/* PTRTYPE */
   416  	{
   417  		DW_TAG_pointer_type,
   418  		DW_CHILDREN_no,
   419  		[]DWAttrForm{
   420  			{DW_AT_name, DW_FORM_string},
   421  			{DW_AT_type, DW_FORM_ref_addr},
   422  			{DW_AT_go_kind, DW_FORM_data1},
   423  		},
   424  	},
   425  
   426  	/* BARE_PTRTYPE */
   427  	{
   428  		DW_TAG_pointer_type,
   429  		DW_CHILDREN_no,
   430  		[]DWAttrForm{
   431  			{DW_AT_name, DW_FORM_string},
   432  		},
   433  	},
   434  
   435  	/* SLICETYPE */
   436  	{
   437  		DW_TAG_structure_type,
   438  		DW_CHILDREN_yes,
   439  		[]DWAttrForm{
   440  			{DW_AT_name, DW_FORM_string},
   441  			{DW_AT_byte_size, DW_FORM_udata},
   442  			{DW_AT_go_kind, DW_FORM_data1},
   443  			{DW_AT_go_elem, DW_FORM_ref_addr},
   444  		},
   445  	},
   446  
   447  	/* STRINGTYPE */
   448  	{
   449  		DW_TAG_structure_type,
   450  		DW_CHILDREN_yes,
   451  		[]DWAttrForm{
   452  			{DW_AT_name, DW_FORM_string},
   453  			{DW_AT_byte_size, DW_FORM_udata},
   454  			{DW_AT_go_kind, DW_FORM_data1},
   455  		},
   456  	},
   457  
   458  	/* STRUCTTYPE */
   459  	{
   460  		DW_TAG_structure_type,
   461  		DW_CHILDREN_yes,
   462  		[]DWAttrForm{
   463  			{DW_AT_name, DW_FORM_string},
   464  			{DW_AT_byte_size, DW_FORM_udata},
   465  			{DW_AT_go_kind, DW_FORM_data1},
   466  		},
   467  	},
   468  
   469  	/* TYPEDECL */
   470  	{
   471  		DW_TAG_typedef,
   472  		DW_CHILDREN_no,
   473  		[]DWAttrForm{
   474  			{DW_AT_name, DW_FORM_string},
   475  			{DW_AT_type, DW_FORM_ref_addr},
   476  		},
   477  	},
   478  }
   479  
   480  func writeabbrev() {
   481  	abbrevo = Cpos()
   482  	for i := 1; i < DW_NABRV; i++ {
   483  		// See section 7.5.3
   484  		uleb128put(int64(i))
   485  
   486  		uleb128put(int64(abbrevs[i].tag))
   487  		Cput(abbrevs[i].children)
   488  		for _, f := range abbrevs[i].attr {
   489  			uleb128put(int64(f.attr))
   490  			uleb128put(int64(f.form))
   491  		}
   492  		uleb128put(0)
   493  		uleb128put(0)
   494  	}
   495  
   496  	Cput(0)
   497  	abbrevsize = Cpos() - abbrevo
   498  }
   499  
   500  /*
   501   * Debugging Information Entries and their attributes.
   502   */
   503  const (
   504  	HASHSIZE = 107
   505  )
   506  
   507  func dwarfhashstr(s string) uint32 {
   508  	h := uint32(0)
   509  	for s != "" {
   510  		h = h + h + h + uint32(s[0])
   511  		s = s[1:]
   512  	}
   513  	return h % HASHSIZE
   514  }
   515  
   516  // For DW_CLS_string and _block, value should contain the length, and
   517  // data the data, for _reference, value is 0 and data is a DWDie* to
   518  // the referenced instance, for all others, value is the whole thing
   519  // and data is null.
   520  
   521  type DWAttr struct {
   522  	link  *DWAttr
   523  	atr   uint16 // DW_AT_
   524  	cls   uint8  // DW_CLS_
   525  	value int64
   526  	data  interface{}
   527  }
   528  
   529  type DWDie struct {
   530  	abbrev int
   531  	link   *DWDie
   532  	child  *DWDie
   533  	attr   *DWAttr
   534  	// offset into .debug_info section, i.e relative to
   535  	// infoo. only valid after call to putdie()
   536  	offs  int64
   537  	hash  []*DWDie // optional index of children by name, enabled by mkindex()
   538  	hlink *DWDie   // bucket chain in parent's index
   539  }
   540  
   541  /*
   542   * Root DIEs for compilation units, types and global variables.
   543   */
   544  var dwroot DWDie
   545  
   546  var dwtypes DWDie
   547  
   548  var dwglobals DWDie
   549  
   550  func newattr(die *DWDie, attr uint16, cls int, value int64, data interface{}) *DWAttr {
   551  	a := new(DWAttr)
   552  	a.link = die.attr
   553  	die.attr = a
   554  	a.atr = attr
   555  	a.cls = uint8(cls)
   556  	a.value = value
   557  	a.data = data
   558  	return a
   559  }
   560  
   561  // Each DIE (except the root ones) has at least 1 attribute: its
   562  // name. getattr moves the desired one to the front so
   563  // frequently searched ones are found faster.
   564  func getattr(die *DWDie, attr uint16) *DWAttr {
   565  	if die.attr.atr == attr {
   566  		return die.attr
   567  	}
   568  
   569  	a := die.attr
   570  	b := a.link
   571  	for b != nil {
   572  		if b.atr == attr {
   573  			a.link = b.link
   574  			b.link = die.attr
   575  			die.attr = b
   576  			return b
   577  		}
   578  
   579  		a = b
   580  		b = b.link
   581  	}
   582  
   583  	return nil
   584  }
   585  
   586  // Every DIE has at least a DW_AT_name attribute (but it will only be
   587  // written out if it is listed in the abbrev).	If its parent is
   588  // keeping an index, the new DIE will be inserted there.
   589  func newdie(parent *DWDie, abbrev int, name string) *DWDie {
   590  	die := new(DWDie)
   591  	die.abbrev = abbrev
   592  	die.link = parent.child
   593  	parent.child = die
   594  
   595  	newattr(die, DW_AT_name, DW_CLS_STRING, int64(len(name)), name)
   596  
   597  	if parent.hash != nil {
   598  		h := int(dwarfhashstr(name))
   599  		die.hlink = parent.hash[h]
   600  		parent.hash[h] = die
   601  	}
   602  
   603  	return die
   604  }
   605  
   606  func mkindex(die *DWDie) {
   607  	die.hash = make([]*DWDie, HASHSIZE)
   608  }
   609  
   610  func walktypedef(die *DWDie) *DWDie {
   611  	// Resolve typedef if present.
   612  	if die.abbrev == DW_ABRV_TYPEDECL {
   613  		for attr := die.attr; attr != nil; attr = attr.link {
   614  			if attr.atr == DW_AT_type && attr.cls == DW_CLS_REFERENCE && attr.data != nil {
   615  				return attr.data.(*DWDie)
   616  			}
   617  		}
   618  	}
   619  
   620  	return die
   621  }
   622  
   623  // Find child by AT_name using hashtable if available or linear scan
   624  // if not.
   625  func find(die *DWDie, name string) *DWDie {
   626  	var a *DWDie
   627  	var b *DWDie
   628  	var die2 *DWDie
   629  	var h int
   630  
   631  top:
   632  	if die.hash == nil {
   633  		for a = die.child; a != nil; a = a.link {
   634  			if name == getattr(a, DW_AT_name).data {
   635  				return a
   636  			}
   637  		}
   638  		goto notfound
   639  	}
   640  
   641  	h = int(dwarfhashstr(name))
   642  	a = die.hash[h]
   643  
   644  	if a == nil {
   645  		goto notfound
   646  	}
   647  
   648  	if name == getattr(a, DW_AT_name).data {
   649  		return a
   650  	}
   651  
   652  	// Move found ones to head of the list.
   653  	b = a.hlink
   654  
   655  	for b != nil {
   656  		if name == getattr(b, DW_AT_name).data {
   657  			a.hlink = b.hlink
   658  			b.hlink = die.hash[h]
   659  			die.hash[h] = b
   660  			return b
   661  		}
   662  
   663  		a = b
   664  		b = b.hlink
   665  	}
   666  
   667  notfound:
   668  	die2 = walktypedef(die)
   669  	if die2 != die {
   670  		die = die2
   671  		goto top
   672  	}
   673  
   674  	return nil
   675  }
   676  
   677  func find_or_diag(die *DWDie, name string) *DWDie {
   678  	r := find(die, name)
   679  	if r == nil {
   680  		Diag("dwarf find: %s %p has no %s", getattr(die, DW_AT_name).data, die, name)
   681  		Errorexit()
   682  	}
   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 = R_ADDR
   694  	r.Add = addend
   695  	r.Xadd = addend
   696  	if Iself && Thearch.Thechar == '6' {
   697  		addend = 0
   698  	}
   699  	switch siz {
   700  	case 4:
   701  		Thearch.Lput(uint32(addend))
   702  
   703  	case 8:
   704  		Thearch.Vput(uint64(addend))
   705  
   706  	default:
   707  		Diag("bad size in adddwarfrel")
   708  	}
   709  }
   710  
   711  func newrefattr(die *DWDie, attr uint16, ref *DWDie) *DWAttr {
   712  	if ref == nil {
   713  		return nil
   714  	}
   715  	return newattr(die, attr, DW_CLS_REFERENCE, 0, ref)
   716  }
   717  
   718  var fwdcount int
   719  
   720  func putattr(abbrev int, form int, cls int, value int64, data interface{}) {
   721  	switch form {
   722  	case DW_FORM_addr: // address
   723  		if Linkmode == LinkExternal {
   724  			value -= (data.(*LSym)).Value
   725  			adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value)
   726  			break
   727  		}
   728  
   729  		addrput(value)
   730  
   731  	case DW_FORM_block1: // block
   732  		if cls == DW_CLS_ADDRESS {
   733  			Cput(uint8(1 + Thearch.Ptrsize))
   734  			Cput(DW_OP_addr)
   735  			if Linkmode == LinkExternal {
   736  				value -= (data.(*LSym)).Value
   737  				adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value)
   738  				break
   739  			}
   740  
   741  			addrput(value)
   742  			break
   743  		}
   744  
   745  		value &= 0xff
   746  		Cput(uint8(value))
   747  		p := data.([]byte)
   748  		for i := 0; int64(i) < value; i++ {
   749  			Cput(uint8(p[i]))
   750  		}
   751  
   752  	case DW_FORM_block2: // block
   753  		value &= 0xffff
   754  
   755  		Thearch.Wput(uint16(value))
   756  		p := data.([]byte)
   757  		for i := 0; int64(i) < value; i++ {
   758  			Cput(uint8(p[i]))
   759  		}
   760  
   761  	case DW_FORM_block4: // block
   762  		value &= 0xffffffff
   763  
   764  		Thearch.Lput(uint32(value))
   765  		p := data.([]byte)
   766  		for i := 0; int64(i) < value; i++ {
   767  			Cput(uint8(p[i]))
   768  		}
   769  
   770  	case DW_FORM_block: // block
   771  		uleb128put(value)
   772  
   773  		p := data.([]byte)
   774  		for i := 0; int64(i) < value; i++ {
   775  			Cput(uint8(p[i]))
   776  		}
   777  
   778  	case DW_FORM_data1: // constant
   779  		Cput(uint8(value))
   780  
   781  	case DW_FORM_data2: // constant
   782  		Thearch.Wput(uint16(value))
   783  
   784  	case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr
   785  		if Linkmode == LinkExternal && cls == DW_CLS_PTR {
   786  			adddwarfrel(infosec, linesym, infoo, 4, value)
   787  			break
   788  		}
   789  
   790  		Thearch.Lput(uint32(value))
   791  
   792  	case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr
   793  		Thearch.Vput(uint64(value))
   794  
   795  	case DW_FORM_sdata: // constant
   796  		sleb128put(value)
   797  
   798  	case DW_FORM_udata: // constant
   799  		uleb128put(value)
   800  
   801  	case DW_FORM_string: // string
   802  		strnput(data.(string), int(value+1))
   803  
   804  	case DW_FORM_flag: // flag
   805  		if value != 0 {
   806  			Cput(1)
   807  		} else {
   808  			Cput(0)
   809  		}
   810  
   811  		// In DWARF 2 (which is what we claim to generate),
   812  	// the ref_addr is the same size as a normal address.
   813  	// In DWARF 3 it is always 32 bits, unless emitting a large
   814  	// (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
   815  	case DW_FORM_ref_addr: // reference to a DIE in the .info section
   816  		if data == nil {
   817  			Diag("dwarf: null reference in %d", abbrev)
   818  			if Thearch.Ptrsize == 8 {
   819  				Thearch.Vput(0) // invalid dwarf, gdb will complain.
   820  			} else {
   821  				Thearch.Lput(0) // invalid dwarf, gdb will complain.
   822  			}
   823  		} else {
   824  			off := (data.(*DWDie)).offs
   825  			if off == 0 {
   826  				fwdcount++
   827  			}
   828  			if Linkmode == LinkExternal {
   829  				adddwarfrel(infosec, infosym, infoo, Thearch.Ptrsize, off)
   830  				break
   831  			}
   832  
   833  			addrput(off)
   834  		}
   835  
   836  	case DW_FORM_ref1, // reference within the compilation unit
   837  		DW_FORM_ref2,      // reference
   838  		DW_FORM_ref4,      // reference
   839  		DW_FORM_ref8,      // reference
   840  		DW_FORM_ref_udata, // reference
   841  
   842  		DW_FORM_strp,     // string
   843  		DW_FORM_indirect: // (see Section 7.5.3)
   844  		fallthrough
   845  	default:
   846  		Diag("dwarf: unsupported attribute form %d / class %d", form, cls)
   847  
   848  		Errorexit()
   849  	}
   850  }
   851  
   852  // Note that we can (and do) add arbitrary attributes to a DIE, but
   853  // only the ones actually listed in the Abbrev will be written out.
   854  func putattrs(abbrev int, attr *DWAttr) {
   855  Outer:
   856  	for _, f := range abbrevs[abbrev].attr {
   857  		for ap := attr; ap != nil; ap = ap.link {
   858  			if ap.atr == f.attr {
   859  				putattr(abbrev, int(f.form), int(ap.cls), ap.value, ap.data)
   860  				continue Outer
   861  			}
   862  		}
   863  
   864  		putattr(abbrev, int(f.form), 0, 0, nil)
   865  	}
   866  }
   867  
   868  func putdies(die *DWDie) {
   869  	for ; die != nil; die = die.link {
   870  		putdie(die)
   871  	}
   872  }
   873  
   874  func putdie(die *DWDie) {
   875  	die.offs = Cpos() - infoo
   876  	uleb128put(int64(die.abbrev))
   877  	putattrs(die.abbrev, die.attr)
   878  	if abbrevs[die.abbrev].children != 0 {
   879  		putdies(die.child)
   880  		Cput(0)
   881  	}
   882  }
   883  
   884  func reverselist(list **DWDie) {
   885  	curr := *list
   886  	var prev *DWDie
   887  	for curr != nil {
   888  		var next *DWDie = curr.link
   889  		curr.link = prev
   890  		prev = curr
   891  		curr = next
   892  	}
   893  
   894  	*list = prev
   895  }
   896  
   897  func reversetree(list **DWDie) {
   898  	reverselist(list)
   899  	for die := *list; die != nil; die = die.link {
   900  		if abbrevs[die.abbrev].children != 0 {
   901  			reversetree(&die.child)
   902  		}
   903  	}
   904  }
   905  
   906  func newmemberoffsetattr(die *DWDie, offs int32) {
   907  	var block [20]byte
   908  
   909  	i := 0
   910  	block[i] = DW_OP_plus_uconst
   911  	i++
   912  	i += uleb128enc(uint64(offs), block[i:])
   913  	newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, int64(i), block[:i])
   914  }
   915  
   916  // GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
   917  // location expression that evals to a const.
   918  func newabslocexprattr(die *DWDie, addr int64, sym *LSym) {
   919  	newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, sym)
   920  	// below
   921  }
   922  
   923  // Lookup predefined types
   924  func lookup_or_diag(n string) *LSym {
   925  	s := Linkrlookup(Ctxt, n, 0)
   926  	if s == nil || s.Size == 0 {
   927  		Diag("dwarf: missing type: %s", n)
   928  		Errorexit()
   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 find_or_diag(&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 find_or_diag(&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: %%Y\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, find_or_diag(&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, find_or_diag(&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, find_or_diag(&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 := find_or_diag(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, find_or_diag(&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, find_or_diag(&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, find_or_diag(&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  
  1423  	if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
  1424  		defgotype(sym)
  1425  		return
  1426  	}
  1427  
  1428  	var dv *DWDie
  1429  
  1430  	var dt *DWDie
  1431  	switch t {
  1432  	default:
  1433  		return
  1434  
  1435  	case 'd', 'b', 'D', 'B':
  1436  		dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s)
  1437  		newabslocexprattr(dv, v, sym)
  1438  		if ver == 0 {
  1439  			newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0)
  1440  		}
  1441  		fallthrough
  1442  
  1443  		// fallthrough
  1444  	case 'a', 'p':
  1445  		dt = defgotype(gotype)
  1446  	}
  1447  
  1448  	if dv != nil {
  1449  		newrefattr(dv, DW_AT_type, dt)
  1450  	}
  1451  }
  1452  
  1453  func movetomodule(parent *DWDie) {
  1454  	die := dwroot.child.child
  1455  	for die.link != nil {
  1456  		die = die.link
  1457  	}
  1458  	die.link = parent.child
  1459  }
  1460  
  1461  // If the pcln table contains runtime/runtime.go, use that to set gdbscript path.
  1462  func finddebugruntimepath(s *LSym) {
  1463  	if gdbscript != "" {
  1464  		return
  1465  	}
  1466  
  1467  	var f *LSym
  1468  	var p string
  1469  	for i := 0; i < s.Pcln.Nfile; i++ {
  1470  		f = s.Pcln.File[i]
  1471  		_ = p
  1472  		if i := strings.Index(f.Name, "runtime/runtime.go"); i >= 0 {
  1473  			gdbscript = f.Name[:i] + "runtime/runtime-gdb.py"
  1474  			break
  1475  		}
  1476  	}
  1477  }
  1478  
  1479  /*
  1480   * Generate short opcodes when possible, long ones when necessary.
  1481   * See section 6.2.5
  1482   */
  1483  const (
  1484  	LINE_BASE   = -1
  1485  	LINE_RANGE  = 4
  1486  	OPCODE_BASE = 10
  1487  )
  1488  
  1489  func putpclcdelta(delta_pc int64, delta_lc int64) {
  1490  	if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE {
  1491  		var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc)
  1492  		if OPCODE_BASE <= opcode && opcode < 256 {
  1493  			Cput(uint8(opcode))
  1494  			return
  1495  		}
  1496  	}
  1497  
  1498  	if delta_pc != 0 {
  1499  		Cput(DW_LNS_advance_pc)
  1500  		sleb128put(delta_pc)
  1501  	}
  1502  
  1503  	Cput(DW_LNS_advance_line)
  1504  	sleb128put(delta_lc)
  1505  	Cput(DW_LNS_copy)
  1506  }
  1507  
  1508  func newcfaoffsetattr(die *DWDie, offs int32) {
  1509  	var block [20]byte
  1510  
  1511  	i := 0
  1512  
  1513  	block[i] = DW_OP_call_frame_cfa
  1514  	i++
  1515  	if offs != 0 {
  1516  		block[i] = DW_OP_consts
  1517  		i++
  1518  		i += sleb128enc(int64(offs), block[i:])
  1519  		block[i] = DW_OP_plus
  1520  		i++
  1521  	}
  1522  
  1523  	newattr(die, DW_AT_location, DW_CLS_BLOCK, int64(i), block[:i])
  1524  }
  1525  
  1526  func mkvarname(name string, da int) string {
  1527  	buf := fmt.Sprintf("%s#%d", name, da)
  1528  	n := buf
  1529  	return n
  1530  }
  1531  
  1532  /*
  1533   * Walk prog table, emit line program and build DIE tree.
  1534   */
  1535  
  1536  // flush previous compilation unit.
  1537  func flushunit(dwinfo *DWDie, pc int64, pcsym *LSym, unitstart int64, header_length int32) {
  1538  	if dwinfo != nil && pc != 0 {
  1539  		newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, pcsym)
  1540  	}
  1541  
  1542  	if unitstart >= 0 {
  1543  		Cput(0) // start extended opcode
  1544  		uleb128put(1)
  1545  		Cput(DW_LNE_end_sequence)
  1546  
  1547  		here := Cpos()
  1548  		Cseek(unitstart)
  1549  		Thearch.Lput(uint32(here - unitstart - 4)) // unit_length
  1550  		Thearch.Wput(2)                            // dwarf version
  1551  		Thearch.Lput(uint32(header_length))        // header length starting here
  1552  		Cseek(here)
  1553  	}
  1554  }
  1555  
  1556  func writelines() {
  1557  	if linesec == nil {
  1558  		linesec = Linklookup(Ctxt, ".dwarfline", 0)
  1559  	}
  1560  	linesec.R = linesec.R[:0]
  1561  
  1562  	unitstart := int64(-1)
  1563  	headerend := int64(-1)
  1564  	epc := int64(0)
  1565  	var epcs *LSym
  1566  	lineo = Cpos()
  1567  	var dwinfo *DWDie
  1568  
  1569  	flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10))
  1570  	unitstart = Cpos()
  1571  
  1572  	lang := DW_LANG_Go
  1573  
  1574  	s := Ctxt.Textp
  1575  
  1576  	dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, "go")
  1577  	newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(lang), 0)
  1578  	newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart-lineo, 0)
  1579  	newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
  1580  
  1581  	// Write .debug_line Line Number Program Header (sec 6.2.4)
  1582  	// Fields marked with (*) must be changed for 64-bit dwarf
  1583  	Thearch.Lput(0) // unit_length (*), will be filled in by flushunit.
  1584  	Thearch.Wput(2) // dwarf version (appendix F)
  1585  	Thearch.Lput(0) // header_length (*), filled in by flushunit.
  1586  
  1587  	// cpos == unitstart + 4 + 2 + 4
  1588  	Cput(1)                // minimum_instruction_length
  1589  	Cput(1)                // default_is_stmt
  1590  	Cput(LINE_BASE & 0xFF) // line_base
  1591  	Cput(LINE_RANGE)       // line_range
  1592  	Cput(OPCODE_BASE)      // opcode_base
  1593  	Cput(0)                // standard_opcode_lengths[1]
  1594  	Cput(1)                // standard_opcode_lengths[2]
  1595  	Cput(1)                // standard_opcode_lengths[3]
  1596  	Cput(1)                // standard_opcode_lengths[4]
  1597  	Cput(1)                // standard_opcode_lengths[5]
  1598  	Cput(0)                // standard_opcode_lengths[6]
  1599  	Cput(0)                // standard_opcode_lengths[7]
  1600  	Cput(0)                // standard_opcode_lengths[8]
  1601  	Cput(1)                // standard_opcode_lengths[9]
  1602  	Cput(0)                // include_directories  (empty)
  1603  
  1604  	files := make([]*LSym, Ctxt.Nhistfile)
  1605  
  1606  	for f := Ctxt.Filesyms; f != nil; f = f.Next {
  1607  		files[f.Value-1] = f
  1608  	}
  1609  
  1610  	for i := 0; int32(i) < Ctxt.Nhistfile; i++ {
  1611  		strnput(files[i].Name, len(files[i].Name)+4)
  1612  	}
  1613  
  1614  	// 4 zeros: the string termination + 3 fields.
  1615  	Cput(0)
  1616  	// terminate file_names.
  1617  	headerend = Cpos()
  1618  
  1619  	Cput(0) // start extended opcode
  1620  	uleb128put(1 + int64(Thearch.Ptrsize))
  1621  	Cput(DW_LNE_set_address)
  1622  
  1623  	pc := s.Value
  1624  	line := 1
  1625  	file := 1
  1626  	if Linkmode == LinkExternal {
  1627  		adddwarfrel(linesec, s, lineo, Thearch.Ptrsize, 0)
  1628  	} else {
  1629  		addrput(pc)
  1630  	}
  1631  
  1632  	var a *Auto
  1633  	var da int
  1634  	var dt int
  1635  	var dwfunc *DWDie
  1636  	var dws **DWDie
  1637  	var dwvar *DWDie
  1638  	var n string
  1639  	var nn string
  1640  	var offs int64
  1641  	var pcfile Pciter
  1642  	var pcline Pciter
  1643  	var varhash [HASHSIZE]*DWDie
  1644  	for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
  1645  		s = Ctxt.Cursym
  1646  
  1647  		dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s.Name)
  1648  		newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
  1649  		epc = s.Value + s.Size
  1650  		epcs = s
  1651  		newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, s)
  1652  		if s.Version == 0 {
  1653  			newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0)
  1654  		}
  1655  
  1656  		if s.Pcln == nil {
  1657  			continue
  1658  		}
  1659  
  1660  		finddebugruntimepath(s)
  1661  
  1662  		pciterinit(Ctxt, &pcfile, &s.Pcln.Pcfile)
  1663  		pciterinit(Ctxt, &pcline, &s.Pcln.Pcline)
  1664  		epc = pc
  1665  		for pcfile.done == 0 && pcline.done == 0 {
  1666  			if epc-s.Value >= int64(pcfile.nextpc) {
  1667  				pciternext(&pcfile)
  1668  				continue
  1669  			}
  1670  
  1671  			if epc-s.Value >= int64(pcline.nextpc) {
  1672  				pciternext(&pcline)
  1673  				continue
  1674  			}
  1675  
  1676  			if int32(file) != pcfile.value {
  1677  				Cput(DW_LNS_set_file)
  1678  				uleb128put(int64(pcfile.value))
  1679  				file = int(pcfile.value)
  1680  			}
  1681  
  1682  			putpclcdelta(s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line))
  1683  
  1684  			pc = s.Value + int64(pcline.pc)
  1685  			line = int(pcline.value)
  1686  			if pcfile.nextpc < pcline.nextpc {
  1687  				epc = int64(pcfile.nextpc)
  1688  			} else {
  1689  				epc = int64(pcline.nextpc)
  1690  			}
  1691  			epc += s.Value
  1692  		}
  1693  
  1694  		da = 0
  1695  		dwfunc.hash = varhash[:] // enable indexing of children by name
  1696  		varhash = [HASHSIZE]*DWDie{}
  1697  		for a = s.Autom; a != nil; a = a.Link {
  1698  			switch a.Name {
  1699  			case A_AUTO:
  1700  				dt = DW_ABRV_AUTO
  1701  				offs = int64(a.Aoffset) - int64(Thearch.Ptrsize)
  1702  
  1703  			case A_PARAM:
  1704  				dt = DW_ABRV_PARAM
  1705  				offs = int64(a.Aoffset)
  1706  
  1707  			default:
  1708  				continue
  1709  			}
  1710  
  1711  			if strings.Contains(a.Asym.Name, ".autotmp_") {
  1712  				continue
  1713  			}
  1714  			if find(dwfunc, a.Asym.Name) != nil {
  1715  				n = mkvarname(a.Asym.Name, da)
  1716  			} else {
  1717  				n = a.Asym.Name
  1718  			}
  1719  
  1720  			// Drop the package prefix from locals and arguments.
  1721  			_ = nn
  1722  			if i := strings.LastIndex(n, "."); i >= 0 {
  1723  				n = n[i+1:]
  1724  			}
  1725  
  1726  			dwvar = newdie(dwfunc, dt, n)
  1727  			newcfaoffsetattr(dwvar, int32(offs))
  1728  			newrefattr(dwvar, DW_AT_type, defgotype(a.Gotype))
  1729  
  1730  			// push dwvar down dwfunc->child to preserve order
  1731  			newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil)
  1732  
  1733  			dwfunc.child = dwvar.link // take dwvar out from the top of the list
  1734  			for dws = &dwfunc.child; *dws != nil; dws = &(*dws).link {
  1735  				if offs > getattr(*dws, DW_AT_internal_location).value {
  1736  					break
  1737  				}
  1738  			}
  1739  			dwvar.link = *dws
  1740  			*dws = dwvar
  1741  
  1742  			da++
  1743  		}
  1744  
  1745  		dwfunc.hash = nil
  1746  	}
  1747  
  1748  	flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10))
  1749  	linesize = Cpos() - lineo
  1750  }
  1751  
  1752  /*
  1753   *  Emit .debug_frame
  1754   */
  1755  const (
  1756  	CIERESERVE          = 16
  1757  	DATAALIGNMENTFACTOR = -4
  1758  	FAKERETURNCOLUMN    = 16 // TODO gdb6 doesn't like > 15?
  1759  )
  1760  
  1761  func putpccfadelta(deltapc int64, cfa int64) {
  1762  	Cput(DW_CFA_def_cfa_offset_sf)
  1763  	sleb128put(cfa / DATAALIGNMENTFACTOR)
  1764  
  1765  	if deltapc < 0x40 {
  1766  		Cput(uint8(DW_CFA_advance_loc + deltapc))
  1767  	} else if deltapc < 0x100 {
  1768  		Cput(DW_CFA_advance_loc1)
  1769  		Cput(uint8(deltapc))
  1770  	} else if deltapc < 0x10000 {
  1771  		Cput(DW_CFA_advance_loc2)
  1772  		Thearch.Wput(uint16(deltapc))
  1773  	} else {
  1774  		Cput(DW_CFA_advance_loc4)
  1775  		Thearch.Lput(uint32(deltapc))
  1776  	}
  1777  }
  1778  
  1779  func writeframes() {
  1780  	if framesec == nil {
  1781  		framesec = Linklookup(Ctxt, ".dwarfframe", 0)
  1782  	}
  1783  	framesec.R = framesec.R[:0]
  1784  	frameo = Cpos()
  1785  
  1786  	// Emit the CIE, Section 6.4.1
  1787  	Thearch.Lput(CIERESERVE)        // initial length, must be multiple of thearch.ptrsize
  1788  	Thearch.Lput(0xffffffff)        // cid.
  1789  	Cput(3)                         // dwarf version (appendix F)
  1790  	Cput(0)                         // augmentation ""
  1791  	uleb128put(1)                   // code_alignment_factor
  1792  	sleb128put(DATAALIGNMENTFACTOR) // guess
  1793  	uleb128put(FAKERETURNCOLUMN)    // return_address_register
  1794  
  1795  	Cput(DW_CFA_def_cfa)
  1796  
  1797  	uleb128put(int64(Thearch.Dwarfregsp)) // register SP (**ABI-dependent, defined in l.h)
  1798  	uleb128put(int64(Thearch.Ptrsize))    // offset
  1799  
  1800  	Cput(DW_CFA_offset + FAKERETURNCOLUMN)                    // return address
  1801  	uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4
  1802  
  1803  	// 4 is to exclude the length field.
  1804  	pad := CIERESERVE + frameo + 4 - Cpos()
  1805  
  1806  	if pad < 0 {
  1807  		Diag("dwarf: CIERESERVE too small by %d bytes.", -pad)
  1808  		Errorexit()
  1809  	}
  1810  
  1811  	strnput("", int(pad))
  1812  
  1813  	var fdeo int64
  1814  	var fdesize int64
  1815  	var nextpc uint32
  1816  	var pcsp Pciter
  1817  	var s *LSym
  1818  	for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
  1819  		s = Ctxt.Cursym
  1820  		if s.Pcln == nil {
  1821  			continue
  1822  		}
  1823  
  1824  		fdeo = Cpos()
  1825  
  1826  		// Emit a FDE, Section 6.4.1, starting wit a placeholder.
  1827  		Thearch.Lput(0) // length, must be multiple of thearch.ptrsize
  1828  		Thearch.Lput(0) // Pointer to the CIE above, at offset 0
  1829  		addrput(0)      // initial location
  1830  		addrput(0)      // address range
  1831  
  1832  		for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
  1833  			nextpc = pcsp.nextpc
  1834  
  1835  			// pciterinit goes up to the end of the function,
  1836  			// but DWARF expects us to stop just before the end.
  1837  			if int64(nextpc) == s.Size {
  1838  				nextpc--
  1839  				if nextpc < pcsp.pc {
  1840  					continue
  1841  				}
  1842  			}
  1843  
  1844  			putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value))
  1845  		}
  1846  
  1847  		fdesize = Cpos() - fdeo - 4 // exclude the length field.
  1848  		pad = Rnd(fdesize, int64(Thearch.Ptrsize)) - fdesize
  1849  		strnput("", int(pad))
  1850  		fdesize += pad
  1851  
  1852  		// Emit the FDE header for real, Section 6.4.1.
  1853  		Cseek(fdeo)
  1854  
  1855  		Thearch.Lput(uint32(fdesize))
  1856  		if Linkmode == LinkExternal {
  1857  			adddwarfrel(framesec, framesym, frameo, 4, 0)
  1858  			adddwarfrel(framesec, s, frameo, Thearch.Ptrsize, 0)
  1859  		} else {
  1860  			Thearch.Lput(0)
  1861  			addrput(s.Value)
  1862  		}
  1863  
  1864  		addrput(s.Size)
  1865  		Cseek(fdeo + 4 + fdesize)
  1866  	}
  1867  
  1868  	Cflush()
  1869  	framesize = Cpos() - frameo
  1870  }
  1871  
  1872  /*
  1873   *  Walk DWarfDebugInfoEntries, and emit .debug_info
  1874   */
  1875  const (
  1876  	COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
  1877  )
  1878  
  1879  func writeinfo() {
  1880  	fwdcount = 0
  1881  	if infosec == nil {
  1882  		infosec = Linklookup(Ctxt, ".dwarfinfo", 0)
  1883  	}
  1884  	infosec.R = infosec.R[:0]
  1885  
  1886  	if arangessec == nil {
  1887  		arangessec = Linklookup(Ctxt, ".dwarfaranges", 0)
  1888  	}
  1889  	arangessec.R = arangessec.R[:0]
  1890  
  1891  	var here int64
  1892  	var unitstart int64
  1893  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1894  		unitstart = Cpos()
  1895  
  1896  		// Write .debug_info Compilation Unit Header (sec 7.5.1)
  1897  		// Fields marked with (*) must be changed for 64-bit dwarf
  1898  		// This must match COMPUNITHEADERSIZE above.
  1899  		Thearch.Lput(0) // unit_length (*), will be filled in later.
  1900  		Thearch.Wput(2) // dwarf version (appendix F)
  1901  
  1902  		// debug_abbrev_offset (*)
  1903  		if Linkmode == LinkExternal {
  1904  			adddwarfrel(infosec, abbrevsym, infoo, 4, 0)
  1905  		} else {
  1906  			Thearch.Lput(0)
  1907  		}
  1908  
  1909  		Cput(uint8(Thearch.Ptrsize)) // address_size
  1910  
  1911  		putdie(compunit)
  1912  
  1913  		here = Cpos()
  1914  		Cseek(unitstart)
  1915  		Thearch.Lput(uint32(here - unitstart - 4)) // exclude the length field.
  1916  		Cseek(here)
  1917  	}
  1918  
  1919  	Cflush()
  1920  }
  1921  
  1922  /*
  1923   *  Emit .debug_pubnames/_types.  _info must have been written before,
  1924   *  because we need die->offs and infoo/infosize;
  1925   */
  1926  func ispubname(die *DWDie) bool {
  1927  	switch die.abbrev {
  1928  	case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE:
  1929  		a := getattr(die, DW_AT_external)
  1930  		return a != nil && a.value != 0
  1931  	}
  1932  
  1933  	return false
  1934  }
  1935  
  1936  func ispubtype(die *DWDie) bool {
  1937  	return die.abbrev >= DW_ABRV_NULLTYPE
  1938  }
  1939  
  1940  func writepub(ispub func(*DWDie) bool) int64 {
  1941  	var die *DWDie
  1942  	var dwa *DWAttr
  1943  	var unitstart int64
  1944  	var unitend int64
  1945  	var here int64
  1946  
  1947  	sectionstart := Cpos()
  1948  
  1949  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1950  		unitstart = compunit.offs - COMPUNITHEADERSIZE
  1951  		if compunit.link != nil {
  1952  			unitend = compunit.link.offs - COMPUNITHEADERSIZE
  1953  		} else {
  1954  			unitend = infoo + infosize
  1955  		}
  1956  
  1957  		// Write .debug_pubnames/types	Header (sec 6.1.1)
  1958  		Thearch.Lput(0)                           // unit_length (*), will be filled in later.
  1959  		Thearch.Wput(2)                           // dwarf version (appendix F)
  1960  		Thearch.Lput(uint32(unitstart))           // debug_info_offset (of the Comp unit Header)
  1961  		Thearch.Lput(uint32(unitend - unitstart)) // debug_info_length
  1962  
  1963  		for die = compunit.child; die != nil; die = die.link {
  1964  			if !ispub(die) {
  1965  				continue
  1966  			}
  1967  			Thearch.Lput(uint32(die.offs - unitstart))
  1968  			dwa = getattr(die, DW_AT_name)
  1969  			strnput(dwa.data.(string), int(dwa.value+1))
  1970  		}
  1971  
  1972  		Thearch.Lput(0)
  1973  
  1974  		here = Cpos()
  1975  		Cseek(sectionstart)
  1976  		Thearch.Lput(uint32(here - sectionstart - 4)) // exclude the length field.
  1977  		Cseek(here)
  1978  	}
  1979  
  1980  	return sectionstart
  1981  }
  1982  
  1983  /*
  1984   *  emit .debug_aranges.  _info must have been written before,
  1985   *  because we need die->offs of dw_globals.
  1986   */
  1987  func writearanges() int64 {
  1988  	var b *DWAttr
  1989  	var e *DWAttr
  1990  	var value int64
  1991  
  1992  	sectionstart := Cpos()
  1993  	headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize))) // don't count unit_length field itself
  1994  
  1995  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1996  		b = getattr(compunit, DW_AT_low_pc)
  1997  		if b == nil {
  1998  			continue
  1999  		}
  2000  		e = getattr(compunit, DW_AT_high_pc)
  2001  		if e == nil {
  2002  			continue
  2003  		}
  2004  
  2005  		// Write .debug_aranges	 Header + entry	 (sec 6.1.2)
  2006  		Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*)
  2007  		Thearch.Wput(2)                                                  // dwarf version (appendix F)
  2008  
  2009  		value = compunit.offs - COMPUNITHEADERSIZE // debug_info_offset
  2010  		if Linkmode == LinkExternal {
  2011  			adddwarfrel(arangessec, infosym, sectionstart, 4, value)
  2012  		} else {
  2013  			Thearch.Lput(uint32(value))
  2014  		}
  2015  
  2016  		Cput(uint8(Thearch.Ptrsize))        // address_size
  2017  		Cput(0)                             // segment_size
  2018  		strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize
  2019  
  2020  		if Linkmode == LinkExternal {
  2021  			adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value)
  2022  		} else {
  2023  			addrput(b.value)
  2024  		}
  2025  
  2026  		addrput(e.value - b.value)
  2027  		addrput(0)
  2028  		addrput(0)
  2029  	}
  2030  
  2031  	Cflush()
  2032  	return sectionstart
  2033  }
  2034  
  2035  func writegdbscript() int64 {
  2036  	sectionstart := Cpos()
  2037  
  2038  	if gdbscript != "" {
  2039  		Cput(1) // magic 1 byte?
  2040  		strnput(gdbscript, len(gdbscript)+1)
  2041  		Cflush()
  2042  	}
  2043  
  2044  	return sectionstart
  2045  }
  2046  
  2047  func align(size int64) {
  2048  	if HEADTYPE == Hwindows { // Only Windows PE need section align.
  2049  		strnput("", int(Rnd(size, PEFILEALIGN)-size))
  2050  	}
  2051  }
  2052  
  2053  func writedwarfreloc(s *LSym) int64 {
  2054  	var i int
  2055  	var r *Reloc
  2056  
  2057  	start := Cpos()
  2058  	for ri := 0; ri < len(s.R); ri++ {
  2059  		r = &s.R[ri]
  2060  		if Iself {
  2061  			i = Thearch.Elfreloc1(r, int64(r.Off))
  2062  		} else if HEADTYPE == Hdarwin {
  2063  			i = Thearch.Machoreloc1(r, int64(r.Off))
  2064  		} else {
  2065  			i = -1
  2066  		}
  2067  		if i < 0 {
  2068  			Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
  2069  		}
  2070  	}
  2071  
  2072  	return start
  2073  }
  2074  
  2075  /*
  2076   * This is the main entry point for generating dwarf.  After emitting
  2077   * the mandatory debug_abbrev section, it calls writelines() to set up
  2078   * the per-compilation unit part of the DIE tree, while simultaneously
  2079   * emitting the debug_line section.  When the final tree contains
  2080   * forward references, it will write the debug_info section in 2
  2081   * passes.
  2082   *
  2083   */
  2084  func Dwarfemitdebugsections() {
  2085  	if Debug['w'] != 0 { // disable dwarf
  2086  		return
  2087  	}
  2088  
  2089  	if Linkmode == LinkExternal && !Iself {
  2090  		return
  2091  	}
  2092  
  2093  	// For diagnostic messages.
  2094  	newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes")
  2095  
  2096  	mkindex(&dwroot)
  2097  	mkindex(&dwtypes)
  2098  	mkindex(&dwglobals)
  2099  
  2100  	// Some types that must exist to define other ones.
  2101  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>")
  2102  
  2103  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "void")
  2104  	newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer")
  2105  
  2106  	die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr") // needed for array size
  2107  	newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
  2108  	newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0)
  2109  	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0)
  2110  
  2111  	// Needed by the prettyprinter code for interface inspection.
  2112  	defgotype(lookup_or_diag("type.runtime._type"))
  2113  
  2114  	defgotype(lookup_or_diag("type.runtime.interfacetype"))
  2115  	defgotype(lookup_or_diag("type.runtime.itab"))
  2116  
  2117  	genasmsym(defdwsymb)
  2118  
  2119  	writeabbrev()
  2120  	align(abbrevsize)
  2121  	writelines()
  2122  	align(linesize)
  2123  	writeframes()
  2124  	align(framesize)
  2125  
  2126  	synthesizestringtypes(dwtypes.child)
  2127  	synthesizeslicetypes(dwtypes.child)
  2128  	synthesizemaptypes(dwtypes.child)
  2129  	synthesizechantypes(dwtypes.child)
  2130  
  2131  	reversetree(&dwroot.child)
  2132  	reversetree(&dwtypes.child)
  2133  	reversetree(&dwglobals.child)
  2134  
  2135  	movetomodule(&dwtypes)
  2136  	movetomodule(&dwglobals)
  2137  
  2138  	infoo = Cpos()
  2139  	writeinfo()
  2140  	infoe := Cpos()
  2141  	pubnameso = infoe
  2142  	pubtypeso = infoe
  2143  	arangeso = infoe
  2144  	gdbscripto = infoe
  2145  
  2146  	if fwdcount > 0 {
  2147  		if Debug['v'] != 0 {
  2148  			fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime())
  2149  		}
  2150  		Cseek(infoo)
  2151  		writeinfo()
  2152  		if fwdcount > 0 {
  2153  			Diag("dwarf: unresolved references after first dwarf info pass")
  2154  			Errorexit()
  2155  		}
  2156  
  2157  		if infoe != Cpos() {
  2158  			Diag("dwarf: inconsistent second dwarf info pass")
  2159  			Errorexit()
  2160  		}
  2161  	}
  2162  
  2163  	infosize = infoe - infoo
  2164  	align(infosize)
  2165  
  2166  	pubnameso = writepub(ispubname)
  2167  	pubnamessize = Cpos() - pubnameso
  2168  	align(pubnamessize)
  2169  
  2170  	pubtypeso = writepub(ispubtype)
  2171  	pubtypessize = Cpos() - pubtypeso
  2172  	align(pubtypessize)
  2173  
  2174  	arangeso = writearanges()
  2175  	arangessize = Cpos() - arangeso
  2176  	align(arangessize)
  2177  
  2178  	gdbscripto = writegdbscript()
  2179  	gdbscriptsize = Cpos() - gdbscripto
  2180  	align(gdbscriptsize)
  2181  
  2182  	for Cpos()&7 != 0 {
  2183  		Cput(0)
  2184  	}
  2185  	inforeloco = writedwarfreloc(infosec)
  2186  	inforelocsize = Cpos() - inforeloco
  2187  	align(inforelocsize)
  2188  
  2189  	arangesreloco = writedwarfreloc(arangessec)
  2190  	arangesrelocsize = Cpos() - arangesreloco
  2191  	align(arangesrelocsize)
  2192  
  2193  	linereloco = writedwarfreloc(linesec)
  2194  	linerelocsize = Cpos() - linereloco
  2195  	align(linerelocsize)
  2196  
  2197  	framereloco = writedwarfreloc(framesec)
  2198  	framerelocsize = Cpos() - framereloco
  2199  	align(framerelocsize)
  2200  }
  2201  
  2202  /*
  2203   *  Elf.
  2204   */
  2205  const (
  2206  	ElfStrDebugAbbrev = iota
  2207  	ElfStrDebugAranges
  2208  	ElfStrDebugFrame
  2209  	ElfStrDebugInfo
  2210  	ElfStrDebugLine
  2211  	ElfStrDebugLoc
  2212  	ElfStrDebugMacinfo
  2213  	ElfStrDebugPubNames
  2214  	ElfStrDebugPubTypes
  2215  	ElfStrDebugRanges
  2216  	ElfStrDebugStr
  2217  	ElfStrGDBScripts
  2218  	ElfStrRelDebugInfo
  2219  	ElfStrRelDebugAranges
  2220  	ElfStrRelDebugLine
  2221  	ElfStrRelDebugFrame
  2222  	NElfStrDbg
  2223  )
  2224  
  2225  var elfstrdbg [NElfStrDbg]int64
  2226  
  2227  func dwarfaddshstrings(shstrtab *LSym) {
  2228  	if Debug['w'] != 0 { // disable dwarf
  2229  		return
  2230  	}
  2231  
  2232  	elfstrdbg[ElfStrDebugAbbrev] = Addstring(shstrtab, ".debug_abbrev")
  2233  	elfstrdbg[ElfStrDebugAranges] = Addstring(shstrtab, ".debug_aranges")
  2234  	elfstrdbg[ElfStrDebugFrame] = Addstring(shstrtab, ".debug_frame")
  2235  	elfstrdbg[ElfStrDebugInfo] = Addstring(shstrtab, ".debug_info")
  2236  	elfstrdbg[ElfStrDebugLine] = Addstring(shstrtab, ".debug_line")
  2237  	elfstrdbg[ElfStrDebugLoc] = Addstring(shstrtab, ".debug_loc")
  2238  	elfstrdbg[ElfStrDebugMacinfo] = Addstring(shstrtab, ".debug_macinfo")
  2239  	elfstrdbg[ElfStrDebugPubNames] = Addstring(shstrtab, ".debug_pubnames")
  2240  	elfstrdbg[ElfStrDebugPubTypes] = Addstring(shstrtab, ".debug_pubtypes")
  2241  	elfstrdbg[ElfStrDebugRanges] = Addstring(shstrtab, ".debug_ranges")
  2242  	elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str")
  2243  	elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts")
  2244  	if Linkmode == LinkExternal {
  2245  		switch Thearch.Thechar {
  2246  		case '6', '7', '9':
  2247  			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info")
  2248  			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges")
  2249  			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line")
  2250  			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame")
  2251  		default:
  2252  			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info")
  2253  			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges")
  2254  			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line")
  2255  			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rel.debug_frame")
  2256  		}
  2257  
  2258  		infosym = Linklookup(Ctxt, ".debug_info", 0)
  2259  		infosym.Hide = 1
  2260  
  2261  		abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
  2262  		abbrevsym.Hide = 1
  2263  
  2264  		linesym = Linklookup(Ctxt, ".debug_line", 0)
  2265  		linesym.Hide = 1
  2266  
  2267  		framesym = Linklookup(Ctxt, ".debug_frame", 0)
  2268  		framesym.Hide = 1
  2269  	}
  2270  }
  2271  
  2272  // Add section symbols for DWARF debug info.  This is called before
  2273  // dwarfaddelfheaders.
  2274  func dwarfaddelfsectionsyms() {
  2275  	if infosym != nil {
  2276  		infosympos = Cpos()
  2277  		putelfsectionsym(infosym, 0)
  2278  	}
  2279  
  2280  	if abbrevsym != nil {
  2281  		abbrevsympos = Cpos()
  2282  		putelfsectionsym(abbrevsym, 0)
  2283  	}
  2284  
  2285  	if linesym != nil {
  2286  		linesympos = Cpos()
  2287  		putelfsectionsym(linesym, 0)
  2288  	}
  2289  
  2290  	if framesym != nil {
  2291  		framesympos = Cpos()
  2292  		putelfsectionsym(framesym, 0)
  2293  	}
  2294  }
  2295  
  2296  func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) {
  2297  	sh := newElfShdr(elfstrdbg[elfstr])
  2298  	switch Thearch.Thechar {
  2299  	case '6', '7', '9':
  2300  		sh.type_ = SHT_RELA
  2301  	default:
  2302  		sh.type_ = SHT_REL
  2303  	}
  2304  
  2305  	sh.entsize = uint64(Thearch.Ptrsize) * 2
  2306  	if sh.type_ == SHT_RELA {
  2307  		sh.entsize += uint64(Thearch.Ptrsize)
  2308  	}
  2309  	sh.link = uint32(elfshname(".symtab").shnum)
  2310  	sh.info = uint32(shdata.shnum)
  2311  	sh.off = uint64(off)
  2312  	sh.size = uint64(size)
  2313  	sh.addralign = uint64(Thearch.Ptrsize)
  2314  }
  2315  
  2316  func dwarfaddelfheaders() {
  2317  	if Debug['w'] != 0 { // disable dwarf
  2318  		return
  2319  	}
  2320  
  2321  	sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev])
  2322  	sh.type_ = SHT_PROGBITS
  2323  	sh.off = uint64(abbrevo)
  2324  	sh.size = uint64(abbrevsize)
  2325  	sh.addralign = 1
  2326  	if abbrevsympos > 0 {
  2327  		putelfsymshndx(abbrevsympos, sh.shnum)
  2328  	}
  2329  
  2330  	sh = newElfShdr(elfstrdbg[ElfStrDebugLine])
  2331  	sh.type_ = SHT_PROGBITS
  2332  	sh.off = uint64(lineo)
  2333  	sh.size = uint64(linesize)
  2334  	sh.addralign = 1
  2335  	if linesympos > 0 {
  2336  		putelfsymshndx(linesympos, sh.shnum)
  2337  	}
  2338  	shline := sh
  2339  
  2340  	sh = newElfShdr(elfstrdbg[ElfStrDebugFrame])
  2341  	sh.type_ = SHT_PROGBITS
  2342  	sh.off = uint64(frameo)
  2343  	sh.size = uint64(framesize)
  2344  	sh.addralign = 1
  2345  	if framesympos > 0 {
  2346  		putelfsymshndx(framesympos, sh.shnum)
  2347  	}
  2348  	shframe := sh
  2349  
  2350  	sh = newElfShdr(elfstrdbg[ElfStrDebugInfo])
  2351  	sh.type_ = SHT_PROGBITS
  2352  	sh.off = uint64(infoo)
  2353  	sh.size = uint64(infosize)
  2354  	sh.addralign = 1
  2355  	if infosympos > 0 {
  2356  		putelfsymshndx(infosympos, sh.shnum)
  2357  	}
  2358  	shinfo := sh
  2359  
  2360  	if pubnamessize > 0 {
  2361  		sh := newElfShdr(elfstrdbg[ElfStrDebugPubNames])
  2362  		sh.type_ = SHT_PROGBITS
  2363  		sh.off = uint64(pubnameso)
  2364  		sh.size = uint64(pubnamessize)
  2365  		sh.addralign = 1
  2366  	}
  2367  
  2368  	if pubtypessize > 0 {
  2369  		sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes])
  2370  		sh.type_ = SHT_PROGBITS
  2371  		sh.off = uint64(pubtypeso)
  2372  		sh.size = uint64(pubtypessize)
  2373  		sh.addralign = 1
  2374  	}
  2375  
  2376  	var sharanges *ElfShdr
  2377  	if arangessize != 0 {
  2378  		sh := newElfShdr(elfstrdbg[ElfStrDebugAranges])
  2379  		sh.type_ = SHT_PROGBITS
  2380  		sh.off = uint64(arangeso)
  2381  		sh.size = uint64(arangessize)
  2382  		sh.addralign = 1
  2383  		sharanges = sh
  2384  	}
  2385  
  2386  	if gdbscriptsize != 0 {
  2387  		sh := newElfShdr(elfstrdbg[ElfStrGDBScripts])
  2388  		sh.type_ = SHT_PROGBITS
  2389  		sh.off = uint64(gdbscripto)
  2390  		sh.size = uint64(gdbscriptsize)
  2391  		sh.addralign = 1
  2392  	}
  2393  
  2394  	if inforelocsize != 0 {
  2395  		dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize)
  2396  	}
  2397  
  2398  	if arangesrelocsize != 0 {
  2399  		dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize)
  2400  	}
  2401  
  2402  	if linerelocsize != 0 {
  2403  		dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize)
  2404  	}
  2405  
  2406  	if framerelocsize != 0 {
  2407  		dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize)
  2408  	}
  2409  }
  2410  
  2411  /*
  2412   * Macho
  2413   */
  2414  func dwarfaddmachoheaders() {
  2415  	if Debug['w'] != 0 { // disable dwarf
  2416  		return
  2417  	}
  2418  
  2419  	// Zero vsize segments won't be loaded in memory, even so they
  2420  	// have to be page aligned in the file.
  2421  	fakestart := abbrevo &^ 0xfff
  2422  
  2423  	nsect := 4
  2424  	if pubnamessize > 0 {
  2425  		nsect++
  2426  	}
  2427  	if pubtypessize > 0 {
  2428  		nsect++
  2429  	}
  2430  	if arangessize > 0 {
  2431  		nsect++
  2432  	}
  2433  	if gdbscriptsize > 0 {
  2434  		nsect++
  2435  	}
  2436  
  2437  	ms := newMachoSeg("__DWARF", nsect)
  2438  	ms.fileoffset = uint64(fakestart)
  2439  	ms.filesize = uint64(abbrevo) - uint64(fakestart)
  2440  	ms.vaddr = ms.fileoffset + Segdata.Vaddr - Segdata.Fileoff
  2441  
  2442  	msect := newMachoSect(ms, "__debug_abbrev", "__DWARF")
  2443  	msect.off = uint32(abbrevo)
  2444  	msect.size = uint64(abbrevsize)
  2445  	msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff
  2446  	ms.filesize += msect.size
  2447  
  2448  	msect = newMachoSect(ms, "__debug_line", "__DWARF")
  2449  	msect.off = uint32(lineo)
  2450  	msect.size = uint64(linesize)
  2451  	msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff
  2452  	ms.filesize += msect.size
  2453  
  2454  	msect = newMachoSect(ms, "__debug_frame", "__DWARF")
  2455  	msect.off = uint32(frameo)
  2456  	msect.size = uint64(framesize)
  2457  	msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff
  2458  	ms.filesize += msect.size
  2459  
  2460  	msect = newMachoSect(ms, "__debug_info", "__DWARF")
  2461  	msect.off = uint32(infoo)
  2462  	msect.size = uint64(infosize)
  2463  	msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff
  2464  	ms.filesize += msect.size
  2465  
  2466  	if pubnamessize > 0 {
  2467  		msect := newMachoSect(ms, "__debug_pubnames", "__DWARF")
  2468  		msect.off = uint32(pubnameso)
  2469  		msect.size = uint64(pubnamessize)
  2470  		msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff
  2471  		ms.filesize += msect.size
  2472  	}
  2473  
  2474  	if pubtypessize > 0 {
  2475  		msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF")
  2476  		msect.off = uint32(pubtypeso)
  2477  		msect.size = uint64(pubtypessize)
  2478  		msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff
  2479  		ms.filesize += msect.size
  2480  	}
  2481  
  2482  	if arangessize > 0 {
  2483  		msect := newMachoSect(ms, "__debug_aranges", "__DWARF")
  2484  		msect.off = uint32(arangeso)
  2485  		msect.size = uint64(arangessize)
  2486  		msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff
  2487  		ms.filesize += msect.size
  2488  	}
  2489  
  2490  	// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
  2491  	if gdbscriptsize > 0 {
  2492  		msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF")
  2493  		msect.off = uint32(gdbscripto)
  2494  		msect.size = uint64(gdbscriptsize)
  2495  		msect.addr = uint64(msect.off) + Segdata.Vaddr - Segdata.Fileoff
  2496  		ms.filesize += msect.size
  2497  	}
  2498  }
  2499  
  2500  /*
  2501   * Windows PE
  2502   */
  2503  func dwarfaddpeheaders() {
  2504  	if Debug['w'] != 0 { // disable dwarf
  2505  		return
  2506  	}
  2507  
  2508  	newPEDWARFSection(".debug_abbrev", abbrevsize)
  2509  	newPEDWARFSection(".debug_line", linesize)
  2510  	newPEDWARFSection(".debug_frame", framesize)
  2511  	newPEDWARFSection(".debug_info", infosize)
  2512  	newPEDWARFSection(".debug_pubnames", pubnamessize)
  2513  	newPEDWARFSection(".debug_pubtypes", pubtypessize)
  2514  	newPEDWARFSection(".debug_aranges", arangessize)
  2515  	newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize)
  2516  }