// Copyright 2009 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.

package gc

import (
	"cmd/internal/obj"
	"fmt"
	"strconv"
)

/*
 * architecture-independent object file output
 */
const (
	ArhdrSize = 60
)

func formathdr(arhdr []byte, name string, size int64) {
	copy(arhdr[:], fmt.Sprintf("%-16s%-12d%-6d%-6d%-8o%-10d`\n", name, 0, 0, 0, 0644, size))
}

func dumpobj() {
	var err error
	bout, err = obj.Bopenw(outfile)
	if err != nil {
		Flusherrors()
		fmt.Printf("can't create %s: %v\n", outfile, err)
		errorexit()
	}

	startobj := int64(0)
	var arhdr [ArhdrSize]byte
	if writearchive != 0 {
		obj.Bwritestring(bout, "!<arch>\n")
		arhdr = [ArhdrSize]byte{}
		obj.Bwrite(bout, arhdr[:])
		startobj = obj.Boffset(bout)
	}

	fmt.Fprintf(bout, "go object %s %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion(), obj.Expstring())
	dumpexport()

	if writearchive != 0 {
		obj.Bflush(bout)
		size := obj.Boffset(bout) - startobj
		if size&1 != 0 {
			obj.Bputc(bout, 0)
		}
		obj.Bseek(bout, startobj-ArhdrSize, 0)
		formathdr(arhdr[:], "__.PKGDEF", size)
		obj.Bwrite(bout, arhdr[:])
		obj.Bflush(bout)

		obj.Bseek(bout, startobj+size+(size&1), 0)
		arhdr = [ArhdrSize]byte{}
		obj.Bwrite(bout, arhdr[:])
		startobj = obj.Boffset(bout)
		fmt.Fprintf(bout, "go object %s %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion(), obj.Expstring())
	}

	if pragcgobuf != "" {
		if writearchive != 0 {
			// write empty export section; must be before cgo section
			fmt.Fprintf(bout, "\n$$\n\n$$\n\n")
		}

		fmt.Fprintf(bout, "\n$$  // cgo\n")
		fmt.Fprintf(bout, "%s\n$$\n\n", pragcgobuf)
	}

	fmt.Fprintf(bout, "\n!\n")

	var externs *NodeList
	if externdcl != nil {
		externs = externdcl.End
	}

	dumpglobls()
	dumptypestructs()

	// Dump extra globals.
	tmp := externdcl

	if externs != nil {
		externdcl = externs.Next
	}
	dumpglobls()
	externdcl = tmp

	zero := Pkglookup("zerovalue", Runtimepkg)
	ggloblsym(zero, int32(zerosize), obj.DUPOK|obj.RODATA)

	dumpdata()
	obj.Writeobjdirect(Ctxt, bout)

	if writearchive != 0 {
		obj.Bflush(bout)
		size := obj.Boffset(bout) - startobj
		if size&1 != 0 {
			obj.Bputc(bout, 0)
		}
		obj.Bseek(bout, startobj-ArhdrSize, 0)
		name := fmt.Sprintf("_go_.%c", Thearch.Thechar)
		formathdr(arhdr[:], name, size)
		obj.Bwrite(bout, arhdr[:])
	}

	obj.Bterm(bout)
}

func dumpglobls() {
	var n *Node

	// add globals
	for l := externdcl; l != nil; l = l.Next {
		n = l.N
		if n.Op != ONAME {
			continue
		}

		if n.Type == nil {
			Fatal("external %v nil type\n", n)
		}
		if n.Class == PFUNC {
			continue
		}
		if n.Sym.Pkg != localpkg {
			continue
		}
		dowidth(n.Type)

		ggloblnod(n)
	}

	for l := funcsyms; l != nil; l = l.Next {
		n = l.N
		dsymptr(n.Sym, 0, n.Sym.Def.Func.Shortname.Sym, 0)
		ggloblsym(n.Sym, int32(Widthptr), obj.DUPOK|obj.RODATA)
	}

	// Do not reprocess funcsyms on next dumpglobls call.
	funcsyms = nil
}

func Bputname(b *obj.Biobuf, s *obj.LSym) {
	obj.Bwritestring(b, s.Name)
	obj.Bputc(b, 0)
}

func Linksym(s *Sym) *obj.LSym {
	if s == nil {
		return nil
	}
	if s.Lsym != nil {
		return s.Lsym
	}
	var name string
	if isblanksym(s) {
		name = "_"
	} else if s.Linkname != "" {
		name = s.Linkname
	} else {
		name = s.Pkg.Prefix + "." + s.Name
	}

	ls := obj.Linklookup(Ctxt, name, 0)
	s.Lsym = ls
	return ls
}

func duintxx(s *Sym, off int, v uint64, wid int) int {
	// Update symbol data directly instead of generating a
	// DATA instruction that liblink will have to interpret later.
	// This reduces compilation time and memory usage.
	off = int(Rnd(int64(off), int64(wid)))

	return int(obj.Setuintxx(Ctxt, Linksym(s), int64(off), v, int64(wid)))
}

func duint8(s *Sym, off int, v uint8) int {
	return duintxx(s, off, uint64(v), 1)
}

func duint16(s *Sym, off int, v uint16) int {
	return duintxx(s, off, uint64(v), 2)
}

func duint32(s *Sym, off int, v uint32) int {
	return duintxx(s, off, uint64(v), 4)
}

func duint64(s *Sym, off int, v uint64) int {
	return duintxx(s, off, v, 8)
}

func duintptr(s *Sym, off int, v uint64) int {
	return duintxx(s, off, v, Widthptr)
}

var stringsym_gen int

func stringsym(s string) *Sym {
	var symname string
	var pkg *Pkg
	if len(s) > 100 {
		// huge strings are made static to avoid long names
		stringsym_gen++
		symname = fmt.Sprintf(".gostring.%d", stringsym_gen)

		pkg = localpkg
	} else {
		// small strings get named by their contents,
		// so that multiple modules using the same string
		// can share it.
		symname = strconv.Quote(s)
		pkg = gostringpkg
	}

	sym := Pkglookup(symname, pkg)

	// SymUniq flag indicates that data is generated already
	if sym.Flags&SymUniq != 0 {
		return sym
	}
	sym.Flags |= SymUniq
	sym.Def = newname(sym)

	off := 0

	// string header
	off = dsymptr(sym, off, sym, Widthptr+Widthint)
	off = duintxx(sym, off, uint64(len(s)), Widthint)

	// string data
	var m int
	for n := 0; n < len(s); n += m {
		m = 8
		if m > len(s)-n {
			m = len(s) - n
		}
		off = dsname(sym, off, s[n:n+m])
	}

	off = duint8(sym, off, 0)                    // terminating NUL for runtime
	off = (off + Widthptr - 1) &^ (Widthptr - 1) // round to pointer alignment
	ggloblsym(sym, int32(off), obj.DUPOK|obj.RODATA|obj.LOCAL)

	return sym
}

var slicebytes_gen int

func slicebytes(nam *Node, s string, len int) {
	var m int

	slicebytes_gen++
	symname := fmt.Sprintf(".gobytes.%d", slicebytes_gen)
	sym := Pkglookup(symname, localpkg)
	sym.Def = newname(sym)

	off := 0
	for n := 0; n < len; n += m {
		m = 8
		if m > len-n {
			m = len - n
		}
		off = dsname(sym, off, s[n:n+m])
	}

	ggloblsym(sym, int32(off), obj.NOPTR|obj.LOCAL)

	if nam.Op != ONAME {
		Fatal("slicebytes %v", nam)
	}
	off = int(nam.Xoffset)
	off = dsymptr(nam.Sym, off, sym, 0)
	off = duintxx(nam.Sym, off, uint64(len), Widthint)
	duintxx(nam.Sym, off, uint64(len), Widthint)
}

func dstringptr(s *Sym, off int, str string) int {
	off = int(Rnd(int64(off), int64(Widthptr)))
	p := Thearch.Gins(obj.ADATA, nil, nil)
	p.From.Type = obj.TYPE_MEM
	p.From.Name = obj.NAME_EXTERN
	p.From.Sym = Linksym(s)
	p.From.Offset = int64(off)
	p.From3.Type = obj.TYPE_CONST
	p.From3.Offset = int64(Widthptr)

	Datastring(str+"\x00", &p.To) // TODO(rsc): Remove NUL
	p.To.Type = obj.TYPE_ADDR
	p.To.Etype = Simtype[TINT]
	off += Widthptr

	return off
}

func Datastring(s string, a *obj.Addr) {
	sym := stringsym(s)
	a.Type = obj.TYPE_MEM
	a.Name = obj.NAME_EXTERN
	a.Sym = Linksym(sym)
	a.Node = sym.Def
	a.Offset = int64(Widthptr) + int64(Widthint) // skip header
	a.Etype = Simtype[TINT]
}

func datagostring(sval string, a *obj.Addr) {
	sym := stringsym(sval)
	a.Type = obj.TYPE_MEM
	a.Name = obj.NAME_EXTERN
	a.Sym = Linksym(sym)
	a.Node = sym.Def
	a.Offset = 0 // header
	a.Etype = TSTRING
}

func dgostringptr(s *Sym, off int, str string) int {
	if str == "" {
		return duintptr(s, off, 0)
	}
	return dgostrlitptr(s, off, &str)
}

func dgostrlitptr(s *Sym, off int, lit *string) int {
	if lit == nil {
		return duintptr(s, off, 0)
	}
	off = int(Rnd(int64(off), int64(Widthptr)))
	p := Thearch.Gins(obj.ADATA, nil, nil)
	p.From.Type = obj.TYPE_MEM
	p.From.Name = obj.NAME_EXTERN
	p.From.Sym = Linksym(s)
	p.From.Offset = int64(off)
	p.From3.Type = obj.TYPE_CONST
	p.From3.Offset = int64(Widthptr)
	datagostring(*lit, &p.To)
	p.To.Type = obj.TYPE_ADDR
	p.To.Etype = Simtype[TINT]
	off += Widthptr

	return off
}

func dsname(s *Sym, off int, t string) int {
	p := Thearch.Gins(obj.ADATA, nil, nil)
	p.From.Type = obj.TYPE_MEM
	p.From.Name = obj.NAME_EXTERN
	p.From.Offset = int64(off)
	p.From.Sym = Linksym(s)
	p.From3.Type = obj.TYPE_CONST
	p.From3.Offset = int64(len(t))

	p.To.Type = obj.TYPE_SCONST
	p.To.Val = t
	return off + len(t)
}

func dsymptr(s *Sym, off int, x *Sym, xoff int) int {
	off = int(Rnd(int64(off), int64(Widthptr)))

	p := Thearch.Gins(obj.ADATA, nil, nil)
	p.From.Type = obj.TYPE_MEM
	p.From.Name = obj.NAME_EXTERN
	p.From.Sym = Linksym(s)
	p.From.Offset = int64(off)
	p.From3.Type = obj.TYPE_CONST
	p.From3.Offset = int64(Widthptr)
	p.To.Type = obj.TYPE_ADDR
	p.To.Name = obj.NAME_EXTERN
	p.To.Sym = Linksym(x)
	p.To.Offset = int64(xoff)
	off += Widthptr

	return off
}

func gdata(nam *Node, nr *Node, wid int) {
	if nr.Op == OLITERAL {
		switch nr.Val.Ctype {
		case CTCPLX:
			gdatacomplex(nam, nr.Val.U.Cval)
			return

		case CTSTR:
			gdatastring(nam, nr.Val.U.Sval)
			return
		}
	}

	p := Thearch.Gins(obj.ADATA, nam, nr)
	p.From3.Type = obj.TYPE_CONST
	p.From3.Offset = int64(wid)
}

func gdatacomplex(nam *Node, cval *Mpcplx) {
	w := cplxsubtype(int(nam.Type.Etype))
	w = int(Types[w].Width)

	p := Thearch.Gins(obj.ADATA, nam, nil)
	p.From3.Type = obj.TYPE_CONST
	p.From3.Offset = int64(w)
	p.To.Type = obj.TYPE_FCONST
	p.To.Val = mpgetflt(&cval.Real)

	p = Thearch.Gins(obj.ADATA, nam, nil)
	p.From3.Type = obj.TYPE_CONST
	p.From3.Offset = int64(w)
	p.From.Offset += int64(w)
	p.To.Type = obj.TYPE_FCONST
	p.To.Val = mpgetflt(&cval.Imag)
}

func gdatastring(nam *Node, sval string) {
	var nod1 Node

	p := Thearch.Gins(obj.ADATA, nam, nil)
	Datastring(sval, &p.To)
	p.From3.Type = obj.TYPE_CONST
	p.From3.Offset = Types[Tptr].Width
	p.To.Type = obj.TYPE_ADDR

	//print("%P\n", p);

	Nodconst(&nod1, Types[TINT], int64(len(sval)))

	p = Thearch.Gins(obj.ADATA, nam, &nod1)
	p.From3.Type = obj.TYPE_CONST
	p.From3.Offset = int64(Widthint)
	p.From.Offset += int64(Widthptr)
}
