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