github.com/aloncn/graphics-go@v0.0.1/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 prev *DWDie
   629  	for ; die != prev; prev, die = die, walktypedef(die) {
   630  
   631  		if die.hash == nil {
   632  			for a := die.child; a != nil; a = a.link {
   633  				if name == getattr(a, DW_AT_name).data {
   634  					return a
   635  				}
   636  			}
   637  			continue
   638  		}
   639  
   640  		h := int(dwarfhashstr(name))
   641  		a := die.hash[h]
   642  
   643  		if a == nil {
   644  			continue
   645  		}
   646  
   647  		if name == getattr(a, DW_AT_name).data {
   648  			return a
   649  		}
   650  
   651  		// Move found ones to head of the list.
   652  		for b := a.hlink; b != nil; b = b.hlink {
   653  			if name == getattr(b, DW_AT_name).data {
   654  				a.hlink = b.hlink
   655  				b.hlink = die.hash[h]
   656  				die.hash[h] = b
   657  				return b
   658  			}
   659  			a = b
   660  		}
   661  	}
   662  	return nil
   663  }
   664  
   665  func mustFind(die *DWDie, name string) *DWDie {
   666  	r := find(die, name)
   667  	if r == nil {
   668  		Exitf("dwarf find: %s %p has no %s", getattr(die, DW_AT_name).data, die, name)
   669  	}
   670  	return r
   671  }
   672  
   673  func adddwarfrel(sec *LSym, sym *LSym, offsetbase int64, siz int, addend int64) {
   674  	r := Addrel(sec)
   675  	r.Sym = sym
   676  	r.Xsym = sym
   677  	r.Off = int32(Cpos() - offsetbase)
   678  	r.Siz = uint8(siz)
   679  	r.Type = obj.R_ADDR
   680  	r.Add = addend
   681  	r.Xadd = addend
   682  	if Iself && Thearch.Thechar == '6' {
   683  		addend = 0
   684  	}
   685  	if HEADTYPE == obj.Hdarwin {
   686  		addend += sym.Value
   687  	}
   688  	switch siz {
   689  	case 4:
   690  		Thearch.Lput(uint32(addend))
   691  
   692  	case 8:
   693  		Thearch.Vput(uint64(addend))
   694  
   695  	default:
   696  		Diag("bad size in adddwarfrel")
   697  	}
   698  }
   699  
   700  func newrefattr(die *DWDie, attr uint16, ref *DWDie) *DWAttr {
   701  	if ref == nil {
   702  		return nil
   703  	}
   704  	return newattr(die, attr, DW_CLS_REFERENCE, 0, ref)
   705  }
   706  
   707  var fwdcount int
   708  
   709  func putattr(abbrev int, form int, cls int, value int64, data interface{}) {
   710  	switch form {
   711  	case DW_FORM_addr: // address
   712  		if Linkmode == LinkExternal {
   713  			value -= (data.(*LSym)).Value
   714  			adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value)
   715  			break
   716  		}
   717  
   718  		addrput(value)
   719  
   720  	case DW_FORM_block1: // block
   721  		if cls == DW_CLS_ADDRESS {
   722  			Cput(uint8(1 + Thearch.Ptrsize))
   723  			Cput(DW_OP_addr)
   724  			if Linkmode == LinkExternal {
   725  				value -= (data.(*LSym)).Value
   726  				adddwarfrel(infosec, data.(*LSym), infoo, Thearch.Ptrsize, value)
   727  				break
   728  			}
   729  
   730  			addrput(value)
   731  			break
   732  		}
   733  
   734  		value &= 0xff
   735  		Cput(uint8(value))
   736  		p := data.([]byte)
   737  		for i := 0; int64(i) < value; i++ {
   738  			Cput(uint8(p[i]))
   739  		}
   740  
   741  	case DW_FORM_block2: // block
   742  		value &= 0xffff
   743  
   744  		Thearch.Wput(uint16(value))
   745  		p := data.([]byte)
   746  		for i := 0; int64(i) < value; i++ {
   747  			Cput(uint8(p[i]))
   748  		}
   749  
   750  	case DW_FORM_block4: // block
   751  		value &= 0xffffffff
   752  
   753  		Thearch.Lput(uint32(value))
   754  		p := data.([]byte)
   755  		for i := 0; int64(i) < value; i++ {
   756  			Cput(uint8(p[i]))
   757  		}
   758  
   759  	case DW_FORM_block: // block
   760  		uleb128put(value)
   761  
   762  		p := data.([]byte)
   763  		for i := 0; int64(i) < value; i++ {
   764  			Cput(uint8(p[i]))
   765  		}
   766  
   767  	case DW_FORM_data1: // constant
   768  		Cput(uint8(value))
   769  
   770  	case DW_FORM_data2: // constant
   771  		Thearch.Wput(uint16(value))
   772  
   773  	case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr
   774  		if Linkmode == LinkExternal && cls == DW_CLS_PTR {
   775  			adddwarfrel(infosec, linesym, infoo, 4, value)
   776  			break
   777  		}
   778  
   779  		Thearch.Lput(uint32(value))
   780  
   781  	case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr
   782  		Thearch.Vput(uint64(value))
   783  
   784  	case DW_FORM_sdata: // constant
   785  		sleb128put(value)
   786  
   787  	case DW_FORM_udata: // constant
   788  		uleb128put(value)
   789  
   790  	case DW_FORM_string: // string
   791  		strnput(data.(string), int(value+1))
   792  
   793  	case DW_FORM_flag: // flag
   794  		if value != 0 {
   795  			Cput(1)
   796  		} else {
   797  			Cput(0)
   798  		}
   799  
   800  		// In DWARF 2 (which is what we claim to generate),
   801  	// the ref_addr is the same size as a normal address.
   802  	// In DWARF 3 it is always 32 bits, unless emitting a large
   803  	// (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
   804  	case DW_FORM_ref_addr: // reference to a DIE in the .info section
   805  		if data == nil {
   806  			Diag("dwarf: null reference in %d", abbrev)
   807  			if Thearch.Ptrsize == 8 {
   808  				Thearch.Vput(0) // invalid dwarf, gdb will complain.
   809  			} else {
   810  				Thearch.Lput(0) // invalid dwarf, gdb will complain.
   811  			}
   812  		} else {
   813  			off := (data.(*DWDie)).offs
   814  			if off == 0 {
   815  				fwdcount++
   816  			}
   817  			if Linkmode == LinkExternal {
   818  				adddwarfrel(infosec, infosym, infoo, Thearch.Ptrsize, off)
   819  				break
   820  			}
   821  
   822  			addrput(off)
   823  		}
   824  
   825  	case DW_FORM_ref1, // reference within the compilation unit
   826  		DW_FORM_ref2,      // reference
   827  		DW_FORM_ref4,      // reference
   828  		DW_FORM_ref8,      // reference
   829  		DW_FORM_ref_udata, // reference
   830  
   831  		DW_FORM_strp,     // string
   832  		DW_FORM_indirect: // (see Section 7.5.3)
   833  		fallthrough
   834  	default:
   835  		Exitf("dwarf: unsupported attribute form %d / class %d", form, cls)
   836  	}
   837  }
   838  
   839  // Note that we can (and do) add arbitrary attributes to a DIE, but
   840  // only the ones actually listed in the Abbrev will be written out.
   841  func putattrs(abbrev int, attr *DWAttr) {
   842  Outer:
   843  	for _, f := range abbrevs[abbrev].attr {
   844  		for ap := attr; ap != nil; ap = ap.link {
   845  			if ap.atr == f.attr {
   846  				putattr(abbrev, int(f.form), int(ap.cls), ap.value, ap.data)
   847  				continue Outer
   848  			}
   849  		}
   850  
   851  		putattr(abbrev, int(f.form), 0, 0, nil)
   852  	}
   853  }
   854  
   855  func putdies(die *DWDie) {
   856  	for ; die != nil; die = die.link {
   857  		putdie(die)
   858  	}
   859  }
   860  
   861  func putdie(die *DWDie) {
   862  	die.offs = Cpos() - infoo
   863  	uleb128put(int64(die.abbrev))
   864  	putattrs(die.abbrev, die.attr)
   865  	if abbrevs[die.abbrev].children != 0 {
   866  		putdies(die.child)
   867  		Cput(0)
   868  	}
   869  }
   870  
   871  func reverselist(list **DWDie) {
   872  	curr := *list
   873  	var prev *DWDie
   874  	for curr != nil {
   875  		var next *DWDie = curr.link
   876  		curr.link = prev
   877  		prev = curr
   878  		curr = next
   879  	}
   880  
   881  	*list = prev
   882  }
   883  
   884  func reversetree(list **DWDie) {
   885  	reverselist(list)
   886  	for die := *list; die != nil; die = die.link {
   887  		if abbrevs[die.abbrev].children != 0 {
   888  			reversetree(&die.child)
   889  		}
   890  	}
   891  }
   892  
   893  func newmemberoffsetattr(die *DWDie, offs int32) {
   894  	var block [20]byte
   895  
   896  	i := 0
   897  	block[i] = DW_OP_plus_uconst
   898  	i++
   899  	i += uleb128enc(uint64(offs), block[i:])
   900  	newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, int64(i), block[:i])
   901  }
   902  
   903  // GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
   904  // location expression that evals to a const.
   905  func newabslocexprattr(die *DWDie, addr int64, sym *LSym) {
   906  	newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, sym)
   907  	// below
   908  }
   909  
   910  // Lookup predefined types
   911  func lookup_or_diag(n string) *LSym {
   912  	s := Linkrlookup(Ctxt, n, 0)
   913  	if s == nil || s.Size == 0 {
   914  		Exitf("dwarf: missing type: %s", n)
   915  	}
   916  
   917  	return s
   918  }
   919  
   920  func dotypedef(parent *DWDie, name string, def *DWDie) {
   921  	// Only emit typedefs for real names.
   922  	if strings.HasPrefix(name, "map[") {
   923  		return
   924  	}
   925  	if strings.HasPrefix(name, "struct {") {
   926  		return
   927  	}
   928  	if strings.HasPrefix(name, "chan ") {
   929  		return
   930  	}
   931  	if name[0] == '[' || name[0] == '*' {
   932  		return
   933  	}
   934  	if def == nil {
   935  		Diag("dwarf: bad def in dotypedef")
   936  	}
   937  
   938  	// The typedef entry must be created after the def,
   939  	// so that future lookups will find the typedef instead
   940  	// of the real definition. This hooks the typedef into any
   941  	// circular definition loops, so that gdb can understand them.
   942  	die := newdie(parent, DW_ABRV_TYPEDECL, name)
   943  
   944  	newrefattr(die, DW_AT_type, def)
   945  }
   946  
   947  // Define gotype, for composite ones recurse into constituents.
   948  func defgotype(gotype *LSym) *DWDie {
   949  	if gotype == nil {
   950  		return mustFind(&dwtypes, "<unspecified>")
   951  	}
   952  
   953  	if !strings.HasPrefix(gotype.Name, "type.") {
   954  		Diag("dwarf: type name doesn't start with \".type\": %s", gotype.Name)
   955  		return mustFind(&dwtypes, "<unspecified>")
   956  	}
   957  
   958  	name := gotype.Name[5:] // could also decode from Type.string
   959  
   960  	die := find(&dwtypes, name)
   961  
   962  	if die != nil {
   963  		return die
   964  	}
   965  
   966  	if false && Debug['v'] > 2 {
   967  		fmt.Printf("new type: %v\n", gotype)
   968  	}
   969  
   970  	kind := decodetype_kind(gotype)
   971  	bytesize := decodetype_size(gotype)
   972  
   973  	switch kind {
   974  	case obj.KindBool:
   975  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
   976  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_boolean, 0)
   977  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   978  
   979  	case obj.KindInt,
   980  		obj.KindInt8,
   981  		obj.KindInt16,
   982  		obj.KindInt32,
   983  		obj.KindInt64:
   984  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
   985  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_signed, 0)
   986  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   987  
   988  	case obj.KindUint,
   989  		obj.KindUint8,
   990  		obj.KindUint16,
   991  		obj.KindUint32,
   992  		obj.KindUint64,
   993  		obj.KindUintptr:
   994  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
   995  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
   996  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
   997  
   998  	case obj.KindFloat32,
   999  		obj.KindFloat64:
  1000  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
  1001  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_float, 0)
  1002  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
  1003  
  1004  	case obj.KindComplex64,
  1005  		obj.KindComplex128:
  1006  		die = newdie(&dwtypes, DW_ABRV_BASETYPE, name)
  1007  		newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_complex_float, 0)
  1008  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
  1009  
  1010  	case obj.KindArray:
  1011  		die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name)
  1012  		dotypedef(&dwtypes, name, die)
  1013  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
  1014  		s := decodetype_arrayelem(gotype)
  1015  		newrefattr(die, DW_AT_type, defgotype(s))
  1016  		fld := newdie(die, DW_ABRV_ARRAYRANGE, "range")
  1017  
  1018  		// use actual length not upper bound; correct for 0-length arrays.
  1019  		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0)
  1020  
  1021  		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
  1022  
  1023  	case obj.KindChan:
  1024  		die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name)
  1025  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
  1026  		s := decodetype_chanelem(gotype)
  1027  		newrefattr(die, DW_AT_go_elem, defgotype(s))
  1028  
  1029  	case obj.KindFunc:
  1030  		die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name)
  1031  		dotypedef(&dwtypes, name, die)
  1032  		newrefattr(die, DW_AT_type, mustFind(&dwtypes, "void"))
  1033  		nfields := decodetype_funcincount(gotype)
  1034  		var fld *DWDie
  1035  		var s *LSym
  1036  		for i := 0; i < nfields; i++ {
  1037  			s = decodetype_funcintype(gotype, i)
  1038  			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:])
  1039  			newrefattr(fld, DW_AT_type, defgotype(s))
  1040  		}
  1041  
  1042  		if decodetype_funcdotdotdot(gotype) != 0 {
  1043  			newdie(die, DW_ABRV_DOTDOTDOT, "...")
  1044  		}
  1045  		nfields = decodetype_funcoutcount(gotype)
  1046  		for i := 0; i < nfields; i++ {
  1047  			s = decodetype_funcouttype(gotype, i)
  1048  			fld = newdie(die, DW_ABRV_FUNCTYPEPARAM, s.Name[5:])
  1049  			newrefattr(fld, DW_AT_type, defptrto(defgotype(s)))
  1050  		}
  1051  
  1052  	case obj.KindInterface:
  1053  		die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name)
  1054  		dotypedef(&dwtypes, name, die)
  1055  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
  1056  		nfields := int(decodetype_ifacemethodcount(gotype))
  1057  		var s *LSym
  1058  		if nfields == 0 {
  1059  			s = lookup_or_diag("type.runtime.eface")
  1060  		} else {
  1061  			s = lookup_or_diag("type.runtime.iface")
  1062  		}
  1063  		newrefattr(die, DW_AT_type, defgotype(s))
  1064  
  1065  	case obj.KindMap:
  1066  		die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name)
  1067  		s := decodetype_mapkey(gotype)
  1068  		newrefattr(die, DW_AT_go_key, defgotype(s))
  1069  		s = decodetype_mapvalue(gotype)
  1070  		newrefattr(die, DW_AT_go_elem, defgotype(s))
  1071  
  1072  	case obj.KindPtr:
  1073  		die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name)
  1074  		dotypedef(&dwtypes, name, die)
  1075  		s := decodetype_ptrelem(gotype)
  1076  		newrefattr(die, DW_AT_type, defgotype(s))
  1077  
  1078  	case obj.KindSlice:
  1079  		die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name)
  1080  		dotypedef(&dwtypes, name, die)
  1081  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
  1082  		s := decodetype_arrayelem(gotype)
  1083  		newrefattr(die, DW_AT_go_elem, defgotype(s))
  1084  
  1085  	case obj.KindString:
  1086  		die = newdie(&dwtypes, DW_ABRV_STRINGTYPE, name)
  1087  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
  1088  
  1089  	case obj.KindStruct:
  1090  		die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name)
  1091  		dotypedef(&dwtypes, name, die)
  1092  		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0)
  1093  		nfields := decodetype_structfieldcount(gotype)
  1094  		var f string
  1095  		var fld *DWDie
  1096  		var s *LSym
  1097  		for i := 0; i < nfields; i++ {
  1098  			f = decodetype_structfieldname(gotype, i)
  1099  			s = decodetype_structfieldtype(gotype, i)
  1100  			if f == "" {
  1101  				f = s.Name[5:] // skip "type."
  1102  			}
  1103  			fld = newdie(die, DW_ABRV_STRUCTFIELD, f)
  1104  			newrefattr(fld, DW_AT_type, defgotype(s))
  1105  			newmemberoffsetattr(fld, int32(decodetype_structfieldoffs(gotype, i)))
  1106  		}
  1107  
  1108  	case obj.KindUnsafePointer:
  1109  		die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name)
  1110  
  1111  	default:
  1112  		Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name)
  1113  		die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name)
  1114  		newrefattr(die, DW_AT_type, mustFind(&dwtypes, "<unspecified>"))
  1115  	}
  1116  
  1117  	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, int64(kind), 0)
  1118  
  1119  	return die
  1120  }
  1121  
  1122  // Find or construct *T given T.
  1123  func defptrto(dwtype *DWDie) *DWDie {
  1124  	ptrname := fmt.Sprintf("*%s", getattr(dwtype, DW_AT_name).data)
  1125  	die := find(&dwtypes, ptrname)
  1126  	if die == nil {
  1127  		die = newdie(&dwtypes, DW_ABRV_PTRTYPE, ptrname)
  1128  		newrefattr(die, DW_AT_type, dwtype)
  1129  	}
  1130  
  1131  	return die
  1132  }
  1133  
  1134  // Copies src's children into dst. Copies attributes by value.
  1135  // DWAttr.data is copied as pointer only.  If except is one of
  1136  // the top-level children, it will not be copied.
  1137  func copychildrenexcept(dst *DWDie, src *DWDie, except *DWDie) {
  1138  	for src = src.child; src != nil; src = src.link {
  1139  		if src == except {
  1140  			continue
  1141  		}
  1142  		c := newdie(dst, src.abbrev, getattr(src, DW_AT_name).data.(string))
  1143  		for a := src.attr; a != nil; a = a.link {
  1144  			newattr(c, a.atr, int(a.cls), a.value, a.data)
  1145  		}
  1146  		copychildrenexcept(c, src, nil)
  1147  	}
  1148  
  1149  	reverselist(&dst.child)
  1150  }
  1151  
  1152  func copychildren(dst *DWDie, src *DWDie) {
  1153  	copychildrenexcept(dst, src, nil)
  1154  }
  1155  
  1156  // Search children (assumed to have DW_TAG_member) for the one named
  1157  // field and set its DW_AT_type to dwtype
  1158  func substitutetype(structdie *DWDie, field string, dwtype *DWDie) {
  1159  	child := mustFind(structdie, field)
  1160  	if child == nil {
  1161  		return
  1162  	}
  1163  
  1164  	a := getattr(child, DW_AT_type)
  1165  	if a != nil {
  1166  		a.data = dwtype
  1167  	} else {
  1168  		newrefattr(child, DW_AT_type, dwtype)
  1169  	}
  1170  }
  1171  
  1172  func synthesizestringtypes(die *DWDie) {
  1173  	prototype := walktypedef(defgotype(lookup_or_diag("type.runtime.stringStructDWARF")))
  1174  	if prototype == nil {
  1175  		return
  1176  	}
  1177  
  1178  	for ; die != nil; die = die.link {
  1179  		if die.abbrev != DW_ABRV_STRINGTYPE {
  1180  			continue
  1181  		}
  1182  		copychildren(die, prototype)
  1183  	}
  1184  }
  1185  
  1186  func synthesizeslicetypes(die *DWDie) {
  1187  	prototype := walktypedef(defgotype(lookup_or_diag("type.runtime.slice")))
  1188  	if prototype == nil {
  1189  		return
  1190  	}
  1191  
  1192  	for ; die != nil; die = die.link {
  1193  		if die.abbrev != DW_ABRV_SLICETYPE {
  1194  			continue
  1195  		}
  1196  		copychildren(die, prototype)
  1197  		elem := getattr(die, DW_AT_go_elem).data.(*DWDie)
  1198  		substitutetype(die, "array", defptrto(elem))
  1199  	}
  1200  }
  1201  
  1202  func mkinternaltypename(base string, arg1 string, arg2 string) string {
  1203  	var buf string
  1204  
  1205  	if arg2 == "" {
  1206  		buf = fmt.Sprintf("%s<%s>", base, arg1)
  1207  	} else {
  1208  		buf = fmt.Sprintf("%s<%s,%s>", base, arg1, arg2)
  1209  	}
  1210  	n := buf
  1211  	return n
  1212  }
  1213  
  1214  // synthesizemaptypes is way too closely married to runtime/hashmap.c
  1215  const (
  1216  	MaxKeySize = 128
  1217  	MaxValSize = 128
  1218  	BucketSize = 8
  1219  )
  1220  
  1221  func synthesizemaptypes(die *DWDie) {
  1222  	hash := walktypedef(defgotype(lookup_or_diag("type.runtime.hmap")))
  1223  	bucket := walktypedef(defgotype(lookup_or_diag("type.runtime.bmap")))
  1224  
  1225  	if hash == nil {
  1226  		return
  1227  	}
  1228  
  1229  	for ; die != nil; die = die.link {
  1230  		if die.abbrev != DW_ABRV_MAPTYPE {
  1231  			continue
  1232  		}
  1233  
  1234  		keytype := walktypedef(getattr(die, DW_AT_go_key).data.(*DWDie))
  1235  		valtype := walktypedef(getattr(die, DW_AT_go_elem).data.(*DWDie))
  1236  
  1237  		// compute size info like hashmap.c does.
  1238  		keysize, valsize := Thearch.Ptrsize, Thearch.Ptrsize
  1239  		a := getattr(keytype, DW_AT_byte_size)
  1240  		if a != nil {
  1241  			keysize = int(a.value)
  1242  		}
  1243  		a = getattr(valtype, DW_AT_byte_size)
  1244  		if a != nil {
  1245  			valsize = int(a.value)
  1246  		}
  1247  		indirect_key, indirect_val := false, false
  1248  		if keysize > MaxKeySize {
  1249  			keysize = Thearch.Ptrsize
  1250  			indirect_key = true
  1251  		}
  1252  		if valsize > MaxValSize {
  1253  			valsize = Thearch.Ptrsize
  1254  			indirect_val = true
  1255  		}
  1256  
  1257  		// Construct type to represent an array of BucketSize keys
  1258  		dwhk := newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]key", getattr(keytype, DW_AT_name).data.(string), ""))
  1259  
  1260  		newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(keysize), 0)
  1261  		t := keytype
  1262  		if indirect_key {
  1263  			t = defptrto(keytype)
  1264  		}
  1265  		newrefattr(dwhk, DW_AT_type, t)
  1266  		fld := newdie(dwhk, DW_ABRV_ARRAYRANGE, "size")
  1267  		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
  1268  		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
  1269  
  1270  		// Construct type to represent an array of BucketSize values
  1271  		dwhv := newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]val", getattr(valtype, DW_AT_name).data.(string), ""))
  1272  
  1273  		newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize*int64(valsize), 0)
  1274  		t = valtype
  1275  		if indirect_val {
  1276  			t = defptrto(valtype)
  1277  		}
  1278  		newrefattr(dwhv, DW_AT_type, t)
  1279  		fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size")
  1280  		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
  1281  		newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
  1282  
  1283  		// Construct bucket<K,V>
  1284  		dwhb := newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("bucket", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string)))
  1285  
  1286  		// Copy over all fields except the field "data" from the generic bucket.
  1287  		// "data" will be replaced with keys/values below.
  1288  		copychildrenexcept(dwhb, bucket, find(bucket, "data"))
  1289  
  1290  		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "keys")
  1291  		newrefattr(fld, DW_AT_type, dwhk)
  1292  		newmemberoffsetattr(fld, BucketSize)
  1293  		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "values")
  1294  		newrefattr(fld, DW_AT_type, dwhv)
  1295  		newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize))
  1296  		fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow")
  1297  		newrefattr(fld, DW_AT_type, defptrto(dwhb))
  1298  		newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
  1299  		if Thearch.Regsize > Thearch.Ptrsize {
  1300  			fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad")
  1301  			newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
  1302  			newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(Thearch.Ptrsize))
  1303  		}
  1304  
  1305  		newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize+BucketSize*int64(keysize)+BucketSize*int64(valsize)+int64(Thearch.Regsize), 0)
  1306  
  1307  		// Construct hash<K,V>
  1308  		dwh := newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("hash", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string)))
  1309  
  1310  		copychildren(dwh, hash)
  1311  		substitutetype(dwh, "buckets", defptrto(dwhb))
  1312  		substitutetype(dwh, "oldbuckets", defptrto(dwhb))
  1313  		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hash, DW_AT_byte_size).value, nil)
  1314  
  1315  		// make map type a pointer to hash<K,V>
  1316  		newrefattr(die, DW_AT_type, defptrto(dwh))
  1317  	}
  1318  }
  1319  
  1320  func synthesizechantypes(die *DWDie) {
  1321  	sudog := walktypedef(defgotype(lookup_or_diag("type.runtime.sudog")))
  1322  	waitq := walktypedef(defgotype(lookup_or_diag("type.runtime.waitq")))
  1323  	hchan := walktypedef(defgotype(lookup_or_diag("type.runtime.hchan")))
  1324  	if sudog == nil || waitq == nil || hchan == nil {
  1325  		return
  1326  	}
  1327  
  1328  	sudogsize := int(getattr(sudog, DW_AT_byte_size).value)
  1329  
  1330  	for ; die != nil; die = die.link {
  1331  		if die.abbrev != DW_ABRV_CHANTYPE {
  1332  			continue
  1333  		}
  1334  		elemsize := Thearch.Ptrsize
  1335  		elemtype := getattr(die, DW_AT_go_elem).data.(*DWDie)
  1336  		a := getattr(elemtype, DW_AT_byte_size)
  1337  		if a != nil {
  1338  			elemsize = int(a.value)
  1339  		}
  1340  
  1341  		// sudog<T>
  1342  		dws := newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("sudog", getattr(elemtype, DW_AT_name).data.(string), ""))
  1343  
  1344  		copychildren(dws, sudog)
  1345  		substitutetype(dws, "elem", elemtype)
  1346  		if elemsize > 8 {
  1347  			elemsize -= 8
  1348  		} else {
  1349  			elemsize = 0
  1350  		}
  1351  		newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT, int64(sudogsize)+int64(elemsize), nil)
  1352  
  1353  		// waitq<T>
  1354  		dww := newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("waitq", getattr(elemtype, DW_AT_name).data.(string), ""))
  1355  
  1356  		copychildren(dww, waitq)
  1357  		substitutetype(dww, "first", defptrto(dws))
  1358  		substitutetype(dww, "last", defptrto(dws))
  1359  		newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(waitq, DW_AT_byte_size).value, nil)
  1360  
  1361  		// hchan<T>
  1362  		dwh := newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("hchan", getattr(elemtype, DW_AT_name).data.(string), ""))
  1363  
  1364  		copychildren(dwh, hchan)
  1365  		substitutetype(dwh, "recvq", dww)
  1366  		substitutetype(dwh, "sendq", dww)
  1367  		newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT, getattr(hchan, DW_AT_byte_size).value, nil)
  1368  
  1369  		newrefattr(die, DW_AT_type, defptrto(dwh))
  1370  	}
  1371  }
  1372  
  1373  // For use with pass.c::genasmsym
  1374  func defdwsymb(sym *LSym, s string, t int, v int64, size int64, ver int, gotype *LSym) {
  1375  	if strings.HasPrefix(s, "go.string.") {
  1376  		return
  1377  	}
  1378  	if strings.HasPrefix(s, "runtime.gcbits.") {
  1379  		return
  1380  	}
  1381  
  1382  	if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
  1383  		defgotype(sym)
  1384  		return
  1385  	}
  1386  
  1387  	var dv *DWDie
  1388  
  1389  	var dt *DWDie
  1390  	switch t {
  1391  	default:
  1392  		return
  1393  
  1394  	case 'd', 'b', 'D', 'B':
  1395  		dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s)
  1396  		newabslocexprattr(dv, v, sym)
  1397  		if ver == 0 {
  1398  			newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0)
  1399  		}
  1400  		fallthrough
  1401  
  1402  	case 'a', 'p':
  1403  		dt = defgotype(gotype)
  1404  	}
  1405  
  1406  	if dv != nil {
  1407  		newrefattr(dv, DW_AT_type, dt)
  1408  	}
  1409  }
  1410  
  1411  func movetomodule(parent *DWDie) {
  1412  	die := dwroot.child.child
  1413  	for die.link != nil {
  1414  		die = die.link
  1415  	}
  1416  	die.link = parent.child
  1417  }
  1418  
  1419  // If the pcln table contains runtime/runtime.go, use that to set gdbscript path.
  1420  func finddebugruntimepath(s *LSym) {
  1421  	if gdbscript != "" {
  1422  		return
  1423  	}
  1424  
  1425  	for i := 0; i < s.Pcln.Nfile; i++ {
  1426  		f := s.Pcln.File[i]
  1427  		if i := strings.Index(f.Name, "runtime/runtime.go"); i >= 0 {
  1428  			gdbscript = f.Name[:i] + "runtime/runtime-gdb.py"
  1429  			break
  1430  		}
  1431  	}
  1432  }
  1433  
  1434  /*
  1435   * Generate short opcodes when possible, long ones when necessary.
  1436   * See section 6.2.5
  1437   */
  1438  const (
  1439  	LINE_BASE   = -1
  1440  	LINE_RANGE  = 4
  1441  	OPCODE_BASE = 10
  1442  )
  1443  
  1444  func putpclcdelta(delta_pc int64, delta_lc int64) {
  1445  	if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE {
  1446  		var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc)
  1447  		if OPCODE_BASE <= opcode && opcode < 256 {
  1448  			Cput(uint8(opcode))
  1449  			return
  1450  		}
  1451  	}
  1452  
  1453  	if delta_pc != 0 {
  1454  		Cput(DW_LNS_advance_pc)
  1455  		sleb128put(delta_pc)
  1456  	}
  1457  
  1458  	Cput(DW_LNS_advance_line)
  1459  	sleb128put(delta_lc)
  1460  	Cput(DW_LNS_copy)
  1461  }
  1462  
  1463  func newcfaoffsetattr(die *DWDie, offs int32) {
  1464  	var block [20]byte
  1465  
  1466  	i := 0
  1467  
  1468  	block[i] = DW_OP_call_frame_cfa
  1469  	i++
  1470  	if offs != 0 {
  1471  		block[i] = DW_OP_consts
  1472  		i++
  1473  		i += sleb128enc(int64(offs), block[i:])
  1474  		block[i] = DW_OP_plus
  1475  		i++
  1476  	}
  1477  
  1478  	newattr(die, DW_AT_location, DW_CLS_BLOCK, int64(i), block[:i])
  1479  }
  1480  
  1481  func mkvarname(name string, da int) string {
  1482  	buf := fmt.Sprintf("%s#%d", name, da)
  1483  	n := buf
  1484  	return n
  1485  }
  1486  
  1487  /*
  1488   * Walk prog table, emit line program and build DIE tree.
  1489   */
  1490  
  1491  // flush previous compilation unit.
  1492  func flushunit(dwinfo *DWDie, pc int64, pcsym *LSym, unitstart int64, header_length int32) {
  1493  	if dwinfo != nil && pc != 0 {
  1494  		newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, pcsym)
  1495  	}
  1496  
  1497  	if unitstart >= 0 {
  1498  		Cput(0) // start extended opcode
  1499  		uleb128put(1)
  1500  		Cput(DW_LNE_end_sequence)
  1501  
  1502  		here := Cpos()
  1503  		Cseek(unitstart)
  1504  		Thearch.Lput(uint32(here - unitstart - 4)) // unit_length
  1505  		Thearch.Wput(2)                            // dwarf version
  1506  		Thearch.Lput(uint32(header_length))        // header length starting here
  1507  		Cseek(here)
  1508  	}
  1509  }
  1510  
  1511  func getCompilationDir() string {
  1512  	if dir, err := os.Getwd(); err == nil {
  1513  		return dir
  1514  	}
  1515  	return "/"
  1516  }
  1517  
  1518  func writelines() {
  1519  	if linesec == nil {
  1520  		linesec = Linklookup(Ctxt, ".dwarfline", 0)
  1521  	}
  1522  	linesec.R = linesec.R[:0]
  1523  
  1524  	unitstart := int64(-1)
  1525  	headerend := int64(-1)
  1526  	epc := int64(0)
  1527  	var epcs *LSym
  1528  	lineo = Cpos()
  1529  	var dwinfo *DWDie
  1530  	flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10))
  1531  	unitstart = Cpos()
  1532  
  1533  	lang := DW_LANG_Go
  1534  
  1535  	s := Ctxt.Textp
  1536  
  1537  	dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, "go")
  1538  	newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(lang), 0)
  1539  	newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart-lineo, 0)
  1540  	newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
  1541  	// OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
  1542  	compDir := getCompilationDir()
  1543  	newattr(dwinfo, DW_AT_comp_dir, DW_CLS_STRING, int64(len(compDir)), compDir)
  1544  
  1545  	// Write .debug_line Line Number Program Header (sec 6.2.4)
  1546  	// Fields marked with (*) must be changed for 64-bit dwarf
  1547  	Thearch.Lput(0) // unit_length (*), will be filled in by flushunit.
  1548  	Thearch.Wput(2) // dwarf version (appendix F)
  1549  	Thearch.Lput(0) // header_length (*), filled in by flushunit.
  1550  
  1551  	// cpos == unitstart + 4 + 2 + 4
  1552  	Cput(1)                // minimum_instruction_length
  1553  	Cput(1)                // default_is_stmt
  1554  	Cput(LINE_BASE & 0xFF) // line_base
  1555  	Cput(LINE_RANGE)       // line_range
  1556  	Cput(OPCODE_BASE)      // opcode_base
  1557  	Cput(0)                // standard_opcode_lengths[1]
  1558  	Cput(1)                // standard_opcode_lengths[2]
  1559  	Cput(1)                // standard_opcode_lengths[3]
  1560  	Cput(1)                // standard_opcode_lengths[4]
  1561  	Cput(1)                // standard_opcode_lengths[5]
  1562  	Cput(0)                // standard_opcode_lengths[6]
  1563  	Cput(0)                // standard_opcode_lengths[7]
  1564  	Cput(0)                // standard_opcode_lengths[8]
  1565  	Cput(1)                // standard_opcode_lengths[9]
  1566  	Cput(0)                // include_directories  (empty)
  1567  
  1568  	files := make([]*LSym, Ctxt.Nhistfile)
  1569  
  1570  	for f := Ctxt.Filesyms; f != nil; f = f.Next {
  1571  		files[f.Value-1] = f
  1572  	}
  1573  
  1574  	for i := 0; int32(i) < Ctxt.Nhistfile; i++ {
  1575  		strnput(files[i].Name, len(files[i].Name)+4)
  1576  	}
  1577  
  1578  	// 4 zeros: the string termination + 3 fields.
  1579  	Cput(0)
  1580  	// terminate file_names.
  1581  	headerend = Cpos()
  1582  
  1583  	Cput(0) // start extended opcode
  1584  	uleb128put(1 + int64(Thearch.Ptrsize))
  1585  	Cput(DW_LNE_set_address)
  1586  
  1587  	pc := s.Value
  1588  	line := 1
  1589  	file := 1
  1590  	if Linkmode == LinkExternal {
  1591  		adddwarfrel(linesec, s, lineo, Thearch.Ptrsize, 0)
  1592  	} else {
  1593  		addrput(pc)
  1594  	}
  1595  
  1596  	var pcfile Pciter
  1597  	var pcline Pciter
  1598  	for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
  1599  		s = Ctxt.Cursym
  1600  
  1601  		dwfunc := newdie(dwinfo, DW_ABRV_FUNCTION, s.Name)
  1602  		newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s.Value, s)
  1603  		epc = s.Value + s.Size
  1604  		epcs = s
  1605  		newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, s)
  1606  		if s.Version == 0 {
  1607  			newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0)
  1608  		}
  1609  
  1610  		if s.Pcln == nil {
  1611  			continue
  1612  		}
  1613  
  1614  		finddebugruntimepath(s)
  1615  
  1616  		pciterinit(Ctxt, &pcfile, &s.Pcln.Pcfile)
  1617  		pciterinit(Ctxt, &pcline, &s.Pcln.Pcline)
  1618  		epc = pc
  1619  		for pcfile.done == 0 && pcline.done == 0 {
  1620  			if epc-s.Value >= int64(pcfile.nextpc) {
  1621  				pciternext(&pcfile)
  1622  				continue
  1623  			}
  1624  
  1625  			if epc-s.Value >= int64(pcline.nextpc) {
  1626  				pciternext(&pcline)
  1627  				continue
  1628  			}
  1629  
  1630  			if int32(file) != pcfile.value {
  1631  				Cput(DW_LNS_set_file)
  1632  				uleb128put(int64(pcfile.value))
  1633  				file = int(pcfile.value)
  1634  			}
  1635  
  1636  			putpclcdelta(s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line))
  1637  
  1638  			pc = s.Value + int64(pcline.pc)
  1639  			line = int(pcline.value)
  1640  			if pcfile.nextpc < pcline.nextpc {
  1641  				epc = int64(pcfile.nextpc)
  1642  			} else {
  1643  				epc = int64(pcline.nextpc)
  1644  			}
  1645  			epc += s.Value
  1646  		}
  1647  
  1648  		var (
  1649  			dt      int
  1650  			offs    int64
  1651  			varhash [HASHSIZE]*DWDie
  1652  		)
  1653  		da := 0
  1654  		dwfunc.hash = varhash[:] // enable indexing of children by name
  1655  		for a := s.Autom; a != nil; a = a.Link {
  1656  			switch a.Name {
  1657  			case obj.A_AUTO:
  1658  				dt = DW_ABRV_AUTO
  1659  				offs = int64(a.Aoffset)
  1660  				if !haslinkregister() {
  1661  					offs -= int64(Thearch.Ptrsize)
  1662  				}
  1663  
  1664  			case obj.A_PARAM:
  1665  				dt = DW_ABRV_PARAM
  1666  				offs = int64(a.Aoffset) + Ctxt.FixedFrameSize()
  1667  
  1668  			default:
  1669  				continue
  1670  			}
  1671  
  1672  			if strings.Contains(a.Asym.Name, ".autotmp_") {
  1673  				continue
  1674  			}
  1675  			var n string
  1676  			if find(dwfunc, a.Asym.Name) != nil {
  1677  				n = mkvarname(a.Asym.Name, da)
  1678  			} else {
  1679  				n = a.Asym.Name
  1680  			}
  1681  
  1682  			// Drop the package prefix from locals and arguments.
  1683  			if i := strings.LastIndex(n, "."); i >= 0 {
  1684  				n = n[i+1:]
  1685  			}
  1686  
  1687  			dwvar := newdie(dwfunc, dt, n)
  1688  			newcfaoffsetattr(dwvar, int32(offs))
  1689  			newrefattr(dwvar, DW_AT_type, defgotype(a.Gotype))
  1690  
  1691  			// push dwvar down dwfunc->child to preserve order
  1692  			newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil)
  1693  
  1694  			dwfunc.child = dwvar.link // take dwvar out from the top of the list
  1695  			dws := &dwfunc.child
  1696  			for ; *dws != nil; dws = &(*dws).link {
  1697  				if offs > getattr(*dws, DW_AT_internal_location).value {
  1698  					break
  1699  				}
  1700  			}
  1701  			dwvar.link = *dws
  1702  			*dws = dwvar
  1703  
  1704  			da++
  1705  		}
  1706  
  1707  		dwfunc.hash = nil
  1708  	}
  1709  
  1710  	flushunit(dwinfo, epc, epcs, unitstart, int32(headerend-unitstart-10))
  1711  	linesize = Cpos() - lineo
  1712  }
  1713  
  1714  /*
  1715   *  Emit .debug_frame
  1716   */
  1717  const (
  1718  	CIERESERVE          = 16
  1719  	DATAALIGNMENTFACTOR = -4
  1720  )
  1721  
  1722  func putpccfadelta(deltapc int64, cfa int64) {
  1723  	Cput(DW_CFA_def_cfa_offset_sf)
  1724  	sleb128put(cfa / DATAALIGNMENTFACTOR)
  1725  
  1726  	if deltapc < 0x40 {
  1727  		Cput(uint8(DW_CFA_advance_loc + deltapc))
  1728  	} else if deltapc < 0x100 {
  1729  		Cput(DW_CFA_advance_loc1)
  1730  		Cput(uint8(deltapc))
  1731  	} else if deltapc < 0x10000 {
  1732  		Cput(DW_CFA_advance_loc2)
  1733  		Thearch.Wput(uint16(deltapc))
  1734  	} else {
  1735  		Cput(DW_CFA_advance_loc4)
  1736  		Thearch.Lput(uint32(deltapc))
  1737  	}
  1738  }
  1739  
  1740  func writeframes() {
  1741  	if framesec == nil {
  1742  		framesec = Linklookup(Ctxt, ".dwarfframe", 0)
  1743  	}
  1744  	framesec.R = framesec.R[:0]
  1745  	frameo = Cpos()
  1746  
  1747  	// Emit the CIE, Section 6.4.1
  1748  	Thearch.Lput(CIERESERVE)              // initial length, must be multiple of thearch.ptrsize
  1749  	Thearch.Lput(0xffffffff)              // cid.
  1750  	Cput(3)                               // dwarf version (appendix F)
  1751  	Cput(0)                               // augmentation ""
  1752  	uleb128put(1)                         // code_alignment_factor
  1753  	sleb128put(DATAALIGNMENTFACTOR)       // guess
  1754  	uleb128put(int64(Thearch.Dwarfreglr)) // return_address_register
  1755  
  1756  	Cput(DW_CFA_def_cfa)
  1757  
  1758  	uleb128put(int64(Thearch.Dwarfregsp)) // register SP (**ABI-dependent, defined in l.h)
  1759  	if haslinkregister() {
  1760  		uleb128put(int64(0)) // offset
  1761  	} else {
  1762  		uleb128put(int64(Thearch.Ptrsize)) // offset
  1763  	}
  1764  
  1765  	Cput(DW_CFA_offset_extended)
  1766  	uleb128put(int64(Thearch.Dwarfreglr)) // return address
  1767  	if haslinkregister() {
  1768  		uleb128put(int64(0) / DATAALIGNMENTFACTOR) // at cfa - 0
  1769  	} else {
  1770  		uleb128put(int64(-Thearch.Ptrsize) / DATAALIGNMENTFACTOR) // at cfa - x*4
  1771  	}
  1772  
  1773  	// 4 is to exclude the length field.
  1774  	pad := CIERESERVE + frameo + 4 - Cpos()
  1775  
  1776  	if pad < 0 {
  1777  		Exitf("dwarf: CIERESERVE too small by %d bytes.", -pad)
  1778  	}
  1779  
  1780  	strnput("", int(pad))
  1781  
  1782  	var pcsp Pciter
  1783  	for Ctxt.Cursym = Ctxt.Textp; Ctxt.Cursym != nil; Ctxt.Cursym = Ctxt.Cursym.Next {
  1784  		s := Ctxt.Cursym
  1785  		if s.Pcln == nil {
  1786  			continue
  1787  		}
  1788  
  1789  		fdeo := Cpos()
  1790  
  1791  		// Emit a FDE, Section 6.4.1, starting wit a placeholder.
  1792  		Thearch.Lput(0) // length, must be multiple of thearch.ptrsize
  1793  		Thearch.Lput(0) // Pointer to the CIE above, at offset 0
  1794  		addrput(0)      // initial location
  1795  		addrput(0)      // address range
  1796  
  1797  		for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
  1798  			nextpc := pcsp.nextpc
  1799  
  1800  			// pciterinit goes up to the end of the function,
  1801  			// but DWARF expects us to stop just before the end.
  1802  			if int64(nextpc) == s.Size {
  1803  				nextpc--
  1804  				if nextpc < pcsp.pc {
  1805  					continue
  1806  				}
  1807  			}
  1808  
  1809  			if haslinkregister() {
  1810  				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
  1811  			} else {
  1812  				putpccfadelta(int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value))
  1813  			}
  1814  		}
  1815  
  1816  		fdesize := Cpos() - fdeo - 4 // exclude the length field.
  1817  		pad = Rnd(fdesize, int64(Thearch.Ptrsize)) - fdesize
  1818  		strnput("", int(pad))
  1819  		fdesize += pad
  1820  
  1821  		// Emit the FDE header for real, Section 6.4.1.
  1822  		Cseek(fdeo)
  1823  
  1824  		Thearch.Lput(uint32(fdesize))
  1825  		if Linkmode == LinkExternal {
  1826  			adddwarfrel(framesec, framesym, frameo, 4, 0)
  1827  			adddwarfrel(framesec, s, frameo, Thearch.Ptrsize, 0)
  1828  		} else {
  1829  			Thearch.Lput(0)
  1830  			addrput(s.Value)
  1831  		}
  1832  
  1833  		addrput(s.Size)
  1834  		Cseek(fdeo + 4 + fdesize)
  1835  	}
  1836  
  1837  	Cflush()
  1838  	framesize = Cpos() - frameo
  1839  }
  1840  
  1841  /*
  1842   *  Walk DWarfDebugInfoEntries, and emit .debug_info
  1843   */
  1844  const (
  1845  	COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
  1846  )
  1847  
  1848  func writeinfo() {
  1849  	fwdcount = 0
  1850  	if infosec == nil {
  1851  		infosec = Linklookup(Ctxt, ".dwarfinfo", 0)
  1852  	}
  1853  	infosec.R = infosec.R[:0]
  1854  
  1855  	if arangessec == nil {
  1856  		arangessec = Linklookup(Ctxt, ".dwarfaranges", 0)
  1857  	}
  1858  	arangessec.R = arangessec.R[:0]
  1859  
  1860  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1861  		unitstart := Cpos()
  1862  
  1863  		// Write .debug_info Compilation Unit Header (sec 7.5.1)
  1864  		// Fields marked with (*) must be changed for 64-bit dwarf
  1865  		// This must match COMPUNITHEADERSIZE above.
  1866  		Thearch.Lput(0) // unit_length (*), will be filled in later.
  1867  		Thearch.Wput(2) // dwarf version (appendix F)
  1868  
  1869  		// debug_abbrev_offset (*)
  1870  		if Linkmode == LinkExternal {
  1871  			adddwarfrel(infosec, abbrevsym, infoo, 4, 0)
  1872  		} else {
  1873  			Thearch.Lput(0)
  1874  		}
  1875  
  1876  		Cput(uint8(Thearch.Ptrsize)) // address_size
  1877  
  1878  		putdie(compunit)
  1879  
  1880  		here := Cpos()
  1881  		Cseek(unitstart)
  1882  		Thearch.Lput(uint32(here - unitstart - 4)) // exclude the length field.
  1883  		Cseek(here)
  1884  	}
  1885  
  1886  	Cflush()
  1887  }
  1888  
  1889  /*
  1890   *  Emit .debug_pubnames/_types.  _info must have been written before,
  1891   *  because we need die->offs and infoo/infosize;
  1892   */
  1893  func ispubname(die *DWDie) bool {
  1894  	switch die.abbrev {
  1895  	case DW_ABRV_FUNCTION, DW_ABRV_VARIABLE:
  1896  		a := getattr(die, DW_AT_external)
  1897  		return a != nil && a.value != 0
  1898  	}
  1899  
  1900  	return false
  1901  }
  1902  
  1903  func ispubtype(die *DWDie) bool {
  1904  	return die.abbrev >= DW_ABRV_NULLTYPE
  1905  }
  1906  
  1907  func writepub(ispub func(*DWDie) bool) int64 {
  1908  	sectionstart := Cpos()
  1909  
  1910  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1911  		unitend := infoo + infosize
  1912  		unitstart := compunit.offs - COMPUNITHEADERSIZE
  1913  		if compunit.link != nil {
  1914  			unitend = compunit.link.offs - COMPUNITHEADERSIZE
  1915  		}
  1916  
  1917  		// Write .debug_pubnames/types	Header (sec 6.1.1)
  1918  		Thearch.Lput(0)                           // unit_length (*), will be filled in later.
  1919  		Thearch.Wput(2)                           // dwarf version (appendix F)
  1920  		Thearch.Lput(uint32(unitstart))           // debug_info_offset (of the Comp unit Header)
  1921  		Thearch.Lput(uint32(unitend - unitstart)) // debug_info_length
  1922  
  1923  		for die := compunit.child; die != nil; die = die.link {
  1924  			if !ispub(die) {
  1925  				continue
  1926  			}
  1927  			Thearch.Lput(uint32(die.offs - unitstart))
  1928  			dwa := getattr(die, DW_AT_name)
  1929  			strnput(dwa.data.(string), int(dwa.value+1))
  1930  		}
  1931  
  1932  		Thearch.Lput(0)
  1933  
  1934  		here := Cpos()
  1935  		Cseek(sectionstart)
  1936  		Thearch.Lput(uint32(here - sectionstart - 4)) // exclude the length field.
  1937  		Cseek(here)
  1938  	}
  1939  
  1940  	return sectionstart
  1941  }
  1942  
  1943  /*
  1944   *  emit .debug_aranges.  _info must have been written before,
  1945   *  because we need die->offs of dw_globals.
  1946   */
  1947  func writearanges() int64 {
  1948  	sectionstart := Cpos()
  1949  	// The first tuple is aligned to a multiple of the size of a single tuple
  1950  	// (twice the size of an address)
  1951  	headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize*2))) // don't count unit_length field itself
  1952  
  1953  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1954  		b := getattr(compunit, DW_AT_low_pc)
  1955  		if b == nil {
  1956  			continue
  1957  		}
  1958  		e := getattr(compunit, DW_AT_high_pc)
  1959  		if e == nil {
  1960  			continue
  1961  		}
  1962  
  1963  		// Write .debug_aranges	 Header + entry	 (sec 6.1.2)
  1964  		Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*)
  1965  		Thearch.Wput(2)                                                  // dwarf version (appendix F)
  1966  
  1967  		value := compunit.offs - COMPUNITHEADERSIZE // debug_info_offset
  1968  		if Linkmode == LinkExternal {
  1969  			adddwarfrel(arangessec, infosym, sectionstart, 4, value)
  1970  		} else {
  1971  			Thearch.Lput(uint32(value))
  1972  		}
  1973  
  1974  		Cput(uint8(Thearch.Ptrsize))        // address_size
  1975  		Cput(0)                             // segment_size
  1976  		strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize
  1977  
  1978  		if Linkmode == LinkExternal {
  1979  			adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value)
  1980  		} else {
  1981  			addrput(b.value)
  1982  		}
  1983  
  1984  		addrput(e.value - b.value)
  1985  		addrput(0)
  1986  		addrput(0)
  1987  	}
  1988  
  1989  	Cflush()
  1990  	return sectionstart
  1991  }
  1992  
  1993  func writegdbscript() int64 {
  1994  	sectionstart := Cpos()
  1995  
  1996  	if gdbscript != "" {
  1997  		Cput(1) // magic 1 byte?
  1998  		strnput(gdbscript, len(gdbscript)+1)
  1999  		Cflush()
  2000  	}
  2001  
  2002  	return sectionstart
  2003  }
  2004  
  2005  func align(size int64) {
  2006  	if HEADTYPE == obj.Hwindows { // Only Windows PE need section align.
  2007  		strnput("", int(Rnd(size, PEFILEALIGN)-size))
  2008  	}
  2009  }
  2010  
  2011  func writedwarfreloc(s *LSym) int64 {
  2012  	start := Cpos()
  2013  	for ri := 0; ri < len(s.R); ri++ {
  2014  		r := &s.R[ri]
  2015  		i := -1
  2016  		if Iself {
  2017  			i = Thearch.Elfreloc1(r, int64(r.Off))
  2018  		} else if HEADTYPE == obj.Hdarwin {
  2019  			i = Thearch.Machoreloc1(r, int64(r.Off))
  2020  		}
  2021  		if i < 0 {
  2022  			Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
  2023  		}
  2024  	}
  2025  
  2026  	return start
  2027  }
  2028  
  2029  func addmachodwarfsect(prev *Section, name string) *Section {
  2030  	sect := addsection(&Segdwarf, name, 04)
  2031  	sect.Extnum = prev.Extnum + 1
  2032  	sym := Linklookup(Ctxt, name, 0)
  2033  	sym.Sect = sect
  2034  	return sect
  2035  }
  2036  
  2037  /*
  2038   * This is the main entry point for generating dwarf.  After emitting
  2039   * the mandatory debug_abbrev section, it calls writelines() to set up
  2040   * the per-compilation unit part of the DIE tree, while simultaneously
  2041   * emitting the debug_line section.  When the final tree contains
  2042   * forward references, it will write the debug_info section in 2
  2043   * passes.
  2044   *
  2045   */
  2046  func Dwarfemitdebugsections() {
  2047  	if Debug['w'] != 0 { // disable dwarf
  2048  		return
  2049  	}
  2050  
  2051  	if Linkmode == LinkExternal {
  2052  		if !Iself && HEADTYPE != obj.Hdarwin {
  2053  			return
  2054  		}
  2055  		if HEADTYPE == obj.Hdarwin {
  2056  			sect := Segdata.Sect
  2057  			// find the last section.
  2058  			for sect.Next != nil {
  2059  				sect = sect.Next
  2060  			}
  2061  			sect = addmachodwarfsect(sect, ".debug_abbrev")
  2062  			sect = addmachodwarfsect(sect, ".debug_line")
  2063  			sect = addmachodwarfsect(sect, ".debug_frame")
  2064  			sect = addmachodwarfsect(sect, ".debug_info")
  2065  
  2066  			infosym = Linklookup(Ctxt, ".debug_info", 0)
  2067  			infosym.Hide = 1
  2068  
  2069  			abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
  2070  			abbrevsym.Hide = 1
  2071  
  2072  			linesym = Linklookup(Ctxt, ".debug_line", 0)
  2073  			linesym.Hide = 1
  2074  
  2075  			framesym = Linklookup(Ctxt, ".debug_frame", 0)
  2076  			framesym.Hide = 1
  2077  		}
  2078  	}
  2079  
  2080  	// For diagnostic messages.
  2081  	newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes")
  2082  
  2083  	mkindex(&dwroot)
  2084  	mkindex(&dwtypes)
  2085  	mkindex(&dwglobals)
  2086  
  2087  	// Some types that must exist to define other ones.
  2088  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>")
  2089  
  2090  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "void")
  2091  	newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer")
  2092  
  2093  	die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr") // needed for array size
  2094  	newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
  2095  	newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0)
  2096  	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0)
  2097  
  2098  	// Needed by the prettyprinter code for interface inspection.
  2099  	defgotype(lookup_or_diag("type.runtime._type"))
  2100  
  2101  	defgotype(lookup_or_diag("type.runtime.interfacetype"))
  2102  	defgotype(lookup_or_diag("type.runtime.itab"))
  2103  
  2104  	genasmsym(defdwsymb)
  2105  
  2106  	writeabbrev()
  2107  	align(abbrevsize)
  2108  	writelines()
  2109  	align(linesize)
  2110  	writeframes()
  2111  	align(framesize)
  2112  
  2113  	synthesizestringtypes(dwtypes.child)
  2114  	synthesizeslicetypes(dwtypes.child)
  2115  	synthesizemaptypes(dwtypes.child)
  2116  	synthesizechantypes(dwtypes.child)
  2117  
  2118  	reversetree(&dwroot.child)
  2119  	reversetree(&dwtypes.child)
  2120  	reversetree(&dwglobals.child)
  2121  
  2122  	movetomodule(&dwtypes)
  2123  	movetomodule(&dwglobals)
  2124  
  2125  	infoo = Cpos()
  2126  	writeinfo()
  2127  	infoe := Cpos()
  2128  	pubnameso = infoe
  2129  	pubtypeso = infoe
  2130  	arangeso = infoe
  2131  	gdbscripto = infoe
  2132  
  2133  	if fwdcount > 0 {
  2134  		if Debug['v'] != 0 {
  2135  			fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime())
  2136  		}
  2137  		Cseek(infoo)
  2138  		writeinfo()
  2139  		if fwdcount > 0 {
  2140  			Exitf("dwarf: unresolved references after first dwarf info pass")
  2141  		}
  2142  
  2143  		if infoe != Cpos() {
  2144  			Exitf("dwarf: inconsistent second dwarf info pass")
  2145  		}
  2146  	}
  2147  
  2148  	infosize = infoe - infoo
  2149  	align(infosize)
  2150  
  2151  	pubnameso = writepub(ispubname)
  2152  	pubnamessize = Cpos() - pubnameso
  2153  	align(pubnamessize)
  2154  
  2155  	pubtypeso = writepub(ispubtype)
  2156  	pubtypessize = Cpos() - pubtypeso
  2157  	align(pubtypessize)
  2158  
  2159  	arangeso = writearanges()
  2160  	arangessize = Cpos() - arangeso
  2161  	align(arangessize)
  2162  
  2163  	gdbscripto = writegdbscript()
  2164  	gdbscriptsize = Cpos() - gdbscripto
  2165  	align(gdbscriptsize)
  2166  
  2167  	for Cpos()&7 != 0 {
  2168  		Cput(0)
  2169  	}
  2170  	if HEADTYPE != obj.Hdarwin {
  2171  		dwarfemitreloc()
  2172  	}
  2173  }
  2174  
  2175  func dwarfemitreloc() {
  2176  	if Debug['w'] != 0 { // disable dwarf
  2177  		return
  2178  	}
  2179  	inforeloco = writedwarfreloc(infosec)
  2180  	inforelocsize = Cpos() - inforeloco
  2181  	align(inforelocsize)
  2182  
  2183  	arangesreloco = writedwarfreloc(arangessec)
  2184  	arangesrelocsize = Cpos() - arangesreloco
  2185  	align(arangesrelocsize)
  2186  
  2187  	linereloco = writedwarfreloc(linesec)
  2188  	linerelocsize = Cpos() - linereloco
  2189  	align(linerelocsize)
  2190  
  2191  	framereloco = writedwarfreloc(framesec)
  2192  	framerelocsize = Cpos() - framereloco
  2193  	align(framerelocsize)
  2194  }
  2195  
  2196  /*
  2197   *  Elf.
  2198   */
  2199  const (
  2200  	ElfStrDebugAbbrev = iota
  2201  	ElfStrDebugAranges
  2202  	ElfStrDebugFrame
  2203  	ElfStrDebugInfo
  2204  	ElfStrDebugLine
  2205  	ElfStrDebugLoc
  2206  	ElfStrDebugMacinfo
  2207  	ElfStrDebugPubNames
  2208  	ElfStrDebugPubTypes
  2209  	ElfStrDebugRanges
  2210  	ElfStrDebugStr
  2211  	ElfStrGDBScripts
  2212  	ElfStrRelDebugInfo
  2213  	ElfStrRelDebugAranges
  2214  	ElfStrRelDebugLine
  2215  	ElfStrRelDebugFrame
  2216  	NElfStrDbg
  2217  )
  2218  
  2219  var elfstrdbg [NElfStrDbg]int64
  2220  
  2221  func dwarfaddshstrings(shstrtab *LSym) {
  2222  	if Debug['w'] != 0 { // disable dwarf
  2223  		return
  2224  	}
  2225  
  2226  	elfstrdbg[ElfStrDebugAbbrev] = Addstring(shstrtab, ".debug_abbrev")
  2227  	elfstrdbg[ElfStrDebugAranges] = Addstring(shstrtab, ".debug_aranges")
  2228  	elfstrdbg[ElfStrDebugFrame] = Addstring(shstrtab, ".debug_frame")
  2229  	elfstrdbg[ElfStrDebugInfo] = Addstring(shstrtab, ".debug_info")
  2230  	elfstrdbg[ElfStrDebugLine] = Addstring(shstrtab, ".debug_line")
  2231  	elfstrdbg[ElfStrDebugLoc] = Addstring(shstrtab, ".debug_loc")
  2232  	elfstrdbg[ElfStrDebugMacinfo] = Addstring(shstrtab, ".debug_macinfo")
  2233  	elfstrdbg[ElfStrDebugPubNames] = Addstring(shstrtab, ".debug_pubnames")
  2234  	elfstrdbg[ElfStrDebugPubTypes] = Addstring(shstrtab, ".debug_pubtypes")
  2235  	elfstrdbg[ElfStrDebugRanges] = Addstring(shstrtab, ".debug_ranges")
  2236  	elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str")
  2237  	elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts")
  2238  	if Linkmode == LinkExternal {
  2239  		switch Thearch.Thechar {
  2240  		case '0', '6', '7', '9':
  2241  			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info")
  2242  			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges")
  2243  			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line")
  2244  			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame")
  2245  		default:
  2246  			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info")
  2247  			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges")
  2248  			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line")
  2249  			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rel.debug_frame")
  2250  		}
  2251  
  2252  		infosym = Linklookup(Ctxt, ".debug_info", 0)
  2253  		infosym.Hide = 1
  2254  
  2255  		abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
  2256  		abbrevsym.Hide = 1
  2257  
  2258  		linesym = Linklookup(Ctxt, ".debug_line", 0)
  2259  		linesym.Hide = 1
  2260  
  2261  		framesym = Linklookup(Ctxt, ".debug_frame", 0)
  2262  		framesym.Hide = 1
  2263  	}
  2264  }
  2265  
  2266  // Add section symbols for DWARF debug info.  This is called before
  2267  // dwarfaddelfheaders.
  2268  func dwarfaddelfsectionsyms() {
  2269  	if infosym != nil {
  2270  		infosympos = Cpos()
  2271  		putelfsectionsym(infosym, 0)
  2272  	}
  2273  
  2274  	if abbrevsym != nil {
  2275  		abbrevsympos = Cpos()
  2276  		putelfsectionsym(abbrevsym, 0)
  2277  	}
  2278  
  2279  	if linesym != nil {
  2280  		linesympos = Cpos()
  2281  		putelfsectionsym(linesym, 0)
  2282  	}
  2283  
  2284  	if framesym != nil {
  2285  		framesympos = Cpos()
  2286  		putelfsectionsym(framesym, 0)
  2287  	}
  2288  }
  2289  
  2290  func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) {
  2291  	sh := newElfShdr(elfstrdbg[elfstr])
  2292  	switch Thearch.Thechar {
  2293  	case '0', '6', '7', '9':
  2294  		sh.type_ = SHT_RELA
  2295  	default:
  2296  		sh.type_ = SHT_REL
  2297  	}
  2298  
  2299  	sh.entsize = uint64(Thearch.Ptrsize) * 2
  2300  	if sh.type_ == SHT_RELA {
  2301  		sh.entsize += uint64(Thearch.Ptrsize)
  2302  	}
  2303  	sh.link = uint32(elfshname(".symtab").shnum)
  2304  	sh.info = uint32(shdata.shnum)
  2305  	sh.off = uint64(off)
  2306  	sh.size = uint64(size)
  2307  	sh.addralign = uint64(Thearch.Ptrsize)
  2308  }
  2309  
  2310  func dwarfaddelfheaders() {
  2311  	if Debug['w'] != 0 { // disable dwarf
  2312  		return
  2313  	}
  2314  
  2315  	sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev])
  2316  	sh.type_ = SHT_PROGBITS
  2317  	sh.off = uint64(abbrevo)
  2318  	sh.size = uint64(abbrevsize)
  2319  	sh.addralign = 1
  2320  	if abbrevsympos > 0 {
  2321  		putelfsymshndx(abbrevsympos, sh.shnum)
  2322  	}
  2323  
  2324  	sh = newElfShdr(elfstrdbg[ElfStrDebugLine])
  2325  	sh.type_ = SHT_PROGBITS
  2326  	sh.off = uint64(lineo)
  2327  	sh.size = uint64(linesize)
  2328  	sh.addralign = 1
  2329  	if linesympos > 0 {
  2330  		putelfsymshndx(linesympos, sh.shnum)
  2331  	}
  2332  	shline := sh
  2333  
  2334  	sh = newElfShdr(elfstrdbg[ElfStrDebugFrame])
  2335  	sh.type_ = SHT_PROGBITS
  2336  	sh.off = uint64(frameo)
  2337  	sh.size = uint64(framesize)
  2338  	sh.addralign = 1
  2339  	if framesympos > 0 {
  2340  		putelfsymshndx(framesympos, sh.shnum)
  2341  	}
  2342  	shframe := sh
  2343  
  2344  	sh = newElfShdr(elfstrdbg[ElfStrDebugInfo])
  2345  	sh.type_ = SHT_PROGBITS
  2346  	sh.off = uint64(infoo)
  2347  	sh.size = uint64(infosize)
  2348  	sh.addralign = 1
  2349  	if infosympos > 0 {
  2350  		putelfsymshndx(infosympos, sh.shnum)
  2351  	}
  2352  	shinfo := sh
  2353  
  2354  	if pubnamessize > 0 {
  2355  		sh := newElfShdr(elfstrdbg[ElfStrDebugPubNames])
  2356  		sh.type_ = SHT_PROGBITS
  2357  		sh.off = uint64(pubnameso)
  2358  		sh.size = uint64(pubnamessize)
  2359  		sh.addralign = 1
  2360  	}
  2361  
  2362  	if pubtypessize > 0 {
  2363  		sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes])
  2364  		sh.type_ = SHT_PROGBITS
  2365  		sh.off = uint64(pubtypeso)
  2366  		sh.size = uint64(pubtypessize)
  2367  		sh.addralign = 1
  2368  	}
  2369  
  2370  	var sharanges *ElfShdr
  2371  	if arangessize != 0 {
  2372  		sh := newElfShdr(elfstrdbg[ElfStrDebugAranges])
  2373  		sh.type_ = SHT_PROGBITS
  2374  		sh.off = uint64(arangeso)
  2375  		sh.size = uint64(arangessize)
  2376  		sh.addralign = 1
  2377  		sharanges = sh
  2378  	}
  2379  
  2380  	if gdbscriptsize != 0 {
  2381  		sh := newElfShdr(elfstrdbg[ElfStrGDBScripts])
  2382  		sh.type_ = SHT_PROGBITS
  2383  		sh.off = uint64(gdbscripto)
  2384  		sh.size = uint64(gdbscriptsize)
  2385  		sh.addralign = 1
  2386  	}
  2387  
  2388  	if inforelocsize != 0 {
  2389  		dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize)
  2390  	}
  2391  
  2392  	if arangesrelocsize != 0 {
  2393  		dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize)
  2394  	}
  2395  
  2396  	if linerelocsize != 0 {
  2397  		dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize)
  2398  	}
  2399  
  2400  	if framerelocsize != 0 {
  2401  		dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize)
  2402  	}
  2403  }
  2404  
  2405  /*
  2406   * Macho
  2407   */
  2408  func dwarfaddmachoheaders(ms *MachoSeg) {
  2409  	if Debug['w'] != 0 { // disable dwarf
  2410  		return
  2411  	}
  2412  
  2413  	// Zero vsize segments won't be loaded in memory, even so they
  2414  	// have to be page aligned in the file.
  2415  	fakestart := Rnd(int64(Segdwarf.Fileoff), 0x1000)
  2416  	addr := Segdata.Vaddr + Segdata.Length
  2417  
  2418  	nsect := 4
  2419  	if pubnamessize > 0 {
  2420  		nsect++
  2421  	}
  2422  	if pubtypessize > 0 {
  2423  		nsect++
  2424  	}
  2425  	if arangessize > 0 {
  2426  		nsect++
  2427  	}
  2428  	if gdbscriptsize > 0 {
  2429  		nsect++
  2430  	}
  2431  
  2432  	if Linkmode != LinkExternal {
  2433  		ms = newMachoSeg("__DWARF", nsect)
  2434  		ms.fileoffset = uint64(fakestart)
  2435  		ms.filesize = Segdwarf.Filelen
  2436  		ms.vaddr = addr
  2437  	}
  2438  
  2439  	msect := newMachoSect(ms, "__debug_abbrev", "__DWARF")
  2440  	msect.off = uint32(abbrevo)
  2441  	msect.size = uint64(abbrevsize)
  2442  	msect.addr = addr
  2443  	addr += msect.size
  2444  	msect.flag = 0x02000000
  2445  	if abbrevsym != nil {
  2446  		abbrevsym.Value = int64(msect.addr)
  2447  	}
  2448  
  2449  	msect = newMachoSect(ms, "__debug_line", "__DWARF")
  2450  	msect.off = uint32(lineo)
  2451  	msect.size = uint64(linesize)
  2452  	msect.addr = addr
  2453  	addr += msect.size
  2454  	msect.flag = 0x02000000
  2455  	if linesym != nil {
  2456  		linesym.Value = int64(msect.addr)
  2457  	}
  2458  	if linerelocsize > 0 {
  2459  		msect.nreloc = uint32(len(linesec.R))
  2460  		msect.reloc = uint32(linereloco)
  2461  	}
  2462  
  2463  	msect = newMachoSect(ms, "__debug_frame", "__DWARF")
  2464  	msect.off = uint32(frameo)
  2465  	msect.size = uint64(framesize)
  2466  	msect.addr = addr
  2467  	addr += msect.size
  2468  	msect.flag = 0x02000000
  2469  	if framesym != nil {
  2470  		framesym.Value = int64(msect.addr)
  2471  	}
  2472  	if framerelocsize > 0 {
  2473  		msect.nreloc = uint32(len(framesec.R))
  2474  		msect.reloc = uint32(framereloco)
  2475  	}
  2476  
  2477  	msect = newMachoSect(ms, "__debug_info", "__DWARF")
  2478  	msect.off = uint32(infoo)
  2479  	msect.size = uint64(infosize)
  2480  	msect.addr = addr
  2481  	addr += msect.size
  2482  	msect.flag = 0x02000000
  2483  	if infosym != nil {
  2484  		infosym.Value = int64(msect.addr)
  2485  	}
  2486  	if inforelocsize > 0 {
  2487  		msect.nreloc = uint32(len(infosec.R))
  2488  		msect.reloc = uint32(inforeloco)
  2489  	}
  2490  
  2491  	if pubnamessize > 0 {
  2492  		msect := newMachoSect(ms, "__debug_pubnames", "__DWARF")
  2493  		msect.off = uint32(pubnameso)
  2494  		msect.size = uint64(pubnamessize)
  2495  		msect.addr = addr
  2496  		addr += msect.size
  2497  		msect.flag = 0x02000000
  2498  	}
  2499  
  2500  	if pubtypessize > 0 {
  2501  		msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF")
  2502  		msect.off = uint32(pubtypeso)
  2503  		msect.size = uint64(pubtypessize)
  2504  		msect.addr = addr
  2505  		addr += msect.size
  2506  		msect.flag = 0x02000000
  2507  	}
  2508  
  2509  	if arangessize > 0 {
  2510  		msect := newMachoSect(ms, "__debug_aranges", "__DWARF")
  2511  		msect.off = uint32(arangeso)
  2512  		msect.size = uint64(arangessize)
  2513  		msect.addr = addr
  2514  		addr += msect.size
  2515  		msect.flag = 0x02000000
  2516  		if arangesrelocsize > 0 {
  2517  			msect.nreloc = uint32(len(arangessec.R))
  2518  			msect.reloc = uint32(arangesreloco)
  2519  		}
  2520  	}
  2521  
  2522  	// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
  2523  	if gdbscriptsize > 0 {
  2524  		msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF")
  2525  		msect.off = uint32(gdbscripto)
  2526  		msect.size = uint64(gdbscriptsize)
  2527  		msect.addr = addr
  2528  		addr += msect.size
  2529  		msect.flag = 0x02000000
  2530  	}
  2531  }
  2532  
  2533  /*
  2534   * Windows PE
  2535   */
  2536  func dwarfaddpeheaders() {
  2537  	if Debug['w'] != 0 { // disable dwarf
  2538  		return
  2539  	}
  2540  
  2541  	newPEDWARFSection(".debug_abbrev", abbrevsize)
  2542  	newPEDWARFSection(".debug_line", linesize)
  2543  	newPEDWARFSection(".debug_frame", framesize)
  2544  	newPEDWARFSection(".debug_info", infosize)
  2545  	newPEDWARFSection(".debug_pubnames", pubnamessize)
  2546  	newPEDWARFSection(".debug_pubtypes", pubtypessize)
  2547  	newPEDWARFSection(".debug_aranges", arangessize)
  2548  	newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize)
  2549  }