// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
//go:generate bundle -o objabi.go -pkg objabi -prefix= cmd/internal/objabi

// Originally, Go object files were Plan 9 object files, but no longer.
// Now they are more like standard object files, in that each symbol is defined
// by an associated memory image (bytes) and a list of relocations to apply
// during linking. We do not (yet?) use a standard file format, however.
// For now, the format is chosen to be as simple as possible to read and write.
// It may change for reasons of efficiency, or we may even switch to a
// standard file format if there are compelling benefits to doing so.
// See golang.org/s/go13linker for more background.
//
// The file format is:
//
// 	- magic header: "\x00go114ld"
// 	- byte 1 - version number
// 	- sequence of strings giving dependencies (imported packages)
// 	- empty string (marks end of sequence)
// 	- number of entries in the following sequence
// 	- sequence of filename strings to generate debug information
// 	- sequence of symbol references used by the defined symbols
// 	- byte 0xff (marks end of sequence)
// 	- sequence of integer lengths:
// 		- total data length
// 		- total number of relocations
// 		- total number of pcdata
// 		- total number of automatics
// 		- total number of funcdata
// 		- total number of files
// 	- data, the content of the defined symbols
// 	- sequence of defined symbols
// 	- byte 0xff (marks end of sequence)
// 	- magic footer: "\xffgo114ld"
//
// All integers are stored in a zigzag varint format.
// See golang.org/s/go12symtab for a definition.
//
// Data blocks and strings are both stored as an integer
// followed by that many bytes.
//
// A symbol reference is a string name followed by an ABI or -1 for static.
//
// A symbol points to other symbols using an index into the symbol
// reference sequence. Index 0 corresponds to a nil symbol pointer.
// In the symbol layout described below "symref index" stands for this
// index.
//
// Each symbol is laid out as the following fields:
//
// 	- byte 0xfe (sanity check for synchronization)
// 	- type [byte]
// 	- name & ABI [symref index]
// 	- flags [int]
// 		1<<0 dupok
// 		1<<1 local
// 		1<<2 add to typelink table
// 	- size [int]
// 	- gotype [symref index]
// 	- p [data block]
// 	- nr [int]
// 	- r [nr relocations, sorted by off]
//
// If type == STEXT, there are a few more fields:
//
// 	- args [int]
// 	- locals [int]
// 	- nosplit [int]
// 	- flags [int]
// 		1<<0 leaf
// 		1<<1 C function
// 		1<<2 function may call reflect.Type.Method
// 		1<<3 function compiled with -shared
// 	- nlocal [int]
// 	- local [nlocal automatics]
// 	- pcln [pcln table]
//
// Each relocation has the encoding:
//
// 	- off [int]
// 	- siz [int]
// 	- type [int]
// 	- add [int]
// 	- sym [symref index]
//
// Each local has the encoding:
//
// 	- asym [symref index]
// 	- offset [int]
// 	- type [int]
// 	- gotype [symref index]
//
// The pcln table has the encoding:
//
// 	- pcsp [data block]
// 	- pcfile [data block]
// 	- pcline [data block]
// 	- pcinline [data block]
// 	- npcdata [int]
// 	- pcdata [npcdata data blocks]
// 	- nfuncdata [int]
// 	- funcdata [nfuncdata symref index]
// 	- funcdatasym [nfuncdata ints]
// 	- nfile [int]
// 	- file [nfile symref index]
// 	- ninlinedcall [int]
// 	- inlinedcall [ninlinedcall int symref int symref]
//
// The file layout and meaning of type integers are architecture-independent.
//
// TODO(rsc): The file format is good for a first pass but needs work.
// 	- There are SymID in the object file that should really just be strings.
//

package objabi

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
)

// Auto.name
const (
	A_AUTO = 1 + iota
	A_PARAM
	A_DELETED_AUTO
)

func Flagcount(name, usage string, val *int) {
	flag.Var((*count)(val), name, usage)
}

func Flagfn1(name, usage string, f func(string)) {
	flag.Var(fn1(f), name, usage)
}

func Flagprint(w io.Writer) {
	flag.CommandLine.SetOutput(w)
	flag.PrintDefaults()
}

func Flagparse(usage func()) {
	flag.Usage = usage
	os.Args = expandArgs(os.Args)
	flag.Parse()
}

// expandArgs expands "response files" arguments in the provided slice.
//
// A "response file" argument starts with '@' and the rest of that
// argument is a filename with CR-or-CRLF-separated arguments. Each
// argument in the named files can also contain response file
// arguments. See Issue 18468.
//
// The returned slice 'out' aliases 'in' iff the input did not contain
// any response file arguments.
//
// TODO: handle relative paths of recursive expansions in different directories?
// Is there a spec for this? Are relative paths allowed?
func expandArgs(in []string) (out []string) {
	// out is nil until we see a "@" argument.
	for i, s := range in {
		if strings.HasPrefix(s, "@") {
			if out == nil {
				out = make([]string, 0, len(in)*2)
				out = append(out, in[:i]...)
			}
			slurp, err := ioutil.ReadFile(s[1:])
			if err != nil {
				log.Fatal(err)
			}
			args := strings.Split(strings.TrimSpace(strings.Replace(string(slurp), "\r", "", -1)), "\n")
			out = append(out, expandArgs(args)...)
		} else if out != nil {
			out = append(out, s)
		}
	}
	if out == nil {
		return in
	}
	return
}

func AddVersionFlag() {
	flag.Var(versionFlag{}, "V", "print version and exit")
}

var buildID string // filled in by linker

type versionFlag struct{}

func (versionFlag) IsBoolFlag() bool { return true }

func (versionFlag) Get() interface{} { return nil }

func (versionFlag) String() string { return "" }

func (versionFlag) Set(s string) error {
	name := os.Args[0]
	name = name[strings.LastIndex(name, `/`)+1:]
	name = name[strings.LastIndex(name, `\`)+1:]
	name = strings.TrimSuffix(name, ".exe")

	// If there's an active experiment, include that,
	// to distinguish go1.10.2 with an experiment
	// from go1.10.2 without an experiment.
	p := Expstring()
	if p == DefaultExpstring() {
		p = ""
	}
	sep := ""
	if p != "" {
		sep = " "
	}

	// The go command invokes -V=full to get a unique identifier
	// for this tool. It is assumed that the release version is sufficient
	// for releases, but during development we include the full
	// build ID of the binary, so that if the compiler is changed and
	// rebuilt, we notice and rebuild all packages.
	if s == "full" {
		if strings.HasPrefix(Version, "devel") {
			p += " buildID=" + buildID
		}
	}

	fmt.Printf("%s version %s%s%s\n", name, Version, sep, p)
	os.Exit(0)
	return nil
}

// count is a flag.Value that is like a flag.Bool and a flag.Int.
// If used as -name, it increments the count, but -name=x sets the count.
// Used for verbose flag -v.
type count int

func (c *count) String() string {
	return fmt.Sprint(int(*c))
}

func (c *count) Set(s string) error {
	switch s {
	case "true":
		*c++
	case "false":
		*c = 0
	default:
		n, err := strconv.Atoi(s)
		if err != nil {
			return fmt.Errorf("invalid count %q", s)
		}
		*c = count(n)
	}
	return nil
}

func (c *count) Get() interface{} {
	return int(*c)
}

func (c *count) IsBoolFlag() bool {
	return true
}

func (c *count) IsCountFlag() bool {
	return true
}

type fn1 func(string)

func (f fn1) Set(s string) error {
	f(s)
	return nil
}

func (f fn1) String() string { return "" }

// This file defines the IDs for PCDATA and FUNCDATA instructions
// in Go binaries.
//
// These must agree with ../../../runtime/funcdata.h and
// ../../../runtime/symtab.go.

const (
	PCDATA_RegMapIndex   = 0 // if !go115ReduceLiveness
	PCDATA_UnsafePoint   = 0 // if go115ReduceLiveness
	PCDATA_StackMapIndex = 1
	PCDATA_InlTreeIndex  = 2

	FUNCDATA_ArgsPointerMaps    = 0
	FUNCDATA_LocalsPointerMaps  = 1
	FUNCDATA_RegPointerMaps     = 2 // if !go115ReduceLiveness
	FUNCDATA_StackObjects       = 3
	FUNCDATA_InlTree            = 4
	FUNCDATA_OpenCodedDeferInfo = 5

	// ArgsSizeUnknown is set in Func.argsize to mark all functions
	// whose argument size is unknown (C vararg functions, and
	// assembly code without an explicit specification).
	// This value is generated by the compiler, assembler, or linker.
	ArgsSizeUnknown = -0x80000000
)

// Special PCDATA values.
const (
	// PCDATA_RegMapIndex values.
	//
	// Only if !go115ReduceLiveness.
	PCDATA_RegMapUnsafe = -2 // Unsafe for async preemption

	// PCDATA_UnsafePoint values.
	PCDATA_UnsafePointSafe   = -1 // Safe for async preemption
	PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption

	// PCDATA_Restart1(2) apply on a sequence of instructions, within
	// which if an async preemption happens, we should back off the PC
	// to the start of the sequence when resuming.
	// We need two so we can distinguish the start/end of the sequence
	// in case that two sequences are next to each other.
	PCDATA_Restart1 = -3
	PCDATA_Restart2 = -4

	// Like PCDATA_Restart1, but back to function entry if async preempted.
	PCDATA_RestartAtEntry = -5
)

// A FuncID identifies particular functions that need to be treated
// specially by the runtime.
// Note that in some situations involving plugins, there may be multiple
// copies of a particular special runtime function.
// Note: this list must match the list in runtime/symtab.go.
type FuncID uint8

const (
	FuncID_normal FuncID = iota // not a special function
	FuncID_runtime_main
	FuncID_goexit
	FuncID_jmpdefer
	FuncID_mcall
	FuncID_morestack
	FuncID_mstart
	FuncID_rt0_go
	FuncID_asmcgocall
	FuncID_sigpanic
	FuncID_runfinq
	FuncID_gcBgMarkWorker
	FuncID_systemstack_switch
	FuncID_systemstack
	FuncID_cgocallback_gofunc
	FuncID_gogo
	FuncID_externalthreadhandler
	FuncID_debugCallV1
	FuncID_gopanic
	FuncID_panicwrap
	FuncID_handleAsyncEvent
	FuncID_asyncPreempt
	FuncID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.)
)

// Get the function ID for the named function in the named file.
// The function should be package-qualified.
func GetFuncID(name, file string) FuncID {
	switch name {
	case "runtime.main":
		return FuncID_runtime_main
	case "runtime.goexit":
		return FuncID_goexit
	case "runtime.jmpdefer":
		return FuncID_jmpdefer
	case "runtime.mcall":
		return FuncID_mcall
	case "runtime.morestack":
		return FuncID_morestack
	case "runtime.mstart":
		return FuncID_mstart
	case "runtime.rt0_go":
		return FuncID_rt0_go
	case "runtime.asmcgocall":
		return FuncID_asmcgocall
	case "runtime.sigpanic":
		return FuncID_sigpanic
	case "runtime.runfinq":
		return FuncID_runfinq
	case "runtime.gcBgMarkWorker":
		return FuncID_gcBgMarkWorker
	case "runtime.systemstack_switch":
		return FuncID_systemstack_switch
	case "runtime.systemstack":
		return FuncID_systemstack
	case "runtime.cgocallback_gofunc":
		return FuncID_cgocallback_gofunc
	case "runtime.gogo":
		return FuncID_gogo
	case "runtime.externalthreadhandler":
		return FuncID_externalthreadhandler
	case "runtime.debugCallV1":
		return FuncID_debugCallV1
	case "runtime.gopanic":
		return FuncID_gopanic
	case "runtime.panicwrap":
		return FuncID_panicwrap
	case "runtime.handleAsyncEvent":
		return FuncID_handleAsyncEvent
	case "runtime.asyncPreempt":
		return FuncID_asyncPreempt
	case "runtime.deferreturn":
		// Don't show in the call stack (used when invoking defer functions)
		return FuncID_wrapper
	case "runtime.runOpenDeferFrame":
		// Don't show in the call stack (used when invoking defer functions)
		return FuncID_wrapper
	case "runtime.reflectcallSave":
		// Don't show in the call stack (used when invoking defer functions)
		return FuncID_wrapper
	}
	if file == "<autogenerated>" {
		return FuncID_wrapper
	}
	if strings.HasPrefix(name, "runtime.call") {
		if _, err := strconv.Atoi(name[12:]); err == nil {
			// runtime.callXX reflect call wrappers.
			return FuncID_wrapper
		}
	}
	if strings.HasSuffix(name, "-fm") {
		return FuncID_wrapper
	}
	return FuncID_normal
}

// HeadType is the executable header type.
type HeadType uint8

const (
	Hunknown HeadType = iota
	Hdarwin
	Hdragonfly
	Hfreebsd
	Hjs
	Hlinux
	Hnetbsd
	Hopenbsd
	Hplan9
	Hsolaris
	Hwindows
	Haix
)

func (h *HeadType) Set(s string) error {
	switch s {
	case "aix":
		*h = Haix
	case "darwin":
		*h = Hdarwin
	case "dragonfly":
		*h = Hdragonfly
	case "freebsd":
		*h = Hfreebsd
	case "js":
		*h = Hjs
	case "linux", "android":
		*h = Hlinux
	case "netbsd":
		*h = Hnetbsd
	case "openbsd":
		*h = Hopenbsd
	case "plan9":
		*h = Hplan9
	case "illumos", "solaris":
		*h = Hsolaris
	case "windows":
		*h = Hwindows
	default:
		return fmt.Errorf("invalid headtype: %q", s)
	}
	return nil
}

func (h *HeadType) String() string {
	switch *h {
	case Haix:
		return "aix"
	case Hdarwin:
		return "darwin"
	case Hdragonfly:
		return "dragonfly"
	case Hfreebsd:
		return "freebsd"
	case Hjs:
		return "js"
	case Hlinux:
		return "linux"
	case Hnetbsd:
		return "netbsd"
	case Hopenbsd:
		return "openbsd"
	case Hplan9:
		return "plan9"
	case Hsolaris:
		return "solaris"
	case Hwindows:
		return "windows"
	}
	return fmt.Sprintf("HeadType(%d)", *h)
}

// WorkingDir returns the current working directory
// (or "/???" if the directory cannot be identified),
// with "/" as separator.
func WorkingDir() string {
	var path string
	path, _ = os.Getwd()
	if path == "" {
		path = "/???"
	}
	return filepath.ToSlash(path)
}

// AbsFile returns the absolute filename for file in the given directory,
// as rewritten by the rewrites argument.
// For unrewritten paths, AbsFile rewrites a leading $GOROOT prefix to the literal "$GOROOT".
// If the resulting path is the empty string, the result is "??".
//
// The rewrites argument is a ;-separated list of rewrites.
// Each rewrite is of the form "prefix" or "prefix=>replace",
// where prefix must match a leading sequence of path elements
// and is either removed entirely or replaced by the replacement.
func AbsFile(dir, file, rewrites string) string {
	abs := file
	if dir != "" && !filepath.IsAbs(file) {
		abs = filepath.Join(dir, file)
	}

	start := 0
	for i := 0; i <= len(rewrites); i++ {
		if i == len(rewrites) || rewrites[i] == ';' {
			if new, ok := applyRewrite(abs, rewrites[start:i]); ok {
				abs = new
				goto Rewritten
			}
			start = i + 1
		}
	}
	if hasPathPrefix(abs, GOROOT) {
		abs = "$GOROOT" + abs[len(GOROOT):]
	}

Rewritten:
	if abs == "" {
		abs = "??"
	}
	return abs
}

// applyRewrite applies the rewrite to the path,
// returning the rewritten path and a boolean
// indicating whether the rewrite applied at all.
func applyRewrite(path, rewrite string) (string, bool) {
	prefix, replace := rewrite, ""
	if j := strings.LastIndex(rewrite, "=>"); j >= 0 {
		prefix, replace = rewrite[:j], rewrite[j+len("=>"):]
	}

	if prefix == "" || !hasPathPrefix(path, prefix) {
		return path, false
	}
	if len(path) == len(prefix) {
		return replace, true
	}
	if replace == "" {
		return path[len(prefix)+1:], true
	}
	return replace + path[len(prefix):], true
}

// Does s have t as a path prefix?
// That is, does s == t or does s begin with t followed by a slash?
// For portability, we allow ASCII case folding, so that hasPathPrefix("a/b/c", "A/B") is true.
// Similarly, we allow slash folding, so that hasPathPrefix("a/b/c", "a\\b") is true.
// We do not allow full Unicode case folding, for fear of causing more confusion
// or harm than good. (For an example of the kinds of things that can go wrong,
// see http://article.gmane.org/gmane.linux.kernel/1853266.)
func hasPathPrefix(s string, t string) bool {
	if len(t) > len(s) {
		return false
	}
	var i int
	for i = 0; i < len(t); i++ {
		cs := int(s[i])
		ct := int(t[i])
		if 'A' <= cs && cs <= 'Z' {
			cs += 'a' - 'A'
		}
		if 'A' <= ct && ct <= 'Z' {
			ct += 'a' - 'A'
		}
		if cs == '\\' {
			cs = '/'
		}
		if ct == '\\' {
			ct = '/'
		}
		if cs != ct {
			return false
		}
	}
	return i >= len(s) || s[i] == '/' || s[i] == '\\'
}

// PathToPrefix converts raw string to the prefix that will be used in the
// symbol table. All control characters, space, '%' and '"', as well as
// non-7-bit clean bytes turn into %xx. The period needs escaping only in the
// last segment of the path, and it makes for happier users if we escape that as
// little as possible.
func PathToPrefix(s string) string {
	slash := strings.LastIndex(s, "/")
	// check for chars that need escaping
	n := 0
	for r := 0; r < len(s); r++ {
		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
			n++
		}
	}

	// quick exit
	if n == 0 {
		return s
	}

	// escape
	const hex = "0123456789abcdef"
	p := make([]byte, 0, len(s)+2*n)
	for r := 0; r < len(s); r++ {
		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
			p = append(p, '%', hex[c>>4], hex[c&0xF])
		} else {
			p = append(p, c)
		}
	}

	return string(p)
}

type RelocType int16

//go:generate stringer -type=RelocType
const (
	R_ADDR RelocType = 1 + iota
	// R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit
	// immediates in the low half of the instruction word), usually addis followed by
	// another add or a load, inserting the "high adjusted" 16 bits of the address of
	// the referenced symbol into the immediate field of the first instruction and the
	// low 16 bits into that of the second instruction.
	R_ADDRPOWER
	// R_ADDRARM64 relocates an adrp, add pair to compute the address of the
	// referenced symbol.
	R_ADDRARM64
	// R_ADDRMIPS (only used on mips/mips64) resolves to the low 16 bits of an external
	// address, by encoding it into the instruction.
	R_ADDRMIPS
	// R_ADDROFF resolves to a 32-bit offset from the beginning of the section
	// holding the data being relocated to the referenced symbol.
	R_ADDROFF
	// R_WEAKADDROFF resolves just like R_ADDROFF but is a weak relocation.
	// A weak relocation does not make the symbol it refers to reachable,
	// and is only honored by the linker if the symbol is in some other way
	// reachable.
	R_WEAKADDROFF
	R_SIZE
	R_CALL
	R_CALLARM
	R_CALLARM64
	R_CALLIND
	R_CALLPOWER
	// R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address
	// of a CALL (JAL) instruction, by encoding the address into the instruction.
	R_CALLMIPS
	// R_CALLRISCV marks RISC-V CALLs for stack checking.
	R_CALLRISCV
	R_CONST
	R_PCREL
	// R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the
	// thread-local symbol from the thread local base and is used to implement the
	// "local exec" model for tls access (r.Sym is not set on intel platforms but is
	// set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking).
	R_TLS_LE
	// R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT
	// slot containing the offset from the thread-local symbol from the thread local
	// base and is used to implemented the "initial exec" model for tls access (r.Sym
	// is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in
	// the linker when externally linking).
	R_TLS_IE
	R_GOTOFF
	R_PLT0
	R_PLT1
	R_PLT2
	R_USEFIELD
	// R_USETYPE resolves to an *rtype, but no relocation is created. The
	// linker uses this as a signal that the pointed-to type information
	// should be linked into the final binary, even if there are no other
	// direct references. (This is used for types reachable by reflection.)
	R_USETYPE
	// R_METHODOFF resolves to a 32-bit offset from the beginning of the section
	// holding the data being relocated to the referenced symbol.
	// It is a variant of R_ADDROFF used when linking from the uncommonType of a
	// *rtype, and may be set to zero by the linker if it determines the method
	// text is unreachable by the linked program.
	R_METHODOFF
	R_POWER_TOC
	R_GOTPCREL
	// R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address
	// of a JMP instruction, by encoding the address into the instruction.
	// The stack nosplit check ignores this since it is not a function call.
	R_JMPMIPS

	// R_DWARFSECREF resolves to the offset of the symbol from its section.
	// Target of relocation must be size 4 (in current implementation).
	R_DWARFSECREF

	// R_DWARFFILEREF resolves to an index into the DWARF .debug_line
	// file table for the specified file symbol. Must be applied to an
	// attribute of form DW_FORM_data4.
	R_DWARFFILEREF

	// Platform dependent relocations. Architectures with fixed width instructions
	// have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be
	// stuffed into a 32-bit instruction, so an address needs to be spread across
	// several instructions, and in turn this requires a sequence of relocations, each
	// updating a part of an instruction. This leads to relocation codes that are
	// inherently processor specific.

	// Arm64.

	// Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread
	// local base to the thread local variable defined by the referenced (thread
	// local) symbol. Error if the offset does not fit into 16 bits.
	R_ARM64_TLS_LE

	// Relocates an ADRP; LD64 instruction sequence to load the offset between
	// the thread local base and the thread local variable defined by the
	// referenced (thread local) symbol from the GOT.
	R_ARM64_TLS_IE

	// R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT
	// slot of the referenced symbol.
	R_ARM64_GOTPCREL

	// R_ARM64_GOT resolves a GOT-relative instruction sequence, usually an adrp
	// followed by another ld instruction.
	R_ARM64_GOT

	// R_ARM64_PCREL resolves a PC-relative addresses instruction sequence, usually an
	// adrp followed by another add instruction.
	R_ARM64_PCREL

	// R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address.
	R_ARM64_LDST8

	// R_ARM64_LDST32 sets a LD/ST immediate value to bits [11:2] of a local address.
	R_ARM64_LDST32

	// R_ARM64_LDST64 sets a LD/ST immediate value to bits [11:3] of a local address.
	R_ARM64_LDST64

	// R_ARM64_LDST128 sets a LD/ST immediate value to bits [11:4] of a local address.
	R_ARM64_LDST128

	// PPC64.

	// R_POWER_TLS_LE is used to implement the "local exec" model for tls
	// access. It resolves to the offset of the thread-local symbol from the
	// thread pointer (R13) and inserts this value into the low 16 bits of an
	// instruction word.
	R_POWER_TLS_LE

	// R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It
	// relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It
	// inserts to the offset of GOT slot for the thread-local symbol from the TOC (the
	// GOT slot is filled by the dynamic linker with the offset of the thread-local
	// symbol from the thread pointer (R13)).
	R_POWER_TLS_IE

	// R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as
	// accessing a particular thread-local symbol. It does not affect code generation
	// but is used by the system linker when relaxing "initial exec" model code to
	// "local exec" model code.
	R_POWER_TLS

	// R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second
	// instruction is a "DS-form" instruction, which has an immediate field occupying
	// bits [15:2] of the instruction word. Bits [15:2] of the address of the
	// relocated symbol are inserted into this field; it is an error if the last two
	// bits of the address are not 0.
	R_ADDRPOWER_DS

	// R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like
	// R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol
	// from the TOC rather than the symbol's address.
	R_ADDRPOWER_GOT

	// R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but
	// inserts the displacement from the place being relocated to the address of the
	// relocated symbol instead of just its address.
	R_ADDRPOWER_PCREL

	// R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but
	// inserts the offset from the TOC to the address of the relocated symbol
	// rather than the symbol's address.
	R_ADDRPOWER_TOCREL

	// R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like
	// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the
	// relocated symbol rather than the symbol's address.
	R_ADDRPOWER_TOCREL_DS

	// RISC-V.

	// R_RISCV_PCREL_ITYPE resolves a 32-bit PC-relative address using an
	// AUIPC + I-type instruction pair.
	R_RISCV_PCREL_ITYPE

	// R_RISCV_PCREL_STYPE resolves a 32-bit PC-relative address using an
	// AUIPC + S-type instruction pair.
	R_RISCV_PCREL_STYPE

	// R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses.
	// TODO(mundaym): remove once variants can be serialized - see issue 14218.
	R_PCRELDBL

	// R_ADDRMIPSU (only used on mips/mips64) resolves to the sign-adjusted "upper" 16
	// bits (bit 16-31) of an external address, by encoding it into the instruction.
	R_ADDRMIPSU
	// R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS
	// address (offset from thread pointer), by encoding it into the instruction.
	R_ADDRMIPSTLS

	// R_ADDRCUOFF resolves to a pointer-sized offset from the start of the
	// symbol's DWARF compile unit.
	R_ADDRCUOFF

	// R_WASMIMPORT resolves to the index of the WebAssembly function import.
	R_WASMIMPORT

	// R_XCOFFREF (only used on aix/ppc64) prevents garbage collection by ld
	// of a symbol. This isn't a real relocation, it can be placed in anywhere
	// in a symbol and target any symbols.
	R_XCOFFREF
)

// IsDirectCall reports whether r is a relocation for a direct call.
// A direct call is a CALL instruction that takes the target address
// as an immediate. The address is embedded into the instruction, possibly
// with limited width. An indirect call is a CALL instruction that takes
// the target address in register or memory.
func (r RelocType) IsDirectCall() bool {
	switch r {
	case R_CALL, R_CALLARM, R_CALLARM64, R_CALLMIPS, R_CALLPOWER, R_CALLRISCV:
		return true
	}
	return false
}

// IsDirectJump reports whether r is a relocation for a direct jump.
// A direct jump is a JMP instruction that takes the target address
// as an immediate. The address is embedded into the instruction, possibly
// with limited width. An indirect jump is a JMP instruction that takes
// the target address in register or memory.
func (r RelocType) IsDirectJump() bool {
	switch r {
	case R_JMPMIPS:
		return true
	}
	return false
}

// IsDirectCallOrJump reports whether r is a relocation for a direct
// call or a direct jump.
func (r RelocType) IsDirectCallOrJump() bool {
	return r.IsDirectCall() || r.IsDirectJump()
}

const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"

var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 219, 230, 240, 249, 262, 276, 290, 304, 320, 331, 344, 357, 371, 385, 400, 414, 428, 439, 453, 468, 485, 503, 524, 543, 562, 572, 583, 596, 607, 619, 629}

func (i RelocType) String() string {
	i -= 1
	if i < 0 || i >= RelocType(len(_RelocType_index)-1) {
		return "RelocType(" + strconv.FormatInt(int64(i+1), 10) + ")"
	}
	return _RelocType_name[_RelocType_index[i]:_RelocType_index[i+1]]
}

// For the linkers. Must match Go definitions.

const (
	STACKSYSTEM = 0
	StackSystem = STACKSYSTEM
	StackBig    = 4096
	StackSmall  = 128
)

const (
	StackPreempt = -1314 // 0xfff...fade
)

// Initialize StackGuard and StackLimit according to target system.
var StackGuard = 928*stackGuardMultiplier() + StackSystem

var StackLimit = StackGuard - StackSystem - StackSmall

// stackGuardMultiplier returns a multiplier to apply to the default
// stack guard size. Larger multipliers are used for non-optimized
// builds that have larger stack frames or for specific targets.
func stackGuardMultiplier() int {
	// On AIX, a larger stack is needed for syscalls.
	if GOOS == "aix" {
		return 2
	}
	return stackGuardMultiplierDefault
}

// A SymKind describes the kind of memory represented by a symbol.
type SymKind uint8

// Defined SymKind values.
// These are used to index into cmd/link/internal/sym/AbiSymKindToSymKind
//
// TODO(rsc): Give idiomatic Go names.
//go:generate stringer -type=SymKind
const (
	// An otherwise invalid zero value for the type
	Sxxx SymKind = iota
	// Executable instructions
	STEXT
	// Read only static data
	SRODATA
	// Static data that does not contain any pointers
	SNOPTRDATA
	// Static data
	SDATA
	// Statically data that is initially all 0s
	SBSS
	// Statically data that is initially all 0s and does not contain pointers
	SNOPTRBSS
	// Thread-local data that is initially all 0s
	STLSBSS
	// Debugging data
	SDWARFINFO
	SDWARFRANGE
	SDWARFLOC
	SDWARFLINES
	// ABI alias. An ABI alias symbol is an empty symbol with a
	// single relocation with 0 size that references the native
	// function implementation symbol.
	//
	// TODO(austin): Remove this and all uses once the compiler
	// generates real ABI wrappers rather than symbol aliases.
	SABIALIAS
	// Coverage instrumentation counter for libfuzzer.
	SLIBFUZZER_EXTRA_COUNTER
	// Update cmd/link/internal/sym/AbiSymKindToSymKind for new SymKind values.

)

func _() {
	// An "invalid array index" compiler error signifies that the constant values have changed.
	// Re-run the stringer command to generate them again.
	var x [1]struct{}
	_ = x[Sxxx-0]
	_ = x[STEXT-1]
	_ = x[SRODATA-2]
	_ = x[SNOPTRDATA-3]
	_ = x[SDATA-4]
	_ = x[SBSS-5]
	_ = x[SNOPTRBSS-6]
	_ = x[STLSBSS-7]
	_ = x[SDWARFINFO-8]
	_ = x[SDWARFRANGE-9]
	_ = x[SDWARFLOC-10]
	_ = x[SDWARFLINES-11]
	_ = x[SABIALIAS-12]
	_ = x[SLIBFUZZER_EXTRA_COUNTER-13]
}

const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIASSLIBFUZZER_EXTRA_COUNTER"

var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 61, 72, 81, 92, 101, 125}

func (i SymKind) String() string {
	if i >= SymKind(len(_SymKind_index)-1) {
		return "SymKind(" + strconv.FormatInt(int64(i), 10) + ")"
	}
	return _SymKind_name[_SymKind_index[i]:_SymKind_index[i+1]]
}

// Must match runtime and reflect.
// Included by cmd/gc.

const (
	KindBool = 1 + iota
	KindInt
	KindInt8
	KindInt16
	KindInt32
	KindInt64
	KindUint
	KindUint8
	KindUint16
	KindUint32
	KindUint64
	KindUintptr
	KindFloat32
	KindFloat64
	KindComplex64
	KindComplex128
	KindArray
	KindChan
	KindFunc
	KindInterface
	KindMap
	KindPtr
	KindSlice
	KindString
	KindStruct
	KindUnsafePointer
	KindDirectIface = 1 << 5
	KindGCProg      = 1 << 6
	KindMask        = (1 << 5) - 1
)

func envOr(key, value string) string {
	if x := os.Getenv(key); x != "" {
		return x
	}
	return value
}

var (
	defaultGOROOT string // set by linker

	GOROOT   = envOr("GOROOT", defaultGOROOT)
	GOARCH   = envOr("GOARCH", defaultGOARCH)
	GOOS     = envOr("GOOS", defaultGOOS)
	GO386    = envOr("GO386", defaultGO386)
	GOAMD64  = goamd64()
	GOARM    = goarm()
	GOMIPS   = gomips()
	GOMIPS64 = gomips64()
	GOPPC64  = goppc64()
	GOWASM   = gowasm()
	GO_LDSO  = defaultGO_LDSO
	Version  = version
)

const (
	ElfRelocOffset   = 256
	MachoRelocOffset = 2048           // reserve enough space for ELF relocations
	Go115AMD64       = "alignedjumps" // Should be "alignedjumps" or "normaljumps"; this replaces environment variable introduced in CL 219357.
)

// TODO(1.16): assuming no issues in 1.15 release, remove this and related constant.
func goamd64() string {
	return Go115AMD64
}

func goarm() int {
	switch v := envOr("GOARM", defaultGOARM); v {
	case "5":
		return 5
	case "6":
		return 6
	case "7":
		return 7
	}
	// Fail here, rather than validate at multiple call sites.
	log.Fatalf("Invalid GOARM value. Must be 5, 6, or 7.")
	panic("unreachable")
}

func gomips() string {
	switch v := envOr("GOMIPS", defaultGOMIPS); v {
	case "hardfloat", "softfloat":
		return v
	}
	log.Fatalf("Invalid GOMIPS value. Must be hardfloat or softfloat.")
	panic("unreachable")
}

func gomips64() string {
	switch v := envOr("GOMIPS64", defaultGOMIPS64); v {
	case "hardfloat", "softfloat":
		return v
	}
	log.Fatalf("Invalid GOMIPS64 value. Must be hardfloat or softfloat.")
	panic("unreachable")
}

func goppc64() int {
	switch v := envOr("GOPPC64", defaultGOPPC64); v {
	case "power8":
		return 8
	case "power9":
		return 9
	}
	log.Fatalf("Invalid GOPPC64 value. Must be power8 or power9.")
	panic("unreachable")
}

type gowasmFeatures struct {
	SignExt bool
	SatConv bool
}

func (f gowasmFeatures) String() string {
	var flags []string
	if f.SatConv {
		flags = append(flags, "satconv")
	}
	if f.SignExt {
		flags = append(flags, "signext")
	}
	return strings.Join(flags, ",")
}

func gowasm() (f gowasmFeatures) {
	for _, opt := range strings.Split(envOr("GOWASM", ""), ",") {
		switch opt {
		case "satconv":
			f.SatConv = true
		case "signext":
			f.SignExt = true
		case "":
			// ignore
		default:
			log.Fatalf("Invalid GOWASM value. No such feature: " + opt)
		}
	}
	return
}

func Getgoextlinkenabled() string {
	return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
}

func init() {
	for _, f := range strings.Split(goexperiment, ",") {
		if f != "" {
			addexp(f)
		}
	}
}

func Framepointer_enabled(goos, goarch string) bool {
	return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && (goos == "linux" || goos == "darwin"))
}

func addexp(s string) {
	// Could do general integer parsing here, but the runtime copy doesn't yet.
	v := 1
	name := s
	if len(name) > 2 && name[:2] == "no" {
		v = 0
		name = name[2:]
	}
	for i := 0; i < len(exper); i++ {
		if exper[i].name == name {
			if exper[i].val != nil {
				*exper[i].val = v
			}
			return
		}
	}

	fmt.Printf("unknown experiment %s\n", s)
	os.Exit(2)
}

var (
	framepointer_enabled      int = 1
	Fieldtrack_enabled        int
	Preemptibleloops_enabled  int
	Staticlockranking_enabled int
)

// Toolchain experiments.
// These are controlled by the GOEXPERIMENT environment
// variable recorded when the toolchain is built.
// This list is also known to cmd/gc.
var exper = []struct {
	name string
	val  *int
}{
	{"fieldtrack", &Fieldtrack_enabled},
	{"framepointer", &framepointer_enabled},
	{"preemptibleloops", &Preemptibleloops_enabled},
	{"staticlockranking", &Staticlockranking_enabled},
}

var defaultExpstring = Expstring()

func DefaultExpstring() string {
	return defaultExpstring
}

func Expstring() string {
	buf := "X"
	for i := range exper {
		if *exper[i].val != 0 {
			buf += "," + exper[i].name
		}
	}
	if buf == "X" {
		buf += ",none"
	}
	return "X:" + buf[2:]
}

const defaultGO386 = `sse2`

const defaultGOARM = `5`

const defaultGOMIPS = `hardfloat`

const defaultGOMIPS64 = `hardfloat`

const defaultGOPPC64 = `power8`

const defaultGOOS = runtime.GOOS

const defaultGOARCH = runtime.GOARCH

const defaultGO_EXTLINK_ENABLED = ``

const defaultGO_LDSO = ``

const version = `devel +11f92e9 Mon Jul 20 18:18:56 2020 +0000`

const stackGuardMultiplierDefault = 1

const goexperiment = ``
