github.com/huandu/go@v0.0.0-20151114150818-04e615e41150/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._string")))
  1191  	if prototype == nil {
  1192  		return
  1193  	}
  1194  
  1195  	for ; die != nil; die = die.link {
  1196  		if die.abbrev != DW_ABRV_STRINGTYPE {
  1197  			continue
  1198  		}
  1199  		copychildren(die, prototype)
  1200  	}
  1201  }
  1202  
  1203  func synthesizeslicetypes(die *DWDie) {
  1204  	prototype := walktypedef(defgotype(lookup_or_diag("type.runtime.slice")))
  1205  	if prototype == nil {
  1206  		return
  1207  	}
  1208  
  1209  	var elem *DWDie
  1210  	for ; die != nil; die = die.link {
  1211  		if die.abbrev != DW_ABRV_SLICETYPE {
  1212  			continue
  1213  		}
  1214  		copychildren(die, prototype)
  1215  		elem = getattr(die, DW_AT_go_elem).data.(*DWDie)
  1216  		substitutetype(die, "array", defptrto(elem))
  1217  	}
  1218  }
  1219  
  1220  func mkinternaltypename(base string, arg1 string, arg2 string) string {
  1221  	var buf string
  1222  
  1223  	if arg2 == "" {
  1224  		buf = fmt.Sprintf("%s<%s>", base, arg1)
  1225  	} else {
  1226  		buf = fmt.Sprintf("%s<%s,%s>", base, arg1, arg2)
  1227  	}
  1228  	n := buf
  1229  	return n
  1230  }
  1231  
  1232  // synthesizemaptypes is way too closely married to runtime/hashmap.c
  1233  const (
  1234  	MaxKeySize = 128
  1235  	MaxValSize = 128
  1236  	BucketSize = 8
  1237  )
  1238  
  1239  func synthesizemaptypes(die *DWDie) {
  1240  	hash := walktypedef(defgotype(lookup_or_diag("type.runtime.hmap")))
  1241  	bucket := walktypedef(defgotype(lookup_or_diag("type.runtime.bmap")))
  1242  
  1243  	if hash == nil {
  1244  		return
  1245  	}
  1246  
  1247  	var a *DWAttr
  1248  	var dwh *DWDie
  1249  	var dwhb *DWDie
  1250  	var dwhk *DWDie
  1251  	var dwhv *DWDie
  1252  	var fld *DWDie
  1253  	var indirect_key int
  1254  	var indirect_val int
  1255  	var keysize int
  1256  	var keytype *DWDie
  1257  	var t *DWDie
  1258  	var valsize int
  1259  	var valtype *DWDie
  1260  	for ; die != nil; die = die.link {
  1261  		if die.abbrev != DW_ABRV_MAPTYPE {
  1262  			continue
  1263  		}
  1264  
  1265  		keytype = walktypedef(getattr(die, DW_AT_go_key).data.(*DWDie))
  1266  		valtype = walktypedef(getattr(die, DW_AT_go_elem).data.(*DWDie))
  1267  
  1268  		// compute size info like hashmap.c does.
  1269  		a = getattr(keytype, DW_AT_byte_size)
  1270  
  1271  		if a != nil {
  1272  			keysize = int(a.value)
  1273  		} else {
  1274  			keysize = Thearch.Ptrsize
  1275  		}
  1276  		a = getattr(valtype, DW_AT_byte_size)
  1277  		if a != nil {
  1278  			valsize = int(a.value)
  1279  		} else {
  1280  			valsize = Thearch.Ptrsize
  1281  		}
  1282  		indirect_key = 0
  1283  		indirect_val = 0
  1284  		if keysize > MaxKeySize {
  1285  			keysize = Thearch.Ptrsize
  1286  			indirect_key = 1
  1287  		}
  1288  
  1289  		if valsize > MaxValSize {
  1290  			valsize = Thearch.Ptrsize
  1291  			indirect_val = 1
  1292  		}
  1293  
  1294  		// Construct type to represent an array of BucketSize keys
  1295  		dwhk = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]key", getattr(keytype, DW_AT_name).data.(string), ""))
  1296  
  1297  		newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(keysize), 0)
  1298  		t = keytype
  1299  		if indirect_key != 0 {
  1300  			t = defptrto(keytype)
  1301  		}
  1302  		newrefattr(dwhk, DW_AT_type, t)
  1303  		fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size")
  1304  		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
  1305  		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
  1306  
  1307  		// Construct type to represent an array of BucketSize values
  1308  		dwhv = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]val", getattr(valtype, DW_AT_name).data.(string), ""))
  1309  
  1310  		newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(valsize), 0)
  1311  		t = valtype
  1312  		if indirect_val != 0 {
  1313  			t = defptrto(valtype)
  1314  		}
  1315  		newrefattr(dwhv, DW_AT_type, t)
  1316  		fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size")
  1317  		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
  1318  		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
  1319  
  1320  		// Construct bucket<K,V>
  1321  		dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("bucket", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string)))
  1322  
  1323  		// Copy over all fields except the field "data" from the generic bucket.
  1324  		// "data" will be replaced with keys/values below.
  1325  		copychildrenexcept(dwhb, bucket, find(bucket, "data"))
  1326  
  1327  		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys")
  1328  		newrefattr(fld, DW_AT_type, dwhk)
  1329  		newmemberoffsetattr(fld, BucketSize)
  1330  		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values")
  1331  		newrefattr(fld, DW_AT_type, dwhv)
  1332  		newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize))
  1333  		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow")
  1334  		newrefattr(fld, DW_AT_type, defptrto(dwhb))
  1335  		newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
  1336  		if Thearch.Regsize > Thearch.Ptrsize {
  1337  			fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad")
  1338  			newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
  1339  			newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(Thearch.Ptrsize))
  1340  		}
  1341  
  1342  		newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize+BucketSize*int64(keysize)+BucketSize*int64(valsize)+int64(Thearch.Regsize), 0)
  1343  
  1344  		// Construct hash<K,V>
  1345  		dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("hash", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string)))
  1346  
  1347  		copychildren(dwh, hash)
  1348  		substitutetype(dwh, "buckets", defptrto(dwhb))
  1349  		substitutetype(dwh, "oldbuckets", defptrto(dwhb))
  1350  		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hash, DW_AT_byte_size).value, nil)
  1351  
  1352  		// make map type a pointer to hash<K,V>
  1353  		newrefattr(die, DW_AT_type, defptrto(dwh))
  1354  	}
  1355  }
  1356  
  1357  func synthesizechantypes(die *DWDie) {
  1358  	sudog := walktypedef(defgotype(lookup_or_diag("type.runtime.sudog")))
  1359  	waitq := walktypedef(defgotype(lookup_or_diag("type.runtime.waitq")))
  1360  	hchan := walktypedef(defgotype(lookup_or_diag("type.runtime.hchan")))
  1361  	if sudog == nil || waitq == nil || hchan == nil {
  1362  		return
  1363  	}
  1364  
  1365  	sudogsize := int(getattr(sudog, DW_AT_byte_size).value)
  1366  
  1367  	var a *DWAttr
  1368  	var dwh *DWDie
  1369  	var dws *DWDie
  1370  	var dww *DWDie
  1371  	var elemsize int
  1372  	var elemtype *DWDie
  1373  	for ; die != nil; die = die.link {
  1374  		if die.abbrev != DW_ABRV_CHANTYPE {
  1375  			continue
  1376  		}
  1377  		elemtype = getattr(die, DW_AT_go_elem).data.(*DWDie)
  1378  		a = getattr(elemtype, DW_AT_byte_size)
  1379  		if a != nil {
  1380  			elemsize = int(a.value)
  1381  		} else {
  1382  			elemsize = Thearch.Ptrsize
  1383  		}
  1384  
  1385  		// sudog<T>
  1386  		dws = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("sudog", getattr(elemtype, DW_AT_name).data.(string), ""))
  1387  
  1388  		copychildren(dws, sudog)
  1389  		substitutetype(dws, "elem", elemtype)
  1390  		if elemsize > 8 {
  1391  			elemsize -= 8
  1392  		} else {
  1393  			elemsize = 0
  1394  		}
  1395  		newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT, int64(sudogsize)+int64(elemsize), nil)
  1396  
  1397  		// waitq<T>
  1398  		dww = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("waitq", getattr(elemtype, DW_AT_name).data.(string), ""))
  1399  
  1400  		copychildren(dww, waitq)
  1401  		substitutetype(dww, "first", defptrto(dws))
  1402  		substitutetype(dww, "last", defptrto(dws))
  1403  		newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(waitq, DW_AT_byte_size).value, nil)
  1404  
  1405  		// hchan<T>
  1406  		dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("hchan", getattr(elemtype, DW_AT_name).data.(string), ""))
  1407  
  1408  		copychildren(dwh, hchan)
  1409  		substitutetype(dwh, "recvq", dww)
  1410  		substitutetype(dwh, "sendq", dww)
  1411  		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hchan, DW_AT_byte_size).value, nil)
  1412  
  1413  		newrefattr(die, DW_AT_type, defptrto(dwh))
  1414  	}
  1415  }
  1416  
  1417  // For use with pass.c::genasmsym
  1418  func defdwsymb(sym *LSym, s string, t int, v int64, size int64, ver int, gotype *LSym) {
  1419  	if strings.HasPrefix(s, "go.string.") {
  1420  		return
  1421  	}
  1422  	if strings.HasPrefix(s, "runtime.gcbits.") {
  1423  		return
  1424  	}
  1425  
  1426  	if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
  1427  		defgotype(sym)
  1428  		return
  1429  	}
  1430  
  1431  	var dv *DWDie
  1432  
  1433  	var dt *DWDie
  1434  	switch t {
  1435  	default:
  1436  		return
  1437  
  1438  	case 'd', 'b', 'D', 'B':
  1439  		dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s)
  1440  		newabslocexprattr(dv, v, sym)
  1441  		if ver == 0 {
  1442  			newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0)
  1443  		}
  1444  		fallthrough
  1445  
  1446  	case 'a', 'p':
  1447  		dt = defgotype(gotype)
  1448  	}
  1449  
  1450  	if dv != nil {
  1451  		newrefattr(dv, DW_AT_type, dt)
  1452  	}
  1453  }
  1454  
  1455  func movetomodule(parent *DWDie) {
  1456  	die := dwroot.child.child
  1457  	for die.link != nil {
  1458  		die = die.link
  1459  	}
  1460  	die.link = parent.child
  1461  }
  1462  
  1463  // If the pcln table contains runtime/runtime.go, use that to set gdbscript path.
  1464  func finddebugruntimepath(s *LSym) {
  1465  	if gdbscript != "" {
  1466  		return
  1467  	}
  1468  
  1469  	var f *LSym
  1470  	var p string
  1471  	for i := 0; i < s.Pcln.Nfile; i++ {
  1472  		f = s.Pcln.File[i]
  1473  		_ = p
  1474  		if i := strings.Index(f.Name, "runtime/runtime.go"); i >= 0 {
  1475  			gdbscript = f.Name[:i] + "runtime/runtime-gdb.py"
  1476  			break
  1477  		}
  1478  	}
  1479  }
  1480  
  1481  /*
  1482   * Generate short opcodes when possible, long ones when necessary.
  1483   * See section 6.2.5
  1484   */
  1485  const (
  1486  	LINE_BASE   = -1
  1487  	LINE_RANGE  = 4
  1488  	OPCODE_BASE = 10
  1489  )
  1490  
  1491  func putpclcdelta(delta_pc int64, delta_lc int64) {
  1492  	if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE {
  1493  		var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc)
  1494  		if OPCODE_BASE <= opcode && opcode < 256 {
  1495  			Cput(uint8(opcode))
  1496  			return
  1497  		}
  1498  	}
  1499  
  1500  	if delta_pc != 0 {
  1501  		Cput(DW_LNS_advance_pc)
  1502  		sleb128put(delta_pc)
  1503  	}
  1504  
  1505  	Cput(DW_LNS_advance_line)
  1506  	sleb128put(delta_lc)
  1507  	Cput(DW_LNS_copy)
  1508  }
  1509  
  1510  func newcfaoffsetattr(die *DWDie, offs int32) {
  1511  	var block [20]byte
  1512  
  1513  	i := 0
  1514  
  1515  	block[i] = DW_OP_call_frame_cfa
  1516  	i++
  1517  	if offs != 0 {
  1518  		block[i] = DW_OP_consts
  1519  		i++
  1520  		i += sleb128enc(int64(offs), block[i:])
  1521  		block[i] = DW_OP_plus
  1522  		i++
  1523  	}
  1524  
  1525  	newattr(die, DW_AT_location, DW_CLS_BLOCK, int64(i), block[:i])
  1526  }
  1527  
  1528  func mkvarname(name string, da int) string {
  1529  	buf := fmt.Sprintf("%s#%d", name, da)
  1530  	n := buf
  1531  	return n
  1532  }
  1533  
  1534  /*
  1535   * Walk prog table, emit line program and build DIE tree.
  1536   */
  1537  
  1538  // flush previous compilation unit.
  1539  func flushunit(dwinfo *DWDie, pc int64, pcsym *LSym, unitstart int64, header_length int32) {
  1540  	if dwinfo != nil && pc != 0 {
  1541  		newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, pcsym)
  1542  	}
  1543  
  1544  	if unitstart >= 0 {
  1545  		Cput(0) // start extended opcode
  1546  		uleb128put(1)
  1547  		Cput(DW_LNE_end_sequence)
  1548  
  1549  		here := Cpos()
  1550  		Cseek(unitstart)
  1551  		Thearch.Lput(uint32(here - unitstart - 4)) // unit_length
  1552  		Thearch.Wput(2)                            // dwarf version
  1553  		Thearch.Lput(uint32(header_length))        // header length starting here
  1554  		Cseek(here)
  1555  	}
  1556  }
  1557  
  1558  func getCompilationDir() string {
  1559  	if dir, err := os.Getwd(); err == nil {
  1560  		return dir
  1561  	}
  1562  	return "/"
  1563  }
  1564  
  1565  func writelines() {
  1566  	if linesec == nil {
  1567  		linesec = Linklookup(Ctxt, ".dwarfline", 0)
  1568  	}
  1569  	linesec.R = linesec.R[:0]
  1570  
  1571  	unitstart := int64(-1)
  1572  	headerend := int64(-1)
  1573  	epc := int64(0)
  1574  	var epcs *LSym
  1575  	lineo = Cpos()
  1576  	var dwinfo *DWDie
  1577  
  1578  	flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10))
  1579  	unitstart = Cpos()
  1580  
  1581  	lang := DW_LANG_Go
  1582  
  1583  	s := Ctxt.Textp
  1584  
  1585  	dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, "go")
  1586  	newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(lang), 0)
  1587  	newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart-lineo, 0)
  1588  	newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
  1589  	// OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
  1590  	compDir := getCompilationDir()
  1591  	newattr(dwinfo, DW_AT_comp_dir, DW_CLS_STRING, int64(len(compDir)), compDir)
  1592  
  1593  	// Write .debug_line Line Number Program Header (sec 6.2.4)
  1594  	// Fields marked with (*) must be changed for 64-bit dwarf
  1595  	Thearch.Lput(0) // unit_length (*), will be filled in by flushunit.
  1596  	Thearch.Wput(2) // dwarf version (appendix F)
  1597  	Thearch.Lput(0) // header_length (*), filled in by flushunit.
  1598  
  1599  	// cpos == unitstart + 4 + 2 + 4
  1600  	Cput(1)                // minimum_instruction_length
  1601  	Cput(1)                // default_is_stmt
  1602  	Cput(LINE_BASE & 0xFF) // line_base
  1603  	Cput(LINE_RANGE)       // line_range
  1604  	Cput(OPCODE_BASE)      // opcode_base
  1605  	Cput(0)                // standard_opcode_lengths[1]
  1606  	Cput(1)                // standard_opcode_lengths[2]
  1607  	Cput(1)                // standard_opcode_lengths[3]
  1608  	Cput(1)                // standard_opcode_lengths[4]
  1609  	Cput(1)                // standard_opcode_lengths[5]
  1610  	Cput(0)                // standard_opcode_lengths[6]
  1611  	Cput(0)                // standard_opcode_lengths[7]
  1612  	Cput(0)                // standard_opcode_lengths[8]
  1613  	Cput(1)                // standard_opcode_lengths[9]
  1614  	Cput(0)                // include_directories  (empty)
  1615  
  1616  	files := make([]*LSym, Ctxt.Nhistfile)
  1617  
  1618  	for f := Ctxt.Filesyms; f != nil; f = f.Next {
  1619  		files[f.Value-1] = f
  1620  	}
  1621  
  1622  	for i := 0; int32(i) < Ctxt.Nhistfile; i++ {
  1623  		strnput(files[i].Name, len(files[i].Name)+4)
  1624  	}
  1625  
  1626  	// 4 zeros: the string termination + 3 fields.
  1627  	Cput(0)
  1628  	// terminate file_names.
  1629  	headerend = Cpos()
  1630  
  1631  	Cput(0) // start extended opcode
  1632  	uleb128put(1 + int64(Thearch.Ptrsize))
  1633  	Cput(DW_LNE_set_address)
  1634  
  1635  	pc := s.Value
  1636  	line := 1
  1637  	file := 1
  1638  	if Linkmode == LinkExternal {
  1639  		adddwarfrel(linesec, s, lineo, Thearch.Ptrsize, 0)
  1640  	} else {
  1641  		addrput(pc)
  1642  	}
  1643  
  1644  	var a *Auto
  1645  	var da int
  1646  	var dt int
  1647  	var dwfunc *DWDie
  1648  	var dws **DWDie
  1649  	var dwvar *DWDie
  1650  	var n string
  1651  	var nn string
  1652  	var offs int64
  1653  	var pcfile Pciter
  1654  	var pcline Pciter
  1655  	var varhash [HASHSIZE]*DWDie
  1656  	for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
  1657  		s = Ctxt.Cursym
  1658  
  1659  		dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s.Name)
  1660  		newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
  1661  		epc = s.Value + s.Size
  1662  		epcs = s
  1663  		newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, s)
  1664  		if s.Version == 0 {
  1665  			newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0)
  1666  		}
  1667  
  1668  		if s.Pcln == nil {
  1669  			continue
  1670  		}
  1671  
  1672  		finddebugruntimepath(s)
  1673  
  1674  		pciterinit(Ctxt, &pcfile, &s.Pcln.Pcfile)
  1675  		pciterinit(Ctxt, &pcline, &s.Pcln.Pcline)
  1676  		epc = pc
  1677  		for pcfile.done == 0 && pcline.done == 0 {
  1678  			if epc-s.Value >= int64(pcfile.nextpc) {
  1679  				pciternext(&pcfile)
  1680  				continue
  1681  			}
  1682  
  1683  			if epc-s.Value >= int64(pcline.nextpc) {
  1684  				pciternext(&pcline)
  1685  				continue
  1686  			}
  1687  
  1688  			if int32(file) != pcfile.value {
  1689  				Cput(DW_LNS_set_file)
  1690  				uleb128put(int64(pcfile.value))
  1691  				file = int(pcfile.value)
  1692  			}
  1693  
  1694  			putpclcdelta(s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line))
  1695  
  1696  			pc = s.Value + int64(pcline.pc)
  1697  			line = int(pcline.value)
  1698  			if pcfile.nextpc < pcline.nextpc {
  1699  				epc = int64(pcfile.nextpc)
  1700  			} else {
  1701  				epc = int64(pcline.nextpc)
  1702  			}
  1703  			epc += s.Value
  1704  		}
  1705  
  1706  		da = 0
  1707  		dwfunc.hash = varhash[:] // enable indexing of children by name
  1708  		varhash = [HASHSIZE]*DWDie{}
  1709  		for a = s.Autom; a != nil; a = a.Link {
  1710  			switch a.Name {
  1711  			case obj.A_AUTO:
  1712  				dt = DW_ABRV_AUTO
  1713  				offs = int64(a.Aoffset)
  1714  				if !haslinkregister() {
  1715  					offs -= int64(Thearch.Ptrsize)
  1716  				}
  1717  
  1718  			case obj.A_PARAM:
  1719  				dt = DW_ABRV_PARAM
  1720  				offs = int64(a.Aoffset)
  1721  				if haslinkregister() {
  1722  					offs += int64(Thearch.Ptrsize)
  1723  				}
  1724  
  1725  			default:
  1726  				continue
  1727  			}
  1728  
  1729  			if strings.Contains(a.Asym.Name, ".autotmp_") {
  1730  				continue
  1731  			}
  1732  			if find(dwfunc, a.Asym.Name) != nil {
  1733  				n = mkvarname(a.Asym.Name, da)
  1734  			} else {
  1735  				n = a.Asym.Name
  1736  			}
  1737  
  1738  			// Drop the package prefix from locals and arguments.
  1739  			_ = nn
  1740  			if i := strings.LastIndex(n, "."); i >= 0 {
  1741  				n = n[i+1:]
  1742  			}
  1743  
  1744  			dwvar = newdie(dwfunc, dt, n)
  1745  			newcfaoffsetattr(dwvar, int32(offs))
  1746  			newrefattr(dwvar, DW_AT_type, defgotype(a.Gotype))
  1747  
  1748  			// push dwvar down dwfunc->child to preserve order
  1749  			newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil)
  1750  
  1751  			dwfunc.child = dwvar.link // take dwvar out from the top of the list
  1752  			for dws = &dwfunc.child; *dws != nil; dws = &(*dws).link {
  1753  				if offs > getattr(*dws, DW_AT_internal_location).value {
  1754  					break
  1755  				}
  1756  			}
  1757  			dwvar.link = *dws
  1758  			*dws = dwvar
  1759  
  1760  			da++
  1761  		}
  1762  
  1763  		dwfunc.hash = nil
  1764  	}
  1765  
  1766  	flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10))
  1767  	linesize = Cpos() - lineo
  1768  }
  1769  
  1770  /*
  1771   *  Emit .debug_frame
  1772   */
  1773  const (
  1774  	CIERESERVE          = 16
  1775  	DATAALIGNMENTFACTOR = -4
  1776  )
  1777  
  1778  func putpccfadelta(deltapc int64, cfa int64) {
  1779  	Cput(DW_CFA_def_cfa_offset_sf)
  1780  	sleb128put(cfa / DATAALIGNMENTFACTOR)
  1781  
  1782  	if deltapc < 0x40 {
  1783  		Cput(uint8(DW_CFA_advance_loc + deltapc))
  1784  	} else if deltapc < 0x100 {
  1785  		Cput(DW_CFA_advance_loc1)
  1786  		Cput(uint8(deltapc))
  1787  	} else if deltapc < 0x10000 {
  1788  		Cput(DW_CFA_advance_loc2)
  1789  		Thearch.Wput(uint16(deltapc))
  1790  	} else {
  1791  		Cput(DW_CFA_advance_loc4)
  1792  		Thearch.Lput(uint32(deltapc))
  1793  	}
  1794  }
  1795  
  1796  func writeframes() {
  1797  	if framesec == nil {
  1798  		framesec = Linklookup(Ctxt, ".dwarfframe", 0)
  1799  	}
  1800  	framesec.R = framesec.R[:0]
  1801  	frameo = Cpos()
  1802  
  1803  	// Emit the CIE, Section 6.4.1
  1804  	Thearch.Lput(CIERESERVE)              // initial length, must be multiple of thearch.ptrsize
  1805  	Thearch.Lput(0xffffffff)              // cid.
  1806  	Cput(3)                               // dwarf version (appendix F)
  1807  	Cput(0)                               // augmentation ""
  1808  	uleb128put(1)                         // code_alignment_factor
  1809  	sleb128put(DATAALIGNMENTFACTOR)       // guess
  1810  	uleb128put(int64(Thearch.Dwarfreglr)) // return_address_register
  1811  
  1812  	Cput(DW_CFA_def_cfa)
  1813  
  1814  	uleb128put(int64(Thearch.Dwarfregsp)) // register SP (**ABI-dependent, defined in l.h)
  1815  	if haslinkregister() {
  1816  		uleb128put(int64(0)) // offset
  1817  	} else {
  1818  		uleb128put(int64(Thearch.Ptrsize)) // offset
  1819  	}
  1820  
  1821  	Cput(DW_CFA_offset_extended)
  1822  	uleb128put(int64(Thearch.Dwarfreglr)) // return address
  1823  	if haslinkregister() {
  1824  		uleb128put(int64(0) / DATAALIGNMENTFACTOR) // at cfa - 0
  1825  	} else {
  1826  		uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4
  1827  	}
  1828  
  1829  	// 4 is to exclude the length field.
  1830  	pad := CIERESERVE + frameo + 4 - Cpos()
  1831  
  1832  	if pad < 0 {
  1833  		Exitf("dwarf: CIERESERVE too small by %d bytes.", -pad)
  1834  	}
  1835  
  1836  	strnput("", int(pad))
  1837  
  1838  	var fdeo int64
  1839  	var fdesize int64
  1840  	var nextpc uint32
  1841  	var pcsp Pciter
  1842  	var s *LSym
  1843  	for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
  1844  		s = Ctxt.Cursym
  1845  		if s.Pcln == nil {
  1846  			continue
  1847  		}
  1848  
  1849  		fdeo = Cpos()
  1850  
  1851  		// Emit a FDE, Section 6.4.1, starting wit a placeholder.
  1852  		Thearch.Lput(0) // length, must be multiple of thearch.ptrsize
  1853  		Thearch.Lput(0) // Pointer to the CIE above, at offset 0
  1854  		addrput(0)      // initial location
  1855  		addrput(0)      // address range
  1856  
  1857  		for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
  1858  			nextpc = pcsp.nextpc
  1859  
  1860  			// pciterinit goes up to the end of the function,
  1861  			// but DWARF expects us to stop just before the end.
  1862  			if int64(nextpc) == s.Size {
  1863  				nextpc--
  1864  				if nextpc < pcsp.pc {
  1865  					continue
  1866  				}
  1867  			}
  1868  
  1869  			if haslinkregister() {
  1870  				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
  1871  			} else {
  1872  				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value))
  1873  			}
  1874  		}
  1875  
  1876  		fdesize = Cpos() - fdeo - 4 // exclude the length field.
  1877  		pad = Rnd(fdesize, int64(Thearch.Ptrsize)) - fdesize
  1878  		strnput("", int(pad))
  1879  		fdesize += pad
  1880  
  1881  		// Emit the FDE header for real, Section 6.4.1.
  1882  		Cseek(fdeo)
  1883  
  1884  		Thearch.Lput(uint32(fdesize))
  1885  		if Linkmode == LinkExternal {
  1886  			adddwarfrel(framesec, framesym, frameo, 4, 0)
  1887  			adddwarfrel(framesec, s, frameo, Thearch.Ptrsize, 0)
  1888  		} else {
  1889  			Thearch.Lput(0)
  1890  			addrput(s.Value)
  1891  		}
  1892  
  1893  		addrput(s.Size)
  1894  		Cseek(fdeo + 4 + fdesize)
  1895  	}
  1896  
  1897  	Cflush()
  1898  	framesize = Cpos() - frameo
  1899  }
  1900  
  1901  /*
  1902   *  Walk DWarfDebugInfoEntries, and emit .debug_info
  1903   */
  1904  const (
  1905  	COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
  1906  )
  1907  
  1908  func writeinfo() {
  1909  	fwdcount = 0
  1910  	if infosec == nil {
  1911  		infosec = Linklookup(Ctxt, ".dwarfinfo", 0)
  1912  	}
  1913  	infosec.R = infosec.R[:0]
  1914  
  1915  	if arangessec == nil {
  1916  		arangessec = Linklookup(Ctxt, ".dwarfaranges", 0)
  1917  	}
  1918  	arangessec.R = arangessec.R[:0]
  1919  
  1920  	var here int64
  1921  	var unitstart int64
  1922  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1923  		unitstart = Cpos()
  1924  
  1925  		// Write .debug_info Compilation Unit Header (sec 7.5.1)
  1926  		// Fields marked with (*) must be changed for 64-bit dwarf
  1927  		// This must match COMPUNITHEADERSIZE above.
  1928  		Thearch.Lput(0) // unit_length (*), will be filled in later.
  1929  		Thearch.Wput(2) // dwarf version (appendix F)
  1930  
  1931  		// debug_abbrev_offset (*)
  1932  		if Linkmode == LinkExternal {
  1933  			adddwarfrel(infosec, abbrevsym, infoo, 4, 0)
  1934  		} else {
  1935  			Thearch.Lput(0)
  1936  		}
  1937  
  1938  		Cput(uint8(Thearch.Ptrsize)) // address_size
  1939  
  1940  		putdie(compunit)
  1941  
  1942  		here = Cpos()
  1943  		Cseek(unitstart)
  1944  		Thearch.Lput(uint32(here - unitstart - 4)) // exclude the length field.
  1945  		Cseek(here)
  1946  	}
  1947  
  1948  	Cflush()
  1949  }
  1950  
  1951  /*
  1952   *  Emit .debug_pubnames/_types.  _info must have been written before,
  1953   *  because we need die->offs and infoo/infosize;
  1954   */
  1955  func ispubname(die *DWDie) bool {
  1956  	switch die.abbrev {
  1957  	case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE:
  1958  		a := getattr(die, DW_AT_external)
  1959  		return a != nil && a.value != 0
  1960  	}
  1961  
  1962  	return false
  1963  }
  1964  
  1965  func ispubtype(die *DWDie) bool {
  1966  	return die.abbrev >= DW_ABRV_NULLTYPE
  1967  }
  1968  
  1969  func writepub(ispub func(*DWDie) bool) int64 {
  1970  	var die *DWDie
  1971  	var dwa *DWAttr
  1972  	var unitstart int64
  1973  	var unitend int64
  1974  	var here int64
  1975  
  1976  	sectionstart := Cpos()
  1977  
  1978  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1979  		unitstart = compunit.offs - COMPUNITHEADERSIZE
  1980  		if compunit.link != nil {
  1981  			unitend = compunit.link.offs - COMPUNITHEADERSIZE
  1982  		} else {
  1983  			unitend = infoo + infosize
  1984  		}
  1985  
  1986  		// Write .debug_pubnames/types	Header (sec 6.1.1)
  1987  		Thearch.Lput(0)                           // unit_length (*), will be filled in later.
  1988  		Thearch.Wput(2)                           // dwarf version (appendix F)
  1989  		Thearch.Lput(uint32(unitstart))           // debug_info_offset (of the Comp unit Header)
  1990  		Thearch.Lput(uint32(unitend - unitstart)) // debug_info_length
  1991  
  1992  		for die = compunit.child; die != nil; die = die.link {
  1993  			if !ispub(die) {
  1994  				continue
  1995  			}
  1996  			Thearch.Lput(uint32(die.offs - unitstart))
  1997  			dwa = getattr(die, DW_AT_name)
  1998  			strnput(dwa.data.(string), int(dwa.value+1))
  1999  		}
  2000  
  2001  		Thearch.Lput(0)
  2002  
  2003  		here = Cpos()
  2004  		Cseek(sectionstart)
  2005  		Thearch.Lput(uint32(here - sectionstart - 4)) // exclude the length field.
  2006  		Cseek(here)
  2007  	}
  2008  
  2009  	return sectionstart
  2010  }
  2011  
  2012  /*
  2013   *  emit .debug_aranges.  _info must have been written before,
  2014   *  because we need die->offs of dw_globals.
  2015   */
  2016  func writearanges() int64 {
  2017  	var b *DWAttr
  2018  	var e *DWAttr
  2019  	var value int64
  2020  
  2021  	sectionstart := Cpos()
  2022  	headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize))) // don't count unit_length field itself
  2023  
  2024  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  2025  		b = getattr(compunit, DW_AT_low_pc)
  2026  		if b == nil {
  2027  			continue
  2028  		}
  2029  		e = getattr(compunit, DW_AT_high_pc)
  2030  		if e == nil {
  2031  			continue
  2032  		}
  2033  
  2034  		// Write .debug_aranges	 Header + entry	 (sec 6.1.2)
  2035  		Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*)
  2036  		Thearch.Wput(2)                                                  // dwarf version (appendix F)
  2037  
  2038  		value = compunit.offs - COMPUNITHEADERSIZE // debug_info_offset
  2039  		if Linkmode == LinkExternal {
  2040  			adddwarfrel(arangessec, infosym, sectionstart, 4, value)
  2041  		} else {
  2042  			Thearch.Lput(uint32(value))
  2043  		}
  2044  
  2045  		Cput(uint8(Thearch.Ptrsize))        // address_size
  2046  		Cput(0)                             // segment_size
  2047  		strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize
  2048  
  2049  		if Linkmode == LinkExternal {
  2050  			adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value)
  2051  		} else {
  2052  			addrput(b.value)
  2053  		}
  2054  
  2055  		addrput(e.value - b.value)
  2056  		addrput(0)
  2057  		addrput(0)
  2058  	}
  2059  
  2060  	Cflush()
  2061  	return sectionstart
  2062  }
  2063  
  2064  func writegdbscript() int64 {
  2065  	sectionstart := Cpos()
  2066  
  2067  	if gdbscript != "" {
  2068  		Cput(1) // magic 1 byte?
  2069  		strnput(gdbscript, len(gdbscript)+1)
  2070  		Cflush()
  2071  	}
  2072  
  2073  	return sectionstart
  2074  }
  2075  
  2076  func align(size int64) {
  2077  	if HEADTYPE == obj.Hwindows { // Only Windows PE need section align.
  2078  		strnput("", int(Rnd(size, PEFILEALIGN)-size))
  2079  	}
  2080  }
  2081  
  2082  func writedwarfreloc(s *LSym) int64 {
  2083  	var i int
  2084  	var r *Reloc
  2085  
  2086  	start := Cpos()
  2087  	for ri := 0; ri < len(s.R); ri++ {
  2088  		r = &s.R[ri]
  2089  		if Iself {
  2090  			i = Thearch.Elfreloc1(r, int64(r.Off))
  2091  		} else if HEADTYPE == obj.Hdarwin {
  2092  			i = Thearch.Machoreloc1(r, int64(r.Off))
  2093  		} else {
  2094  			i = -1
  2095  		}
  2096  		if i < 0 {
  2097  			Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
  2098  		}
  2099  	}
  2100  
  2101  	return start
  2102  }
  2103  
  2104  func addmachodwarfsect(prev *Section, name string) *Section {
  2105  	sect := addsection(&Segdwarf, name, 04)
  2106  	sect.Extnum = prev.Extnum + 1
  2107  	sym := Linklookup(Ctxt, name, 0)
  2108  	sym.Sect = sect
  2109  	return sect
  2110  }
  2111  
  2112  /*
  2113   * This is the main entry point for generating dwarf.  After emitting
  2114   * the mandatory debug_abbrev section, it calls writelines() to set up
  2115   * the per-compilation unit part of the DIE tree, while simultaneously
  2116   * emitting the debug_line section.  When the final tree contains
  2117   * forward references, it will write the debug_info section in 2
  2118   * passes.
  2119   *
  2120   */
  2121  func Dwarfemitdebugsections() {
  2122  	if Debug['w'] != 0 { // disable dwarf
  2123  		return
  2124  	}
  2125  
  2126  	if Linkmode == LinkExternal {
  2127  		if !Iself && HEADTYPE != obj.Hdarwin {
  2128  			return
  2129  		}
  2130  		if HEADTYPE == obj.Hdarwin {
  2131  			sect := Segdata.Sect
  2132  			// find the last section.
  2133  			for sect.Next != nil {
  2134  				sect = sect.Next
  2135  			}
  2136  			sect = addmachodwarfsect(sect, ".debug_abbrev")
  2137  			sect = addmachodwarfsect(sect, ".debug_line")
  2138  			sect = addmachodwarfsect(sect, ".debug_frame")
  2139  			sect = addmachodwarfsect(sect, ".debug_info")
  2140  
  2141  			infosym = Linklookup(Ctxt, ".debug_info", 0)
  2142  			infosym.Hide = 1
  2143  
  2144  			abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
  2145  			abbrevsym.Hide = 1
  2146  
  2147  			linesym = Linklookup(Ctxt, ".debug_line", 0)
  2148  			linesym.Hide = 1
  2149  
  2150  			framesym = Linklookup(Ctxt, ".debug_frame", 0)
  2151  			framesym.Hide = 1
  2152  		}
  2153  	}
  2154  
  2155  	// For diagnostic messages.
  2156  	newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes")
  2157  
  2158  	mkindex(&dwroot)
  2159  	mkindex(&dwtypes)
  2160  	mkindex(&dwglobals)
  2161  
  2162  	// Some types that must exist to define other ones.
  2163  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>")
  2164  
  2165  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "void")
  2166  	newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer")
  2167  
  2168  	die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr") // needed for array size
  2169  	newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
  2170  	newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0)
  2171  	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0)
  2172  
  2173  	// Needed by the prettyprinter code for interface inspection.
  2174  	defgotype(lookup_or_diag("type.runtime._type"))
  2175  
  2176  	defgotype(lookup_or_diag("type.runtime.interfacetype"))
  2177  	defgotype(lookup_or_diag("type.runtime.itab"))
  2178  
  2179  	genasmsym(defdwsymb)
  2180  
  2181  	writeabbrev()
  2182  	align(abbrevsize)
  2183  	writelines()
  2184  	align(linesize)
  2185  	writeframes()
  2186  	align(framesize)
  2187  
  2188  	synthesizestringtypes(dwtypes.child)
  2189  	synthesizeslicetypes(dwtypes.child)
  2190  	synthesizemaptypes(dwtypes.child)
  2191  	synthesizechantypes(dwtypes.child)
  2192  
  2193  	reversetree(&dwroot.child)
  2194  	reversetree(&dwtypes.child)
  2195  	reversetree(&dwglobals.child)
  2196  
  2197  	movetomodule(&dwtypes)
  2198  	movetomodule(&dwglobals)
  2199  
  2200  	infoo = Cpos()
  2201  	writeinfo()
  2202  	infoe := Cpos()
  2203  	pubnameso = infoe
  2204  	pubtypeso = infoe
  2205  	arangeso = infoe
  2206  	gdbscripto = infoe
  2207  
  2208  	if fwdcount > 0 {
  2209  		if Debug['v'] != 0 {
  2210  			fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime())
  2211  		}
  2212  		Cseek(infoo)
  2213  		writeinfo()
  2214  		if fwdcount > 0 {
  2215  			Exitf("dwarf: unresolved references after first dwarf info pass")
  2216  		}
  2217  
  2218  		if infoe != Cpos() {
  2219  			Exitf("dwarf: inconsistent second dwarf info pass")
  2220  		}
  2221  	}
  2222  
  2223  	infosize = infoe - infoo
  2224  	align(infosize)
  2225  
  2226  	pubnameso = writepub(ispubname)
  2227  	pubnamessize = Cpos() - pubnameso
  2228  	align(pubnamessize)
  2229  
  2230  	pubtypeso = writepub(ispubtype)
  2231  	pubtypessize = Cpos() - pubtypeso
  2232  	align(pubtypessize)
  2233  
  2234  	arangeso = writearanges()
  2235  	arangessize = Cpos() - arangeso
  2236  	align(arangessize)
  2237  
  2238  	gdbscripto = writegdbscript()
  2239  	gdbscriptsize = Cpos() - gdbscripto
  2240  	align(gdbscriptsize)
  2241  
  2242  	for Cpos()&7 != 0 {
  2243  		Cput(0)
  2244  	}
  2245  	if HEADTYPE != obj.Hdarwin {
  2246  		dwarfemitreloc()
  2247  	}
  2248  }
  2249  
  2250  func dwarfemitreloc() {
  2251  	if Debug['w'] != 0 { // disable dwarf
  2252  		return
  2253  	}
  2254  	inforeloco = writedwarfreloc(infosec)
  2255  	inforelocsize = Cpos() - inforeloco
  2256  	align(inforelocsize)
  2257  
  2258  	arangesreloco = writedwarfreloc(arangessec)
  2259  	arangesrelocsize = Cpos() - arangesreloco
  2260  	align(arangesrelocsize)
  2261  
  2262  	linereloco = writedwarfreloc(linesec)
  2263  	linerelocsize = Cpos() - linereloco
  2264  	align(linerelocsize)
  2265  
  2266  	framereloco = writedwarfreloc(framesec)
  2267  	framerelocsize = Cpos() - framereloco
  2268  	align(framerelocsize)
  2269  }
  2270  
  2271  /*
  2272   *  Elf.
  2273   */
  2274  const (
  2275  	ElfStrDebugAbbrev = iota
  2276  	ElfStrDebugAranges
  2277  	ElfStrDebugFrame
  2278  	ElfStrDebugInfo
  2279  	ElfStrDebugLine
  2280  	ElfStrDebugLoc
  2281  	ElfStrDebugMacinfo
  2282  	ElfStrDebugPubNames
  2283  	ElfStrDebugPubTypes
  2284  	ElfStrDebugRanges
  2285  	ElfStrDebugStr
  2286  	ElfStrGDBScripts
  2287  	ElfStrRelDebugInfo
  2288  	ElfStrRelDebugAranges
  2289  	ElfStrRelDebugLine
  2290  	ElfStrRelDebugFrame
  2291  	NElfStrDbg
  2292  )
  2293  
  2294  var elfstrdbg [NElfStrDbg]int64
  2295  
  2296  func dwarfaddshstrings(shstrtab *LSym) {
  2297  	if Debug['w'] != 0 { // disable dwarf
  2298  		return
  2299  	}
  2300  
  2301  	elfstrdbg[ElfStrDebugAbbrev] = Addstring(shstrtab, ".debug_abbrev")
  2302  	elfstrdbg[ElfStrDebugAranges] = Addstring(shstrtab, ".debug_aranges")
  2303  	elfstrdbg[ElfStrDebugFrame] = Addstring(shstrtab, ".debug_frame")
  2304  	elfstrdbg[ElfStrDebugInfo] = Addstring(shstrtab, ".debug_info")
  2305  	elfstrdbg[ElfStrDebugLine] = Addstring(shstrtab, ".debug_line")
  2306  	elfstrdbg[ElfStrDebugLoc] = Addstring(shstrtab, ".debug_loc")
  2307  	elfstrdbg[ElfStrDebugMacinfo] = Addstring(shstrtab, ".debug_macinfo")
  2308  	elfstrdbg[ElfStrDebugPubNames] = Addstring(shstrtab, ".debug_pubnames")
  2309  	elfstrdbg[ElfStrDebugPubTypes] = Addstring(shstrtab, ".debug_pubtypes")
  2310  	elfstrdbg[ElfStrDebugRanges] = Addstring(shstrtab, ".debug_ranges")
  2311  	elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str")
  2312  	elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts")
  2313  	if Linkmode == LinkExternal {
  2314  		switch Thearch.Thechar {
  2315  		case '6', '7', '9':
  2316  			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info")
  2317  			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges")
  2318  			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line")
  2319  			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame")
  2320  		default:
  2321  			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info")
  2322  			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges")
  2323  			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line")
  2324  			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rel.debug_frame")
  2325  		}
  2326  
  2327  		infosym = Linklookup(Ctxt, ".debug_info", 0)
  2328  		infosym.Hide = 1
  2329  
  2330  		abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
  2331  		abbrevsym.Hide = 1
  2332  
  2333  		linesym = Linklookup(Ctxt, ".debug_line", 0)
  2334  		linesym.Hide = 1
  2335  
  2336  		framesym = Linklookup(Ctxt, ".debug_frame", 0)
  2337  		framesym.Hide = 1
  2338  	}
  2339  }
  2340  
  2341  // Add section symbols for DWARF debug info.  This is called before
  2342  // dwarfaddelfheaders.
  2343  func dwarfaddelfsectionsyms() {
  2344  	if infosym != nil {
  2345  		infosympos = Cpos()
  2346  		putelfsectionsym(infosym, 0)
  2347  	}
  2348  
  2349  	if abbrevsym != nil {
  2350  		abbrevsympos = Cpos()
  2351  		putelfsectionsym(abbrevsym, 0)
  2352  	}
  2353  
  2354  	if linesym != nil {
  2355  		linesympos = Cpos()
  2356  		putelfsectionsym(linesym, 0)
  2357  	}
  2358  
  2359  	if framesym != nil {
  2360  		framesympos = Cpos()
  2361  		putelfsectionsym(framesym, 0)
  2362  	}
  2363  }
  2364  
  2365  func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) {
  2366  	sh := newElfShdr(elfstrdbg[elfstr])
  2367  	switch Thearch.Thechar {
  2368  	case '6', '7', '9':
  2369  		sh.type_ = SHT_RELA
  2370  	default:
  2371  		sh.type_ = SHT_REL
  2372  	}
  2373  
  2374  	sh.entsize = uint64(Thearch.Ptrsize) * 2
  2375  	if sh.type_ == SHT_RELA {
  2376  		sh.entsize += uint64(Thearch.Ptrsize)
  2377  	}
  2378  	sh.link = uint32(elfshname(".symtab").shnum)
  2379  	sh.info = uint32(shdata.shnum)
  2380  	sh.off = uint64(off)
  2381  	sh.size = uint64(size)
  2382  	sh.addralign = uint64(Thearch.Ptrsize)
  2383  }
  2384  
  2385  func dwarfaddelfheaders() {
  2386  	if Debug['w'] != 0 { // disable dwarf
  2387  		return
  2388  	}
  2389  
  2390  	sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev])
  2391  	sh.type_ = SHT_PROGBITS
  2392  	sh.off = uint64(abbrevo)
  2393  	sh.size = uint64(abbrevsize)
  2394  	sh.addralign = 1
  2395  	if abbrevsympos > 0 {
  2396  		putelfsymshndx(abbrevsympos, sh.shnum)
  2397  	}
  2398  
  2399  	sh = newElfShdr(elfstrdbg[ElfStrDebugLine])
  2400  	sh.type_ = SHT_PROGBITS
  2401  	sh.off = uint64(lineo)
  2402  	sh.size = uint64(linesize)
  2403  	sh.addralign = 1
  2404  	if linesympos > 0 {
  2405  		putelfsymshndx(linesympos, sh.shnum)
  2406  	}
  2407  	shline := sh
  2408  
  2409  	sh = newElfShdr(elfstrdbg[ElfStrDebugFrame])
  2410  	sh.type_ = SHT_PROGBITS
  2411  	sh.off = uint64(frameo)
  2412  	sh.size = uint64(framesize)
  2413  	sh.addralign = 1
  2414  	if framesympos > 0 {
  2415  		putelfsymshndx(framesympos, sh.shnum)
  2416  	}
  2417  	shframe := sh
  2418  
  2419  	sh = newElfShdr(elfstrdbg[ElfStrDebugInfo])
  2420  	sh.type_ = SHT_PROGBITS
  2421  	sh.off = uint64(infoo)
  2422  	sh.size = uint64(infosize)
  2423  	sh.addralign = 1
  2424  	if infosympos > 0 {
  2425  		putelfsymshndx(infosympos, sh.shnum)
  2426  	}
  2427  	shinfo := sh
  2428  
  2429  	if pubnamessize > 0 {
  2430  		sh := newElfShdr(elfstrdbg[ElfStrDebugPubNames])
  2431  		sh.type_ = SHT_PROGBITS
  2432  		sh.off = uint64(pubnameso)
  2433  		sh.size = uint64(pubnamessize)
  2434  		sh.addralign = 1
  2435  	}
  2436  
  2437  	if pubtypessize > 0 {
  2438  		sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes])
  2439  		sh.type_ = SHT_PROGBITS
  2440  		sh.off = uint64(pubtypeso)
  2441  		sh.size = uint64(pubtypessize)
  2442  		sh.addralign = 1
  2443  	}
  2444  
  2445  	var sharanges *ElfShdr
  2446  	if arangessize != 0 {
  2447  		sh := newElfShdr(elfstrdbg[ElfStrDebugAranges])
  2448  		sh.type_ = SHT_PROGBITS
  2449  		sh.off = uint64(arangeso)
  2450  		sh.size = uint64(arangessize)
  2451  		sh.addralign = 1
  2452  		sharanges = sh
  2453  	}
  2454  
  2455  	if gdbscriptsize != 0 {
  2456  		sh := newElfShdr(elfstrdbg[ElfStrGDBScripts])
  2457  		sh.type_ = SHT_PROGBITS
  2458  		sh.off = uint64(gdbscripto)
  2459  		sh.size = uint64(gdbscriptsize)
  2460  		sh.addralign = 1
  2461  	}
  2462  
  2463  	if inforelocsize != 0 {
  2464  		dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize)
  2465  	}
  2466  
  2467  	if arangesrelocsize != 0 {
  2468  		dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize)
  2469  	}
  2470  
  2471  	if linerelocsize != 0 {
  2472  		dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize)
  2473  	}
  2474  
  2475  	if framerelocsize != 0 {
  2476  		dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize)
  2477  	}
  2478  }
  2479  
  2480  /*
  2481   * Macho
  2482   */
  2483  func dwarfaddmachoheaders(ms *MachoSeg) {
  2484  	if Debug['w'] != 0 { // disable dwarf
  2485  		return
  2486  	}
  2487  
  2488  	// Zero vsize segments won't be loaded in memory, even so they
  2489  	// have to be page aligned in the file.
  2490  	fakestart := Rnd(int64(Segdwarf.Fileoff), 0x1000)
  2491  	addr := Segdata.Vaddr + Segdata.Length
  2492  
  2493  	nsect := 4
  2494  	if pubnamessize > 0 {
  2495  		nsect++
  2496  	}
  2497  	if pubtypessize > 0 {
  2498  		nsect++
  2499  	}
  2500  	if arangessize > 0 {
  2501  		nsect++
  2502  	}
  2503  	if gdbscriptsize > 0 {
  2504  		nsect++
  2505  	}
  2506  
  2507  	if Linkmode != LinkExternal {
  2508  		ms = newMachoSeg("__DWARF", nsect)
  2509  		ms.fileoffset = uint64(fakestart)
  2510  		ms.filesize = Segdwarf.Filelen
  2511  		ms.vaddr = addr
  2512  	}
  2513  
  2514  	msect := newMachoSect(ms, "__debug_abbrev", "__DWARF")
  2515  	msect.off = uint32(abbrevo)
  2516  	msect.size = uint64(abbrevsize)
  2517  	msect.addr = addr
  2518  	addr += msect.size
  2519  	msect.flag = 0x02000000
  2520  	if abbrevsym != nil {
  2521  		abbrevsym.Value = int64(msect.addr)
  2522  	}
  2523  
  2524  	msect = newMachoSect(ms, "__debug_line", "__DWARF")
  2525  	msect.off = uint32(lineo)
  2526  	msect.size = uint64(linesize)
  2527  	msect.addr = addr
  2528  	addr += msect.size
  2529  	msect.flag = 0x02000000
  2530  	if linesym != nil {
  2531  		linesym.Value = int64(msect.addr)
  2532  	}
  2533  	if linerelocsize > 0 {
  2534  		msect.nreloc = uint32(len(linesec.R))
  2535  		msect.reloc = uint32(linereloco)
  2536  	}
  2537  
  2538  	msect = newMachoSect(ms, "__debug_frame", "__DWARF")
  2539  	msect.off = uint32(frameo)
  2540  	msect.size = uint64(framesize)
  2541  	msect.addr = addr
  2542  	addr += msect.size
  2543  	msect.flag = 0x02000000
  2544  	if framesym != nil {
  2545  		framesym.Value = int64(msect.addr)
  2546  	}
  2547  	if framerelocsize > 0 {
  2548  		msect.nreloc = uint32(len(framesec.R))
  2549  		msect.reloc = uint32(framereloco)
  2550  	}
  2551  
  2552  	msect = newMachoSect(ms, "__debug_info", "__DWARF")
  2553  	msect.off = uint32(infoo)
  2554  	msect.size = uint64(infosize)
  2555  	msect.addr = addr
  2556  	addr += msect.size
  2557  	msect.flag = 0x02000000
  2558  	if infosym != nil {
  2559  		infosym.Value = int64(msect.addr)
  2560  	}
  2561  	if inforelocsize > 0 {
  2562  		msect.nreloc = uint32(len(infosec.R))
  2563  		msect.reloc = uint32(inforeloco)
  2564  	}
  2565  
  2566  	if pubnamessize > 0 {
  2567  		msect := newMachoSect(ms, "__debug_pubnames", "__DWARF")
  2568  		msect.off = uint32(pubnameso)
  2569  		msect.size = uint64(pubnamessize)
  2570  		msect.addr = addr
  2571  		addr += msect.size
  2572  		msect.flag = 0x02000000
  2573  	}
  2574  
  2575  	if pubtypessize > 0 {
  2576  		msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF")
  2577  		msect.off = uint32(pubtypeso)
  2578  		msect.size = uint64(pubtypessize)
  2579  		msect.addr = addr
  2580  		addr += msect.size
  2581  		msect.flag = 0x02000000
  2582  	}
  2583  
  2584  	if arangessize > 0 {
  2585  		msect := newMachoSect(ms, "__debug_aranges", "__DWARF")
  2586  		msect.off = uint32(arangeso)
  2587  		msect.size = uint64(arangessize)
  2588  		msect.addr = addr
  2589  		addr += msect.size
  2590  		msect.flag = 0x02000000
  2591  		if arangesrelocsize > 0 {
  2592  			msect.nreloc = uint32(len(arangessec.R))
  2593  			msect.reloc = uint32(arangesreloco)
  2594  		}
  2595  	}
  2596  
  2597  	// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
  2598  	if gdbscriptsize > 0 {
  2599  		msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF")
  2600  		msect.off = uint32(gdbscripto)
  2601  		msect.size = uint64(gdbscriptsize)
  2602  		msect.addr = addr
  2603  		addr += msect.size
  2604  		msect.flag = 0x02000000
  2605  	}
  2606  }
  2607  
  2608  /*
  2609   * Windows PE
  2610   */
  2611  func dwarfaddpeheaders() {
  2612  	if Debug['w'] != 0 { // disable dwarf
  2613  		return
  2614  	}
  2615  
  2616  	newPEDWARFSection(".debug_abbrev", abbrevsize)
  2617  	newPEDWARFSection(".debug_line", linesize)
  2618  	newPEDWARFSection(".debug_frame", framesize)
  2619  	newPEDWARFSection(".debug_info", infosize)
  2620  	newPEDWARFSection(".debug_pubnames", pubnamessize)
  2621  	newPEDWARFSection(".debug_pubtypes", pubtypessize)
  2622  	newPEDWARFSection(".debug_aranges", arangessize)
  2623  	newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize)
  2624  }