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