github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/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  	headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize))) // don't count unit_length field itself
  1950  
  1951  	for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
  1952  		b := getattr(compunit, DW_AT_low_pc)
  1953  		if b == nil {
  1954  			continue
  1955  		}
  1956  		e := getattr(compunit, DW_AT_high_pc)
  1957  		if e == nil {
  1958  			continue
  1959  		}
  1960  
  1961  		// Write .debug_aranges	 Header + entry	 (sec 6.1.2)
  1962  		Thearch.Lput(uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4) // unit_length (*)
  1963  		Thearch.Wput(2)                                                  // dwarf version (appendix F)
  1964  
  1965  		value := compunit.offs - COMPUNITHEADERSIZE // debug_info_offset
  1966  		if Linkmode == LinkExternal {
  1967  			adddwarfrel(arangessec, infosym, sectionstart, 4, value)
  1968  		} else {
  1969  			Thearch.Lput(uint32(value))
  1970  		}
  1971  
  1972  		Cput(uint8(Thearch.Ptrsize))        // address_size
  1973  		Cput(0)                             // segment_size
  1974  		strnput("", headersize-(4+2+4+1+1)) // align to thearch.ptrsize
  1975  
  1976  		if Linkmode == LinkExternal {
  1977  			adddwarfrel(arangessec, b.data.(*LSym), sectionstart, Thearch.Ptrsize, b.value-(b.data.(*LSym)).Value)
  1978  		} else {
  1979  			addrput(b.value)
  1980  		}
  1981  
  1982  		addrput(e.value - b.value)
  1983  		addrput(0)
  1984  		addrput(0)
  1985  	}
  1986  
  1987  	Cflush()
  1988  	return sectionstart
  1989  }
  1990  
  1991  func writegdbscript() int64 {
  1992  	sectionstart := Cpos()
  1993  
  1994  	if gdbscript != "" {
  1995  		Cput(1) // magic 1 byte?
  1996  		strnput(gdbscript, len(gdbscript)+1)
  1997  		Cflush()
  1998  	}
  1999  
  2000  	return sectionstart
  2001  }
  2002  
  2003  func align(size int64) {
  2004  	if HEADTYPE == obj.Hwindows { // Only Windows PE need section align.
  2005  		strnput("", int(Rnd(size, PEFILEALIGN)-size))
  2006  	}
  2007  }
  2008  
  2009  func writedwarfreloc(s *LSym) int64 {
  2010  	start := Cpos()
  2011  	for ri := 0; ri < len(s.R); ri++ {
  2012  		r := &s.R[ri]
  2013  		i := -1
  2014  		if Iself {
  2015  			i = Thearch.Elfreloc1(r, int64(r.Off))
  2016  		} else if HEADTYPE == obj.Hdarwin {
  2017  			i = Thearch.Machoreloc1(r, int64(r.Off))
  2018  		}
  2019  		if i < 0 {
  2020  			Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
  2021  		}
  2022  	}
  2023  
  2024  	return start
  2025  }
  2026  
  2027  func addmachodwarfsect(prev *Section, name string) *Section {
  2028  	sect := addsection(&Segdwarf, name, 04)
  2029  	sect.Extnum = prev.Extnum + 1
  2030  	sym := Linklookup(Ctxt, name, 0)
  2031  	sym.Sect = sect
  2032  	return sect
  2033  }
  2034  
  2035  /*
  2036   * This is the main entry point for generating dwarf.  After emitting
  2037   * the mandatory debug_abbrev section, it calls writelines() to set up
  2038   * the per-compilation unit part of the DIE tree, while simultaneously
  2039   * emitting the debug_line section.  When the final tree contains
  2040   * forward references, it will write the debug_info section in 2
  2041   * passes.
  2042   *
  2043   */
  2044  func Dwarfemitdebugsections() {
  2045  	if Debug['w'] != 0 { // disable dwarf
  2046  		return
  2047  	}
  2048  
  2049  	if Linkmode == LinkExternal {
  2050  		if !Iself && HEADTYPE != obj.Hdarwin {
  2051  			return
  2052  		}
  2053  		if HEADTYPE == obj.Hdarwin {
  2054  			sect := Segdata.Sect
  2055  			// find the last section.
  2056  			for sect.Next != nil {
  2057  				sect = sect.Next
  2058  			}
  2059  			sect = addmachodwarfsect(sect, ".debug_abbrev")
  2060  			sect = addmachodwarfsect(sect, ".debug_line")
  2061  			sect = addmachodwarfsect(sect, ".debug_frame")
  2062  			sect = addmachodwarfsect(sect, ".debug_info")
  2063  
  2064  			infosym = Linklookup(Ctxt, ".debug_info", 0)
  2065  			infosym.Hide = 1
  2066  
  2067  			abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
  2068  			abbrevsym.Hide = 1
  2069  
  2070  			linesym = Linklookup(Ctxt, ".debug_line", 0)
  2071  			linesym.Hide = 1
  2072  
  2073  			framesym = Linklookup(Ctxt, ".debug_frame", 0)
  2074  			framesym.Hide = 1
  2075  		}
  2076  	}
  2077  
  2078  	// For diagnostic messages.
  2079  	newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, int64(len("dwtypes")), "dwtypes")
  2080  
  2081  	mkindex(&dwroot)
  2082  	mkindex(&dwtypes)
  2083  	mkindex(&dwglobals)
  2084  
  2085  	// Some types that must exist to define other ones.
  2086  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>")
  2087  
  2088  	newdie(&dwtypes, DW_ABRV_NULLTYPE, "void")
  2089  	newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer")
  2090  
  2091  	die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr") // needed for array size
  2092  	newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
  2093  	newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0)
  2094  	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0)
  2095  
  2096  	// Needed by the prettyprinter code for interface inspection.
  2097  	defgotype(lookup_or_diag("type.runtime._type"))
  2098  
  2099  	defgotype(lookup_or_diag("type.runtime.interfacetype"))
  2100  	defgotype(lookup_or_diag("type.runtime.itab"))
  2101  
  2102  	genasmsym(defdwsymb)
  2103  
  2104  	writeabbrev()
  2105  	align(abbrevsize)
  2106  	writelines()
  2107  	align(linesize)
  2108  	writeframes()
  2109  	align(framesize)
  2110  
  2111  	synthesizestringtypes(dwtypes.child)
  2112  	synthesizeslicetypes(dwtypes.child)
  2113  	synthesizemaptypes(dwtypes.child)
  2114  	synthesizechantypes(dwtypes.child)
  2115  
  2116  	reversetree(&dwroot.child)
  2117  	reversetree(&dwtypes.child)
  2118  	reversetree(&dwglobals.child)
  2119  
  2120  	movetomodule(&dwtypes)
  2121  	movetomodule(&dwglobals)
  2122  
  2123  	infoo = Cpos()
  2124  	writeinfo()
  2125  	infoe := Cpos()
  2126  	pubnameso = infoe
  2127  	pubtypeso = infoe
  2128  	arangeso = infoe
  2129  	gdbscripto = infoe
  2130  
  2131  	if fwdcount > 0 {
  2132  		if Debug['v'] != 0 {
  2133  			fmt.Fprintf(&Bso, "%5.2f dwarf pass 2.\n", obj.Cputime())
  2134  		}
  2135  		Cseek(infoo)
  2136  		writeinfo()
  2137  		if fwdcount > 0 {
  2138  			Exitf("dwarf: unresolved references after first dwarf info pass")
  2139  		}
  2140  
  2141  		if infoe != Cpos() {
  2142  			Exitf("dwarf: inconsistent second dwarf info pass")
  2143  		}
  2144  	}
  2145  
  2146  	infosize = infoe - infoo
  2147  	align(infosize)
  2148  
  2149  	pubnameso = writepub(ispubname)
  2150  	pubnamessize = Cpos() - pubnameso
  2151  	align(pubnamessize)
  2152  
  2153  	pubtypeso = writepub(ispubtype)
  2154  	pubtypessize = Cpos() - pubtypeso
  2155  	align(pubtypessize)
  2156  
  2157  	arangeso = writearanges()
  2158  	arangessize = Cpos() - arangeso
  2159  	align(arangessize)
  2160  
  2161  	gdbscripto = writegdbscript()
  2162  	gdbscriptsize = Cpos() - gdbscripto
  2163  	align(gdbscriptsize)
  2164  
  2165  	for Cpos()&7 != 0 {
  2166  		Cput(0)
  2167  	}
  2168  	if HEADTYPE != obj.Hdarwin {
  2169  		dwarfemitreloc()
  2170  	}
  2171  }
  2172  
  2173  func dwarfemitreloc() {
  2174  	if Debug['w'] != 0 { // disable dwarf
  2175  		return
  2176  	}
  2177  	inforeloco = writedwarfreloc(infosec)
  2178  	inforelocsize = Cpos() - inforeloco
  2179  	align(inforelocsize)
  2180  
  2181  	arangesreloco = writedwarfreloc(arangessec)
  2182  	arangesrelocsize = Cpos() - arangesreloco
  2183  	align(arangesrelocsize)
  2184  
  2185  	linereloco = writedwarfreloc(linesec)
  2186  	linerelocsize = Cpos() - linereloco
  2187  	align(linerelocsize)
  2188  
  2189  	framereloco = writedwarfreloc(framesec)
  2190  	framerelocsize = Cpos() - framereloco
  2191  	align(framerelocsize)
  2192  }
  2193  
  2194  /*
  2195   *  Elf.
  2196   */
  2197  const (
  2198  	ElfStrDebugAbbrev = iota
  2199  	ElfStrDebugAranges
  2200  	ElfStrDebugFrame
  2201  	ElfStrDebugInfo
  2202  	ElfStrDebugLine
  2203  	ElfStrDebugLoc
  2204  	ElfStrDebugMacinfo
  2205  	ElfStrDebugPubNames
  2206  	ElfStrDebugPubTypes
  2207  	ElfStrDebugRanges
  2208  	ElfStrDebugStr
  2209  	ElfStrGDBScripts
  2210  	ElfStrRelDebugInfo
  2211  	ElfStrRelDebugAranges
  2212  	ElfStrRelDebugLine
  2213  	ElfStrRelDebugFrame
  2214  	NElfStrDbg
  2215  )
  2216  
  2217  var elfstrdbg [NElfStrDbg]int64
  2218  
  2219  func dwarfaddshstrings(shstrtab *LSym) {
  2220  	if Debug['w'] != 0 { // disable dwarf
  2221  		return
  2222  	}
  2223  
  2224  	elfstrdbg[ElfStrDebugAbbrev] = Addstring(shstrtab, ".debug_abbrev")
  2225  	elfstrdbg[ElfStrDebugAranges] = Addstring(shstrtab, ".debug_aranges")
  2226  	elfstrdbg[ElfStrDebugFrame] = Addstring(shstrtab, ".debug_frame")
  2227  	elfstrdbg[ElfStrDebugInfo] = Addstring(shstrtab, ".debug_info")
  2228  	elfstrdbg[ElfStrDebugLine] = Addstring(shstrtab, ".debug_line")
  2229  	elfstrdbg[ElfStrDebugLoc] = Addstring(shstrtab, ".debug_loc")
  2230  	elfstrdbg[ElfStrDebugMacinfo] = Addstring(shstrtab, ".debug_macinfo")
  2231  	elfstrdbg[ElfStrDebugPubNames] = Addstring(shstrtab, ".debug_pubnames")
  2232  	elfstrdbg[ElfStrDebugPubTypes] = Addstring(shstrtab, ".debug_pubtypes")
  2233  	elfstrdbg[ElfStrDebugRanges] = Addstring(shstrtab, ".debug_ranges")
  2234  	elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str")
  2235  	elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts")
  2236  	if Linkmode == LinkExternal {
  2237  		switch Thearch.Thechar {
  2238  		case '0', '6', '7', '9':
  2239  			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info")
  2240  			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges")
  2241  			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line")
  2242  			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame")
  2243  		default:
  2244  			elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info")
  2245  			elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges")
  2246  			elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line")
  2247  			elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rel.debug_frame")
  2248  		}
  2249  
  2250  		infosym = Linklookup(Ctxt, ".debug_info", 0)
  2251  		infosym.Hide = 1
  2252  
  2253  		abbrevsym = Linklookup(Ctxt, ".debug_abbrev", 0)
  2254  		abbrevsym.Hide = 1
  2255  
  2256  		linesym = Linklookup(Ctxt, ".debug_line", 0)
  2257  		linesym.Hide = 1
  2258  
  2259  		framesym = Linklookup(Ctxt, ".debug_frame", 0)
  2260  		framesym.Hide = 1
  2261  	}
  2262  }
  2263  
  2264  // Add section symbols for DWARF debug info.  This is called before
  2265  // dwarfaddelfheaders.
  2266  func dwarfaddelfsectionsyms() {
  2267  	if infosym != nil {
  2268  		infosympos = Cpos()
  2269  		putelfsectionsym(infosym, 0)
  2270  	}
  2271  
  2272  	if abbrevsym != nil {
  2273  		abbrevsympos = Cpos()
  2274  		putelfsectionsym(abbrevsym, 0)
  2275  	}
  2276  
  2277  	if linesym != nil {
  2278  		linesympos = Cpos()
  2279  		putelfsectionsym(linesym, 0)
  2280  	}
  2281  
  2282  	if framesym != nil {
  2283  		framesympos = Cpos()
  2284  		putelfsectionsym(framesym, 0)
  2285  	}
  2286  }
  2287  
  2288  func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) {
  2289  	sh := newElfShdr(elfstrdbg[elfstr])
  2290  	switch Thearch.Thechar {
  2291  	case '0', '6', '7', '9':
  2292  		sh.type_ = SHT_RELA
  2293  	default:
  2294  		sh.type_ = SHT_REL
  2295  	}
  2296  
  2297  	sh.entsize = uint64(Thearch.Ptrsize) * 2
  2298  	if sh.type_ == SHT_RELA {
  2299  		sh.entsize += uint64(Thearch.Ptrsize)
  2300  	}
  2301  	sh.link = uint32(elfshname(".symtab").shnum)
  2302  	sh.info = uint32(shdata.shnum)
  2303  	sh.off = uint64(off)
  2304  	sh.size = uint64(size)
  2305  	sh.addralign = uint64(Thearch.Ptrsize)
  2306  }
  2307  
  2308  func dwarfaddelfheaders() {
  2309  	if Debug['w'] != 0 { // disable dwarf
  2310  		return
  2311  	}
  2312  
  2313  	sh := newElfShdr(elfstrdbg[ElfStrDebugAbbrev])
  2314  	sh.type_ = SHT_PROGBITS
  2315  	sh.off = uint64(abbrevo)
  2316  	sh.size = uint64(abbrevsize)
  2317  	sh.addralign = 1
  2318  	if abbrevsympos > 0 {
  2319  		putelfsymshndx(abbrevsympos, sh.shnum)
  2320  	}
  2321  
  2322  	sh = newElfShdr(elfstrdbg[ElfStrDebugLine])
  2323  	sh.type_ = SHT_PROGBITS
  2324  	sh.off = uint64(lineo)
  2325  	sh.size = uint64(linesize)
  2326  	sh.addralign = 1
  2327  	if linesympos > 0 {
  2328  		putelfsymshndx(linesympos, sh.shnum)
  2329  	}
  2330  	shline := sh
  2331  
  2332  	sh = newElfShdr(elfstrdbg[ElfStrDebugFrame])
  2333  	sh.type_ = SHT_PROGBITS
  2334  	sh.off = uint64(frameo)
  2335  	sh.size = uint64(framesize)
  2336  	sh.addralign = 1
  2337  	if framesympos > 0 {
  2338  		putelfsymshndx(framesympos, sh.shnum)
  2339  	}
  2340  	shframe := sh
  2341  
  2342  	sh = newElfShdr(elfstrdbg[ElfStrDebugInfo])
  2343  	sh.type_ = SHT_PROGBITS
  2344  	sh.off = uint64(infoo)
  2345  	sh.size = uint64(infosize)
  2346  	sh.addralign = 1
  2347  	if infosympos > 0 {
  2348  		putelfsymshndx(infosympos, sh.shnum)
  2349  	}
  2350  	shinfo := sh
  2351  
  2352  	if pubnamessize > 0 {
  2353  		sh := newElfShdr(elfstrdbg[ElfStrDebugPubNames])
  2354  		sh.type_ = SHT_PROGBITS
  2355  		sh.off = uint64(pubnameso)
  2356  		sh.size = uint64(pubnamessize)
  2357  		sh.addralign = 1
  2358  	}
  2359  
  2360  	if pubtypessize > 0 {
  2361  		sh := newElfShdr(elfstrdbg[ElfStrDebugPubTypes])
  2362  		sh.type_ = SHT_PROGBITS
  2363  		sh.off = uint64(pubtypeso)
  2364  		sh.size = uint64(pubtypessize)
  2365  		sh.addralign = 1
  2366  	}
  2367  
  2368  	var sharanges *ElfShdr
  2369  	if arangessize != 0 {
  2370  		sh := newElfShdr(elfstrdbg[ElfStrDebugAranges])
  2371  		sh.type_ = SHT_PROGBITS
  2372  		sh.off = uint64(arangeso)
  2373  		sh.size = uint64(arangessize)
  2374  		sh.addralign = 1
  2375  		sharanges = sh
  2376  	}
  2377  
  2378  	if gdbscriptsize != 0 {
  2379  		sh := newElfShdr(elfstrdbg[ElfStrGDBScripts])
  2380  		sh.type_ = SHT_PROGBITS
  2381  		sh.off = uint64(gdbscripto)
  2382  		sh.size = uint64(gdbscriptsize)
  2383  		sh.addralign = 1
  2384  	}
  2385  
  2386  	if inforelocsize != 0 {
  2387  		dwarfaddelfrelocheader(ElfStrRelDebugInfo, shinfo, inforeloco, inforelocsize)
  2388  	}
  2389  
  2390  	if arangesrelocsize != 0 {
  2391  		dwarfaddelfrelocheader(ElfStrRelDebugAranges, sharanges, arangesreloco, arangesrelocsize)
  2392  	}
  2393  
  2394  	if linerelocsize != 0 {
  2395  		dwarfaddelfrelocheader(ElfStrRelDebugLine, shline, linereloco, linerelocsize)
  2396  	}
  2397  
  2398  	if framerelocsize != 0 {
  2399  		dwarfaddelfrelocheader(ElfStrRelDebugFrame, shframe, framereloco, framerelocsize)
  2400  	}
  2401  }
  2402  
  2403  /*
  2404   * Macho
  2405   */
  2406  func dwarfaddmachoheaders(ms *MachoSeg) {
  2407  	if Debug['w'] != 0 { // disable dwarf
  2408  		return
  2409  	}
  2410  
  2411  	// Zero vsize segments won't be loaded in memory, even so they
  2412  	// have to be page aligned in the file.
  2413  	fakestart := Rnd(int64(Segdwarf.Fileoff), 0x1000)
  2414  	addr := Segdata.Vaddr + Segdata.Length
  2415  
  2416  	nsect := 4
  2417  	if pubnamessize > 0 {
  2418  		nsect++
  2419  	}
  2420  	if pubtypessize > 0 {
  2421  		nsect++
  2422  	}
  2423  	if arangessize > 0 {
  2424  		nsect++
  2425  	}
  2426  	if gdbscriptsize > 0 {
  2427  		nsect++
  2428  	}
  2429  
  2430  	if Linkmode != LinkExternal {
  2431  		ms = newMachoSeg("__DWARF", nsect)
  2432  		ms.fileoffset = uint64(fakestart)
  2433  		ms.filesize = Segdwarf.Filelen
  2434  		ms.vaddr = addr
  2435  	}
  2436  
  2437  	msect := newMachoSect(ms, "__debug_abbrev", "__DWARF")
  2438  	msect.off = uint32(abbrevo)
  2439  	msect.size = uint64(abbrevsize)
  2440  	msect.addr = addr
  2441  	addr += msect.size
  2442  	msect.flag = 0x02000000
  2443  	if abbrevsym != nil {
  2444  		abbrevsym.Value = int64(msect.addr)
  2445  	}
  2446  
  2447  	msect = newMachoSect(ms, "__debug_line", "__DWARF")
  2448  	msect.off = uint32(lineo)
  2449  	msect.size = uint64(linesize)
  2450  	msect.addr = addr
  2451  	addr += msect.size
  2452  	msect.flag = 0x02000000
  2453  	if linesym != nil {
  2454  		linesym.Value = int64(msect.addr)
  2455  	}
  2456  	if linerelocsize > 0 {
  2457  		msect.nreloc = uint32(len(linesec.R))
  2458  		msect.reloc = uint32(linereloco)
  2459  	}
  2460  
  2461  	msect = newMachoSect(ms, "__debug_frame", "__DWARF")
  2462  	msect.off = uint32(frameo)
  2463  	msect.size = uint64(framesize)
  2464  	msect.addr = addr
  2465  	addr += msect.size
  2466  	msect.flag = 0x02000000
  2467  	if framesym != nil {
  2468  		framesym.Value = int64(msect.addr)
  2469  	}
  2470  	if framerelocsize > 0 {
  2471  		msect.nreloc = uint32(len(framesec.R))
  2472  		msect.reloc = uint32(framereloco)
  2473  	}
  2474  
  2475  	msect = newMachoSect(ms, "__debug_info", "__DWARF")
  2476  	msect.off = uint32(infoo)
  2477  	msect.size = uint64(infosize)
  2478  	msect.addr = addr
  2479  	addr += msect.size
  2480  	msect.flag = 0x02000000
  2481  	if infosym != nil {
  2482  		infosym.Value = int64(msect.addr)
  2483  	}
  2484  	if inforelocsize > 0 {
  2485  		msect.nreloc = uint32(len(infosec.R))
  2486  		msect.reloc = uint32(inforeloco)
  2487  	}
  2488  
  2489  	if pubnamessize > 0 {
  2490  		msect := newMachoSect(ms, "__debug_pubnames", "__DWARF")
  2491  		msect.off = uint32(pubnameso)
  2492  		msect.size = uint64(pubnamessize)
  2493  		msect.addr = addr
  2494  		addr += msect.size
  2495  		msect.flag = 0x02000000
  2496  	}
  2497  
  2498  	if pubtypessize > 0 {
  2499  		msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF")
  2500  		msect.off = uint32(pubtypeso)
  2501  		msect.size = uint64(pubtypessize)
  2502  		msect.addr = addr
  2503  		addr += msect.size
  2504  		msect.flag = 0x02000000
  2505  	}
  2506  
  2507  	if arangessize > 0 {
  2508  		msect := newMachoSect(ms, "__debug_aranges", "__DWARF")
  2509  		msect.off = uint32(arangeso)
  2510  		msect.size = uint64(arangessize)
  2511  		msect.addr = addr
  2512  		addr += msect.size
  2513  		msect.flag = 0x02000000
  2514  		if arangesrelocsize > 0 {
  2515  			msect.nreloc = uint32(len(arangessec.R))
  2516  			msect.reloc = uint32(arangesreloco)
  2517  		}
  2518  	}
  2519  
  2520  	// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
  2521  	if gdbscriptsize > 0 {
  2522  		msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF")
  2523  		msect.off = uint32(gdbscripto)
  2524  		msect.size = uint64(gdbscriptsize)
  2525  		msect.addr = addr
  2526  		addr += msect.size
  2527  		msect.flag = 0x02000000
  2528  	}
  2529  }
  2530  
  2531  /*
  2532   * Windows PE
  2533   */
  2534  func dwarfaddpeheaders() {
  2535  	if Debug['w'] != 0 { // disable dwarf
  2536  		return
  2537  	}
  2538  
  2539  	newPEDWARFSection(".debug_abbrev", abbrevsize)
  2540  	newPEDWARFSection(".debug_line", linesize)
  2541  	newPEDWARFSection(".debug_frame", framesize)
  2542  	newPEDWARFSection(".debug_info", infosize)
  2543  	newPEDWARFSection(".debug_pubnames", pubnamessize)
  2544  	newPEDWARFSection(".debug_pubtypes", pubtypessize)
  2545  	newPEDWARFSection(".debug_aranges", arangessize)
  2546  	newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize)
  2547  }