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

// Automatic symbol generation.

// TODO(rsc): Handle go.typelink, go.track symbols.
// TODO(rsc): Do not handle $f64. and $f32. symbols. Instead, generate those
// from the compiler and assemblers as dupok data, and then remove autoData below.
package main

import (
	"cmd/internal/goobj"
	"strconv"
	"strings"
)

// linkerDefined lists the symbols supplied by other parts of the linker
// (runtime.go and layout.go).
var linkerDefined = map[string]bool{
	"runtime.bss":        true,
	"runtime.data":       true,
	"runtime.ebss":       true,
	"runtime.edata":      true,
	"runtime.efunctab":   true,
	"runtime.end":        true,
	"runtime.enoptrbss":  true,
	"runtime.enoptrdata": true,
	"runtime.erodata":    true,
	"runtime.etext":      true,
	"runtime.etypelink":  true,
	"runtime.functab":    true,
	"runtime.gcbss":      true,
	"runtime.gcdata":     true,
	"runtime.noptrbss":   true,
	"runtime.noptrdata":  true,
	"runtime.pclntab":    true,
	"runtime.rodata":     true,
	"runtime.text":       true,
	"runtime.typelink":   true,
}

// isAuto reports whether sym is an automatically-generated data or constant symbol.
func (p *Prog) isAuto(sym goobj.SymID) bool {
	return strings.HasPrefix(sym.Name, "go.weak.") ||
		strings.HasPrefix(sym.Name, "$f64.") ||
		strings.HasPrefix(sym.Name, "$f32.") ||
		linkerDefined[sym.Name]
}

// autoData defines the automatically generated data symbols needed by p.
func (p *Prog) autoData() {
	for sym := range p.Missing {
		switch {
		// Floating-point constants that need to be loaded from memory are
		// written as $f64.{16 hex digits} or $f32.{8 hex digits}; the hex digits
		// give the IEEE bit pattern of the constant. As far as the layout into
		// memory is concerned, we interpret these as uint64 or uint32 constants.
		case strings.HasPrefix(sym.Name, "$f64."), strings.HasPrefix(sym.Name, "$f32."):
			size := 64
			if sym.Name[2:4] == "32" {
				size = 32
			}
			delete(p.Missing, sym)
			fbits, err := strconv.ParseUint(sym.Name[len("$f64."):], 16, size)
			if err != nil {
				p.errorf("unexpected floating point symbol %s", sym)
				continue
			}
			data := make([]byte, size/8)
			if size == 64 {
				p.byteorder.PutUint64(data, fbits)
			} else {
				p.byteorder.PutUint32(data, uint32(fbits))
			}
			p.addSym(&Sym{
				Sym: &goobj.Sym{
					SymID: sym,
					Kind:  goobj.SRODATA,
					Size:  size / 8,
				},
				Bytes: data,
			})
		}
	}
}

// autoConst defines the automatically generated constant symbols needed by p.
func (p *Prog) autoConst() {
	for sym := range p.Missing {
		switch {
		case strings.HasPrefix(sym.Name, "go.weak."):
			// weak symbol resolves to actual symbol if present, or else nil.
			delete(p.Missing, sym)
			targ := sym
			targ.Name = sym.Name[len("go.weak."):]
			var addr Addr
			if s := p.Syms[targ]; s != nil {
				addr = s.Addr
			}
			p.defineConst(sym.Name, addr)
		}
	}
}

// defineConst defines a new symbol with the given name and constant address.
func (p *Prog) defineConst(name string, addr Addr) {
	sym := goobj.SymID{Name: name}
	p.addSym(&Sym{
		Sym: &goobj.Sym{
			SymID: sym,
			Kind:  goobj.SCONST,
		},
		Package: nil,
		Addr:    addr,
	})
}
