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