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 }