// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Writing of Go object files.

package obj

import (
	"bufio"
	"cmd/internal/dwarf"
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"fmt"
	"log"
	"path/filepath"
	"sort"
	"sync"
)

// objWriter writes Go object files.
type objWriter struct {
	wr   *bufio.Writer
	ctxt *Link
	// Temporary buffer for zigzag int writing.
	varintbuf [10]uint8

	// Provide the index of a symbol reference by symbol name.
	// One map for versioned symbols and one for unversioned symbols.
	// Used for deduplicating the symbol reference list.
	refIdx  map[string]int
	vrefIdx map[string]int

	// Number of objects written of each type.
	nRefs     int
	nData     int
	nReloc    int
	nPcdata   int
	nAutom    int
	nFuncdata int
	nFile     int
}

func (w *objWriter) addLengths(s *LSym) {
	w.nData += len(s.P)
	w.nReloc += len(s.R)

	if s.Type != objabi.STEXT {
		return
	}

	pc := &s.Func.Pcln

	data := 0
	data += len(pc.Pcsp.P)
	data += len(pc.Pcfile.P)
	data += len(pc.Pcline.P)
	data += len(pc.Pcinline.P)
	for i := 0; i < len(pc.Pcdata); i++ {
		data += len(pc.Pcdata[i].P)
	}

	w.nData += data
	w.nPcdata += len(pc.Pcdata)

	w.nAutom += len(s.Func.Autom)
	w.nFuncdata += len(pc.Funcdataoff)
	w.nFile += len(pc.File)
}

func (w *objWriter) writeLengths() {
	w.writeInt(int64(w.nData))
	w.writeInt(int64(w.nReloc))
	w.writeInt(int64(w.nPcdata))
	w.writeInt(int64(w.nAutom))
	w.writeInt(int64(w.nFuncdata))
	w.writeInt(int64(w.nFile))
}

func newObjWriter(ctxt *Link, b *bufio.Writer) *objWriter {
	return &objWriter{
		ctxt:    ctxt,
		wr:      b,
		vrefIdx: make(map[string]int),
		refIdx:  make(map[string]int),
	}
}

func WriteObjFile(ctxt *Link, b *bufio.Writer) {
	w := newObjWriter(ctxt, b)

	// Magic header
	w.wr.WriteString("\x00\x00go19ld")

	// Version
	w.wr.WriteByte(1)

	// Autolib
	for _, pkg := range ctxt.Imports {
		w.writeString(pkg)
	}
	w.writeString("")

	// Symbol references
	for _, s := range ctxt.Text {
		w.writeRefs(s)
		w.addLengths(s)
	}
	for _, s := range ctxt.Data {
		w.writeRefs(s)
		w.addLengths(s)
	}
	// End symbol references
	w.wr.WriteByte(0xff)

	// Lengths
	w.writeLengths()

	// Data block
	for _, s := range ctxt.Text {
		w.wr.Write(s.P)
		pc := &s.Func.Pcln
		w.wr.Write(pc.Pcsp.P)
		w.wr.Write(pc.Pcfile.P)
		w.wr.Write(pc.Pcline.P)
		w.wr.Write(pc.Pcinline.P)
		for i := 0; i < len(pc.Pcdata); i++ {
			w.wr.Write(pc.Pcdata[i].P)
		}
	}
	for _, s := range ctxt.Data {
		if len(s.P) > 0 {
			switch s.Type {
			case objabi.SBSS, objabi.SNOPTRBSS, objabi.STLSBSS:
				ctxt.Diag("cannot provide data for %v sym %v", s.Type, s.Name)
			}
		}
		w.wr.Write(s.P)
	}

	// Symbols
	for _, s := range ctxt.Text {
		w.writeSym(s)
	}
	for _, s := range ctxt.Data {
		w.writeSym(s)
	}

	// Magic footer
	w.wr.WriteString("\xff\xffgo19ld")
}

// Symbols are prefixed so their content doesn't get confused with the magic footer.
const symPrefix = 0xfe

func (w *objWriter) writeRef(s *LSym, isPath bool) {
	if s == nil || s.RefIdx != 0 {
		return
	}
	var m map[string]int
	if !s.Static() {
		m = w.refIdx
	} else {
		m = w.vrefIdx
	}

	if idx := m[s.Name]; idx != 0 {
		s.RefIdx = idx
		return
	}
	w.wr.WriteByte(symPrefix)
	if isPath {
		w.writeString(filepath.ToSlash(s.Name))
	} else {
		w.writeString(s.Name)
	}
	// Write "version".
	if s.Static() {
		w.writeInt(1)
	} else {
		w.writeInt(0)
	}
	w.nRefs++
	s.RefIdx = w.nRefs
	m[s.Name] = w.nRefs
}

func (w *objWriter) writeRefs(s *LSym) {
	w.writeRef(s, false)
	w.writeRef(s.Gotype, false)
	for i := range s.R {
		w.writeRef(s.R[i].Sym, false)
	}

	if s.Type == objabi.STEXT {
		for _, a := range s.Func.Autom {
			w.writeRef(a.Asym, false)
			w.writeRef(a.Gotype, false)
		}
		pc := &s.Func.Pcln
		for _, d := range pc.Funcdata {
			w.writeRef(d, false)
		}
		for _, f := range pc.File {
			fsym := w.ctxt.Lookup(f)
			w.writeRef(fsym, true)
		}
		for _, call := range pc.InlTree.nodes {
			w.writeRef(call.Func, false)
			f, _ := linkgetlineFromPos(w.ctxt, call.Pos)
			fsym := w.ctxt.Lookup(f)
			w.writeRef(fsym, true)
		}
	}
}

func (w *objWriter) writeSymDebug(s *LSym) {
	ctxt := w.ctxt
	fmt.Fprintf(ctxt.Bso, "%s ", s.Name)
	if s.Type != 0 {
		fmt.Fprintf(ctxt.Bso, "%v ", s.Type)
	}
	if s.Static() {
		fmt.Fprint(ctxt.Bso, "static ")
	}
	if s.DuplicateOK() {
		fmt.Fprintf(ctxt.Bso, "dupok ")
	}
	if s.CFunc() {
		fmt.Fprintf(ctxt.Bso, "cfunc ")
	}
	if s.NoSplit() {
		fmt.Fprintf(ctxt.Bso, "nosplit ")
	}
	fmt.Fprintf(ctxt.Bso, "size=%d", s.Size)
	if s.Type == objabi.STEXT {
		fmt.Fprintf(ctxt.Bso, " args=%#x locals=%#x", uint64(s.Func.Args), uint64(s.Func.Locals))
		if s.Leaf() {
			fmt.Fprintf(ctxt.Bso, " leaf")
		}
	}
	fmt.Fprintf(ctxt.Bso, "\n")
	if s.Type == objabi.STEXT {
		for p := s.Func.Text; p != nil; p = p.Link {
			fmt.Fprintf(ctxt.Bso, "\t%#04x %v\n", uint(int(p.Pc)), p)
		}
	}
	for i := 0; i < len(s.P); i += 16 {
		fmt.Fprintf(ctxt.Bso, "\t%#04x", uint(i))
		j := i
		for j = i; j < i+16 && j < len(s.P); j++ {
			fmt.Fprintf(ctxt.Bso, " %02x", s.P[j])
		}
		for ; j < i+16; j++ {
			fmt.Fprintf(ctxt.Bso, "   ")
		}
		fmt.Fprintf(ctxt.Bso, "  ")
		for j = i; j < i+16 && j < len(s.P); j++ {
			c := int(s.P[j])
			if ' ' <= c && c <= 0x7e {
				fmt.Fprintf(ctxt.Bso, "%c", c)
			} else {
				fmt.Fprintf(ctxt.Bso, ".")
			}
		}

		fmt.Fprintf(ctxt.Bso, "\n")
	}

	sort.Sort(relocByOff(s.R)) // generate stable output
	for _, r := range s.R {
		name := ""
		if r.Sym != nil {
			name = r.Sym.Name
		} else if r.Type == objabi.R_TLS_LE {
			name = "TLS"
		}
		if ctxt.Arch.InFamily(sys.ARM, sys.PPC64) {
			fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(r.Add))
		} else {
			fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, r.Add)
		}
	}
}

func (w *objWriter) writeSym(s *LSym) {
	ctxt := w.ctxt
	if ctxt.Debugasm {
		w.writeSymDebug(s)
	}

	w.wr.WriteByte(symPrefix)
	w.wr.WriteByte(byte(s.Type))
	w.writeRefIndex(s)
	flags := int64(0)
	if s.DuplicateOK() {
		flags |= 1
	}
	if s.Local() {
		flags |= 1 << 1
	}
	if s.MakeTypelink() {
		flags |= 1 << 2
	}
	w.writeInt(flags)
	w.writeInt(s.Size)
	w.writeRefIndex(s.Gotype)
	w.writeInt(int64(len(s.P)))

	w.writeInt(int64(len(s.R)))
	var r *Reloc
	for i := 0; i < len(s.R); i++ {
		r = &s.R[i]
		w.writeInt(int64(r.Off))
		w.writeInt(int64(r.Siz))
		w.writeInt(int64(r.Type))
		w.writeInt(r.Add)
		w.writeRefIndex(r.Sym)
	}

	if s.Type != objabi.STEXT {
		return
	}

	w.writeInt(int64(s.Func.Args))
	w.writeInt(int64(s.Func.Locals))
	if s.NoSplit() {
		w.writeInt(1)
	} else {
		w.writeInt(0)
	}
	flags = int64(0)
	if s.Leaf() {
		flags |= 1
	}
	if s.CFunc() {
		flags |= 1 << 1
	}
	if s.ReflectMethod() {
		flags |= 1 << 2
	}
	if ctxt.Flag_shared {
		flags |= 1 << 3
	}
	w.writeInt(flags)
	w.writeInt(int64(len(s.Func.Autom)))
	for _, a := range s.Func.Autom {
		w.writeRefIndex(a.Asym)
		w.writeInt(int64(a.Aoffset))
		if a.Name == NAME_AUTO {
			w.writeInt(objabi.A_AUTO)
		} else if a.Name == NAME_PARAM {
			w.writeInt(objabi.A_PARAM)
		} else if a.Name == NAME_DELETED_AUTO {
			w.writeInt(objabi.A_DELETED_AUTO)
		} else {
			log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name)
		}
		w.writeRefIndex(a.Gotype)
	}

	pc := &s.Func.Pcln
	w.writeInt(int64(len(pc.Pcsp.P)))
	w.writeInt(int64(len(pc.Pcfile.P)))
	w.writeInt(int64(len(pc.Pcline.P)))
	w.writeInt(int64(len(pc.Pcinline.P)))
	w.writeInt(int64(len(pc.Pcdata)))
	for i := 0; i < len(pc.Pcdata); i++ {
		w.writeInt(int64(len(pc.Pcdata[i].P)))
	}
	w.writeInt(int64(len(pc.Funcdataoff)))
	for i := 0; i < len(pc.Funcdataoff); i++ {
		w.writeRefIndex(pc.Funcdata[i])
	}
	for i := 0; i < len(pc.Funcdataoff); i++ {
		w.writeInt(pc.Funcdataoff[i])
	}
	w.writeInt(int64(len(pc.File)))
	for _, f := range pc.File {
		fsym := ctxt.Lookup(f)
		w.writeRefIndex(fsym)
	}
	w.writeInt(int64(len(pc.InlTree.nodes)))
	for _, call := range pc.InlTree.nodes {
		w.writeInt(int64(call.Parent))
		f, l := linkgetlineFromPos(w.ctxt, call.Pos)
		fsym := ctxt.Lookup(f)
		w.writeRefIndex(fsym)
		w.writeInt(int64(l))
		w.writeRefIndex(call.Func)
	}
}

func (w *objWriter) writeInt(sval int64) {
	var v uint64
	uv := (uint64(sval) << 1) ^ uint64(sval>>63)
	p := w.varintbuf[:]
	for v = uv; v >= 0x80; v >>= 7 {
		p[0] = uint8(v | 0x80)
		p = p[1:]
	}
	p[0] = uint8(v)
	p = p[1:]
	w.wr.Write(w.varintbuf[:len(w.varintbuf)-len(p)])
}

func (w *objWriter) writeString(s string) {
	w.writeInt(int64(len(s)))
	w.wr.WriteString(s)
}

func (w *objWriter) writeRefIndex(s *LSym) {
	if s == nil {
		w.writeInt(0)
		return
	}
	if s.RefIdx == 0 {
		log.Fatalln("writing an unreferenced symbol", s.Name)
	}
	w.writeInt(int64(s.RefIdx))
}

// relocByOff sorts relocations by their offsets.
type relocByOff []Reloc

func (x relocByOff) Len() int           { return len(x) }
func (x relocByOff) Less(i, j int) bool { return x[i].Off < x[j].Off }
func (x relocByOff) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }

// implement dwarf.Context
type dwCtxt struct{ *Link }

func (c dwCtxt) PtrSize() int {
	return c.Arch.PtrSize
}
func (c dwCtxt) AddInt(s dwarf.Sym, size int, i int64) {
	ls := s.(*LSym)
	ls.WriteInt(c.Link, ls.Size, size, i)
}
func (c dwCtxt) AddBytes(s dwarf.Sym, b []byte) {
	ls := s.(*LSym)
	ls.WriteBytes(c.Link, ls.Size, b)
}
func (c dwCtxt) AddString(s dwarf.Sym, v string) {
	ls := s.(*LSym)
	ls.WriteString(c.Link, ls.Size, len(v), v)
	ls.WriteInt(c.Link, ls.Size, 1, 0)
}
func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
	ls := s.(*LSym)
	size := c.PtrSize()
	if data != nil {
		rsym := data.(*LSym)
		ls.WriteAddr(c.Link, ls.Size, size, rsym, value)
	} else {
		ls.WriteInt(c.Link, ls.Size, size, value)
	}
}
func (c dwCtxt) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) {
	ls := s.(*LSym)
	rsym := data.(*LSym)
	ls.WriteCURelativeAddr(c.Link, ls.Size, rsym, value)
}
func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
	ls := s.(*LSym)
	rsym := t.(*LSym)
	ls.WriteAddr(c.Link, ls.Size, size, rsym, ofs)
	r := &ls.R[len(ls.R)-1]
	r.Type = objabi.R_DWARFSECREF
}
func (c dwCtxt) AddFileRef(s dwarf.Sym, f interface{}) {
	ls := s.(*LSym)
	rsym := f.(*LSym)
	ls.WriteAddr(c.Link, ls.Size, 4, rsym, 0)
	r := &ls.R[len(ls.R)-1]
	r.Type = objabi.R_DWARFFILEREF
}

func (c dwCtxt) CurrentOffset(s dwarf.Sym) int64 {
	ls := s.(*LSym)
	return ls.Size
}

// Here "from" is a symbol corresponding to an inlined or concrete
// function, "to" is the symbol for the corresponding abstract
// function, and "dclIdx" is the index of the symbol of interest with
// respect to the Dcl slice of the original pre-optimization version
// of the inlined function.
func (c dwCtxt) RecordDclReference(from dwarf.Sym, to dwarf.Sym, dclIdx int, inlIndex int) {
	ls := from.(*LSym)
	tls := to.(*LSym)
	ridx := len(ls.R) - 1
	c.Link.DwFixups.ReferenceChildDIE(ls, ridx, tls, dclIdx, inlIndex)
}

func (c dwCtxt) RecordChildDieOffsets(s dwarf.Sym, vars []*dwarf.Var, offsets []int32) {
	ls := s.(*LSym)
	c.Link.DwFixups.RegisterChildDIEOffsets(ls, vars, offsets)
}

func (c dwCtxt) Logf(format string, args ...interface{}) {
	c.Link.Logf(format, args...)
}

func (ctxt *Link) dwarfSym(s *LSym) (dwarfInfoSym, dwarfLocSym, dwarfRangesSym, dwarfAbsFnSym *LSym) {
	if s.Type != objabi.STEXT {
		ctxt.Diag("dwarfSym of non-TEXT %v", s)
	}
	if s.Func.dwarfInfoSym == nil {
		s.Func.dwarfInfoSym = ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name)
		if ctxt.Flag_locationlists {
			s.Func.dwarfLocSym = ctxt.LookupDerived(s, dwarf.LocPrefix+s.Name)
		}
		s.Func.dwarfRangesSym = ctxt.LookupDerived(s, dwarf.RangePrefix+s.Name)
		if s.WasInlined() {
			s.Func.dwarfAbsFnSym = ctxt.DwFixups.AbsFuncDwarfSym(s)
		}

	}
	return s.Func.dwarfInfoSym, s.Func.dwarfLocSym, s.Func.dwarfRangesSym, s.Func.dwarfAbsFnSym
}

func (s *LSym) Len() int64 {
	return s.Size
}

// fileSymbol returns a symbol corresponding to the source file of the
// first instruction (prog) of the specified function. This will
// presumably be the file in which the function is defined.
func (ctxt *Link) fileSymbol(fn *LSym) *LSym {
	p := fn.Func.Text
	if p != nil {
		f, _ := linkgetlineFromPos(ctxt, p.Pos)
		fsym := ctxt.Lookup(f)
		return fsym
	}
	return nil
}

// populateDWARF fills in the DWARF Debugging Information Entries for
// TEXT symbol 's'. The various DWARF symbols must already have been
// initialized in InitTextSym.
func (ctxt *Link) populateDWARF(curfn interface{}, s *LSym, myimportpath string) {
	info, loc, ranges, absfunc := ctxt.dwarfSym(s)
	if info.Size != 0 {
		ctxt.Diag("makeFuncDebugEntry double process %v", s)
	}
	var scopes []dwarf.Scope
	var inlcalls dwarf.InlCalls
	if ctxt.DebugInfo != nil {
		scopes, inlcalls = ctxt.DebugInfo(s, curfn)
	}
	var err error
	dwctxt := dwCtxt{ctxt}
	filesym := ctxt.fileSymbol(s)
	fnstate := &dwarf.FnState{
		Name:       s.Name,
		Importpath: myimportpath,
		Info:       info,
		Filesym:    filesym,
		Loc:        loc,
		Ranges:     ranges,
		Absfn:      absfunc,
		StartPC:    s,
		Size:       s.Size,
		External:   !s.Static(),
		Scopes:     scopes,
		InlCalls:   inlcalls,
	}
	if absfunc != nil {
		err = dwarf.PutAbstractFunc(dwctxt, fnstate)
		if err != nil {
			ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
		}
		err = dwarf.PutConcreteFunc(dwctxt, fnstate)
	} else {
		err = dwarf.PutDefaultFunc(dwctxt, fnstate)
	}
	if err != nil {
		ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
	}
}

// DwarfIntConst creates a link symbol for an integer constant with the
// given name, type and value.
func (ctxt *Link) DwarfIntConst(myimportpath, name, typename string, val int64) {
	if myimportpath == "" {
		return
	}
	s := ctxt.LookupInit(dwarf.ConstInfoPrefix+myimportpath, func(s *LSym) {
		s.Type = objabi.SDWARFINFO
		ctxt.Data = append(ctxt.Data, s)
	})
	dwarf.PutIntConst(dwCtxt{ctxt}, s, ctxt.Lookup(dwarf.InfoPrefix+typename), myimportpath+"."+name, val)
}

func (ctxt *Link) DwarfAbstractFunc(curfn interface{}, s *LSym, myimportpath string) {
	absfn := ctxt.DwFixups.AbsFuncDwarfSym(s)
	if absfn.Size != 0 {
		ctxt.Diag("internal error: DwarfAbstractFunc double process %v", s)
	}
	if s.Func == nil {
		s.Func = new(FuncInfo)
	}
	scopes, _ := ctxt.DebugInfo(s, curfn)
	dwctxt := dwCtxt{ctxt}
	filesym := ctxt.fileSymbol(s)
	fnstate := dwarf.FnState{
		Name:       s.Name,
		Importpath: myimportpath,
		Info:       absfn,
		Filesym:    filesym,
		Absfn:      absfn,
		External:   !s.Static(),
		Scopes:     scopes,
	}
	if err := dwarf.PutAbstractFunc(dwctxt, &fnstate); err != nil {
		ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
	}
}

// This table is designed to aid in the creation of references betweeen
// DWARF subprogram DIEs.
//
// In most cases when one DWARF DIE has to refer to another DWARF DIE,
// the target of the reference has an LSym, which makes it easy to use
// the existing relocation mechanism. For DWARF inlined routine DIEs,
// however, the subprogram DIE has to refer to a child
// parameter/variable DIE of the abstract subprogram. This child DIE
// doesn't have an LSym, and also of interest is the fact that when
// DWARF generation is happening for inlined function F within caller
// G, it's possible that DWARF generation hasn't happened yet for F,
// so there is no way to know the offset of a child DIE within F's
// abstract function. Making matters more complex, each inlined
// instance of F may refer to a subset of the original F's variables
// (depending on what happens with optimization, some vars may be
// eliminated).
//
// The fixup table below helps overcome this hurdle. At the point
// where a parameter/variable reference is made (via a call to
// "ReferenceChildDIE"), a fixup record is generate that records
// the relocation that is targeting that child variable. At a later
// point when the abstract function DIE is emitted, there will be
// a call to "RegisterChildDIEOffsets", at which point the offsets
// needed to apply fixups are captured. Finally, once the parallel
// portion of the compilation is done, fixups can actually be applied
// during the "Finalize" method (this can't be done during the
// parallel portion of the compile due to the possibility of data
// races).
//
// This table is also used to record the "precursor" function node for
// each function that is the target of an inline -- child DIE references
// have to be made with respect to the original pre-optimization
// version of the function (to allow for the fact that each inlined
// body may be optimized differently).
type DwarfFixupTable struct {
	ctxt      *Link
	mu        sync.Mutex
	symtab    map[*LSym]int // maps abstract fn LSYM to index in svec
	svec      []symFixups
	precursor map[*LSym]fnState // maps fn Lsym to precursor Node, absfn sym
}

type symFixups struct {
	fixups   []relFixup
	doffsets []declOffset
	inlIndex int32
	defseen  bool
}

type declOffset struct {
	// Index of variable within DCL list of pre-optimization function
	dclIdx int32
	// Offset of var's child DIE with respect to containing subprogram DIE
	offset int32
}

type relFixup struct {
	refsym *LSym
	relidx int32
	dclidx int32
}

type fnState struct {
	// precursor function (really *gc.Node)
	precursor interface{}
	// abstract function symbol
	absfn *LSym
}

func NewDwarfFixupTable(ctxt *Link) *DwarfFixupTable {
	return &DwarfFixupTable{
		ctxt:      ctxt,
		symtab:    make(map[*LSym]int),
		precursor: make(map[*LSym]fnState),
	}
}

func (ft *DwarfFixupTable) GetPrecursorFunc(s *LSym) interface{} {
	if fnstate, found := ft.precursor[s]; found {
		return fnstate.precursor
	}
	return nil
}

func (ft *DwarfFixupTable) SetPrecursorFunc(s *LSym, fn interface{}) {
	if _, found := ft.precursor[s]; found {
		ft.ctxt.Diag("internal error: DwarfFixupTable.SetPrecursorFunc double call on %v", s)
	}

	// initialize abstract function symbol now. This is done here so
	// as to avoid data races later on during the parallel portion of
	// the back end.
	absfn := ft.ctxt.LookupDerived(s, dwarf.InfoPrefix+s.Name+dwarf.AbstractFuncSuffix)
	absfn.Set(AttrDuplicateOK, true)
	absfn.Type = objabi.SDWARFINFO
	ft.ctxt.Data = append(ft.ctxt.Data, absfn)

	ft.precursor[s] = fnState{precursor: fn, absfn: absfn}
}

// Make a note of a child DIE reference: relocation 'ridx' within symbol 's'
// is targeting child 'c' of DIE with symbol 'tgt'.
func (ft *DwarfFixupTable) ReferenceChildDIE(s *LSym, ridx int, tgt *LSym, dclidx int, inlIndex int) {
	// Protect against concurrent access if multiple backend workers
	ft.mu.Lock()
	defer ft.mu.Unlock()

	// Create entry for symbol if not already present.
	idx, found := ft.symtab[tgt]
	if !found {
		ft.svec = append(ft.svec, symFixups{inlIndex: int32(inlIndex)})
		idx = len(ft.svec) - 1
		ft.symtab[tgt] = idx
	}

	// Do we have child DIE offsets available? If so, then apply them,
	// otherwise create a fixup record.
	sf := &ft.svec[idx]
	if len(sf.doffsets) > 0 {
		found := false
		for _, do := range sf.doffsets {
			if do.dclIdx == int32(dclidx) {
				off := do.offset
				s.R[ridx].Add += int64(off)
				found = true
				break
			}
		}
		if !found {
			ft.ctxt.Diag("internal error: DwarfFixupTable.ReferenceChildDIE unable to locate child DIE offset for dclIdx=%d src=%v tgt=%v", dclidx, s, tgt)
		}
	} else {
		sf.fixups = append(sf.fixups, relFixup{s, int32(ridx), int32(dclidx)})
	}
}

// Called once DWARF generation is complete for a given abstract function,
// whose children might have been referenced via a call above. Stores
// the offsets for any child DIEs (vars, params) so that they can be
// consumed later in on DwarfFixupTable.Finalize, which applies any
// outstanding fixups.
func (ft *DwarfFixupTable) RegisterChildDIEOffsets(s *LSym, vars []*dwarf.Var, coffsets []int32) {
	// Length of these two slices should agree
	if len(vars) != len(coffsets) {
		ft.ctxt.Diag("internal error: RegisterChildDIEOffsets vars/offsets length mismatch")
		return
	}

	// Generate the slice of declOffset's based in vars/coffsets
	doffsets := make([]declOffset, len(coffsets))
	for i := 0; i < len(coffsets); i++ {
		doffsets[i].dclIdx = vars[i].ChildIndex
		doffsets[i].offset = coffsets[i]
	}

	ft.mu.Lock()
	defer ft.mu.Unlock()

	// Store offsets for this symbol.
	idx, found := ft.symtab[s]
	if !found {
		sf := symFixups{inlIndex: -1, defseen: true, doffsets: doffsets}
		ft.svec = append(ft.svec, sf)
		ft.symtab[s] = len(ft.svec) - 1
	} else {
		sf := &ft.svec[idx]
		sf.doffsets = doffsets
		sf.defseen = true
	}
}

func (ft *DwarfFixupTable) processFixups(slot int, s *LSym) {
	sf := &ft.svec[slot]
	for _, f := range sf.fixups {
		dfound := false
		for i := 0; i < len(sf.doffsets); i++ {
			if sf.doffsets[i].dclIdx == f.dclidx {
				f.refsym.R[f.relidx].Add += int64(sf.doffsets[i].offset)
				dfound = true
				break
			}
		}
		if !dfound {
			ft.ctxt.Diag("internal error: DwarfFixupTable has orphaned fixup on %v targeting %v relidx=%d dclidx=%d", f.refsym, s, f.relidx, f.dclidx)
		}
	}
}

// return the LSym corresponding to the 'abstract subprogram' DWARF
// info entry for a function.
func (ft *DwarfFixupTable) AbsFuncDwarfSym(fnsym *LSym) *LSym {
	// Protect against concurrent access if multiple backend workers
	ft.mu.Lock()
	defer ft.mu.Unlock()

	if fnstate, found := ft.precursor[fnsym]; found {
		return fnstate.absfn
	}
	ft.ctxt.Diag("internal error: AbsFuncDwarfSym requested for %v, not seen during inlining", fnsym)
	return nil
}

// Called after all functions have been compiled; the main job of this
// function is to identify cases where there are outstanding fixups.
// This scenario crops up when we have references to variables of an
// inlined routine, but that routine is defined in some other package.
// This helper walks through and locate these fixups, then invokes a
// helper to create an abstract subprogram DIE for each one.
func (ft *DwarfFixupTable) Finalize(myimportpath string, trace bool) {
	if trace {
		ft.ctxt.Logf("DwarfFixupTable.Finalize invoked for %s\n", myimportpath)
	}

	// Collect up the keys from the precursor map, then sort the
	// resulting list (don't want to rely on map ordering here).
	fns := make([]*LSym, len(ft.precursor))
	idx := 0
	for fn, _ := range ft.precursor {
		fns[idx] = fn
		idx++
	}
	sort.Sort(bySymName(fns))

	// Should not be called during parallel portion of compilation.
	if ft.ctxt.InParallel {
		ft.ctxt.Diag("internal error: DwarfFixupTable.Finalize call during parallel backend")
	}

	// Generate any missing abstract functions.
	for i := 0; i < len(fns); i++ {
		s := fns[i]
		absfn := ft.AbsFuncDwarfSym(s)
		slot, found := ft.symtab[absfn]
		if !found || !ft.svec[slot].defseen {
			ft.ctxt.GenAbstractFunc(s)
		}
	}

	// Apply fixups.
	for i := 0; i < len(fns); i++ {
		s := fns[i]
		absfn := ft.AbsFuncDwarfSym(s)
		slot, found := ft.symtab[absfn]
		if !found {
			ft.ctxt.Diag("internal error: DwarfFixupTable.Finalize orphan abstract function for %v", s)
		} else {
			ft.processFixups(slot, s)
		}
	}
}

type bySymName []*LSym

func (s bySymName) Len() int           { return len(s) }
func (s bySymName) Less(i, j int) bool { return s[i].Name < s[j].Name }
func (s bySymName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
