summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/gops/internal/obj/link.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/google/gops/internal/obj/link.go')
-rw-r--r--vendor/github.com/google/gops/internal/obj/link.go974
1 files changed, 0 insertions, 974 deletions
diff --git a/vendor/github.com/google/gops/internal/obj/link.go b/vendor/github.com/google/gops/internal/obj/link.go
deleted file mode 100644
index e2530615..00000000
--- a/vendor/github.com/google/gops/internal/obj/link.go
+++ /dev/null
@@ -1,974 +0,0 @@
-// Derived from Inferno utils/6l/l.h and related files.
-// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
-//
-// 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 (
- "bufio"
- "fmt"
-
- "github.com/google/gops/internal/sys"
-)
-
-// An Addr is an argument to an instruction.
-// The general forms and their encodings are:
-//
-// sym±offset(symkind)(reg)(index*scale)
-// Memory reference at address &sym(symkind) + offset + reg + index*scale.
-// Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted.
-// If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg).
-// To force a parsing as index*scale, write (index*1).
-// Encoding:
-// type = TYPE_MEM
-// name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE)
-// sym = sym
-// offset = ±offset
-// reg = reg (REG_*)
-// index = index (REG_*)
-// scale = scale (1, 2, 4, 8)
-//
-// $<mem>
-// Effective address of memory reference <mem>, defined above.
-// Encoding: same as memory reference, but type = TYPE_ADDR.
-//
-// $<±integer value>
-// This is a special case of $<mem>, in which only ±offset is present.
-// It has a separate type for easy recognition.
-// Encoding:
-// type = TYPE_CONST
-// offset = ±integer value
-//
-// *<mem>
-// Indirect reference through memory reference <mem>, defined above.
-// Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function
-// pointer stored in the data word sym(SB), not a function named sym(SB).
-// Encoding: same as above, but type = TYPE_INDIR.
-//
-// $*$<mem>
-// No longer used.
-// On machines with actual SB registers, $*$<mem> forced the
-// instruction encoding to use a full 32-bit constant, never a
-// reference relative to SB.
-//
-// $<floating point literal>
-// Floating point constant value.
-// Encoding:
-// type = TYPE_FCONST
-// val = floating point value
-//
-// $<string literal, up to 8 chars>
-// String literal value (raw bytes used for DATA instruction).
-// Encoding:
-// type = TYPE_SCONST
-// val = string
-//
-// <register name>
-// Any register: integer, floating point, control, segment, and so on.
-// If looking for specific register kind, must check type and reg value range.
-// Encoding:
-// type = TYPE_REG
-// reg = reg (REG_*)
-//
-// x(PC)
-// Encoding:
-// type = TYPE_BRANCH
-// val = Prog* reference OR ELSE offset = target pc (branch takes priority)
-//
-// $±x-±y
-// Final argument to TEXT, specifying local frame size x and argument size y.
-// In this form, x and y are integer literals only, not arbitrary expressions.
-// This avoids parsing ambiguities due to the use of - as a separator.
-// The ± are optional.
-// If the final argument to TEXT omits the -±y, the encoding should still
-// use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown.
-// Encoding:
-// type = TYPE_TEXTSIZE
-// offset = x
-// val = int32(y)
-//
-// reg<<shift, reg>>shift, reg->shift, reg@>shift
-// Shifted register value, for ARM and ARM64.
-// In this form, reg must be a register and shift can be a register or an integer constant.
-// Encoding:
-// type = TYPE_SHIFT
-// On ARM:
-// offset = (reg&15) | shifttype<<5 | count
-// shifttype = 0, 1, 2, 3 for <<, >>, ->, @>
-// count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant.
-// On ARM64:
-// offset = (reg&31)<<16 | shifttype<<22 | (count&63)<<10
-// shifttype = 0, 1, 2 for <<, >>, ->
-//
-// (reg, reg)
-// A destination register pair. When used as the last argument of an instruction,
-// this form makes clear that both registers are destinations.
-// Encoding:
-// type = TYPE_REGREG
-// reg = first register
-// offset = second register
-//
-// [reg, reg, reg-reg]
-// Register list for ARM.
-// Encoding:
-// type = TYPE_REGLIST
-// offset = bit mask of registers in list; R0 is low bit.
-//
-// reg, reg
-// Register pair for ARM.
-// TYPE_REGREG2
-//
-// (reg+reg)
-// Register pair for PPC64.
-// Encoding:
-// type = TYPE_MEM
-// reg = first register
-// index = second register
-// scale = 1
-//
-type Addr struct {
- Reg int16
- Index int16
- Scale int16 // Sometimes holds a register.
- Type AddrType
- Name int8
- Class int8
- Offset int64
- Sym *LSym
-
- // argument value:
- // for TYPE_SCONST, a string
- // for TYPE_FCONST, a float64
- // for TYPE_BRANCH, a *Prog (optional)
- // for TYPE_TEXTSIZE, an int32 (optional)
- Val interface{}
-
- Node interface{} // for use by compiler
-}
-
-type AddrType uint8
-
-const (
- NAME_NONE = 0 + iota
- NAME_EXTERN
- NAME_STATIC
- NAME_AUTO
- NAME_PARAM
- // A reference to name@GOT(SB) is a reference to the entry in the global offset
- // table for 'name'.
- NAME_GOTREF
-)
-
-const (
- TYPE_NONE AddrType = 0
-
- TYPE_BRANCH AddrType = 5 + iota
- TYPE_TEXTSIZE
- TYPE_MEM
- TYPE_CONST
- TYPE_FCONST
- TYPE_SCONST
- TYPE_REG
- TYPE_ADDR
- TYPE_SHIFT
- TYPE_REGREG
- TYPE_REGREG2
- TYPE_INDIR
- TYPE_REGLIST
-)
-
-// Prog describes a single machine instruction.
-//
-// The general instruction form is:
-//
-// As.Scond From, Reg, From3, To, RegTo2
-//
-// where As is an opcode and the others are arguments:
-// From, Reg, From3 are sources, and To, RegTo2 are destinations.
-// Usually, not all arguments are present.
-// For example, MOVL R1, R2 encodes using only As=MOVL, From=R1, To=R2.
-// The Scond field holds additional condition bits for systems (like arm)
-// that have generalized conditional execution.
-//
-// Jump instructions use the Pcond field to point to the target instruction,
-// which must be in the same linked list as the jump instruction.
-//
-// The Progs for a given function are arranged in a list linked through the Link field.
-//
-// Each Prog is charged to a specific source line in the debug information,
-// specified by Lineno, an index into the line history (see LineHist).
-// Every Prog has a Ctxt field that defines various context, including the current LineHist.
-// Progs should be allocated using ctxt.NewProg(), not new(Prog).
-//
-// The other fields not yet mentioned are for use by the back ends and should
-// be left zeroed by creators of Prog lists.
-type Prog struct {
- Ctxt *Link // linker context
- Link *Prog // next Prog in linked list
- From Addr // first source operand
- From3 *Addr // third source operand (second is Reg below)
- To Addr // destination operand (second is RegTo2 below)
- Pcond *Prog // target of conditional jump
- Opt interface{} // available to optimization passes to hold per-Prog state
- Forwd *Prog // for x86 back end
- Rel *Prog // for x86, arm back ends
- Pc int64 // for back ends or assembler: virtual or actual program counter, depending on phase
- Lineno int32 // line number of this instruction
- Spadj int32 // effect of instruction on stack pointer (increment or decrement amount)
- As As // assembler opcode
- Reg int16 // 2nd source operand
- RegTo2 int16 // 2nd destination operand
- Mark uint16 // bitmask of arch-specific items
- Optab uint16 // arch-specific opcode index
- Scond uint8 // condition bits for conditional instruction (e.g., on ARM)
- Back uint8 // for x86 back end: backwards branch state
- Ft uint8 // for x86 back end: type index of Prog.From
- Tt uint8 // for x86 back end: type index of Prog.To
- Isize uint8 // for x86 back end: size of the instruction in bytes
- Mode int8 // for x86 back end: 32- or 64-bit mode
-}
-
-// From3Type returns From3.Type, or TYPE_NONE when From3 is nil.
-func (p *Prog) From3Type() AddrType {
- if p.From3 == nil {
- return TYPE_NONE
- }
- return p.From3.Type
-}
-
-// From3Offset returns From3.Offset, or 0 when From3 is nil.
-func (p *Prog) From3Offset() int64 {
- if p.From3 == nil {
- return 0
- }
- return p.From3.Offset
-}
-
-// An As denotes an assembler opcode.
-// There are some portable opcodes, declared here in package obj,
-// that are common to all architectures.
-// However, the majority of opcodes are arch-specific
-// and are declared in their respective architecture's subpackage.
-type As int16
-
-// These are the portable opcodes.
-const (
- AXXX As = iota
- ACALL
- ADUFFCOPY
- ADUFFZERO
- AEND
- AFUNCDATA
- AJMP
- ANOP
- APCDATA
- ARET
- ATEXT
- ATYPE
- AUNDEF
- AUSEFIELD
- AVARDEF
- AVARKILL
- AVARLIVE
- A_ARCHSPECIFIC
-)
-
-// Each architecture is allotted a distinct subspace of opcode values
-// for declaring its arch-specific opcodes.
-// Within this subspace, the first arch-specific opcode should be
-// at offset A_ARCHSPECIFIC.
-//
-// Subspaces are aligned to a power of two so opcodes can be masked
-// with AMask and used as compact array indices.
-const (
- ABase386 = (1 + iota) << 10
- ABaseARM
- ABaseAMD64
- ABasePPC64
- ABaseARM64
- ABaseMIPS64
- ABaseS390X
-
- AllowedOpCodes = 1 << 10 // The number of opcodes available for any given architecture.
- AMask = AllowedOpCodes - 1 // AND with this to use the opcode as an array index.
-)
-
-// An LSym is the sort of symbol that is written to an object file.
-type LSym struct {
- Name string
- Type SymKind
- Version int16
- Attribute
-
- RefIdx int // Index of this symbol in the symbol reference list.
- Args int32
- Locals int32
- Size int64
- Gotype *LSym
- Autom *Auto
- Text *Prog
- Pcln *Pcln
- P []byte
- R []Reloc
-}
-
-// Attribute is a set of symbol attributes.
-type Attribute int16
-
-const (
- AttrDuplicateOK Attribute = 1 << iota
- AttrCFunc
- AttrNoSplit
- AttrLeaf
- AttrSeenGlobl
- AttrOnList
-
- // MakeTypelink means that the type should have an entry in the typelink table.
- AttrMakeTypelink
-
- // ReflectMethod means the function may call reflect.Type.Method or
- // reflect.Type.MethodByName. Matching is imprecise (as reflect.Type
- // can be used through a custom interface), so ReflectMethod may be
- // set in some cases when the reflect package is not called.
- //
- // Used by the linker to determine what methods can be pruned.
- AttrReflectMethod
-
- // Local means make the symbol local even when compiling Go code to reference Go
- // symbols in other shared libraries, as in this mode symbols are global by
- // default. "local" here means in the sense of the dynamic linker, i.e. not
- // visible outside of the module (shared library or executable) that contains its
- // definition. (When not compiling to support Go shared libraries, all symbols are
- // local in this sense unless there is a cgo_export_* directive).
- AttrLocal
-)
-
-func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
-func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 }
-func (a Attribute) CFunc() bool { return a&AttrCFunc != 0 }
-func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 }
-func (a Attribute) Leaf() bool { return a&AttrLeaf != 0 }
-func (a Attribute) SeenGlobl() bool { return a&AttrSeenGlobl != 0 }
-func (a Attribute) OnList() bool { return a&AttrOnList != 0 }
-func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 }
-func (a Attribute) Local() bool { return a&AttrLocal != 0 }
-
-func (a *Attribute) Set(flag Attribute, value bool) {
- if value {
- *a |= flag
- } else {
- *a &^= flag
- }
-}
-
-// The compiler needs LSym to satisfy fmt.Stringer, because it stores
-// an LSym in ssa.ExternSymbol.
-func (s *LSym) String() string {
- return s.Name
-}
-
-type Pcln struct {
- Pcsp Pcdata
- Pcfile Pcdata
- Pcline Pcdata
- Pcdata []Pcdata
- Funcdata []*LSym
- Funcdataoff []int64
- File []*LSym
- Lastfile *LSym
- Lastindex int
-}
-
-// A SymKind describes the kind of memory represented by a symbol.
-type SymKind int16
-
-// Defined SymKind values.
-//
-// TODO(rsc): Give idiomatic Go names.
-// TODO(rsc): Reduce the number of symbol types in the object files.
-//go:generate stringer -type=SymKind
-const (
- Sxxx SymKind = iota
- STEXT
- SELFRXSECT
-
- // Read-only sections.
- STYPE
- SSTRING
- SGOSTRING
- SGOFUNC
- SGCBITS
- SRODATA
- SFUNCTAB
-
- SELFROSECT
- SMACHOPLT
-
- // Read-only sections with relocations.
- //
- // Types STYPE-SFUNCTAB above are written to the .rodata section by default.
- // When linking a shared object, some conceptually "read only" types need to
- // be written to by relocations and putting them in a section called
- // ".rodata" interacts poorly with the system linkers. The GNU linkers
- // support this situation by arranging for sections of the name
- // ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after
- // relocations have applied, so when the Go linker is creating a shared
- // object it checks all objects of the above types and bumps any object that
- // has a relocation to it to the corresponding type below, which are then
- // written to sections with appropriate magic names.
- STYPERELRO
- SSTRINGRELRO
- SGOSTRINGRELRO
- SGOFUNCRELRO
- SGCBITSRELRO
- SRODATARELRO
- SFUNCTABRELRO
-
- // Part of .data.rel.ro if it exists, otherwise part of .rodata.
- STYPELINK
- SITABLINK
- SSYMTAB
- SPCLNTAB
-
- // Writable sections.
- SELFSECT
- SMACHO
- SMACHOGOT
- SWINDOWS
- SELFGOT
- SNOPTRDATA
- SINITARR
- SDATA
- SBSS
- SNOPTRBSS
- STLSBSS
- SXREF
- SMACHOSYMSTR
- SMACHOSYMTAB
- SMACHOINDIRECTPLT
- SMACHOINDIRECTGOT
- SFILE
- SFILEPATH
- SCONST
- SDYNIMPORT
- SHOSTOBJ
- SDWARFSECT
- SDWARFINFO
- SSUB = SymKind(1 << 8)
- SMASK = SymKind(SSUB - 1)
- SHIDDEN = SymKind(1 << 9)
- SCONTAINER = SymKind(1 << 10) // has a sub-symbol
-)
-
-// ReadOnly are the symbol kinds that form read-only sections. In some
-// cases, if they will require relocations, they are transformed into
-// rel-ro sections using RelROMap.
-var ReadOnly = []SymKind{
- STYPE,
- SSTRING,
- SGOSTRING,
- SGOFUNC,
- SGCBITS,
- SRODATA,
- SFUNCTAB,
-}
-
-// RelROMap describes the transformation of read-only symbols to rel-ro
-// symbols.
-var RelROMap = map[SymKind]SymKind{
- STYPE: STYPERELRO,
- SSTRING: SSTRINGRELRO,
- SGOSTRING: SGOSTRINGRELRO,
- SGOFUNC: SGOFUNCRELRO,
- SGCBITS: SGCBITSRELRO,
- SRODATA: SRODATARELRO,
- SFUNCTAB: SFUNCTABRELRO,
-}
-
-type Reloc struct {
- Off int32
- Siz uint8
- Type RelocType
- Add int64
- Sym *LSym
-}
-
-type RelocType int32
-
-//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 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_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_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_DWARFREF resolves to the offset of the symbol from its section.
- R_DWARFREF
-
- // 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
-
- // 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
- // 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 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 the
- // relocated symbol rather than the symbol's address.
- R_ADDRPOWER_TOCREL_DS
-
- // 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 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
-)
-
-// IsDirectJump returns whether r is a relocation for a direct jump.
-// A direct jump is a CALL or JMP instruction that takes the target address
-// as immediate. The address is embedded into the instruction, possibly
-// with limited width.
-// An indirect jump is a CALL or JMP instruction that takes the target address
-// in register or memory.
-func (r RelocType) IsDirectJump() bool {
- switch r {
- case R_CALL, R_CALLARM, R_CALLARM64, R_CALLPOWER, R_CALLMIPS, R_JMPMIPS:
- return true
- }
- return false
-}
-
-type Auto struct {
- Asym *LSym
- Link *Auto
- Aoffset int32
- Name int16
- Gotype *LSym
-}
-
-// Auto.name
-const (
- A_AUTO = 1 + iota
- A_PARAM
-)
-
-type Pcdata struct {
- P []byte
-}
-
-// symbol version, incremented each time a file is loaded.
-// version==1 is reserved for savehist.
-const (
- HistVersion = 1
-)
-
-// Link holds the context for writing object code from a compiler
-// to be linker input or for reading that input into the linker.
-type Link struct {
- Headtype HeadType
- Arch *LinkArch
- Debugasm int32
- Debugvlog int32
- Debugdivmod int32
- Debugpcln int32
- Flag_shared bool
- Flag_dynlink bool
- Flag_optimize bool
- Bso *bufio.Writer
- Pathname string
- Hash map[SymVer]*LSym
- LineHist LineHist
- Imports []string
- Plists []*Plist
- Sym_div *LSym
- Sym_divu *LSym
- Sym_mod *LSym
- Sym_modu *LSym
- Plan9privates *LSym
- Curp *Prog
- Printp *Prog
- Blitrl *Prog
- Elitrl *Prog
- Rexflag int
- Vexflag int
- Rep int
- Repn int
- Lock int
- Asmode int
- AsmBuf AsmBuf // instruction buffer for x86
- Instoffset int64
- Autosize int32
- Armsize int32
- Pc int64
- DiagFunc func(string, ...interface{})
- Mode int
- Cursym *LSym
- Version int
- Errors int
-
- Framepointer_enabled bool
-
- // state for writing objects
- Text []*LSym
- Data []*LSym
-
- // Cache of Progs
- allocIdx int
- progs [10000]Prog
-}
-
-func (ctxt *Link) Diag(format string, args ...interface{}) {
- ctxt.Errors++
- ctxt.DiagFunc(format, args...)
-}
-
-func (ctxt *Link) Logf(format string, args ...interface{}) {
- fmt.Fprintf(ctxt.Bso, format, args...)
- ctxt.Bso.Flush()
-}
-
-// The smallest possible offset from the hardware stack pointer to a local
-// variable on the stack. Architectures that use a link register save its value
-// on the stack in the function prologue and so always have a pointer between
-// the hardware stack pointer and the local variable area.
-func (ctxt *Link) FixedFrameSize() int64 {
- switch ctxt.Arch.Family {
- case sys.AMD64, sys.I386:
- return 0
- case sys.PPC64:
- // PIC code on ppc64le requires 32 bytes of stack, and it's easier to
- // just use that much stack always on ppc64x.
- return int64(4 * ctxt.Arch.PtrSize)
- default:
- return int64(ctxt.Arch.PtrSize)
- }
-}
-
-type SymVer struct {
- Name string
- Version int // TODO: make int16 to match LSym.Version?
-}
-
-// LinkArch is the definition of a single architecture.
-type LinkArch struct {
- *sys.Arch
- Preprocess func(*Link, *LSym)
- Assemble func(*Link, *LSym)
- Follow func(*Link, *LSym)
- Progedit func(*Link, *Prog)
- UnaryDst map[As]bool // Instruction takes one operand, a destination.
-}
-
-// HeadType is the executable header type.
-type HeadType uint8
-
-const (
- Hunknown HeadType = iota
- Hdarwin
- Hdragonfly
- Hfreebsd
- Hlinux
- Hnacl
- Hnetbsd
- Hopenbsd
- Hplan9
- Hsolaris
- Hwindows
- Hwindowsgui
-)
-
-func (h *HeadType) Set(s string) error {
- switch s {
- case "darwin":
- *h = Hdarwin
- case "dragonfly":
- *h = Hdragonfly
- case "freebsd":
- *h = Hfreebsd
- case "linux", "android":
- *h = Hlinux
- case "nacl":
- *h = Hnacl
- case "netbsd":
- *h = Hnetbsd
- case "openbsd":
- *h = Hopenbsd
- case "plan9":
- *h = Hplan9
- case "solaris":
- *h = Hsolaris
- case "windows":
- *h = Hwindows
- case "windowsgui":
- *h = Hwindowsgui
- default:
- return fmt.Errorf("invalid headtype: %q", s)
- }
- return nil
-}
-
-func (h *HeadType) String() string {
- switch *h {
- case Hdarwin:
- return "darwin"
- case Hdragonfly:
- return "dragonfly"
- case Hfreebsd:
- return "freebsd"
- case Hlinux:
- return "linux"
- case Hnacl:
- return "nacl"
- case Hnetbsd:
- return "netbsd"
- case Hopenbsd:
- return "openbsd"
- case Hplan9:
- return "plan9"
- case Hsolaris:
- return "solaris"
- case Hwindows:
- return "windows"
- case Hwindowsgui:
- return "windowsgui"
- }
- return fmt.Sprintf("HeadType(%d)", *h)
-}
-
-// AsmBuf is a simple buffer to assemble variable-length x86 instructions into.
-type AsmBuf struct {
- buf [100]byte
- off int
-}
-
-// Put1 appends one byte to the end of the buffer.
-func (a *AsmBuf) Put1(x byte) {
- a.buf[a.off] = x
- a.off++
-}
-
-// Put2 appends two bytes to the end of the buffer.
-func (a *AsmBuf) Put2(x, y byte) {
- a.buf[a.off+0] = x
- a.buf[a.off+1] = y
- a.off += 2
-}
-
-// Put3 appends three bytes to the end of the buffer.
-func (a *AsmBuf) Put3(x, y, z byte) {
- a.buf[a.off+0] = x
- a.buf[a.off+1] = y
- a.buf[a.off+2] = z
- a.off += 3
-}
-
-// Put4 appends four bytes to the end of the buffer.
-func (a *AsmBuf) Put4(x, y, z, w byte) {
- a.buf[a.off+0] = x
- a.buf[a.off+1] = y
- a.buf[a.off+2] = z
- a.buf[a.off+3] = w
- a.off += 4
-}
-
-// PutInt16 writes v into the buffer using little-endian encoding.
-func (a *AsmBuf) PutInt16(v int16) {
- a.buf[a.off+0] = byte(v)
- a.buf[a.off+1] = byte(v >> 8)
- a.off += 2
-}
-
-// PutInt32 writes v into the buffer using little-endian encoding.
-func (a *AsmBuf) PutInt32(v int32) {
- a.buf[a.off+0] = byte(v)
- a.buf[a.off+1] = byte(v >> 8)
- a.buf[a.off+2] = byte(v >> 16)
- a.buf[a.off+3] = byte(v >> 24)
- a.off += 4
-}
-
-// PutInt64 writes v into the buffer using little-endian encoding.
-func (a *AsmBuf) PutInt64(v int64) {
- a.buf[a.off+0] = byte(v)
- a.buf[a.off+1] = byte(v >> 8)
- a.buf[a.off+2] = byte(v >> 16)
- a.buf[a.off+3] = byte(v >> 24)
- a.buf[a.off+4] = byte(v >> 32)
- a.buf[a.off+5] = byte(v >> 40)
- a.buf[a.off+6] = byte(v >> 48)
- a.buf[a.off+7] = byte(v >> 56)
- a.off += 8
-}
-
-// Put copies b into the buffer.
-func (a *AsmBuf) Put(b []byte) {
- copy(a.buf[a.off:], b)
- a.off += len(b)
-}
-
-// Insert inserts b at offset i.
-func (a *AsmBuf) Insert(i int, b byte) {
- a.off++
- copy(a.buf[i+1:a.off], a.buf[i:a.off-1])
- a.buf[i] = b
-}
-
-// Last returns the byte at the end of the buffer.
-func (a *AsmBuf) Last() byte { return a.buf[a.off-1] }
-
-// Len returns the length of the buffer.
-func (a *AsmBuf) Len() int { return a.off }
-
-// Bytes returns the contents of the buffer.
-func (a *AsmBuf) Bytes() []byte { return a.buf[:a.off] }
-
-// Reset empties the buffer.
-func (a *AsmBuf) Reset() { a.off = 0 }
-
-// Peek returns the byte at offset i.
-func (a *AsmBuf) Peek(i int) byte { return a.buf[i] }