Home | History | Annotate | Download | only in dwarf
      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 }
    605