github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/src/cmd/internal/dwarf/dwarf.go (about)

     1  // Copyright 2016 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  // Package dwarf generates DWARF debugging information.
     6  // DWARF generation is split between the compiler and the linker,
     7  // this package contains the shared code.
     8  package dwarf
     9  
    10  import (
    11  	"fmt"
    12  	"strings"
    13  )
    14  
    15  // InfoPrefix is the prefix for all the symbols containing DWARF info entries.
    16  const InfoPrefix = "go.info."
    17  
    18  // Sym represents a symbol.
    19  type Sym interface {
    20  }
    21  
    22  // A Var represents a local variable or a function parameter.
    23  type Var struct {
    24  	Name   string
    25  	Abbrev int // Either DW_ABRV_AUTO or DW_ABRV_PARAM
    26  	Offset int32
    27  	Type   Sym
    28  }
    29  
    30  // A Context specifies how to add data to a Sym.
    31  type Context interface {
    32  	PtrSize() int
    33  	AddInt(s Sym, size int, i int64)
    34  	AddBytes(s Sym, b []byte)
    35  	AddAddress(s Sym, t interface{}, ofs int64)
    36  	AddSectionOffset(s Sym, size int, t interface{}, ofs int64)
    37  	AddString(s Sym, v string)
    38  	SymValue(s Sym) int64
    39  }
    40  
    41  // AppendUleb128 appends v to b using DWARF's unsigned LEB128 encoding.
    42  func AppendUleb128(b []byte, v uint64) []byte {
    43  	for {
    44  		c := uint8(v & 0x7f)
    45  		v >>= 7
    46  		if v != 0 {
    47  			c |= 0x80
    48  		}
    49  		b = append(b, c)
    50  		if c&0x80 == 0 {
    51  			break
    52  		}
    53  	}
    54  	return b
    55  }
    56  
    57  // AppendSleb128 appends v to b using DWARF's signed LEB128 encoding.
    58  func AppendSleb128(b []byte, v int64) []byte {
    59  	for {
    60  		c := uint8(v & 0x7f)
    61  		s := uint8(v & 0x40)
    62  		v >>= 7
    63  		if (v != -1 || s == 0) && (v != 0 || s != 0) {
    64  			c |= 0x80
    65  		}
    66  		b = append(b, c)
    67  		if c&0x80 == 0 {
    68  			break
    69  		}
    70  	}
    71  	return b
    72  }
    73  
    74  var encbuf [20]byte
    75  
    76  // AppendUleb128 appends v to s using DWARF's unsigned LEB128 encoding.
    77  func Uleb128put(ctxt Context, s Sym, v int64) {
    78  	b := AppendUleb128(encbuf[:0], uint64(v))
    79  	ctxt.AddBytes(s, b)
    80  }
    81  
    82  // AppendUleb128 appends v to s using DWARF's signed LEB128 encoding.
    83  func Sleb128put(ctxt Context, s Sym, v int64) {
    84  	b := AppendSleb128(encbuf[:0], v)
    85  	ctxt.AddBytes(s, b)
    86  }
    87  
    88  /*
    89   * Defining Abbrevs.  This is hardcoded, and there will be
    90   * only a handful of them.  The DWARF spec places no restriction on
    91   * the ordering of attributes in the Abbrevs and DIEs, and we will
    92   * always write them out in the order of declaration in the abbrev.
    93   */
    94  type dwAttrForm struct {
    95  	attr uint16
    96  	form uint8
    97  }
    98  
    99  // Go-specific type attributes.
   100  const (
   101  	DW_AT_go_kind = 0x2900
   102  	DW_AT_go_key  = 0x2901
   103  	DW_AT_go_elem = 0x2902
   104  
   105  	DW_AT_internal_location = 253 // params and locals; not emitted
   106  )
   107  
   108  // Index into the abbrevs table below.
   109  // Keep in sync with ispubname() and ispubtype() below.
   110  // ispubtype considers >= NULLTYPE public
   111  const (
   112  	DW_ABRV_NULL = iota
   113  	DW_ABRV_COMPUNIT
   114  	DW_ABRV_FUNCTION
   115  	DW_ABRV_VARIABLE
   116  	DW_ABRV_AUTO
   117  	DW_ABRV_PARAM
   118  	DW_ABRV_STRUCTFIELD
   119  	DW_ABRV_FUNCTYPEPARAM
   120  	DW_ABRV_DOTDOTDOT
   121  	DW_ABRV_ARRAYRANGE
   122  	DW_ABRV_NULLTYPE
   123  	DW_ABRV_BASETYPE
   124  	DW_ABRV_ARRAYTYPE
   125  	DW_ABRV_CHANTYPE
   126  	DW_ABRV_FUNCTYPE
   127  	DW_ABRV_IFACETYPE
   128  	DW_ABRV_MAPTYPE
   129  	DW_ABRV_PTRTYPE
   130  	DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6.
   131  	DW_ABRV_SLICETYPE
   132  	DW_ABRV_STRINGTYPE
   133  	DW_ABRV_STRUCTTYPE
   134  	DW_ABRV_TYPEDECL
   135  	DW_NABRV
   136  )
   137  
   138  type dwAbbrev struct {
   139  	tag      uint8
   140  	children uint8
   141  	attr     []dwAttrForm
   142  }
   143  
   144  var abbrevs = [DW_NABRV]dwAbbrev{
   145  	/* The mandatory DW_ABRV_NULL entry. */
   146  	{0, 0, []dwAttrForm{}},
   147  
   148  	/* COMPUNIT */
   149  	{
   150  		DW_TAG_compile_unit,
   151  		DW_CHILDREN_yes,
   152  		[]dwAttrForm{
   153  			{DW_AT_name, DW_FORM_string},
   154  			{DW_AT_language, DW_FORM_data1},
   155  			{DW_AT_low_pc, DW_FORM_addr},
   156  			{DW_AT_high_pc, DW_FORM_addr},
   157  			{DW_AT_stmt_list, DW_FORM_data4},
   158  			{DW_AT_comp_dir, DW_FORM_string},
   159  		},
   160  	},
   161  
   162  	/* FUNCTION */
   163  	{
   164  		DW_TAG_subprogram,
   165  		DW_CHILDREN_yes,
   166  		[]dwAttrForm{
   167  			{DW_AT_name, DW_FORM_string},
   168  			{DW_AT_low_pc, DW_FORM_addr},
   169  			{DW_AT_high_pc, DW_FORM_addr},
   170  			{DW_AT_external, DW_FORM_flag},
   171  		},
   172  	},
   173  
   174  	/* VARIABLE */
   175  	{
   176  		DW_TAG_variable,
   177  		DW_CHILDREN_no,
   178  		[]dwAttrForm{
   179  			{DW_AT_name, DW_FORM_string},
   180  			{DW_AT_location, DW_FORM_block1},
   181  			{DW_AT_type, DW_FORM_ref_addr},
   182  			{DW_AT_external, DW_FORM_flag},
   183  		},
   184  	},
   185  
   186  	/* AUTO */
   187  	{
   188  		DW_TAG_variable,
   189  		DW_CHILDREN_no,
   190  		[]dwAttrForm{
   191  			{DW_AT_name, DW_FORM_string},
   192  			{DW_AT_location, DW_FORM_block1},
   193  			{DW_AT_type, DW_FORM_ref_addr},
   194  		},
   195  	},
   196  
   197  	/* PARAM */
   198  	{
   199  		DW_TAG_formal_parameter,
   200  		DW_CHILDREN_no,
   201  		[]dwAttrForm{
   202  			{DW_AT_name, DW_FORM_string},
   203  			{DW_AT_location, DW_FORM_block1},
   204  			{DW_AT_type, DW_FORM_ref_addr},
   205  		},
   206  	},
   207  
   208  	/* STRUCTFIELD */
   209  	{
   210  		DW_TAG_member,
   211  		DW_CHILDREN_no,
   212  		[]dwAttrForm{
   213  			{DW_AT_name, DW_FORM_string},
   214  			{DW_AT_data_member_location, DW_FORM_block1},
   215  			{DW_AT_type, DW_FORM_ref_addr},
   216  		},
   217  	},
   218  
   219  	/* FUNCTYPEPARAM */
   220  	{
   221  		DW_TAG_formal_parameter,
   222  		DW_CHILDREN_no,
   223  
   224  		// No name!
   225  		[]dwAttrForm{
   226  			{DW_AT_type, DW_FORM_ref_addr},
   227  		},
   228  	},
   229  
   230  	/* DOTDOTDOT */
   231  	{
   232  		DW_TAG_unspecified_parameters,
   233  		DW_CHILDREN_no,
   234  		[]dwAttrForm{},
   235  	},
   236  
   237  	/* ARRAYRANGE */
   238  	{
   239  		DW_TAG_subrange_type,
   240  		DW_CHILDREN_no,
   241  
   242  		// No name!
   243  		[]dwAttrForm{
   244  			{DW_AT_type, DW_FORM_ref_addr},
   245  			{DW_AT_count, DW_FORM_udata},
   246  		},
   247  	},
   248  
   249  	// Below here are the types considered public by ispubtype
   250  	/* NULLTYPE */
   251  	{
   252  		DW_TAG_unspecified_type,
   253  		DW_CHILDREN_no,
   254  		[]dwAttrForm{
   255  			{DW_AT_name, DW_FORM_string},
   256  		},
   257  	},
   258  
   259  	/* BASETYPE */
   260  	{
   261  		DW_TAG_base_type,
   262  		DW_CHILDREN_no,
   263  		[]dwAttrForm{
   264  			{DW_AT_name, DW_FORM_string},
   265  			{DW_AT_encoding, DW_FORM_data1},
   266  			{DW_AT_byte_size, DW_FORM_data1},
   267  			{DW_AT_go_kind, DW_FORM_data1},
   268  		},
   269  	},
   270  
   271  	/* ARRAYTYPE */
   272  	// child is subrange with upper bound
   273  	{
   274  		DW_TAG_array_type,
   275  		DW_CHILDREN_yes,
   276  		[]dwAttrForm{
   277  			{DW_AT_name, DW_FORM_string},
   278  			{DW_AT_type, DW_FORM_ref_addr},
   279  			{DW_AT_byte_size, DW_FORM_udata},
   280  			{DW_AT_go_kind, DW_FORM_data1},
   281  		},
   282  	},
   283  
   284  	/* CHANTYPE */
   285  	{
   286  		DW_TAG_typedef,
   287  		DW_CHILDREN_no,
   288  		[]dwAttrForm{
   289  			{DW_AT_name, DW_FORM_string},
   290  			{DW_AT_type, DW_FORM_ref_addr},
   291  			{DW_AT_go_kind, DW_FORM_data1},
   292  			{DW_AT_go_elem, DW_FORM_ref_addr},
   293  		},
   294  	},
   295  
   296  	/* FUNCTYPE */
   297  	{
   298  		DW_TAG_subroutine_type,
   299  		DW_CHILDREN_yes,
   300  		[]dwAttrForm{
   301  			{DW_AT_name, DW_FORM_string},
   302  			// {DW_AT_type,	DW_FORM_ref_addr},
   303  			{DW_AT_go_kind, DW_FORM_data1},
   304  		},
   305  	},
   306  
   307  	/* IFACETYPE */
   308  	{
   309  		DW_TAG_typedef,
   310  		DW_CHILDREN_yes,
   311  		[]dwAttrForm{
   312  			{DW_AT_name, DW_FORM_string},
   313  			{DW_AT_type, DW_FORM_ref_addr},
   314  			{DW_AT_go_kind, DW_FORM_data1},
   315  		},
   316  	},
   317  
   318  	/* MAPTYPE */
   319  	{
   320  		DW_TAG_typedef,
   321  		DW_CHILDREN_no,
   322  		[]dwAttrForm{
   323  			{DW_AT_name, DW_FORM_string},
   324  			{DW_AT_type, DW_FORM_ref_addr},
   325  			{DW_AT_go_kind, DW_FORM_data1},
   326  			{DW_AT_go_key, DW_FORM_ref_addr},
   327  			{DW_AT_go_elem, DW_FORM_ref_addr},
   328  		},
   329  	},
   330  
   331  	/* PTRTYPE */
   332  	{
   333  		DW_TAG_pointer_type,
   334  		DW_CHILDREN_no,
   335  		[]dwAttrForm{
   336  			{DW_AT_name, DW_FORM_string},
   337  			{DW_AT_type, DW_FORM_ref_addr},
   338  			{DW_AT_go_kind, DW_FORM_data1},
   339  		},
   340  	},
   341  
   342  	/* BARE_PTRTYPE */
   343  	{
   344  		DW_TAG_pointer_type,
   345  		DW_CHILDREN_no,
   346  		[]dwAttrForm{
   347  			{DW_AT_name, DW_FORM_string},
   348  		},
   349  	},
   350  
   351  	/* SLICETYPE */
   352  	{
   353  		DW_TAG_structure_type,
   354  		DW_CHILDREN_yes,
   355  		[]dwAttrForm{
   356  			{DW_AT_name, DW_FORM_string},
   357  			{DW_AT_byte_size, DW_FORM_udata},
   358  			{DW_AT_go_kind, DW_FORM_data1},
   359  			{DW_AT_go_elem, DW_FORM_ref_addr},
   360  		},
   361  	},
   362  
   363  	/* STRINGTYPE */
   364  	{
   365  		DW_TAG_structure_type,
   366  		DW_CHILDREN_yes,
   367  		[]dwAttrForm{
   368  			{DW_AT_name, DW_FORM_string},
   369  			{DW_AT_byte_size, DW_FORM_udata},
   370  			{DW_AT_go_kind, DW_FORM_data1},
   371  		},
   372  	},
   373  
   374  	/* STRUCTTYPE */
   375  	{
   376  		DW_TAG_structure_type,
   377  		DW_CHILDREN_yes,
   378  		[]dwAttrForm{
   379  			{DW_AT_name, DW_FORM_string},
   380  			{DW_AT_byte_size, DW_FORM_udata},
   381  			{DW_AT_go_kind, DW_FORM_data1},
   382  		},
   383  	},
   384  
   385  	/* TYPEDECL */
   386  	{
   387  		DW_TAG_typedef,
   388  		DW_CHILDREN_no,
   389  		[]dwAttrForm{
   390  			{DW_AT_name, DW_FORM_string},
   391  			{DW_AT_type, DW_FORM_ref_addr},
   392  		},
   393  	},
   394  }
   395  
   396  // GetAbbrev returns the contents of the .debug_abbrev section.
   397  func GetAbbrev() []byte {
   398  	var buf []byte
   399  	for i := 1; i < DW_NABRV; i++ {
   400  		// See section 7.5.3
   401  		buf = AppendUleb128(buf, uint64(i))
   402  
   403  		buf = AppendUleb128(buf, uint64(abbrevs[i].tag))
   404  		buf = append(buf, byte(abbrevs[i].children))
   405  		for _, f := range abbrevs[i].attr {
   406  			buf = AppendUleb128(buf, uint64(f.attr))
   407  			buf = AppendUleb128(buf, uint64(f.form))
   408  		}
   409  		buf = append(buf, 0, 0)
   410  	}
   411  	return append(buf, 0)
   412  }
   413  
   414  /*
   415   * Debugging Information Entries and their attributes.
   416   */
   417  
   418  // DWAttr represents an attribute of a DWDie.
   419  //
   420  // For DW_CLS_string and _block, value should contain the length, and
   421  // data the data, for _reference, value is 0 and data is a DWDie* to
   422  // the referenced instance, for all others, value is the whole thing
   423  // and data is null.
   424  type DWAttr struct {
   425  	Link  *DWAttr
   426  	Atr   uint16 // DW_AT_
   427  	Cls   uint8  // DW_CLS_
   428  	Value int64
   429  	Data  interface{}
   430  }
   431  
   432  // DWDie represents a DWARF debug info entry.
   433  type DWDie struct {
   434  	Abbrev int
   435  	Link   *DWDie
   436  	Child  *DWDie
   437  	Attr   *DWAttr
   438  	Sym    Sym
   439  }
   440  
   441  func putattr(ctxt Context, s Sym, abbrev int, form int, cls int, value int64, data interface{}) error {
   442  	switch form {
   443  	case DW_FORM_addr: // address
   444  		ctxt.AddAddress(s, data, value)
   445  
   446  	case DW_FORM_block1: // block
   447  		if cls == DW_CLS_ADDRESS {
   448  			ctxt.AddInt(s, 1, int64(1+ctxt.PtrSize()))
   449  			ctxt.AddInt(s, 1, DW_OP_addr)
   450  			ctxt.AddAddress(s, data, 0)
   451  			break
   452  		}
   453  
   454  		value &= 0xff
   455  		ctxt.AddInt(s, 1, value)
   456  		p := data.([]byte)[:value]
   457  		ctxt.AddBytes(s, p)
   458  
   459  	case DW_FORM_block2: // block
   460  		value &= 0xffff
   461  
   462  		ctxt.AddInt(s, 2, value)
   463  		p := data.([]byte)[:value]
   464  		ctxt.AddBytes(s, p)
   465  
   466  	case DW_FORM_block4: // block
   467  		value &= 0xffffffff
   468  
   469  		ctxt.AddInt(s, 4, value)
   470  		p := data.([]byte)[:value]
   471  		ctxt.AddBytes(s, p)
   472  
   473  	case DW_FORM_block: // block
   474  		Uleb128put(ctxt, s, value)
   475  
   476  		p := data.([]byte)[:value]
   477  		ctxt.AddBytes(s, p)
   478  
   479  	case DW_FORM_data1: // constant
   480  		ctxt.AddInt(s, 1, value)
   481  
   482  	case DW_FORM_data2: // constant
   483  		ctxt.AddInt(s, 2, value)
   484  
   485  	case DW_FORM_data4: // constant, {line,loclist,mac,rangelist}ptr
   486  		if cls == DW_CLS_PTR { // DW_AT_stmt_list
   487  			ctxt.AddSectionOffset(s, 4, data, 0)
   488  			break
   489  		}
   490  		ctxt.AddInt(s, 4, value)
   491  
   492  	case DW_FORM_data8: // constant, {line,loclist,mac,rangelist}ptr
   493  		ctxt.AddInt(s, 8, value)
   494  
   495  	case DW_FORM_sdata: // constant
   496  		Sleb128put(ctxt, s, value)
   497  
   498  	case DW_FORM_udata: // constant
   499  		Uleb128put(ctxt, s, value)
   500  
   501  	case DW_FORM_string: // string
   502  		str := data.(string)
   503  		ctxt.AddString(s, str)
   504  		// TODO(ribrdb): verify padded strings are never used and remove this
   505  		for i := int64(len(str)); i < value; i++ {
   506  			ctxt.AddInt(s, 1, 0)
   507  		}
   508  
   509  	case DW_FORM_flag: // flag
   510  		if value != 0 {
   511  			ctxt.AddInt(s, 1, 1)
   512  		} else {
   513  			ctxt.AddInt(s, 1, 0)
   514  		}
   515  
   516  	// In DWARF 2 (which is what we claim to generate),
   517  	// the ref_addr is the same size as a normal address.
   518  	// In DWARF 3 it is always 32 bits, unless emitting a large
   519  	// (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
   520  	case DW_FORM_ref_addr: // reference to a DIE in the .info section
   521  		if data == nil {
   522  			return fmt.Errorf("dwarf: null reference in %d", abbrev)
   523  		} else {
   524  			ctxt.AddSectionOffset(s, ctxt.PtrSize(), data, 0)
   525  		}
   526  
   527  	case DW_FORM_ref1, // reference within the compilation unit
   528  		DW_FORM_ref2,      // reference
   529  		DW_FORM_ref4,      // reference
   530  		DW_FORM_ref8,      // reference
   531  		DW_FORM_ref_udata, // reference
   532  
   533  		DW_FORM_strp,     // string
   534  		DW_FORM_indirect: // (see Section 7.5.3)
   535  		fallthrough
   536  	default:
   537  		return fmt.Errorf("dwarf: unsupported attribute form %d / class %d", form, cls)
   538  	}
   539  	return nil
   540  }
   541  
   542  // PutAttrs writes the attributes for a DIE to symbol 's'.
   543  //
   544  // Note that we can (and do) add arbitrary attributes to a DIE, but
   545  // only the ones actually listed in the Abbrev will be written out.
   546  func PutAttrs(ctxt Context, s Sym, abbrev int, attr *DWAttr) {
   547  Outer:
   548  	for _, f := range abbrevs[abbrev].attr {
   549  		for ap := attr; ap != nil; ap = ap.Link {
   550  			if ap.Atr == f.attr {
   551  				putattr(ctxt, s, abbrev, int(f.form), int(ap.Cls), ap.Value, ap.Data)
   552  				continue Outer
   553  			}
   554  		}
   555  
   556  		putattr(ctxt, s, abbrev, int(f.form), 0, 0, nil)
   557  	}
   558  }
   559  
   560  // HasChildren returns true if 'die' uses an abbrev that supports children.
   561  func HasChildren(die *DWDie) bool {
   562  	return abbrevs[die.Abbrev].children != 0
   563  }
   564  
   565  // PutFunc writes a DIE for a function to s.
   566  // It also writes child DIEs for each variable in vars.
   567  func PutFunc(ctxt Context, s Sym, name string, external bool, startPC Sym, size int64, vars []*Var) {
   568  	Uleb128put(ctxt, s, DW_ABRV_FUNCTION)
   569  	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
   570  	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, 0, startPC)
   571  	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_addr, DW_CLS_ADDRESS, size+ctxt.SymValue(startPC), startPC)
   572  	var ev int64
   573  	if external {
   574  		ev = 1
   575  	}
   576  	putattr(ctxt, s, DW_ABRV_FUNCTION, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
   577  	names := make(map[string]bool)
   578  	for _, v := range vars {
   579  		if strings.Contains(v.Name, ".autotmp_") {
   580  			continue
   581  		}
   582  		var n string
   583  		if names[v.Name] {
   584  			n = fmt.Sprintf("%s#%d", v.Name, len(names))
   585  		} else {
   586  			n = v.Name
   587  		}
   588  		names[n] = true
   589  
   590  		Uleb128put(ctxt, s, int64(v.Abbrev))
   591  		putattr(ctxt, s, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
   592  		loc := append(encbuf[:0], DW_OP_call_frame_cfa)
   593  		if v.Offset != 0 {
   594  			loc = append(loc, DW_OP_consts)
   595  			loc = AppendSleb128(loc, int64(v.Offset))
   596  			loc = append(loc, DW_OP_plus)
   597  		}
   598  		putattr(ctxt, s, v.Abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc)
   599  		putattr(ctxt, s, v.Abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)
   600  
   601  	}
   602  	Uleb128put(ctxt, s, 0)
   603  }
   604  
   605  // VarsByOffset attaches the methods of sort.Interface to []*Var,
   606  // sorting in increasing Offset.
   607  type VarsByOffset []*Var
   608  
   609  func (s VarsByOffset) Len() int           { return len(s) }
   610  func (s VarsByOffset) Less(i, j int) bool { return s[i].Offset < s[j].Offset }
   611  func (s VarsByOffset) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }