github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/src/cmd/link/internal/ld/dwarf.go (about)

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