// Do not edit. Bootstrap copy of /usr/local/google/buildbot/src/android/build-tools/out/obj/go/src/cmd/internal/obj/data.go

//line /usr/local/google/buildbot/src/android/build-tools/out/obj/go/src/cmd/internal/obj/data.go:1
// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c
// http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package obj

import (
	"log"
	"math"
)

func mangle(file string) {
	log.Fatalf("%s: mangled input file", file)
}

func Symgrow(ctxt *Link, s *LSym, lsiz int64) {
	siz := int(lsiz)
	if int64(siz) != lsiz {
		log.Fatalf("Symgrow size %d too long", lsiz)
	}
	if len(s.P) >= siz {
		return
	}
	for cap(s.P) < siz {
		s.P = append(s.P[:cap(s.P)], 0)
	}
	s.P = s.P[:siz]
}

func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
	off := int32(p.From.Offset)
	siz := int32(p.From3.Offset)
	if off < 0 || siz < 0 || off >= 1<<30 || siz >= 100 {
		mangle(pn)
	}
	if ctxt.Enforce_data_order != 0 && off < int32(len(s.P)) {
		ctxt.Diag("data out of order (already have %d)\n%v", len(s.P), p)
	}
	Symgrow(ctxt, s, int64(off+siz))

	switch int(p.To.Type) {
	default:
		ctxt.Diag("bad data: %v", p)

	case TYPE_FCONST:
		switch siz {
		default:
			ctxt.Diag("unexpected %d-byte floating point constant", siz)

		case 4:
			flt := math.Float32bits(float32(p.To.Val.(float64)))
			ctxt.Arch.ByteOrder.PutUint32(s.P[off:], flt)

		case 8:
			flt := math.Float64bits(p.To.Val.(float64))
			ctxt.Arch.ByteOrder.PutUint64(s.P[off:], flt)
		}

	case TYPE_SCONST:
		copy(s.P[off:off+siz], p.To.Val.(string))

	case TYPE_CONST, TYPE_ADDR:
		if p.To.Sym != nil || int(p.To.Type) == TYPE_ADDR {
			r := Addrel(s)
			r.Off = off
			r.Siz = uint8(siz)
			r.Sym = p.To.Sym
			r.Type = R_ADDR
			r.Add = p.To.Offset
			break
		}
		o := p.To.Offset
		switch siz {
		default:
			ctxt.Diag("unexpected %d-byte integer constant", siz)
		case 1:
			s.P[off] = byte(o)
		case 2:
			ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(o))
		case 4:
			ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(o))
		case 8:
			ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o))
		}
	}
}

func Addrel(s *LSym) *Reloc {
	s.R = append(s.R, Reloc{})
	return &s.R[len(s.R)-1]
}

func Setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	if s.Size < off+wid {
		s.Size = off + wid
		Symgrow(ctxt, s, s.Size)
	}

	switch wid {
	case 1:
		s.P[off] = uint8(v)
	case 2:
		ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
	case 4:
		ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
	case 8:
		ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(v))
	}

	return off + wid
}

func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
	off := s.Size
	Setuintxx(ctxt, s, off, v, int64(wid))
	return off
}

func adduint8(ctxt *Link, s *LSym, v uint8) int64 {
	return adduintxx(ctxt, s, uint64(v), 1)
}

func adduint16(ctxt *Link, s *LSym, v uint16) int64 {
	return adduintxx(ctxt, s, uint64(v), 2)
}

func Adduint32(ctxt *Link, s *LSym, v uint32) int64 {
	return adduintxx(ctxt, s, uint64(v), 4)
}

func Adduint64(ctxt *Link, s *LSym, v uint64) int64 {
	return adduintxx(ctxt, s, v, 8)
}

func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 {
	return Setuintxx(ctxt, s, r, uint64(v), 1)
}

func setuint16(ctxt *Link, s *LSym, r int64, v uint16) int64 {
	return Setuintxx(ctxt, s, r, uint64(v), 2)
}

func setuint32(ctxt *Link, s *LSym, r int64, v uint32) int64 {
	return Setuintxx(ctxt, s, r, uint64(v), 4)
}

func setuint64(ctxt *Link, s *LSym, r int64, v uint64) int64 {
	return Setuintxx(ctxt, s, r, v, 8)
}

func addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	i := s.Size
	s.Size += int64(ctxt.Arch.Ptrsize)
	Symgrow(ctxt, s, s.Size)
	r := Addrel(s)
	r.Sym = t
	r.Off = int32(i)
	r.Siz = uint8(ctxt.Arch.Ptrsize)
	r.Type = R_ADDR
	r.Add = add
	return i + int64(r.Siz)
}

func addpcrelplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	i := s.Size
	s.Size += 4
	Symgrow(ctxt, s, s.Size)
	r := Addrel(s)
	r.Sym = t
	r.Off = int32(i)
	r.Add = add
	r.Type = R_PCREL
	r.Siz = 4
	return i + int64(r.Siz)
}

func addaddr(ctxt *Link, s *LSym, t *LSym) int64 {
	return addaddrplus(ctxt, s, t, 0)
}

func setaddrplus(ctxt *Link, s *LSym, off int64, t *LSym, add int64) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	if off+int64(ctxt.Arch.Ptrsize) > s.Size {
		s.Size = off + int64(ctxt.Arch.Ptrsize)
		Symgrow(ctxt, s, s.Size)
	}

	r := Addrel(s)
	r.Sym = t
	r.Off = int32(off)
	r.Siz = uint8(ctxt.Arch.Ptrsize)
	r.Type = R_ADDR
	r.Add = add
	return off + int64(r.Siz)
}

func setaddr(ctxt *Link, s *LSym, off int64, t *LSym) int64 {
	return setaddrplus(ctxt, s, off, t, 0)
}

func addsize(ctxt *Link, s *LSym, t *LSym) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	i := s.Size
	s.Size += int64(ctxt.Arch.Ptrsize)
	Symgrow(ctxt, s, s.Size)
	r := Addrel(s)
	r.Sym = t
	r.Off = int32(i)
	r.Siz = uint8(ctxt.Arch.Ptrsize)
	r.Type = R_SIZE
	return i + int64(r.Siz)
}

func addaddrplus4(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
	if s.Type == 0 {
		s.Type = SDATA
	}
	i := s.Size
	s.Size += 4
	Symgrow(ctxt, s, s.Size)
	r := Addrel(s)
	r.Sym = t
	r.Off = int32(i)
	r.Siz = 4
	r.Type = R_ADDR
	r.Add = add
	return i + int64(r.Siz)
}
