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] }