github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/ld/dwarf.go (about)

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