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

// Executable image layout - address assignment.

package main

import (
	"cmd/internal/goobj"
)

// A layoutSection describes a single section to add to the
// final executable. Go binaries only have a fixed set of possible
// sections, and the symbol kind determines the section.
type layoutSection struct {
	Segment string
	Section string
	Kind    goobj.SymKind
	Index   int
}

// layout defines the layout of the generated Go executable.
// The order of entries here is the order in the executable.
// Entries with the same Segment name must be contiguous.
var layout = []layoutSection{
	{Segment: "text", Section: "text", Kind: goobj.STEXT},
	{Segment: "rodata", Section: "rodata", Kind: goobj.SRODATA},
	{Segment: "rodata", Section: "functab", Kind: goobj.SPCLNTAB},
	{Segment: "rodata", Section: "typelink", Kind: goobj.STYPELINK},
	{Segment: "data", Section: "noptrdata", Kind: goobj.SNOPTRDATA},
	{Segment: "data", Section: "data", Kind: goobj.SDATA},
	{Segment: "data", Section: "bss", Kind: goobj.SBSS},
	{Segment: "data", Section: "noptrbss", Kind: goobj.SNOPTRBSS},

	// Later:
	//	{"rodata", "type", goobj.STYPE},
	//	{"rodata", "string", goobj.SSTRING},
	//	{"rodata", "gostring", goobj.SGOSTRING},
	//	{"rodata", "gofunc", goobj.SGOFUNC},
}

// layoutByKind maps from SymKind to an entry in layout.
var layoutByKind []*layoutSection

func init() {
	// Build index from symbol type to layout entry.
	max := 0
	for _, sect := range layout {
		if max <= int(sect.Kind) {
			max = int(sect.Kind) + 1
		}
	}
	layoutByKind = make([]*layoutSection, max)
	for i := range layout {
		sect := &layout[i]
		layoutByKind[sect.Kind] = sect
		sect.Index = i
	}
}

// layout arranges symbols into sections and sections into segments,
// and then it assigns addresses to segments, sections, and symbols.
func (p *Prog) layout() {
	sections := make([]*Section, len(layout))

	// Assign symbols to sections using index, creating sections as needed.
	// Could keep sections separated by type during input instead.
	for _, sym := range p.SymOrder {
		kind := sym.Kind
		if kind < 0 || int(kind) >= len(layoutByKind) || layoutByKind[kind] == nil {
			p.errorf("%s: unexpected symbol kind %v", sym.SymID, kind)
			continue
		}
		lsect := layoutByKind[kind]
		sect := sections[lsect.Index]
		if sect == nil {
			sect = &Section{
				Name:  lsect.Section,
				Align: 1,
			}
			sections[lsect.Index] = sect
		}
		if sym.Data.Size > 0 || len(sym.Bytes) > 0 {
			sect.InFile = true
		}
		sym.Section = sect
		sect.Syms = append(sect.Syms, sym)

		// TODO(rsc): Incorporate alignment information.
		// First that information needs to be added to the object files.
		//
		// if sect.Align < Addr(sym.Align) {
		//	sect.Align = Addr(sym.Align)
		// }
	}

	// Assign sections to segments, creating segments as needed.
	var seg *Segment
	for i, sect := range sections {
		if sect == nil {
			continue
		}
		segName := layout[i].Segment

		// Special case: Mach-O does not support "rodata" segment,
		// so store read-only data in text segment.
		if p.GOOS == "darwin" && segName == "rodata" {
			segName = "text"
		}

		if seg == nil || seg.Name != segName {
			seg = &Segment{
				Name: segName,
			}
			p.Segments = append(p.Segments, seg)
		}
		sect.Segment = seg
		seg.Sections = append(seg.Sections, sect)
	}

	// Assign addresses.

	// TODO(rsc): This choice needs to be informed by both
	// the formatter and the target architecture.
	// And maybe eventually a command line flag (sigh).
	const segAlign = 4096

	// TODO(rsc): Use a larger amount on most systems, which will let the
	// compiler eliminate more nil checks.
	if p.UnmappedSize == 0 {
		p.UnmappedSize = segAlign
	}

	// TODO(rsc): addr := Addr(0) when generating a shared library or PIE.
	addr := p.UnmappedSize

	// Account for initial file header.
	hdrVirt, hdrFile := p.formatter.headerSize(p)
	addr += hdrVirt

	// Assign addresses to segments, sections, symbols.
	// Assign sizes to segments, sections.
	startVirt := addr
	startFile := hdrFile
	for _, seg := range p.Segments {
		addr = round(addr, segAlign)
		seg.VirtAddr = addr
		seg.FileOffset = startFile + seg.VirtAddr - startVirt
		for _, sect := range seg.Sections {
			addr = round(addr, sect.Align)
			sect.VirtAddr = addr
			for _, sym := range sect.Syms {
				// TODO(rsc): Respect alignment once we have that information.
				sym.Addr = addr
				addr += Addr(sym.Size)
			}
			sect.Size = addr - sect.VirtAddr
			if sect.InFile {
				seg.FileSize = addr - seg.VirtAddr
			}
		}
		seg.VirtSize = addr - seg.VirtAddr
	}

	// Define symbols for section names.
	var progEnd Addr
	for i, sect := range sections {
		name := layout[i].Section
		var start, end Addr
		if sect != nil {
			start = sect.VirtAddr
			end = sect.VirtAddr + sect.Size
		}
		p.defineConst("runtime."+name, start)
		p.defineConst("runtime.e"+name, end)
		progEnd = end
	}
	p.defineConst("runtime.end", progEnd)
}
