github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/src/cmd/link/internal/ld/dwarf.go (about) 1 // Copyright 2010 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 // TODO/NICETOHAVE: 6 // - eliminate DW_CLS_ if not used 7 // - package info in compilation units 8 // - assign global variables and types to their packages 9 // - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg 10 // ptype struct '[]uint8' and qualifiers need to be quoted away 11 // - file:line info for variables 12 // - make strings a typedef so prettyprinters can see the underlying string type 13 14 package ld 15 16 import ( 17 "cmd/internal/dwarf" 18 "cmd/internal/objabi" 19 "fmt" 20 "log" 21 "os" 22 "strings" 23 ) 24 25 type dwctxt struct { 26 linkctxt *Link 27 } 28 29 func (c dwctxt) PtrSize() int { 30 return SysArch.PtrSize 31 } 32 func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) { 33 ls := s.(*Symbol) 34 adduintxx(c.linkctxt, ls, uint64(i), size) 35 } 36 func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) { 37 ls := s.(*Symbol) 38 Addbytes(ls, b) 39 } 40 func (c dwctxt) AddString(s dwarf.Sym, v string) { 41 Addstring(s.(*Symbol), v) 42 } 43 func (c dwctxt) SymValue(s dwarf.Sym) int64 { 44 return s.(*Symbol).Value 45 } 46 47 func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) { 48 if value != 0 { 49 value -= (data.(*Symbol)).Value 50 } 51 Addaddrplus(c.linkctxt, s.(*Symbol), data.(*Symbol), value) 52 } 53 54 func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) { 55 ls := s.(*Symbol) 56 switch size { 57 default: 58 Errorf(ls, "invalid size %d in adddwarfref\n", size) 59 fallthrough 60 case SysArch.PtrSize: 61 Addaddr(c.linkctxt, ls, t.(*Symbol)) 62 case 4: 63 addaddrplus4(c.linkctxt, ls, t.(*Symbol), 0) 64 } 65 r := &ls.R[len(ls.R)-1] 66 r.Type = objabi.R_DWARFREF 67 r.Add = ofs 68 } 69 70 var gdbscript string 71 72 var dwarfp []*Symbol 73 74 func writeabbrev(ctxt *Link) *Symbol { 75 s := ctxt.Syms.Lookup(".debug_abbrev", 0) 76 s.Type = SDWARFSECT 77 Addbytes(s, dwarf.GetAbbrev()) 78 return s 79 } 80 81 /* 82 * Root DIEs for compilation units, types and global variables. 83 */ 84 var dwroot dwarf.DWDie 85 86 var dwtypes dwarf.DWDie 87 88 var dwglobals dwarf.DWDie 89 90 func newattr(die *dwarf.DWDie, attr uint16, cls int, value int64, data interface{}) *dwarf.DWAttr { 91 a := new(dwarf.DWAttr) 92 a.Link = die.Attr 93 die.Attr = a 94 a.Atr = attr 95 a.Cls = uint8(cls) 96 a.Value = value 97 a.Data = data 98 return a 99 } 100 101 // Each DIE (except the root ones) has at least 1 attribute: its 102 // name. getattr moves the desired one to the front so 103 // frequently searched ones are found faster. 104 func getattr(die *dwarf.DWDie, attr uint16) *dwarf.DWAttr { 105 if die.Attr.Atr == attr { 106 return die.Attr 107 } 108 109 a := die.Attr 110 b := a.Link 111 for b != nil { 112 if b.Atr == attr { 113 a.Link = b.Link 114 b.Link = die.Attr 115 die.Attr = b 116 return b 117 } 118 119 a = b 120 b = b.Link 121 } 122 123 return nil 124 } 125 126 // Every DIE has at least a AT_name attribute (but it will only be 127 // written out if it is listed in the abbrev). 128 func newdie(ctxt *Link, parent *dwarf.DWDie, abbrev int, name string, version int) *dwarf.DWDie { 129 die := new(dwarf.DWDie) 130 die.Abbrev = abbrev 131 die.Link = parent.Child 132 parent.Child = die 133 134 newattr(die, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len(name)), name) 135 136 if name != "" && (abbrev <= dwarf.DW_ABRV_VARIABLE || abbrev >= dwarf.DW_ABRV_NULLTYPE) { 137 if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 { 138 sym := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version) 139 sym.Attr |= AttrNotInSymbolTable 140 sym.Type = SDWARFINFO 141 die.Sym = sym 142 } 143 } 144 145 return die 146 } 147 148 func walktypedef(die *dwarf.DWDie) *dwarf.DWDie { 149 if die == nil { 150 return nil 151 } 152 // Resolve typedef if present. 153 if die.Abbrev == dwarf.DW_ABRV_TYPEDECL { 154 for attr := die.Attr; attr != nil; attr = attr.Link { 155 if attr.Atr == dwarf.DW_AT_type && attr.Cls == dwarf.DW_CLS_REFERENCE && attr.Data != nil { 156 return attr.Data.(*dwarf.DWDie) 157 } 158 } 159 } 160 161 return die 162 } 163 164 func walksymtypedef(ctxt *Link, s *Symbol) *Symbol { 165 if t := ctxt.Syms.ROLookup(s.Name+"..def", int(s.Version)); t != nil { 166 return t 167 } 168 return s 169 } 170 171 // Find child by AT_name using hashtable if available or linear scan 172 // if not. 173 func findchild(die *dwarf.DWDie, name string) *dwarf.DWDie { 174 var prev *dwarf.DWDie 175 for ; die != prev; prev, die = die, walktypedef(die) { 176 for a := die.Child; a != nil; a = a.Link { 177 if name == getattr(a, dwarf.DW_AT_name).Data { 178 return a 179 } 180 } 181 continue 182 } 183 return nil 184 } 185 186 // Used to avoid string allocation when looking up dwarf symbols 187 var prefixBuf = []byte(dwarf.InfoPrefix) 188 189 func find(ctxt *Link, name string) *Symbol { 190 n := append(prefixBuf, name...) 191 // The string allocation below is optimized away because it is only used in a map lookup. 192 s := ctxt.Syms.ROLookup(string(n), 0) 193 prefixBuf = n[:len(dwarf.InfoPrefix)] 194 if s != nil && s.Type == SDWARFINFO { 195 return s 196 } 197 return nil 198 } 199 200 func mustFind(ctxt *Link, name string) *Symbol { 201 r := find(ctxt, name) 202 if r == nil { 203 Exitf("dwarf find: cannot find %s", name) 204 } 205 return r 206 } 207 208 func adddwarfref(ctxt *Link, s *Symbol, t *Symbol, size int) int64 { 209 var result int64 210 switch size { 211 default: 212 Errorf(s, "invalid size %d in adddwarfref\n", size) 213 fallthrough 214 case SysArch.PtrSize: 215 result = Addaddr(ctxt, s, t) 216 case 4: 217 result = addaddrplus4(ctxt, s, t, 0) 218 } 219 r := &s.R[len(s.R)-1] 220 r.Type = objabi.R_DWARFREF 221 return result 222 } 223 224 func newrefattr(die *dwarf.DWDie, attr uint16, ref *Symbol) *dwarf.DWAttr { 225 if ref == nil { 226 return nil 227 } 228 return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, ref) 229 } 230 231 func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol { 232 for ; die != nil; die = die.Link { 233 syms = putdie(linkctxt, ctxt, syms, die) 234 } 235 Adduint8(linkctxt, syms[len(syms)-1], 0) 236 237 return syms 238 } 239 240 func dtolsym(s dwarf.Sym) *Symbol { 241 if s == nil { 242 return nil 243 } 244 return s.(*Symbol) 245 } 246 247 func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol { 248 s := dtolsym(die.Sym) 249 if s == nil { 250 s = syms[len(syms)-1] 251 } else { 252 if s.Attr.OnList() { 253 log.Fatalf("symbol %s listed multiple times", s.Name) 254 } 255 s.Attr |= AttrOnList 256 syms = append(syms, s) 257 } 258 dwarf.Uleb128put(ctxt, s, int64(die.Abbrev)) 259 dwarf.PutAttrs(ctxt, s, die.Abbrev, die.Attr) 260 if dwarf.HasChildren(die) { 261 return putdies(linkctxt, ctxt, syms, die.Child) 262 } 263 return syms 264 } 265 266 func reverselist(list **dwarf.DWDie) { 267 curr := *list 268 var prev *dwarf.DWDie 269 for curr != nil { 270 var next *dwarf.DWDie = curr.Link 271 curr.Link = prev 272 prev = curr 273 curr = next 274 } 275 276 *list = prev 277 } 278 279 func reversetree(list **dwarf.DWDie) { 280 reverselist(list) 281 for die := *list; die != nil; die = die.Link { 282 if dwarf.HasChildren(die) { 283 reversetree(&die.Child) 284 } 285 } 286 } 287 288 func newmemberoffsetattr(die *dwarf.DWDie, offs int32) { 289 var block [20]byte 290 b := append(block[:0], dwarf.DW_OP_plus_uconst) 291 b = dwarf.AppendUleb128(b, uint64(offs)) 292 newattr(die, dwarf.DW_AT_data_member_location, dwarf.DW_CLS_BLOCK, int64(len(b)), b) 293 } 294 295 // GDB doesn't like FORM_addr for AT_location, so emit a 296 // location expression that evals to a const. 297 func newabslocexprattr(die *dwarf.DWDie, addr int64, sym *Symbol) { 298 newattr(die, dwarf.DW_AT_location, dwarf.DW_CLS_ADDRESS, addr, sym) 299 // below 300 } 301 302 // Lookup predefined types 303 func lookupOrDiag(ctxt *Link, n string) *Symbol { 304 s := ctxt.Syms.ROLookup(n, 0) 305 if s == nil || s.Size == 0 { 306 Exitf("dwarf: missing type: %s", n) 307 } 308 309 return s 310 } 311 312 func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) { 313 // Only emit typedefs for real names. 314 if strings.HasPrefix(name, "map[") { 315 return 316 } 317 if strings.HasPrefix(name, "struct {") { 318 return 319 } 320 if strings.HasPrefix(name, "chan ") { 321 return 322 } 323 if name[0] == '[' || name[0] == '*' { 324 return 325 } 326 if def == nil { 327 Errorf(nil, "dwarf: bad def in dotypedef") 328 } 329 330 sym := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0) 331 sym.Attr |= AttrNotInSymbolTable 332 sym.Type = SDWARFINFO 333 def.Sym = sym 334 335 // The typedef entry must be created after the def, 336 // so that future lookups will find the typedef instead 337 // of the real definition. This hooks the typedef into any 338 // circular definition loops, so that gdb can understand them. 339 die := newdie(ctxt, parent, dwarf.DW_ABRV_TYPEDECL, name, 0) 340 341 newrefattr(die, dwarf.DW_AT_type, sym) 342 } 343 344 // Define gotype, for composite ones recurse into constituents. 345 func defgotype(ctxt *Link, gotype *Symbol) *Symbol { 346 if gotype == nil { 347 return mustFind(ctxt, "<unspecified>") 348 } 349 350 if !strings.HasPrefix(gotype.Name, "type.") { 351 Errorf(gotype, "dwarf: type name doesn't start with \"type.\"") 352 return mustFind(ctxt, "<unspecified>") 353 } 354 355 name := gotype.Name[5:] // could also decode from Type.string 356 357 sdie := find(ctxt, name) 358 359 if sdie != nil { 360 return sdie 361 } 362 363 return newtype(ctxt, gotype).Sym.(*Symbol) 364 } 365 366 func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie { 367 name := gotype.Name[5:] // could also decode from Type.string 368 kind := decodetypeKind(gotype) 369 bytesize := decodetypeSize(ctxt.Arch, gotype) 370 371 var die *dwarf.DWDie 372 switch kind { 373 case objabi.KindBool: 374 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0) 375 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_boolean, 0) 376 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 377 378 case objabi.KindInt, 379 objabi.KindInt8, 380 objabi.KindInt16, 381 objabi.KindInt32, 382 objabi.KindInt64: 383 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0) 384 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_signed, 0) 385 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 386 387 case objabi.KindUint, 388 objabi.KindUint8, 389 objabi.KindUint16, 390 objabi.KindUint32, 391 objabi.KindUint64, 392 objabi.KindUintptr: 393 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0) 394 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0) 395 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 396 397 case objabi.KindFloat32, 398 objabi.KindFloat64: 399 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0) 400 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_float, 0) 401 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 402 403 case objabi.KindComplex64, 404 objabi.KindComplex128: 405 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0) 406 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_complex_float, 0) 407 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 408 409 case objabi.KindArray: 410 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_ARRAYTYPE, name, 0) 411 dotypedef(ctxt, &dwtypes, name, die) 412 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 413 s := decodetypeArrayElem(gotype) 414 newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s)) 415 fld := newdie(ctxt, die, dwarf.DW_ABRV_ARRAYRANGE, "range", 0) 416 417 // use actual length not upper bound; correct for 0-length arrays. 418 newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, decodetypeArrayLen(ctxt.Arch, gotype), 0) 419 420 newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr")) 421 422 case objabi.KindChan: 423 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_CHANTYPE, name, 0) 424 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 425 s := decodetypeChanElem(gotype) 426 newrefattr(die, dwarf.DW_AT_go_elem, defgotype(ctxt, s)) 427 // Save elem type for synthesizechantypes. We could synthesize here 428 // but that would change the order of DIEs we output. 429 newrefattr(die, dwarf.DW_AT_type, s) 430 431 case objabi.KindFunc: 432 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_FUNCTYPE, name, 0) 433 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 434 dotypedef(ctxt, &dwtypes, name, die) 435 newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "void")) 436 nfields := decodetypeFuncInCount(ctxt.Arch, gotype) 437 var fld *dwarf.DWDie 438 var s *Symbol 439 for i := 0; i < nfields; i++ { 440 s = decodetypeFuncInType(gotype, i) 441 fld = newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0) 442 newrefattr(fld, dwarf.DW_AT_type, defgotype(ctxt, s)) 443 } 444 445 if decodetypeFuncDotdotdot(ctxt.Arch, gotype) { 446 newdie(ctxt, die, dwarf.DW_ABRV_DOTDOTDOT, "...", 0) 447 } 448 nfields = decodetypeFuncOutCount(ctxt.Arch, gotype) 449 for i := 0; i < nfields; i++ { 450 s = decodetypeFuncOutType(ctxt.Arch, gotype, i) 451 fld = newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0) 452 newrefattr(fld, dwarf.DW_AT_type, defptrto(ctxt, defgotype(ctxt, s))) 453 } 454 455 case objabi.KindInterface: 456 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_IFACETYPE, name, 0) 457 dotypedef(ctxt, &dwtypes, name, die) 458 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 459 nfields := int(decodetypeIfaceMethodCount(ctxt.Arch, gotype)) 460 var s *Symbol 461 if nfields == 0 { 462 s = lookupOrDiag(ctxt, "type.runtime.eface") 463 } else { 464 s = lookupOrDiag(ctxt, "type.runtime.iface") 465 } 466 newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s)) 467 468 case objabi.KindMap: 469 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_MAPTYPE, name, 0) 470 s := decodetypeMapKey(gotype) 471 newrefattr(die, dwarf.DW_AT_go_key, defgotype(ctxt, s)) 472 s = decodetypeMapValue(gotype) 473 newrefattr(die, dwarf.DW_AT_go_elem, defgotype(ctxt, s)) 474 // Save gotype for use in synthesizemaptypes. We could synthesize here, 475 // but that would change the order of the DIEs. 476 newrefattr(die, dwarf.DW_AT_type, gotype) 477 478 case objabi.KindPtr: 479 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_PTRTYPE, name, 0) 480 dotypedef(ctxt, &dwtypes, name, die) 481 s := decodetypePtrElem(gotype) 482 newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s)) 483 484 case objabi.KindSlice: 485 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_SLICETYPE, name, 0) 486 dotypedef(ctxt, &dwtypes, name, die) 487 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 488 s := decodetypeArrayElem(gotype) 489 elem := defgotype(ctxt, s) 490 newrefattr(die, dwarf.DW_AT_go_elem, elem) 491 492 case objabi.KindString: 493 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_STRINGTYPE, name, 0) 494 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 495 496 case objabi.KindStruct: 497 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_STRUCTTYPE, name, 0) 498 dotypedef(ctxt, &dwtypes, name, die) 499 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0) 500 nfields := decodetypeStructFieldCount(ctxt.Arch, gotype) 501 for i := 0; i < nfields; i++ { 502 f := decodetypeStructFieldName(gotype, i) 503 s := decodetypeStructFieldType(gotype, i) 504 if f == "" { 505 f = s.Name[5:] // skip "type." 506 } 507 fld := newdie(ctxt, die, dwarf.DW_ABRV_STRUCTFIELD, f, 0) 508 newrefattr(fld, dwarf.DW_AT_type, defgotype(ctxt, s)) 509 offsetAnon := decodetypeStructFieldOffsAnon(ctxt.Arch, gotype, i) 510 newmemberoffsetattr(fld, int32(offsetAnon>>1)) 511 if offsetAnon&1 != 0 { // is embedded field 512 newattr(fld, dwarf.DW_AT_go_embedded_field, dwarf.DW_CLS_FLAG, 1, 0) 513 } 514 } 515 516 case objabi.KindUnsafePointer: 517 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, name, 0) 518 519 default: 520 Errorf(gotype, "dwarf: definition of unknown kind %d", kind) 521 die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_TYPEDECL, name, 0) 522 newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "<unspecified>")) 523 } 524 525 newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(kind), 0) 526 527 if _, ok := prototypedies[gotype.Name]; ok { 528 prototypedies[gotype.Name] = die 529 } 530 531 return die 532 } 533 534 func nameFromDIESym(dwtype *Symbol) string { 535 return strings.TrimSuffix(dwtype.Name[len(dwarf.InfoPrefix):], "..def") 536 } 537 538 // Find or construct *T given T. 539 func defptrto(ctxt *Link, dwtype *Symbol) *Symbol { 540 ptrname := "*" + nameFromDIESym(dwtype) 541 die := find(ctxt, ptrname) 542 if die == nil { 543 pdie := newdie(ctxt, &dwtypes, dwarf.DW_ABRV_PTRTYPE, ptrname, 0) 544 newrefattr(pdie, dwarf.DW_AT_type, dwtype) 545 return dtolsym(pdie.Sym) 546 } 547 548 return die 549 } 550 551 // Copies src's children into dst. Copies attributes by value. 552 // DWAttr.data is copied as pointer only. If except is one of 553 // the top-level children, it will not be copied. 554 func copychildrenexcept(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie, except *dwarf.DWDie) { 555 for src = src.Child; src != nil; src = src.Link { 556 if src == except { 557 continue 558 } 559 c := newdie(ctxt, dst, src.Abbrev, getattr(src, dwarf.DW_AT_name).Data.(string), 0) 560 for a := src.Attr; a != nil; a = a.Link { 561 newattr(c, a.Atr, int(a.Cls), a.Value, a.Data) 562 } 563 copychildrenexcept(ctxt, c, src, nil) 564 } 565 566 reverselist(&dst.Child) 567 } 568 569 func copychildren(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie) { 570 copychildrenexcept(ctxt, dst, src, nil) 571 } 572 573 // Search children (assumed to have TAG_member) for the one named 574 // field and set its AT_type to dwtype 575 func substitutetype(structdie *dwarf.DWDie, field string, dwtype *Symbol) { 576 child := findchild(structdie, field) 577 if child == nil { 578 Exitf("dwarf substitutetype: %s does not have member %s", 579 getattr(structdie, dwarf.DW_AT_name).Data, field) 580 return 581 } 582 583 a := getattr(child, dwarf.DW_AT_type) 584 if a != nil { 585 a.Data = dwtype 586 } else { 587 newrefattr(child, dwarf.DW_AT_type, dwtype) 588 } 589 } 590 591 func findprotodie(ctxt *Link, name string) *dwarf.DWDie { 592 die, ok := prototypedies[name] 593 if ok && die == nil { 594 defgotype(ctxt, lookupOrDiag(ctxt, name)) 595 die = prototypedies[name] 596 } 597 return die 598 } 599 600 func synthesizestringtypes(ctxt *Link, die *dwarf.DWDie) { 601 prototype := walktypedef(findprotodie(ctxt, "type.runtime.stringStructDWARF")) 602 if prototype == nil { 603 return 604 } 605 606 for ; die != nil; die = die.Link { 607 if die.Abbrev != dwarf.DW_ABRV_STRINGTYPE { 608 continue 609 } 610 copychildren(ctxt, die, prototype) 611 } 612 } 613 614 func synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) { 615 prototype := walktypedef(findprotodie(ctxt, "type.runtime.slice")) 616 if prototype == nil { 617 return 618 } 619 620 for ; die != nil; die = die.Link { 621 if die.Abbrev != dwarf.DW_ABRV_SLICETYPE { 622 continue 623 } 624 copychildren(ctxt, die, prototype) 625 elem := getattr(die, dwarf.DW_AT_go_elem).Data.(*Symbol) 626 substitutetype(die, "array", defptrto(ctxt, elem)) 627 } 628 } 629 630 func mkinternaltypename(base string, arg1 string, arg2 string) string { 631 var buf string 632 633 if arg2 == "" { 634 buf = fmt.Sprintf("%s<%s>", base, arg1) 635 } else { 636 buf = fmt.Sprintf("%s<%s,%s>", base, arg1, arg2) 637 } 638 n := buf 639 return n 640 } 641 642 // synthesizemaptypes is way too closely married to runtime/hashmap.c 643 const ( 644 MaxKeySize = 128 645 MaxValSize = 128 646 BucketSize = 8 647 ) 648 649 func mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) *Symbol { 650 name := mkinternaltypename(typename, keyname, valname) 651 symname := dwarf.InfoPrefix + name 652 s := ctxt.Syms.ROLookup(symname, 0) 653 if s != nil && s.Type == SDWARFINFO { 654 return s 655 } 656 die := newdie(ctxt, &dwtypes, abbrev, name, 0) 657 f(die) 658 return dtolsym(die.Sym) 659 } 660 661 func synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) { 662 hash := walktypedef(findprotodie(ctxt, "type.runtime.hmap")) 663 bucket := walktypedef(findprotodie(ctxt, "type.runtime.bmap")) 664 665 if hash == nil { 666 return 667 } 668 669 for ; die != nil; die = die.Link { 670 if die.Abbrev != dwarf.DW_ABRV_MAPTYPE { 671 continue 672 } 673 gotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol) 674 keytype := decodetypeMapKey(gotype) 675 valtype := decodetypeMapValue(gotype) 676 keysize, valsize := decodetypeSize(ctxt.Arch, keytype), decodetypeSize(ctxt.Arch, valtype) 677 keytype, valtype = walksymtypedef(ctxt, defgotype(ctxt, keytype)), walksymtypedef(ctxt, defgotype(ctxt, valtype)) 678 679 // compute size info like hashmap.c does. 680 indirectKey, indirectVal := false, false 681 if keysize > MaxKeySize { 682 keysize = int64(SysArch.PtrSize) 683 indirectKey = true 684 } 685 if valsize > MaxValSize { 686 valsize = int64(SysArch.PtrSize) 687 indirectVal = true 688 } 689 690 // Construct type to represent an array of BucketSize keys 691 keyname := nameFromDIESym(keytype) 692 dwhks := mkinternaltype(ctxt, dwarf.DW_ABRV_ARRAYTYPE, "[]key", keyname, "", func(dwhk *dwarf.DWDie) { 693 newattr(dwhk, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize*keysize, 0) 694 t := keytype 695 if indirectKey { 696 t = defptrto(ctxt, keytype) 697 } 698 newrefattr(dwhk, dwarf.DW_AT_type, t) 699 fld := newdie(ctxt, dwhk, dwarf.DW_ABRV_ARRAYRANGE, "size", 0) 700 newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, BucketSize, 0) 701 newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr")) 702 }) 703 704 // Construct type to represent an array of BucketSize values 705 valname := nameFromDIESym(valtype) 706 dwhvs := mkinternaltype(ctxt, dwarf.DW_ABRV_ARRAYTYPE, "[]val", valname, "", func(dwhv *dwarf.DWDie) { 707 newattr(dwhv, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize*valsize, 0) 708 t := valtype 709 if indirectVal { 710 t = defptrto(ctxt, valtype) 711 } 712 newrefattr(dwhv, dwarf.DW_AT_type, t) 713 fld := newdie(ctxt, dwhv, dwarf.DW_ABRV_ARRAYRANGE, "size", 0) 714 newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, BucketSize, 0) 715 newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr")) 716 }) 717 718 // Construct bucket<K,V> 719 dwhbs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "bucket", keyname, valname, func(dwhb *dwarf.DWDie) { 720 // Copy over all fields except the field "data" from the generic 721 // bucket. "data" will be replaced with keys/values below. 722 copychildrenexcept(ctxt, dwhb, bucket, findchild(bucket, "data")) 723 724 fld := newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "keys", 0) 725 newrefattr(fld, dwarf.DW_AT_type, dwhks) 726 newmemberoffsetattr(fld, BucketSize) 727 fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "values", 0) 728 newrefattr(fld, dwarf.DW_AT_type, dwhvs) 729 newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize)) 730 fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "overflow", 0) 731 newrefattr(fld, dwarf.DW_AT_type, defptrto(ctxt, dtolsym(dwhb.Sym))) 732 newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))) 733 if SysArch.RegSize > SysArch.PtrSize { 734 fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "pad", 0) 735 newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr")) 736 newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(SysArch.PtrSize)) 737 } 738 739 newattr(dwhb, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize+BucketSize*keysize+BucketSize*valsize+int64(SysArch.RegSize), 0) 740 }) 741 742 // Construct hash<K,V> 743 dwhs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hash", keyname, valname, func(dwh *dwarf.DWDie) { 744 copychildren(ctxt, dwh, hash) 745 substitutetype(dwh, "buckets", defptrto(ctxt, dwhbs)) 746 substitutetype(dwh, "oldbuckets", defptrto(ctxt, dwhbs)) 747 newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hash, dwarf.DW_AT_byte_size).Value, nil) 748 }) 749 750 // make map type a pointer to hash<K,V> 751 newrefattr(die, dwarf.DW_AT_type, defptrto(ctxt, dwhs)) 752 } 753 } 754 755 func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) { 756 sudog := walktypedef(findprotodie(ctxt, "type.runtime.sudog")) 757 waitq := walktypedef(findprotodie(ctxt, "type.runtime.waitq")) 758 hchan := walktypedef(findprotodie(ctxt, "type.runtime.hchan")) 759 if sudog == nil || waitq == nil || hchan == nil { 760 return 761 } 762 763 sudogsize := int(getattr(sudog, dwarf.DW_AT_byte_size).Value) 764 765 for ; die != nil; die = die.Link { 766 if die.Abbrev != dwarf.DW_ABRV_CHANTYPE { 767 continue 768 } 769 elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol) 770 elemname := elemgotype.Name[5:] 771 elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype)) 772 773 // sudog<T> 774 dwss := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) { 775 copychildren(ctxt, dws, sudog) 776 substitutetype(dws, "elem", defptrto(ctxt, elemtype)) 777 newattr(dws, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(sudogsize), nil) 778 }) 779 780 // waitq<T> 781 dwws := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "waitq", elemname, "", func(dww *dwarf.DWDie) { 782 783 copychildren(ctxt, dww, waitq) 784 substitutetype(dww, "first", defptrto(ctxt, dwss)) 785 substitutetype(dww, "last", defptrto(ctxt, dwss)) 786 newattr(dww, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(waitq, dwarf.DW_AT_byte_size).Value, nil) 787 }) 788 789 // hchan<T> 790 dwhs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hchan", elemname, "", func(dwh *dwarf.DWDie) { 791 copychildren(ctxt, dwh, hchan) 792 substitutetype(dwh, "recvq", dwws) 793 substitutetype(dwh, "sendq", dwws) 794 newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hchan, dwarf.DW_AT_byte_size).Value, nil) 795 }) 796 797 newrefattr(die, dwarf.DW_AT_type, defptrto(ctxt, dwhs)) 798 } 799 } 800 801 // For use with pass.c::genasmsym 802 func defdwsymb(ctxt *Link, sym *Symbol, s string, t SymbolType, v int64, gotype *Symbol) { 803 if strings.HasPrefix(s, "go.string.") { 804 return 805 } 806 if strings.HasPrefix(s, "runtime.gcbits.") { 807 return 808 } 809 810 if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") { 811 defgotype(ctxt, sym) 812 return 813 } 814 815 var dv *dwarf.DWDie 816 817 var dt *Symbol 818 switch t { 819 default: 820 return 821 822 case DataSym, BSSSym: 823 dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, s, int(sym.Version)) 824 newabslocexprattr(dv, v, sym) 825 if sym.Version == 0 { 826 newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0) 827 } 828 fallthrough 829 830 case AutoSym, ParamSym: 831 dt = defgotype(ctxt, gotype) 832 } 833 834 if dv != nil { 835 newrefattr(dv, dwarf.DW_AT_type, dt) 836 } 837 } 838 839 func movetomodule(parent *dwarf.DWDie) { 840 die := dwroot.Child.Child 841 if die == nil { 842 dwroot.Child.Child = parent.Child 843 return 844 } 845 for die.Link != nil { 846 die = die.Link 847 } 848 die.Link = parent.Child 849 } 850 851 // If the pcln table contains runtime/runtime.go, use that to set gdbscript path. 852 func finddebugruntimepath(s *Symbol) { 853 if gdbscript != "" { 854 return 855 } 856 857 for i := range s.FuncInfo.File { 858 f := s.FuncInfo.File[i] 859 if i := strings.Index(f.Name, "runtime/debug.go"); i >= 0 { 860 gdbscript = f.Name[:i] + "runtime/runtime-gdb.py" 861 break 862 } 863 } 864 } 865 866 /* 867 * Generate a sequence of opcodes that is as short as possible. 868 * See section 6.2.5 869 */ 870 const ( 871 LINE_BASE = -4 872 LINE_RANGE = 10 873 PC_RANGE = (255 - OPCODE_BASE) / LINE_RANGE 874 OPCODE_BASE = 10 875 ) 876 877 func putpclcdelta(linkctxt *Link, ctxt dwarf.Context, s *Symbol, deltaPC uint64, deltaLC int64) { 878 // Choose a special opcode that minimizes the number of bytes needed to 879 // encode the remaining PC delta and LC delta. 880 var opcode int64 881 if deltaLC < LINE_BASE { 882 if deltaPC >= PC_RANGE { 883 opcode = OPCODE_BASE + (LINE_RANGE * PC_RANGE) 884 } else { 885 opcode = OPCODE_BASE + (LINE_RANGE * int64(deltaPC)) 886 } 887 } else if deltaLC < LINE_BASE+LINE_RANGE { 888 if deltaPC >= PC_RANGE { 889 opcode = OPCODE_BASE + (deltaLC - LINE_BASE) + (LINE_RANGE * PC_RANGE) 890 if opcode > 255 { 891 opcode -= LINE_RANGE 892 } 893 } else { 894 opcode = OPCODE_BASE + (deltaLC - LINE_BASE) + (LINE_RANGE * int64(deltaPC)) 895 } 896 } else { 897 if deltaPC <= PC_RANGE { 898 opcode = OPCODE_BASE + (LINE_RANGE - 1) + (LINE_RANGE * int64(deltaPC)) 899 if opcode > 255 { 900 opcode = 255 901 } 902 } else { 903 // Use opcode 249 (pc+=23, lc+=5) or 255 (pc+=24, lc+=1). 904 // 905 // Let x=deltaPC-PC_RANGE. If we use opcode 255, x will be the remaining 906 // deltaPC that we need to encode separately before emitting 255. If we 907 // use opcode 249, we will need to encode x+1. If x+1 takes one more 908 // byte to encode than x, then we use opcode 255. 909 // 910 // In all other cases x and x+1 take the same number of bytes to encode, 911 // so we use opcode 249, which may save us a byte in encoding deltaLC, 912 // for similar reasons. 913 switch deltaPC - PC_RANGE { 914 // PC_RANGE is the largest deltaPC we can encode in one byte, using 915 // DW_LNS_const_add_pc. 916 // 917 // (1<<16)-1 is the largest deltaPC we can encode in three bytes, using 918 // DW_LNS_fixed_advance_pc. 919 // 920 // (1<<(7n))-1 is the largest deltaPC we can encode in n+1 bytes for 921 // n=1,3,4,5,..., using DW_LNS_advance_pc. 922 case PC_RANGE, (1 << 7) - 1, (1 << 16) - 1, (1 << 21) - 1, (1 << 28) - 1, 923 (1 << 35) - 1, (1 << 42) - 1, (1 << 49) - 1, (1 << 56) - 1, (1 << 63) - 1: 924 opcode = 255 925 default: 926 opcode = OPCODE_BASE + LINE_RANGE*PC_RANGE - 1 // 249 927 } 928 } 929 } 930 if opcode < OPCODE_BASE || opcode > 255 { 931 panic(fmt.Sprintf("produced invalid special opcode %d", opcode)) 932 } 933 934 // Subtract from deltaPC and deltaLC the amounts that the opcode will add. 935 deltaPC -= uint64((opcode - OPCODE_BASE) / LINE_RANGE) 936 deltaLC -= int64((opcode-OPCODE_BASE)%LINE_RANGE + LINE_BASE) 937 938 // Encode deltaPC. 939 if deltaPC != 0 { 940 if deltaPC <= PC_RANGE { 941 // Adjust the opcode so that we can use the 1-byte DW_LNS_const_add_pc 942 // instruction. 943 opcode -= LINE_RANGE * int64(PC_RANGE-deltaPC) 944 if opcode < OPCODE_BASE { 945 panic(fmt.Sprintf("produced invalid special opcode %d", opcode)) 946 } 947 Adduint8(linkctxt, s, dwarf.DW_LNS_const_add_pc) 948 } else if (1<<14) <= deltaPC && deltaPC < (1<<16) { 949 Adduint8(linkctxt, s, dwarf.DW_LNS_fixed_advance_pc) 950 Adduint16(linkctxt, s, uint16(deltaPC)) 951 } else { 952 Adduint8(linkctxt, s, dwarf.DW_LNS_advance_pc) 953 dwarf.Uleb128put(ctxt, s, int64(deltaPC)) 954 } 955 } 956 957 // Encode deltaLC. 958 if deltaLC != 0 { 959 Adduint8(linkctxt, s, dwarf.DW_LNS_advance_line) 960 dwarf.Sleb128put(ctxt, s, deltaLC) 961 } 962 963 // Output the special opcode. 964 Adduint8(linkctxt, s, uint8(opcode)) 965 } 966 967 /* 968 * Walk prog table, emit line program and build DIE tree. 969 */ 970 971 func getCompilationDir() string { 972 if dir, err := os.Getwd(); err == nil { 973 return dir 974 } 975 return "/" 976 } 977 978 func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) { 979 var dwarfctxt dwarf.Context = dwctxt{ctxt} 980 ls := ctxt.Syms.Lookup(".debug_line", 0) 981 ls.Type = SDWARFSECT 982 ls.R = ls.R[:0] 983 984 syms = append(syms, ls) 985 var funcs []*Symbol 986 987 unitstart := int64(-1) 988 headerstart := int64(-1) 989 headerend := int64(-1) 990 epc := int64(0) 991 var epcs *Symbol 992 var dwinfo *dwarf.DWDie 993 994 lang := dwarf.DW_LANG_Go 995 996 s := ctxt.Textp[0] 997 if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin { 998 s = ctxt.Textp[1] // skip runtime.text 999 } 1000 1001 dwinfo = newdie(ctxt, &dwroot, dwarf.DW_ABRV_COMPUNIT, "go", 0) 1002 newattr(dwinfo, dwarf.DW_AT_language, dwarf.DW_CLS_CONSTANT, int64(lang), 0) 1003 newattr(dwinfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, 0, ls) 1004 newattr(dwinfo, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, s.Value, s) 1005 // OS X linker requires compilation dir or absolute path in comp unit name to output debug info. 1006 compDir := getCompilationDir() 1007 newattr(dwinfo, dwarf.DW_AT_comp_dir, dwarf.DW_CLS_STRING, int64(len(compDir)), compDir) 1008 producer := "Go cmd/compile " + objabi.Version 1009 newattr(dwinfo, dwarf.DW_AT_producer, dwarf.DW_CLS_STRING, int64(len(producer)), producer) 1010 1011 // Write .debug_line Line Number Program Header (sec 6.2.4) 1012 // Fields marked with (*) must be changed for 64-bit dwarf 1013 unitLengthOffset := ls.Size 1014 Adduint32(ctxt, ls, 0) // unit_length (*), filled in at end. 1015 unitstart = ls.Size 1016 Adduint16(ctxt, ls, 2) // dwarf version (appendix F) 1017 headerLengthOffset := ls.Size 1018 Adduint32(ctxt, ls, 0) // header_length (*), filled in at end. 1019 headerstart = ls.Size 1020 1021 // cpos == unitstart + 4 + 2 + 4 1022 Adduint8(ctxt, ls, 1) // minimum_instruction_length 1023 Adduint8(ctxt, ls, 1) // default_is_stmt 1024 Adduint8(ctxt, ls, LINE_BASE&0xFF) // line_base 1025 Adduint8(ctxt, ls, LINE_RANGE) // line_range 1026 Adduint8(ctxt, ls, OPCODE_BASE) // opcode_base 1027 Adduint8(ctxt, ls, 0) // standard_opcode_lengths[1] 1028 Adduint8(ctxt, ls, 1) // standard_opcode_lengths[2] 1029 Adduint8(ctxt, ls, 1) // standard_opcode_lengths[3] 1030 Adduint8(ctxt, ls, 1) // standard_opcode_lengths[4] 1031 Adduint8(ctxt, ls, 1) // standard_opcode_lengths[5] 1032 Adduint8(ctxt, ls, 0) // standard_opcode_lengths[6] 1033 Adduint8(ctxt, ls, 0) // standard_opcode_lengths[7] 1034 Adduint8(ctxt, ls, 0) // standard_opcode_lengths[8] 1035 Adduint8(ctxt, ls, 1) // standard_opcode_lengths[9] 1036 Adduint8(ctxt, ls, 0) // include_directories (empty) 1037 1038 for _, f := range ctxt.Filesyms { 1039 Addstring(ls, f.Name) 1040 Adduint8(ctxt, ls, 0) 1041 Adduint8(ctxt, ls, 0) 1042 Adduint8(ctxt, ls, 0) 1043 } 1044 1045 // 4 zeros: the string termination + 3 fields. 1046 Adduint8(ctxt, ls, 0) 1047 // terminate file_names. 1048 headerend = ls.Size 1049 1050 Adduint8(ctxt, ls, 0) // start extended opcode 1051 dwarf.Uleb128put(dwarfctxt, ls, 1+int64(SysArch.PtrSize)) 1052 Adduint8(ctxt, ls, dwarf.DW_LNE_set_address) 1053 1054 pc := s.Value 1055 line := 1 1056 file := 1 1057 Addaddr(ctxt, ls, s) 1058 1059 var pcfile Pciter 1060 var pcline Pciter 1061 for _, s := range ctxt.Textp { 1062 1063 epc = s.Value + s.Size 1064 epcs = s 1065 1066 dsym := ctxt.Syms.Lookup(dwarf.InfoPrefix+s.Name, int(s.Version)) 1067 dsym.Attr |= AttrNotInSymbolTable | AttrReachable 1068 dsym.Type = SDWARFINFO 1069 for _, r := range dsym.R { 1070 if r.Type == objabi.R_DWARFREF && r.Sym.Size == 0 { 1071 if Buildmode == BuildmodeShared { 1072 // These type symbols may not be present in BuildmodeShared. Skip. 1073 continue 1074 } 1075 n := nameFromDIESym(r.Sym) 1076 defgotype(ctxt, ctxt.Syms.Lookup("type."+n, 0)) 1077 } 1078 } 1079 funcs = append(funcs, dsym) 1080 1081 if s.FuncInfo == nil { 1082 continue 1083 } 1084 1085 finddebugruntimepath(s) 1086 1087 pciterinit(ctxt, &pcfile, &s.FuncInfo.Pcfile) 1088 pciterinit(ctxt, &pcline, &s.FuncInfo.Pcline) 1089 epc = pc 1090 for pcfile.done == 0 && pcline.done == 0 { 1091 if epc-s.Value >= int64(pcfile.nextpc) { 1092 pciternext(&pcfile) 1093 continue 1094 } 1095 1096 if epc-s.Value >= int64(pcline.nextpc) { 1097 pciternext(&pcline) 1098 continue 1099 } 1100 1101 if int32(file) != pcfile.value { 1102 Adduint8(ctxt, ls, dwarf.DW_LNS_set_file) 1103 dwarf.Uleb128put(dwarfctxt, ls, int64(pcfile.value)) 1104 file = int(pcfile.value) 1105 } 1106 1107 putpclcdelta(ctxt, dwarfctxt, ls, uint64(s.Value+int64(pcline.pc)-pc), int64(pcline.value)-int64(line)) 1108 1109 pc = s.Value + int64(pcline.pc) 1110 line = int(pcline.value) 1111 if pcfile.nextpc < pcline.nextpc { 1112 epc = int64(pcfile.nextpc) 1113 } else { 1114 epc = int64(pcline.nextpc) 1115 } 1116 epc += s.Value 1117 } 1118 } 1119 1120 Adduint8(ctxt, ls, 0) // start extended opcode 1121 dwarf.Uleb128put(dwarfctxt, ls, 1) 1122 Adduint8(ctxt, ls, dwarf.DW_LNE_end_sequence) 1123 1124 newattr(dwinfo, dwarf.DW_AT_high_pc, dwarf.DW_CLS_ADDRESS, epc+1, epcs) 1125 1126 setuint32(ctxt, ls, unitLengthOffset, uint32(ls.Size-unitstart)) 1127 setuint32(ctxt, ls, headerLengthOffset, uint32(headerend-headerstart)) 1128 1129 return syms, funcs 1130 } 1131 1132 /* 1133 * Emit .debug_frame 1134 */ 1135 const ( 1136 dataAlignmentFactor = -4 1137 ) 1138 1139 // appendPCDeltaCFA appends per-PC CFA deltas to b and returns the final slice. 1140 func appendPCDeltaCFA(b []byte, deltapc, cfa int64) []byte { 1141 b = append(b, dwarf.DW_CFA_def_cfa_offset_sf) 1142 b = dwarf.AppendSleb128(b, cfa/dataAlignmentFactor) 1143 1144 switch { 1145 case deltapc < 0x40: 1146 b = append(b, uint8(dwarf.DW_CFA_advance_loc+deltapc)) 1147 case deltapc < 0x100: 1148 b = append(b, dwarf.DW_CFA_advance_loc1) 1149 b = append(b, uint8(deltapc)) 1150 case deltapc < 0x10000: 1151 b = append(b, dwarf.DW_CFA_advance_loc2) 1152 b = Thearch.Append16(b, uint16(deltapc)) 1153 default: 1154 b = append(b, dwarf.DW_CFA_advance_loc4) 1155 b = Thearch.Append32(b, uint32(deltapc)) 1156 } 1157 return b 1158 } 1159 1160 func writeframes(ctxt *Link, syms []*Symbol) []*Symbol { 1161 var dwarfctxt dwarf.Context = dwctxt{ctxt} 1162 fs := ctxt.Syms.Lookup(".debug_frame", 0) 1163 fs.Type = SDWARFSECT 1164 fs.R = fs.R[:0] 1165 syms = append(syms, fs) 1166 1167 // Emit the CIE, Section 6.4.1 1168 cieReserve := uint32(16) 1169 if haslinkregister(ctxt) { 1170 cieReserve = 32 1171 } 1172 Adduint32(ctxt, fs, cieReserve) // initial length, must be multiple of thearch.ptrsize 1173 Adduint32(ctxt, fs, 0xffffffff) // cid. 1174 Adduint8(ctxt, fs, 3) // dwarf version (appendix F) 1175 Adduint8(ctxt, fs, 0) // augmentation "" 1176 dwarf.Uleb128put(dwarfctxt, fs, 1) // code_alignment_factor 1177 dwarf.Sleb128put(dwarfctxt, fs, dataAlignmentFactor) // all CFI offset calculations include multiplication with this factor 1178 dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr)) // return_address_register 1179 1180 Adduint8(ctxt, fs, dwarf.DW_CFA_def_cfa) // Set the current frame address.. 1181 dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfregsp)) // ...to use the value in the platform's SP register (defined in l.go)... 1182 if haslinkregister(ctxt) { 1183 dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...plus a 0 offset. 1184 1185 Adduint8(ctxt, fs, dwarf.DW_CFA_same_value) // The platform's link register is unchanged during the prologue. 1186 dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr)) 1187 1188 Adduint8(ctxt, fs, dwarf.DW_CFA_val_offset) // The previous value... 1189 dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfregsp)) // ...of the platform's SP register... 1190 dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...is CFA+0. 1191 } else { 1192 dwarf.Uleb128put(dwarfctxt, fs, int64(SysArch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame). 1193 1194 Adduint8(ctxt, fs, dwarf.DW_CFA_offset_extended) // The previous value... 1195 dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr)) // ...of the return address... 1196 dwarf.Uleb128put(dwarfctxt, fs, int64(-SysArch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)]. 1197 } 1198 1199 // 4 is to exclude the length field. 1200 pad := int64(cieReserve) + 4 - fs.Size 1201 1202 if pad < 0 { 1203 Exitf("dwarf: cieReserve too small by %d bytes.", -pad) 1204 } 1205 1206 Addbytes(fs, zeros[:pad]) 1207 1208 var deltaBuf []byte 1209 var pcsp Pciter 1210 for _, s := range ctxt.Textp { 1211 if s.FuncInfo == nil { 1212 continue 1213 } 1214 1215 // Emit a FDE, Section 6.4.1. 1216 // First build the section contents into a byte buffer. 1217 deltaBuf = deltaBuf[:0] 1218 for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1219 nextpc := pcsp.nextpc 1220 1221 // pciterinit goes up to the end of the function, 1222 // but DWARF expects us to stop just before the end. 1223 if int64(nextpc) == s.Size { 1224 nextpc-- 1225 if nextpc < pcsp.pc { 1226 continue 1227 } 1228 } 1229 1230 if haslinkregister(ctxt) { 1231 // TODO(bryanpkc): This is imprecise. In general, the instruction 1232 // that stores the return address to the stack frame is not the 1233 // same one that allocates the frame. 1234 if pcsp.value > 0 { 1235 // The return address is preserved at (CFA-frame_size) 1236 // after a stack frame has been allocated. 1237 deltaBuf = append(deltaBuf, dwarf.DW_CFA_offset_extended_sf) 1238 deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(Thearch.Dwarfreglr)) 1239 deltaBuf = dwarf.AppendSleb128(deltaBuf, -int64(pcsp.value)/dataAlignmentFactor) 1240 } else { 1241 // The return address is restored into the link register 1242 // when a stack frame has been de-allocated. 1243 deltaBuf = append(deltaBuf, dwarf.DW_CFA_same_value) 1244 deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(Thearch.Dwarfreglr)) 1245 } 1246 deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(pcsp.value)) 1247 } else { 1248 deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(SysArch.PtrSize)+int64(pcsp.value)) 1249 } 1250 } 1251 pad := int(Rnd(int64(len(deltaBuf)), int64(SysArch.PtrSize))) - len(deltaBuf) 1252 deltaBuf = append(deltaBuf, zeros[:pad]...) 1253 1254 // Emit the FDE header, Section 6.4.1. 1255 // 4 bytes: length, must be multiple of thearch.ptrsize 1256 // 4 bytes: Pointer to the CIE above, at offset 0 1257 // ptrsize: initial location 1258 // ptrsize: address range 1259 Adduint32(ctxt, fs, uint32(4+2*SysArch.PtrSize+len(deltaBuf))) // length (excludes itself) 1260 if Linkmode == LinkExternal { 1261 adddwarfref(ctxt, fs, fs, 4) 1262 } else { 1263 Adduint32(ctxt, fs, 0) // CIE offset 1264 } 1265 Addaddr(ctxt, fs, s) 1266 adduintxx(ctxt, fs, uint64(s.Size), SysArch.PtrSize) // address range 1267 Addbytes(fs, deltaBuf) 1268 } 1269 return syms 1270 } 1271 1272 func writeranges(ctxt *Link, syms []*Symbol) []*Symbol { 1273 empty := true 1274 for _, s := range ctxt.Textp { 1275 rangeSym := ctxt.Syms.Lookup(dwarf.RangePrefix+s.Name, int(s.Version)) 1276 if rangeSym.Size == 0 { 1277 continue 1278 } 1279 rangeSym.Attr |= AttrReachable | AttrNotInSymbolTable 1280 rangeSym.Type = SDWARFRANGE 1281 syms = append(syms, rangeSym) 1282 empty = false 1283 } 1284 if !empty { 1285 // PE does not like empty sections 1286 rangesec := ctxt.Syms.Lookup(".debug_ranges", 0) 1287 rangesec.Type = SDWARFRANGE 1288 rangesec.Attr |= AttrReachable 1289 rangesec.R = rangesec.R[:0] 1290 1291 syms = append(syms, rangesec) 1292 } 1293 return syms 1294 } 1295 1296 /* 1297 * Walk DWarfDebugInfoEntries, and emit .debug_info 1298 */ 1299 const ( 1300 COMPUNITHEADERSIZE = 4 + 2 + 4 + 1 1301 ) 1302 1303 func writeinfo(ctxt *Link, syms []*Symbol, funcs []*Symbol, abbrevsym *Symbol) []*Symbol { 1304 infosec := ctxt.Syms.Lookup(".debug_info", 0) 1305 infosec.R = infosec.R[:0] 1306 infosec.Type = SDWARFINFO 1307 infosec.Attr |= AttrReachable 1308 syms = append(syms, infosec) 1309 1310 arangessec := ctxt.Syms.Lookup(".dwarfaranges", 0) 1311 arangessec.R = arangessec.R[:0] 1312 1313 var dwarfctxt dwarf.Context = dwctxt{ctxt} 1314 1315 for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link { 1316 s := dtolsym(compunit.Sym) 1317 1318 // Write .debug_info Compilation Unit Header (sec 7.5.1) 1319 // Fields marked with (*) must be changed for 64-bit dwarf 1320 // This must match COMPUNITHEADERSIZE above. 1321 Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later. 1322 Adduint16(ctxt, s, 4) // dwarf version (appendix F) 1323 1324 // debug_abbrev_offset (*) 1325 adddwarfref(ctxt, s, abbrevsym, 4) 1326 1327 Adduint8(ctxt, s, uint8(SysArch.PtrSize)) // address_size 1328 1329 dwarf.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev)) 1330 dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr) 1331 1332 cu := []*Symbol{s} 1333 if funcs != nil { 1334 cu = append(cu, funcs...) 1335 funcs = nil 1336 } 1337 cu = putdies(ctxt, dwarfctxt, cu, compunit.Child) 1338 var cusize int64 1339 for _, child := range cu { 1340 cusize += child.Size 1341 } 1342 cusize -= 4 // exclude the length field. 1343 setuint32(ctxt, s, 0, uint32(cusize)) 1344 newattr(compunit, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, cusize, 0) 1345 syms = append(syms, cu...) 1346 } 1347 return syms 1348 } 1349 1350 /* 1351 * Emit .debug_pubnames/_types. _info must have been written before, 1352 * because we need die->offs and infoo/infosize; 1353 */ 1354 func ispubname(die *dwarf.DWDie) bool { 1355 switch die.Abbrev { 1356 case dwarf.DW_ABRV_FUNCTION, dwarf.DW_ABRV_VARIABLE: 1357 a := getattr(die, dwarf.DW_AT_external) 1358 return a != nil && a.Value != 0 1359 } 1360 1361 return false 1362 } 1363 1364 func ispubtype(die *dwarf.DWDie) bool { 1365 return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE 1366 } 1367 1368 func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*Symbol) []*Symbol { 1369 s := ctxt.Syms.Lookup(sname, 0) 1370 s.Type = SDWARFSECT 1371 syms = append(syms, s) 1372 1373 for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link { 1374 sectionstart := s.Size 1375 culength := uint32(getattr(compunit, dwarf.DW_AT_byte_size).Value) + 4 1376 1377 // Write .debug_pubnames/types Header (sec 6.1.1) 1378 Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later. 1379 Adduint16(ctxt, s, 2) // dwarf version (appendix F) 1380 adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4) // debug_info_offset (of the Comp unit Header) 1381 Adduint32(ctxt, s, culength) // debug_info_length 1382 1383 for die := compunit.Child; die != nil; die = die.Link { 1384 if !ispub(die) { 1385 continue 1386 } 1387 dwa := getattr(die, dwarf.DW_AT_name) 1388 name := dwa.Data.(string) 1389 if die.Sym == nil { 1390 fmt.Println("Missing sym for ", name) 1391 } 1392 adddwarfref(ctxt, s, dtolsym(die.Sym), 4) 1393 Addstring(s, name) 1394 } 1395 1396 Adduint32(ctxt, s, 0) 1397 1398 setuint32(ctxt, s, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field. 1399 } 1400 1401 return syms 1402 } 1403 1404 /* 1405 * emit .debug_aranges. _info must have been written before, 1406 * because we need die->offs of dwarf.DW_globals. 1407 */ 1408 func writearanges(ctxt *Link, syms []*Symbol) []*Symbol { 1409 s := ctxt.Syms.Lookup(".debug_aranges", 0) 1410 s.Type = SDWARFSECT 1411 // The first tuple is aligned to a multiple of the size of a single tuple 1412 // (twice the size of an address) 1413 headersize := int(Rnd(4+2+4+1+1, int64(SysArch.PtrSize*2))) // don't count unit_length field itself 1414 1415 for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link { 1416 b := getattr(compunit, dwarf.DW_AT_low_pc) 1417 if b == nil { 1418 continue 1419 } 1420 e := getattr(compunit, dwarf.DW_AT_high_pc) 1421 if e == nil { 1422 continue 1423 } 1424 1425 // Write .debug_aranges Header + entry (sec 6.1.2) 1426 unitlength := uint32(headersize) + 4*uint32(SysArch.PtrSize) - 4 1427 Adduint32(ctxt, s, unitlength) // unit_length (*) 1428 Adduint16(ctxt, s, 2) // dwarf version (appendix F) 1429 1430 adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4) 1431 1432 Adduint8(ctxt, s, uint8(SysArch.PtrSize)) // address_size 1433 Adduint8(ctxt, s, 0) // segment_size 1434 padding := headersize - (4 + 2 + 4 + 1 + 1) 1435 for i := 0; i < padding; i++ { 1436 Adduint8(ctxt, s, 0) 1437 } 1438 1439 Addaddrplus(ctxt, s, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value) 1440 adduintxx(ctxt, s, uint64(e.Value-b.Value), SysArch.PtrSize) 1441 adduintxx(ctxt, s, 0, SysArch.PtrSize) 1442 adduintxx(ctxt, s, 0, SysArch.PtrSize) 1443 } 1444 if s.Size > 0 { 1445 syms = append(syms, s) 1446 } 1447 return syms 1448 } 1449 1450 func writegdbscript(ctxt *Link, syms []*Symbol) []*Symbol { 1451 if Linkmode == LinkExternal && Headtype == objabi.Hwindows && Buildmode == BuildmodeCArchive { 1452 // gcc on Windows places .debug_gdb_scripts in the wrong location, which 1453 // causes the program not to run. See https://golang.org/issue/20183 1454 // Non c-archives can avoid this issue via a linker script 1455 // (see fix near writeGDBLinkerScript). 1456 // c-archive users would need to specify the linker script manually. 1457 // For UX it's better not to deal with this. 1458 return syms 1459 } 1460 1461 if gdbscript != "" { 1462 s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0) 1463 s.Type = SDWARFSECT 1464 syms = append(syms, s) 1465 Adduint8(ctxt, s, 1) // magic 1 byte? 1466 Addstring(s, gdbscript) 1467 } 1468 1469 return syms 1470 } 1471 1472 var prototypedies map[string]*dwarf.DWDie 1473 1474 /* 1475 * This is the main entry point for generating dwarf. After emitting 1476 * the mandatory debug_abbrev section, it calls writelines() to set up 1477 * the per-compilation unit part of the DIE tree, while simultaneously 1478 * emitting the debug_line section. When the final tree contains 1479 * forward references, it will write the debug_info section in 2 1480 * passes. 1481 * 1482 */ 1483 func dwarfgeneratedebugsyms(ctxt *Link) { 1484 if *FlagW { // disable dwarf 1485 return 1486 } 1487 if *FlagS && Headtype != objabi.Hdarwin { 1488 return 1489 } 1490 if Headtype == objabi.Hplan9 { 1491 return 1492 } 1493 1494 if Linkmode == LinkExternal { 1495 switch { 1496 case Iself: 1497 case Headtype == objabi.Hdarwin: 1498 case Headtype == objabi.Hwindows: 1499 default: 1500 return 1501 } 1502 } 1503 1504 if ctxt.Debugvlog != 0 { 1505 ctxt.Logf("%5.2f dwarf\n", Cputime()) 1506 } 1507 1508 // Forctxt.Diagnostic messages. 1509 newattr(&dwtypes, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len("dwtypes")), "dwtypes") 1510 1511 // Some types that must exist to define other ones. 1512 newdie(ctxt, &dwtypes, dwarf.DW_ABRV_NULLTYPE, "<unspecified>", 0) 1513 1514 newdie(ctxt, &dwtypes, dwarf.DW_ABRV_NULLTYPE, "void", 0) 1515 newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer", 0) 1516 1517 die := newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size 1518 newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0) 1519 newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(SysArch.PtrSize), 0) 1520 newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, objabi.KindUintptr, 0) 1521 1522 // Prototypes needed for type synthesis. 1523 prototypedies = map[string]*dwarf.DWDie{ 1524 "type.runtime.stringStructDWARF": nil, 1525 "type.runtime.slice": nil, 1526 "type.runtime.hmap": nil, 1527 "type.runtime.bmap": nil, 1528 "type.runtime.sudog": nil, 1529 "type.runtime.waitq": nil, 1530 "type.runtime.hchan": nil, 1531 } 1532 1533 // Needed by the prettyprinter code for interface inspection. 1534 for _, typ := range []string{ 1535 "type.runtime._type", 1536 "type.runtime.arraytype", 1537 "type.runtime.chantype", 1538 "type.runtime.functype", 1539 "type.runtime.maptype", 1540 "type.runtime.ptrtype", 1541 "type.runtime.slicetype", 1542 "type.runtime.structtype", 1543 "type.runtime.interfacetype", 1544 "type.runtime.itab", 1545 "type.runtime.imethod"} { 1546 defgotype(ctxt, lookupOrDiag(ctxt, typ)) 1547 } 1548 1549 genasmsym(ctxt, defdwsymb) 1550 1551 abbrev := writeabbrev(ctxt) 1552 syms := []*Symbol{abbrev} 1553 syms, funcs := writelines(ctxt, syms) 1554 syms = writeframes(ctxt, syms) 1555 1556 synthesizestringtypes(ctxt, dwtypes.Child) 1557 synthesizeslicetypes(ctxt, dwtypes.Child) 1558 synthesizemaptypes(ctxt, dwtypes.Child) 1559 synthesizechantypes(ctxt, dwtypes.Child) 1560 1561 reversetree(&dwroot.Child) 1562 reversetree(&dwtypes.Child) 1563 reversetree(&dwglobals.Child) 1564 1565 movetomodule(&dwtypes) 1566 movetomodule(&dwglobals) 1567 1568 // Need to reorder symbols so SDWARFINFO is after all SDWARFSECT 1569 // (but we need to generate dies before writepub) 1570 infosyms := writeinfo(ctxt, nil, funcs, abbrev) 1571 1572 syms = writepub(ctxt, ".debug_pubnames", ispubname, syms) 1573 syms = writepub(ctxt, ".debug_pubtypes", ispubtype, syms) 1574 syms = writearanges(ctxt, syms) 1575 syms = writegdbscript(ctxt, syms) 1576 syms = append(syms, infosyms...) 1577 syms = collectlocs(ctxt, syms, funcs) 1578 syms = writeranges(ctxt, syms) 1579 dwarfp = syms 1580 } 1581 1582 func collectlocs(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol { 1583 empty := true 1584 for _, fn := range funcs { 1585 for _, reloc := range fn.R { 1586 if reloc.Type == objabi.R_DWARFREF && strings.HasPrefix(reloc.Sym.Name, dwarf.LocPrefix) { 1587 reloc.Sym.Attr |= AttrReachable | AttrNotInSymbolTable 1588 syms = append(syms, reloc.Sym) 1589 empty = false 1590 // One location list entry per function, but many relocations to it. Don't duplicate. 1591 break 1592 } 1593 } 1594 } 1595 // Don't emit .debug_loc if it's empty -- it makes the ARM linker mad. 1596 if !empty { 1597 locsym := ctxt.Syms.Lookup(".debug_loc", 0) 1598 locsym.R = locsym.R[:0] 1599 locsym.Type = SDWARFLOC 1600 locsym.Attr |= AttrReachable 1601 syms = append(syms, locsym) 1602 } 1603 return syms 1604 } 1605 1606 /* 1607 * Elf. 1608 */ 1609 func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) { 1610 if *FlagW { // disable dwarf 1611 return 1612 } 1613 1614 Addstring(shstrtab, ".debug_abbrev") 1615 Addstring(shstrtab, ".debug_aranges") 1616 Addstring(shstrtab, ".debug_frame") 1617 Addstring(shstrtab, ".debug_info") 1618 Addstring(shstrtab, ".debug_loc") 1619 Addstring(shstrtab, ".debug_line") 1620 Addstring(shstrtab, ".debug_pubnames") 1621 Addstring(shstrtab, ".debug_pubtypes") 1622 Addstring(shstrtab, ".debug_gdb_scripts") 1623 Addstring(shstrtab, ".debug_ranges") 1624 if Linkmode == LinkExternal { 1625 Addstring(shstrtab, elfRelType+".debug_info") 1626 Addstring(shstrtab, elfRelType+".debug_loc") 1627 Addstring(shstrtab, elfRelType+".debug_aranges") 1628 Addstring(shstrtab, elfRelType+".debug_line") 1629 Addstring(shstrtab, elfRelType+".debug_frame") 1630 Addstring(shstrtab, elfRelType+".debug_pubnames") 1631 Addstring(shstrtab, elfRelType+".debug_pubtypes") 1632 Addstring(shstrtab, elfRelType+".debug_ranges") 1633 } 1634 } 1635 1636 // Add section symbols for DWARF debug info. This is called before 1637 // dwarfaddelfheaders. 1638 func dwarfaddelfsectionsyms(ctxt *Link) { 1639 if *FlagW { // disable dwarf 1640 return 1641 } 1642 if Linkmode != LinkExternal { 1643 return 1644 } 1645 sym := ctxt.Syms.Lookup(".debug_info", 0) 1646 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 1647 sym = ctxt.Syms.Lookup(".debug_abbrev", 0) 1648 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 1649 sym = ctxt.Syms.Lookup(".debug_line", 0) 1650 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 1651 sym = ctxt.Syms.Lookup(".debug_frame", 0) 1652 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 1653 sym = ctxt.Syms.Lookup(".debug_loc", 0) 1654 if sym.Sect != nil { 1655 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 1656 } 1657 sym = ctxt.Syms.Lookup(".debug_ranges", 0) 1658 if sym.Sect != nil { 1659 putelfsectionsym(sym, sym.Sect.Elfsect.shnum) 1660 } 1661 } 1662 1663 /* 1664 * Windows PE 1665 */ 1666 func dwarfaddpeheaders(ctxt *Link) { 1667 if *FlagW { // disable dwarf 1668 return 1669 } 1670 for _, sect := range Segdwarf.Sections { 1671 h := newPEDWARFSection(ctxt, sect.Name, int64(sect.Length)) 1672 fileoff := sect.Vaddr - Segdwarf.Vaddr + Segdwarf.Fileoff 1673 if uint64(h.PointerToRawData) != fileoff { 1674 Exitf("%s.PointerToRawData = %#x, want %#x", sect.Name, h.PointerToRawData, fileoff) 1675 } 1676 } 1677 }