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