...

Source file src/pkg/cmd/link/internal/ld/dwarf.go

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

View as plain text