1
0
mirror of https://github.com/golang/go synced 2024-11-19 01:04:40 -07:00

cmd: add new common architecture representation

Information about CPU architectures (e.g., name, family, byte
ordering, pointer and register size) is currently redundantly
scattered around the source tree. Instead consolidate the basic
information into a single new package cmd/internal/sys.

Also, introduce new sys.I386, sys.AMD64, etc. names for the constants
'8', '6', etc. and replace most uses of the latter. The notable
exceptions are a couple of error messages that still refer to the old
char-based toolchain names and function reltype in cmd/link.

Passes toolstash/buildall.

Change-Id: I8a6f0cbd49577ec1672a98addebc45f767e36461
Reviewed-on: https://go-review.googlesource.com/21623
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Matthew Dempsky 2016-04-06 12:01:40 -07:00
parent 31cf1c1779
commit c6e11fe037
67 changed files with 639 additions and 743 deletions

View File

@ -13,6 +13,7 @@ import (
"cmd/asm/internal/flags"
"cmd/asm/internal/lex"
"cmd/internal/obj"
"cmd/internal/sys"
)
// TODO: configure the architecture
@ -23,14 +24,14 @@ var testOut *bytes.Buffer // Gathers output when testing.
// If doLabel is set, it also defines the labels collect for this Prog.
func (p *Parser) append(prog *obj.Prog, cond string, doLabel bool) {
if cond != "" {
switch p.arch.Thechar {
case '5':
switch p.arch.Family {
case sys.ARM:
if !arch.ARMConditionCodes(prog, cond) {
p.errorf("unrecognized condition code .%q", cond)
return
}
case '7':
case sys.ARM64:
if !arch.ARM64Suffix(prog, cond) {
p.errorf("unrecognized suffix .%q", cond)
return
@ -361,7 +362,7 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
target = &a[1]
prog.From = a[0]
case 3:
if p.arch.Thechar == '9' {
if p.arch.Family == sys.PPC64 {
// Special 3-operand jumps.
// First two must be constants; a[1] is a register number.
target = &a[2]
@ -378,7 +379,7 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
prog.Reg = reg
break
}
if p.arch.Thechar == '0' {
if p.arch.Family == sys.MIPS64 {
// 3-operand jumps.
// First two must be registers
target = &a[2]
@ -386,7 +387,7 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
prog.Reg = p.getRegister(prog, op, &a[1])
break
}
if p.arch.Thechar == 'z' {
if p.arch.Family == sys.S390X {
// 3-operand jumps.
target = &a[2]
prog.From = a[0]
@ -438,7 +439,7 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
// JMP 4(R0)
prog.To = *target
// On the ppc64, 9a encodes BR (CTR) as BR CTR. We do the same.
if p.arch.Thechar == '9' && target.Offset == 0 {
if p.arch.Family == sys.PPC64 && target.Offset == 0 {
prog.To.Type = obj.TYPE_REG
}
case target.Type == obj.TYPE_CONST:
@ -492,14 +493,14 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.From = a[0]
// prog.To is no address.
}
if p.arch.Thechar == '9' && arch.IsPPC64NEG(op) {
if p.arch.Family == sys.PPC64 && arch.IsPPC64NEG(op) {
// NEG: From and To are both a[0].
prog.To = a[0]
prog.From = a[0]
break
}
case 2:
if p.arch.Thechar == '5' {
if p.arch.Family == sys.ARM {
if arch.IsARMCMP(op) {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
@ -532,11 +533,11 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.Reg = p.getRegister(prog, op, &a[1])
break
}
} else if p.arch.Thechar == '7' && arch.IsARM64CMP(op) {
} else if p.arch.Family == sys.ARM64 && arch.IsARM64CMP(op) {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
break
} else if p.arch.Thechar == '0' {
} else if p.arch.Family == sys.MIPS64 {
if arch.IsMIPS64CMP(op) || arch.IsMIPS64MUL(op) {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
@ -546,12 +547,12 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.From = a[0]
prog.To = a[1]
case 3:
switch p.arch.Thechar {
case '0':
switch p.arch.Family {
case sys.MIPS64:
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.To = a[2]
case '5':
case sys.ARM:
// Special cases.
if arch.IsARMSTREX(op) {
/*
@ -567,7 +568,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.To = a[2]
case '7':
case sys.ARM64:
// ARM64 instructions with one input and two outputs.
if arch.IsARM64STLXR(op) {
prog.From = a[0]
@ -582,11 +583,11 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.To = a[2]
case '6', '8':
case sys.AMD64, sys.I386:
prog.From = a[0]
prog.From3 = newAddr(a[1])
prog.To = a[2]
case '9':
case sys.PPC64:
if arch.IsPPC64CMP(op) {
// CMPW etc.; third argument is a CR register that goes into prog.Reg.
prog.From = a[0]
@ -612,7 +613,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
p.errorf("invalid addressing modes for %s instruction", obj.Aconv(op))
return
}
case 'z':
case sys.S390X:
if arch.IsS390xWithLength(op) || arch.IsS390xWithIndex(op) {
prog.From = a[1]
prog.From3 = newAddr(a[0])
@ -626,7 +627,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
return
}
case 4:
if p.arch.Thechar == '5' && arch.IsARMMULA(op) {
if p.arch.Family == sys.ARM && arch.IsARMMULA(op) {
// All must be registers.
p.getRegister(prog, op, &a[0])
r1 := p.getRegister(prog, op, &a[1])
@ -639,14 +640,14 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.Reg = r1
break
}
if p.arch.Thechar == '7' {
if p.arch.Family == sys.ARM64 {
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
prog.From3 = newAddr(a[2])
prog.To = a[3]
break
}
if p.arch.Thechar == '9' && arch.IsPPC64RLD(op) {
if p.arch.Family == sys.PPC64 && arch.IsPPC64RLD(op) {
// 2nd operand must always be a register.
// TODO: Do we need to guard this with the instruction type?
// That is, are there 4-operand instructions without this property?
@ -656,7 +657,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.To = a[3]
break
}
if p.arch.Thechar == 'z' {
if p.arch.Family == sys.S390X {
prog.From = a[1]
prog.Reg = p.getRegister(prog, op, &a[2])
prog.From3 = newAddr(a[0])
@ -666,7 +667,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
p.errorf("can't handle %s instruction with 4 operands", obj.Aconv(op))
return
case 5:
if p.arch.Thechar == '9' && arch.IsPPC64RLD(op) {
if p.arch.Family == sys.PPC64 && arch.IsPPC64RLD(op) {
// Always reg, reg, con, con, reg. (con, con is a 'mask').
prog.From = a[0]
prog.Reg = p.getRegister(prog, op, &a[1])
@ -688,7 +689,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
p.errorf("can't handle %s instruction with 5 operands", obj.Aconv(op))
return
case 6:
if p.arch.Thechar == '5' && arch.IsARMMRC(op) {
if p.arch.Family == sys.ARM && arch.IsARMMRC(op) {
// Strange special case: MCR, MRC.
prog.To.Type = obj.TYPE_CONST
x0 := p.getConstant(prog, op, &a[0])

View File

@ -19,6 +19,7 @@ import (
"cmd/asm/internal/flags"
"cmd/asm/internal/lex"
"cmd/internal/obj"
"cmd/internal/sys"
)
type Parser struct {
@ -130,7 +131,7 @@ func (p *Parser) line() bool {
for {
tok = p.lex.Next()
if len(operands) == 0 && len(items) == 0 {
if (p.arch.Thechar == '5' || p.arch.Thechar == '7') && tok == '.' {
if p.arch.InFamily(sys.ARM, sys.ARM64) && tok == '.' {
// ARM conditionals.
tok = p.lex.Next()
str := p.lex.Text()
@ -420,7 +421,7 @@ func (p *Parser) atStartOfRegister(name string) bool {
// We have consumed the register or R prefix.
func (p *Parser) atRegisterShift() bool {
// ARM only.
if p.arch.Thechar != '5' {
if p.arch.Family != sys.ARM {
return false
}
// R1<<...
@ -476,15 +477,14 @@ func (p *Parser) register(name string, prefix rune) (r1, r2 int16, scale int8, o
if c == ':' || c == ',' || c == '+' {
// 2nd register; syntax (R1+R2) etc. No two architectures agree.
// Check the architectures match the syntax.
char := p.arch.Thechar
switch p.next().ScanToken {
case ',':
if char != '5' && char != '7' {
if !p.arch.InFamily(sys.ARM, sys.ARM64) {
p.errorf("(register,register) not supported on this architecture")
return
}
case '+':
if char != '9' {
if p.arch.Family != sys.PPC64 {
p.errorf("(register+register) not supported on this architecture")
return
}
@ -649,7 +649,7 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
a.Reg = r1
if r2 != 0 {
// TODO: Consistency in the encoding would be nice here.
if p.arch.Thechar == '5' || p.arch.Thechar == '7' {
if p.arch.InFamily(sys.ARM, sys.ARM64) {
// Special form
// ARM: destination register pair (R1, R2).
// ARM64: register pair (R1, R2) for LDP/STP.
@ -662,7 +662,7 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
// Nothing may follow
return
}
if p.arch.Thechar == '9' {
if p.arch.Family == sys.PPC64 {
// Special form for PPC64: (R1+R2); alias for (R1)(R2*1).
if prefix != 0 || scale != 0 {
p.errorf("illegal address mode for register+register")
@ -752,7 +752,7 @@ ListLoop:
// register number is ARM-specific. It returns the number of the specified register.
func (p *Parser) registerNumber(name string) uint16 {
if p.arch.Thechar == '5' && name == "g" {
if p.arch.Family == sys.ARM && name == "g" {
return 10
}
if name[0] != 'R' {

View File

@ -18,12 +18,7 @@ var (
)
func betypeinit() {
gc.Widthptr = 8
gc.Widthint = 8
gc.Widthreg = 8
if obj.Getgoarch() == "amd64p32" {
gc.Widthptr = 4
gc.Widthint = 4
addptr = x86.AADDL
movptr = x86.AMOVL
leaptr = x86.ALEAL
@ -42,12 +37,9 @@ func Main() {
resvd = append(resvd, x86.REG_BP)
}
gc.Thearch.Thechar = '6'
gc.Thearch.Thestring = "amd64"
gc.Thearch.Thelinkarch = &x86.Linkamd64
gc.Thearch.LinkArch = &x86.Linkamd64
if obj.Getgoarch() == "amd64p32" {
gc.Thearch.Thestring = "amd64p32"
gc.Thearch.Thelinkarch = &x86.Linkamd64p32
gc.Thearch.LinkArch = &x86.Linkamd64p32
}
gc.Thearch.REGSP = x86.REGSP
gc.Thearch.REGCTXT = x86.REGCTXT

View File

@ -11,15 +11,10 @@ import (
)
func betypeinit() {
gc.Widthptr = 4
gc.Widthint = 4
gc.Widthreg = 4
}
func Main() {
gc.Thearch.Thechar = '5'
gc.Thearch.Thestring = "arm"
gc.Thearch.Thelinkarch = &arm.Linkarm
gc.Thearch.LinkArch = &arm.Linkarm
gc.Thearch.REGSP = arm.REGSP
gc.Thearch.REGCTXT = arm.REGCTXT
gc.Thearch.REGCALLX = arm.REG_R1

View File

@ -10,15 +10,10 @@ import (
)
func betypeinit() {
gc.Widthptr = 8
gc.Widthint = 8
gc.Widthreg = 8
}
func Main() {
gc.Thearch.Thechar = '7'
gc.Thearch.Thestring = "arm64"
gc.Thearch.Thelinkarch = &arm64.Linkarm64
gc.Thearch.LinkArch = &arm64.Linkarm64
gc.Thearch.REGSP = arm64.REGSP
gc.Thearch.REGCTXT = arm64.REGCTXT
gc.Thearch.REGCALLX = arm64.REGRT1

View File

@ -7,6 +7,7 @@ package gc
import (
"cmd/internal/obj"
"cmd/internal/obj/ppc64"
"cmd/internal/sys"
"fmt"
)
@ -88,7 +89,7 @@ func cgen_wb(n, res *Node, wb bool) {
if !res.Addable {
if n.Ullman > res.Ullman {
if Ctxt.Arch.Regsize == 4 && Is64(n.Type) {
if Ctxt.Arch.RegSize == 4 && Is64(n.Type) {
var n1 Node
Tempname(&n1, n.Type)
Cgen(n, &n1)
@ -127,7 +128,7 @@ func cgen_wb(n, res *Node, wb bool) {
f = false
}
if !n.Type.IsComplex() && Ctxt.Arch.Regsize == 8 && !wb {
if !n.Type.IsComplex() && Ctxt.Arch.RegSize == 8 && !wb {
a := Thearch.Optoas(OAS, res.Type)
var addr obj.Addr
if Thearch.Sudoaddable(a, res, &addr) {
@ -151,7 +152,7 @@ func cgen_wb(n, res *Node, wb bool) {
}
}
if Ctxt.Arch.Thechar == '8' {
if Ctxt.Arch.Family == sys.I386 {
// no registers to speak of
var n1, n2 Node
Tempname(&n1, n.Type)
@ -203,7 +204,7 @@ func cgen_wb(n, res *Node, wb bool) {
// Write barrier now handled. Code below this line can ignore wb.
if Ctxt.Arch.Thechar == '5' { // TODO(rsc): Maybe more often?
if Ctxt.Arch.Family == sys.ARM { // TODO(rsc): Maybe more often?
// if both are addressable, move
if n.Addable && res.Addable {
if Is64(n.Type) || Is64(res.Type) || n.Op == OREGISTER || res.Op == OREGISTER || n.Type.IsComplex() || res.Type.IsComplex() {
@ -246,12 +247,12 @@ func cgen_wb(n, res *Node, wb bool) {
return
}
if (Ctxt.Arch.Thechar == '6' || Ctxt.Arch.Thechar == '8') && n.Addable {
if Ctxt.Arch.InFamily(sys.AMD64, sys.I386) && n.Addable {
Thearch.Gmove(n, res)
return
}
if Ctxt.Arch.Thechar == '0' || Ctxt.Arch.Thechar == '7' || Ctxt.Arch.Thechar == '9' {
if Ctxt.Arch.InFamily(sys.ARM64, sys.MIPS64, sys.PPC64) {
// if both are addressable, move
if n.Addable {
if n.Op == OREGISTER || res.Op == OREGISTER {
@ -268,7 +269,7 @@ func cgen_wb(n, res *Node, wb bool) {
}
// if n is sudoaddable generate addr and move
if Ctxt.Arch.Thechar == '5' && !Is64(n.Type) && !Is64(res.Type) && !n.Type.IsComplex() && !res.Type.IsComplex() {
if Ctxt.Arch.Family == sys.ARM && !Is64(n.Type) && !Is64(res.Type) && !n.Type.IsComplex() && !res.Type.IsComplex() {
a := Thearch.Optoas(OAS, n.Type)
var addr obj.Addr
if Thearch.Sudoaddable(a, n, &addr) {
@ -310,7 +311,7 @@ func cgen_wb(n, res *Node, wb bool) {
}
// 64-bit ops are hard on 32-bit machine.
if Ctxt.Arch.Regsize == 4 && (Is64(n.Type) || Is64(res.Type) || n.Left != nil && Is64(n.Left.Type)) {
if Ctxt.Arch.RegSize == 4 && (Is64(n.Type) || Is64(res.Type) || n.Left != nil && Is64(n.Left.Type)) {
switch n.Op {
// math goes to cgen64.
case OMINUS,
@ -334,7 +335,7 @@ func cgen_wb(n, res *Node, wb bool) {
return
}
if !n.Type.IsComplex() && Ctxt.Arch.Regsize == 8 {
if !n.Type.IsComplex() && Ctxt.Arch.RegSize == 8 {
a := Thearch.Optoas(OAS, n.Type)
var addr obj.Addr
if Thearch.Sudoaddable(a, n, &addr) {
@ -401,11 +402,11 @@ func cgen_wb(n, res *Node, wb bool) {
Regalloc(&n1, nl.Type, res)
Cgen(nl, &n1)
if Ctxt.Arch.Thechar == '5' {
if Ctxt.Arch.Family == sys.ARM {
var n2 Node
Nodconst(&n2, nl.Type, 0)
Thearch.Gins(a, &n2, &n1)
} else if Ctxt.Arch.Thechar == '7' {
} else if Ctxt.Arch.Family == sys.ARM64 {
Thearch.Gins(a, &n1, &n1)
} else {
Thearch.Gins(a, nil, &n1)
@ -452,7 +453,7 @@ func cgen_wb(n, res *Node, wb bool) {
return
}
if Ctxt.Arch.Thechar == '8' {
if Ctxt.Arch.Family == sys.I386 {
var n1 Node
var n2 Node
Tempname(&n2, n.Type)
@ -465,7 +466,7 @@ func cgen_wb(n, res *Node, wb bool) {
var n1 Node
var n2 Node
if Ctxt.Arch.Thechar == '5' {
if Ctxt.Arch.Family == sys.ARM {
if nl.Addable && !Is64(nl.Type) {
Regalloc(&n1, nl.Type, res)
Thearch.Gmove(nl, &n1)
@ -707,7 +708,7 @@ sbop: // symmetric binary
abop: // asymmetric binary
var n1 Node
var n2 Node
if Ctxt.Arch.Thechar == '8' {
if Ctxt.Arch.Family == sys.I386 {
// no registers, sigh
if Smallintconst(nr) {
var n1 Node
@ -751,14 +752,14 @@ abop: // asymmetric binary
Regalloc(&n1, nl.Type, res)
Cgen(nl, &n1)
if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' { // TODO(rsc): Check opcode for arm
if Smallintconst(nr) && Ctxt.Arch.Family != sys.MIPS64 && Ctxt.Arch.Family != sys.ARM && Ctxt.Arch.Family != sys.ARM64 && Ctxt.Arch.Family != sys.PPC64 { // TODO(rsc): Check opcode for arm
n2 = *nr
} else {
Regalloc(&n2, nr.Type, nil)
Cgen(nr, &n2)
}
} else {
if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' { // TODO(rsc): Check opcode for arm
if Smallintconst(nr) && Ctxt.Arch.Family != sys.MIPS64 && Ctxt.Arch.Family != sys.ARM && Ctxt.Arch.Family != sys.ARM64 && Ctxt.Arch.Family != sys.PPC64 { // TODO(rsc): Check opcode for arm
n2 = *nr
} else {
Regalloc(&n2, nr.Type, res)
@ -876,8 +877,8 @@ func cgen_wbfat(n, res *Node) {
// cgen_norm moves n1 to res, truncating to expected type if necessary.
// n1 is a register, and cgen_norm frees it.
func cgen_norm(n, n1, res *Node) {
switch Ctxt.Arch.Thechar {
case '6', '8':
switch Ctxt.Arch.Family {
case sys.AMD64, sys.I386:
// We use sized math, so the result is already truncated.
default:
switch n.Op {
@ -980,7 +981,7 @@ func Agenr(n *Node, a *Node, res *Node) {
Cgen_checknil(a)
case OINDEX:
if Ctxt.Arch.Thechar == '5' {
if Ctxt.Arch.Family == sys.ARM {
var p2 *obj.Prog // to be patched to panicindex.
w := uint32(n.Type.Width)
bounded := Debug['B'] != 0 || n.Bounded
@ -1127,7 +1128,7 @@ func Agenr(n *Node, a *Node, res *Node) {
Regfree(&n2)
break
}
if Ctxt.Arch.Thechar == '8' {
if Ctxt.Arch.Family == sys.I386 {
var p2 *obj.Prog // to be patched to panicindex.
w := uint32(n.Type.Width)
bounded := Debug['B'] != 0 || n.Bounded
@ -1604,7 +1605,7 @@ func Agen(n *Node, res *Node) {
}
func addOffset(res *Node, offset int64) {
if Ctxt.Arch.Thechar == '6' || Ctxt.Arch.Thechar == '8' {
if Ctxt.Arch.InFamily(sys.AMD64, sys.I386) {
Thearch.Gins(Thearch.Optoas(OADD, Types[Tptr]), Nodintconst(offset), res)
return
}
@ -1825,13 +1826,14 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
return
case ONAME:
// Some architectures might need a temporary or other help here,
// but they don't support direct generation of a bool value yet.
// We can fix that as we go.
mayNeedTemp := Ctxt.Arch.InFamily(sys.ARM, sys.ARM64, sys.MIPS64, sys.PPC64)
if genval {
// 5g, 7g, and 9g might need a temporary or other help here,
// but they don't support direct generation of a bool value yet.
// We can fix that as we go.
switch Ctxt.Arch.Thechar {
case '0', '5', '7', '9':
Fatalf("genval 0g, 5g, 7g, 9g ONAMES not fully implemented")
if mayNeedTemp {
Fatalf("genval ONAMES not fully implemented")
}
Cgen(n, res)
if !wantTrue {
@ -1840,7 +1842,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
return
}
if n.Addable && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '5' && Ctxt.Arch.Thechar != '7' && Ctxt.Arch.Thechar != '9' {
if n.Addable && !mayNeedTemp {
// no need for a temporary
bgenNonZero(n, nil, wantTrue, likely, to)
return
@ -1977,7 +1979,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
return
}
if Ctxt.Arch.Regsize == 4 && Is64(nr.Type) {
if Ctxt.Arch.RegSize == 4 && Is64(nr.Type) {
if genval {
// TODO: Teach Cmp64 to generate boolean values and remove this.
bvgenjump(n, res, wantTrue, false)
@ -2015,7 +2017,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
Regfree(&n2)
} else {
var n1 Node
if !nl.Addable && Ctxt.Arch.Thechar == '8' {
if !nl.Addable && Ctxt.Arch.Family == sys.I386 {
Tempname(&n1, nl.Type)
} else {
Regalloc(&n1, nl.Type, nil)
@ -2024,13 +2026,13 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
Cgen(nl, &n1)
nl = &n1
if Smallintconst(nr) && Ctxt.Arch.Thechar != '0' && Ctxt.Arch.Thechar != '9' {
if Smallintconst(nr) && Ctxt.Arch.Family != sys.MIPS64 && Ctxt.Arch.Family != sys.PPC64 {
Thearch.Gins(Thearch.Optoas(OCMP, nr.Type), nl, nr)
bins(nr.Type, res, op, likely, to)
return
}
if !nr.Addable && Ctxt.Arch.Thechar == '8' {
if !nr.Addable && Ctxt.Arch.Family == sys.I386 {
nr = CgenTemp(nr)
}
@ -2044,13 +2046,13 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
l, r := nl, nr
// On x86, only < and <= work right with NaN; reverse if needed
if Ctxt.Arch.Thechar == '6' && nl.Type.IsFloat() && (op == OGT || op == OGE) {
if Ctxt.Arch.Family == sys.AMD64 && nl.Type.IsFloat() && (op == OGT || op == OGE) {
l, r = r, l
op = Brrev(op)
}
// MIPS does not have CMP instruction
if Ctxt.Arch.Thechar == '0' {
if Ctxt.Arch.Family == sys.MIPS64 {
p := Thearch.Ginscmp(op, nr.Type, l, r, likely)
Patch(p, to)
return
@ -2062,8 +2064,8 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
// Handle floating point special cases.
// Note that 8g has Bgen_float and is handled above.
if nl.Type.IsFloat() {
switch Ctxt.Arch.Thechar {
case '5':
switch Ctxt.Arch.Family {
case sys.ARM:
if genval {
Fatalf("genval 5g Isfloat special cases not implemented")
}
@ -2077,7 +2079,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
Patch(p, Pc)
}
return
case '6':
case sys.AMD64:
switch n.Op {
case OEQ:
// neither NE nor P
@ -2111,7 +2113,7 @@ func bgenx(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
}
return
}
case '7', '9':
case sys.ARM64, sys.PPC64:
if genval {
Fatalf("genval 7g, 9g Isfloat special cases not implemented")
}
@ -2143,7 +2145,7 @@ func bgenNonZero(n, res *Node, wantTrue bool, likely int, to *obj.Prog) {
}
// MIPS does not have CMP instruction
if Thearch.Thechar == '0' {
if Thearch.LinkArch.Family == sys.MIPS64 {
p := Gbranch(Thearch.Optoas(op, n.Type), n.Type, likely)
Naddr(&p.From, n)
Patch(p, to)
@ -2352,7 +2354,7 @@ func Ginscall(f *Node, proc int) {
// into the instruction stream.
Thearch.Ginsnop()
if Thearch.Thechar == '9' {
if Thearch.LinkArch.Family == sys.PPC64 {
// On ppc64, when compiling Go into position
// independent code on ppc64le we insert an
// instruction to reload the TOC pointer from the
@ -2630,7 +2632,7 @@ func cgen_div(op Op, nl *Node, nr *Node, res *Node) {
// in peep and optoas in order to enable this.
// TODO(rsc): ppc64 needs to support the relevant instructions
// in peep and optoas in order to enable this.
if nr.Op != OLITERAL || Ctxt.Arch.Thechar == '0' || Ctxt.Arch.Thechar == '7' || Ctxt.Arch.Thechar == '9' {
if nr.Op != OLITERAL || Ctxt.Arch.Family == sys.MIPS64 || Ctxt.Arch.Family == sys.ARM64 || Ctxt.Arch.Family == sys.PPC64 {
goto longdiv
}
w = int(nl.Type.Width * 8)
@ -2995,7 +2997,7 @@ func cgen_slice(n, res *Node, wb bool) {
regalloc := Regalloc
ginscon := Thearch.Ginscon
gins := Thearch.Gins
if Thearch.Thechar == '8' {
if Thearch.LinkArch.Family == sys.I386 {
regalloc = func(n *Node, t *Type, reuse *Node) {
Tempname(n, t)
}
@ -3238,7 +3240,7 @@ func cgen_slice(n, res *Node, wb bool) {
compare := func(n1, n2 *Node) {
// n1 might be a 64-bit constant, even on 32-bit architectures,
// but it will be represented in 32 bits.
if Ctxt.Arch.Regsize == 4 && Is64(n1.Type) {
if Ctxt.Arch.RegSize == 4 && Is64(n1.Type) {
if n1.Val().U.(*Mpint).CmpInt64(1<<31) >= 0 {
Fatalf("missed slice out of bounds check")
}

View File

@ -8,6 +8,7 @@ package gc
import (
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
)
@ -1174,7 +1175,7 @@ func visitComponents(t *Type, startOffset int64, f func(elem *Type, elemOffset i
}
// NOTE: Assuming little endian (signed top half at offset 4).
// We don't have any 32-bit big-endian systems.
if Thearch.Thechar != '5' && Thearch.Thechar != '8' {
if !Thearch.LinkArch.InFamily(sys.ARM, sys.I386) {
Fatalf("unknown 32-bit architecture")
}
return f(Types[TUINT32], startOffset) &&

View File

@ -360,9 +360,8 @@ const (
)
type Arch struct {
Thechar int
Thestring string
Thelinkarch *obj.LinkArch
LinkArch *obj.LinkArch
REGSP int
REGCTXT int
REGCALLX int // BX

View File

@ -32,6 +32,7 @@ package gc
import (
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
"runtime"
"strings"
@ -57,7 +58,7 @@ func Ismem(n *Node) bool {
return true
case OADDR:
return Thearch.Thechar == '6' || Thearch.Thechar == '9' // because 6g uses PC-relative addressing; TODO(rsc): not sure why 9g too
return Thearch.LinkArch.InFamily(sys.AMD64, sys.PPC64) // because 6g uses PC-relative addressing; TODO(rsc): not sure why 9g too
}
return false
@ -83,7 +84,7 @@ func Gbranch(as obj.As, t *Type, likely int) *obj.Prog {
p := Prog(as)
p.To.Type = obj.TYPE_BRANCH
p.To.Val = nil
if as != obj.AJMP && likely != 0 && Thearch.Thechar != '9' && Thearch.Thechar != '7' && Thearch.Thechar != '0' {
if as != obj.AJMP && likely != 0 && Thearch.LinkArch.Family != sys.PPC64 && Thearch.LinkArch.Family != sys.ARM64 && Thearch.LinkArch.Family != sys.MIPS64 {
p.From.Type = obj.TYPE_CONST
if likely > 0 {
p.From.Offset = 1
@ -330,7 +331,7 @@ func Naddr(a *obj.Addr, n *Node) {
a.Type = obj.TYPE_REG
a.Reg = n.Reg
a.Sym = nil
if Thearch.Thechar == '8' { // TODO(rsc): Never clear a->width.
if Thearch.LinkArch.Family == sys.I386 { // TODO(rsc): Never clear a->width.
a.Width = 0
}
@ -342,7 +343,7 @@ func Naddr(a *obj.Addr, n *Node) {
if a.Offset != int64(int32(a.Offset)) {
Yyerror("offset %d too large for OINDREG", a.Offset)
}
if Thearch.Thechar == '8' { // TODO(rsc): Never clear a->width.
if Thearch.LinkArch.Family == sys.I386 { // TODO(rsc): Never clear a->width.
a.Width = 0
}
@ -424,7 +425,7 @@ func Naddr(a *obj.Addr, n *Node) {
Naddr(a, n.Left)
case OLITERAL:
if Thearch.Thechar == '8' {
if Thearch.LinkArch.Family == sys.I386 {
a.Width = 0
}
switch n.Val().Ctype() {
@ -457,7 +458,7 @@ func Naddr(a *obj.Addr, n *Node) {
case OADDR:
Naddr(a, n.Left)
a.Etype = uint8(Tptr)
if Thearch.Thechar != '0' && Thearch.Thechar != '5' && Thearch.Thechar != '7' && Thearch.Thechar != '9' { // TODO(rsc): Do this even for arm, ppc64.
if !Thearch.LinkArch.InFamily(sys.MIPS64, sys.ARM, sys.ARM64, sys.PPC64) { // TODO(rsc): Do this even for arm, ppc64.
a.Width = int64(Widthptr)
}
if a.Type != obj.TYPE_MEM {
@ -496,7 +497,7 @@ func Naddr(a *obj.Addr, n *Node) {
}
a.Etype = uint8(Simtype[TUINT])
a.Offset += int64(Array_nel)
if Thearch.Thechar != '5' { // TODO(rsc): Do this even on arm.
if Thearch.LinkArch.Family != sys.ARM { // TODO(rsc): Do this even on arm.
a.Width = int64(Widthint)
}
@ -509,7 +510,7 @@ func Naddr(a *obj.Addr, n *Node) {
}
a.Etype = uint8(Simtype[TUINT])
a.Offset += int64(Array_cap)
if Thearch.Thechar != '5' { // TODO(rsc): Do this even on arm.
if Thearch.LinkArch.Family != sys.ARM { // TODO(rsc): Do this even on arm.
a.Width = int64(Widthint)
}
}
@ -695,7 +696,7 @@ func Regalloc(n *Node, t *Type, o *Node) {
Fatalf("regalloc: t nil")
}
et := Simtype[t.Etype]
if Ctxt.Arch.Regsize == 4 && (et == TINT64 || et == TUINT64) {
if Ctxt.Arch.RegSize == 4 && (et == TINT64 || et == TUINT64) {
Fatalf("regalloc 64bit")
}

View File

@ -10,6 +10,7 @@ import (
"bufio"
"cmd/compile/internal/ssa"
"cmd/internal/obj"
"cmd/internal/sys"
"flag"
"fmt"
"io"
@ -96,12 +97,12 @@ func Main() {
// but not other values.
p := obj.Getgoarch()
if !strings.HasPrefix(p, Thearch.Thestring) {
log.Fatalf("cannot use %cg with GOARCH=%s", Thearch.Thechar, p)
if !strings.HasPrefix(p, Thearch.LinkArch.Name) {
log.Fatalf("cannot use %cg with GOARCH=%s", Thearch.LinkArch.Family, p)
}
goarch = p
Ctxt = obj.Linknew(Thearch.Thelinkarch)
Ctxt = obj.Linknew(Thearch.LinkArch)
Ctxt.DiagFunc = Yyerror
Ctxt.Bso = &bstdout
bstdout = *obj.Binitw(os.Stdout)
@ -200,15 +201,13 @@ func Main() {
obj.Flagcount("y", "debug declarations in canned imports (with -d)", &Debug['y'])
var flag_shared int
var flag_dynlink bool
switch Thearch.Thechar {
case '5', '6', '7', '8', '9':
if Thearch.LinkArch.InFamily(sys.ARM, sys.AMD64, sys.ARM64, sys.I386, sys.PPC64) {
obj.Flagcount("shared", "generate code that can be linked into a shared library", &flag_shared)
}
if Thearch.Thechar == '6' {
if Thearch.LinkArch.Family == sys.AMD64 {
obj.Flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel)
}
switch Thearch.Thechar {
case '5', '6', '7', '8', '9':
if Thearch.LinkArch.InFamily(sys.ARM, sys.AMD64, sys.ARM64, sys.I386, sys.PPC64) {
flag.BoolVar(&flag_dynlink, "dynlink", false, "support references to Go symbols defined in other shared libraries")
}
obj.Flagstr("cpuprofile", "write cpu profile to `file`", &cpuprofile)
@ -301,9 +300,9 @@ func Main() {
}
Thearch.Betypeinit()
if Widthptr == 0 {
Fatalf("betypeinit failed")
}
Widthint = Thearch.LinkArch.IntSize
Widthptr = Thearch.LinkArch.PtrSize
Widthreg = Thearch.LinkArch.RegSize
initUniverse()

View File

@ -7,6 +7,7 @@ package gc
import (
"cmd/compile/internal/ssa"
"cmd/internal/obj"
"cmd/internal/sys"
"crypto/md5"
"fmt"
"sort"
@ -286,7 +287,7 @@ func allocauto(ptxt *obj.Prog) {
if haspointers(n.Type) {
stkptrsize = Stksize
}
if Thearch.Thechar == '0' || Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
if Thearch.LinkArch.InFamily(sys.MIPS64, sys.ARM, sys.ARM64, sys.PPC64) {
Stksize = Rnd(Stksize, int64(Widthptr))
}
if Stksize >= 1<<31 {
@ -323,7 +324,7 @@ func Cgen_checknil(n *Node) {
Fatalf("bad checknil")
}
if ((Thearch.Thechar == '0' || Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9') && n.Op != OREGISTER) || !n.Addable || n.Op == OLITERAL {
if (Thearch.LinkArch.InFamily(sys.MIPS64, sys.ARM, sys.ARM64, sys.PPC64) && n.Op != OREGISTER) || !n.Addable || n.Op == OLITERAL {
var reg Node
Regalloc(&reg, Types[Tptr], n)
Cgen(n, &reg)

View File

@ -17,6 +17,7 @@ package gc
import (
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
"sort"
"strings"
@ -1396,7 +1397,7 @@ func livenessepilogue(lv *Liveness) {
// The instruction before a call to deferreturn is always a
// no-op, to keep PC-specific data unambiguous.
prev := p.Opt.(*obj.Prog)
if Ctxt.Arch.Thechar == '9' {
if Ctxt.Arch.Family == sys.PPC64 {
// On ppc64 there is an additional instruction
// (another no-op or reload of toc pointer) before
// the call.

View File

@ -33,6 +33,7 @@ package gc
import (
"bytes"
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
"sort"
"strings"
@ -249,7 +250,7 @@ func addmove(r *Flow, bn int, rn int, f int) {
p1.As = Thearch.Optoas(OAS, Types[uint8(v.etype)])
// TODO(rsc): Remove special case here.
if (Thearch.Thechar == '0' || Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9') && v.etype == TBOOL {
if Thearch.LinkArch.InFamily(sys.MIPS64, sys.ARM, sys.ARM64, sys.PPC64) && v.etype == TBOOL {
p1.As = Thearch.Optoas(OAS, Types[TUINT8])
}
p1.From.Type = obj.TYPE_REG
@ -302,7 +303,7 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
// TODO(rsc): Remove special case here.
case obj.TYPE_ADDR:
var bit Bits
if Thearch.Thechar == '0' || Thearch.Thechar == '5' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
if Thearch.LinkArch.InFamily(sys.MIPS64, sys.ARM, sys.ARM64, sys.PPC64) {
goto memcase
}
a.Type = obj.TYPE_MEM
@ -368,7 +369,7 @@ func mkvar(f *Flow, a *obj.Addr) Bits {
if v.etype == et {
if int64(v.width) == w {
// TODO(rsc): Remove special case for arm here.
if flag == 0 || Thearch.Thechar != '5' {
if flag == 0 || Thearch.LinkArch.Family != sys.ARM {
return blsh(uint(i))
}
}

View File

@ -13,6 +13,7 @@ import (
"cmd/compile/internal/ssa"
"cmd/internal/obj"
"cmd/internal/sys"
)
var ssaEnabled = true
@ -24,13 +25,13 @@ func initssa() *ssa.Config {
ssaExp.unimplemented = false
ssaExp.mustImplement = true
if ssaConfig == nil {
ssaConfig = ssa.NewConfig(Thearch.Thestring, &ssaExp, Ctxt, Debug['N'] == 0)
ssaConfig = ssa.NewConfig(Thearch.LinkArch.Name, &ssaExp, Ctxt, Debug['N'] == 0)
}
return ssaConfig
}
func shouldssa(fn *Node) bool {
switch Thearch.Thestring {
switch Thearch.LinkArch.Name {
default:
// Only available for testing.
if os.Getenv("SSATEST") == "" {
@ -2409,7 +2410,7 @@ func isSSAIntrinsic1(s *Sym) bool {
// so far has only been noticed for Bswap32 and the 16-bit count
// leading/trailing instructions, but heuristics might change
// in the future or on different architectures).
if !ssaEnabled || ssa.IntrinsicsDisable || Thearch.Thechar != '6' {
if !ssaEnabled || ssa.IntrinsicsDisable || Thearch.LinkArch.Family != sys.AMD64 {
return false
}
if s != nil && s.Pkg != nil && s.Pkg.Path == "runtime/internal/sys" {

View File

@ -6,6 +6,7 @@ package gc
import (
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
"strings"
)
@ -672,8 +673,7 @@ opswitch:
walkexprlist(n.List.Slice(), init)
if n.Left.Op == ONAME && n.Left.Sym.Name == "Sqrt" && n.Left.Sym.Pkg.Path == "math" {
switch Thearch.Thechar {
case '5', '6', '7', '9':
if Thearch.LinkArch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.PPC64) {
n.Op = OSQRT
n.Left = n.List.First()
n.List.Set(nil)
@ -1056,7 +1056,7 @@ opswitch:
n = walkexpr(n, init)
case OCONV, OCONVNOP:
if Thearch.Thechar == '5' {
if Thearch.LinkArch.Family == sys.ARM {
if n.Left.Type.IsFloat() {
if n.Type.Etype == TINT64 {
n = mkcall("float64toint64", n.Type, init, conv(n.Left, Types[TFLOAT64]))
@ -3274,7 +3274,7 @@ func samecheap(a *Node, b *Node) bool {
// The result of walkrotate MUST be assigned back to n, e.g.
// n.Left = walkrotate(n.Left)
func walkrotate(n *Node) *Node {
if Thearch.Thechar == '0' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
if Thearch.LinkArch.InFamily(sys.MIPS64, sys.ARM64, sys.PPC64) {
return n
}
@ -3401,7 +3401,7 @@ func walkdiv(n *Node, init *Nodes) *Node {
// if >= 0, nr is 1<<pow // 1 if nr is negative.
// TODO(minux)
if Thearch.Thechar == '0' || Thearch.Thechar == '7' || Thearch.Thechar == '9' {
if Thearch.LinkArch.InFamily(sys.MIPS64, sys.ARM64, sys.PPC64) {
return n
}

View File

@ -11,18 +11,12 @@ import (
)
func betypeinit() {
gc.Widthptr = 8
gc.Widthint = 8
gc.Widthreg = 8
}
func Main() {
gc.Thearch.Thechar = '0'
gc.Thearch.Thestring = "mips64"
gc.Thearch.Thelinkarch = &mips.Linkmips64
gc.Thearch.LinkArch = &mips.Linkmips64
if obj.Getgoarch() == "mips64le" {
gc.Thearch.Thestring = "mips64le"
gc.Thearch.Thelinkarch = &mips.Linkmips64le
gc.Thearch.LinkArch = &mips.Linkmips64le
}
gc.Thearch.REGSP = mips.REGSP
gc.Thearch.REGCTXT = mips.REGCTXT

View File

@ -11,10 +11,6 @@ import (
)
func betypeinit() {
gc.Widthptr = 8
gc.Widthint = 8
gc.Widthreg = 8
if gc.Ctxt.Flag_shared != 0 {
gc.Thearch.ReservedRegs = append(gc.Thearch.ReservedRegs, ppc64.REG_R2)
gc.Thearch.ReservedRegs = append(gc.Thearch.ReservedRegs, ppc64.REG_R12)
@ -22,12 +18,9 @@ func betypeinit() {
}
func Main() {
gc.Thearch.Thechar = '9'
gc.Thearch.Thestring = "ppc64"
gc.Thearch.Thelinkarch = &ppc64.Linkppc64
gc.Thearch.LinkArch = &ppc64.Linkppc64
if obj.Getgoarch() == "ppc64le" {
gc.Thearch.Thestring = "ppc64le"
gc.Thearch.Thelinkarch = &ppc64.Linkppc64le
gc.Thearch.LinkArch = &ppc64.Linkppc64le
}
gc.Thearch.REGSP = ppc64.REGSP
gc.Thearch.REGCTXT = ppc64.REGCTXT

View File

@ -13,15 +13,10 @@ import (
)
func betypeinit() {
gc.Widthptr = 4
gc.Widthint = 4
gc.Widthreg = 4
}
func Main() {
gc.Thearch.Thechar = '8'
gc.Thearch.Thestring = "386"
gc.Thearch.Thelinkarch = &x86.Link386
gc.Thearch.LinkArch = &x86.Link386
gc.Thearch.REGSP = x86.REGSP
gc.Thearch.REGCTXT = x86.REGCTXT
gc.Thearch.REGCALLX = x86.REG_BX

View File

@ -46,6 +46,7 @@ var bootstrapDirs = []string{
"internal/obj/ppc64",
"internal/obj/s390x",
"internal/obj/x86",
"internal/sys",
"link",
"link/internal/amd64",
"link/internal/arm",

View File

@ -32,7 +32,7 @@ package arm
import (
"cmd/internal/obj"
"encoding/binary"
"cmd/internal/sys"
"fmt"
"log"
"math"
@ -412,7 +412,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVW
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
p.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
@ -708,9 +708,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.As = AMOVW
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
if ctxt.Cursym.Cfunc {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
@ -1032,15 +1032,10 @@ var unaryDst = map[obj.As]bool{
}
var Linkarm = obj.LinkArch{
ByteOrder: binary.LittleEndian,
Name: "arm",
Thechar: '5',
Arch: sys.ArchARM,
Preprocess: preprocess,
Assemble: span5,
Follow: follow,
Progedit: progedit,
UnaryDst: unaryDst,
Minlc: 4,
Ptrsize: 4,
Regsize: 4,
}

View File

@ -32,7 +32,7 @@ package arm64
import (
"cmd/internal/obj"
"encoding/binary"
"cmd/internal/sys"
"fmt"
"log"
"math"
@ -56,9 +56,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.As = AMOVD
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
if ctxt.Cursym.Cfunc {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
@ -778,7 +778,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.As = AMOVD
q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG
q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R1
@ -941,15 +941,10 @@ var unaryDst = map[obj.As]bool{
}
var Linkarm64 = obj.LinkArch{
ByteOrder: binary.LittleEndian,
Name: "arm64",
Thechar: '7',
Arch: sys.ArchARM64,
Preprocess: preprocess,
Assemble: span7,
Follow: follow,
Progedit: progedit,
UnaryDst: unaryDst,
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}

View File

@ -110,7 +110,7 @@ func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) {
// WriteAddr writes an address of size siz into s at offset off.
// rsym and roff specify the relocation for the address.
func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
if siz != ctxt.Arch.Ptrsize {
if siz != ctxt.Arch.PtrSize {
ctxt.Diag("WriteAddr: bad address size: %d", siz)
}
s.prepwrite(ctxt, off, siz)

View File

@ -30,7 +30,7 @@
package obj
import "encoding/binary"
import "cmd/internal/sys"
// An Addr is an argument to an instruction.
// The general forms and their encodings are:
@ -682,15 +682,15 @@ func (ctxt *Link) Diag(format string, args ...interface{}) {
// 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.Thechar {
case '6', '8':
switch ctxt.Arch.Family {
case sys.AMD64, sys.I386:
return 0
case '9':
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)
return int64(4 * ctxt.Arch.PtrSize)
default:
return int64(ctxt.Arch.Ptrsize)
return int64(ctxt.Arch.PtrSize)
}
}
@ -701,17 +701,12 @@ type SymVer struct {
// LinkArch is the definition of a single architecture.
type LinkArch struct {
ByteOrder binary.ByteOrder
Name string
Thechar int
*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.
Minlc int
Ptrsize int
Regsize int
}
/* executable header types */

View File

@ -31,7 +31,7 @@ package mips
import (
"cmd/internal/obj"
"encoding/binary"
"cmd/internal/sys"
"fmt"
"math"
)
@ -336,7 +336,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.As = AMOVV
q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG
q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R1
@ -559,9 +559,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.As = AMOVV
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
if ctxt.Cursym.Cfunc {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
@ -1469,27 +1469,17 @@ loop:
}
var Linkmips64 = obj.LinkArch{
ByteOrder: binary.BigEndian,
Name: "mips64",
Thechar: '0',
Arch: sys.ArchMIPS64,
Preprocess: preprocess,
Assemble: span0,
Follow: follow,
Progedit: progedit,
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}
var Linkmips64le = obj.LinkArch{
ByteOrder: binary.LittleEndian,
Name: "mips64le",
Thechar: '0',
Arch: sys.ArchMIPS64LE,
Preprocess: preprocess,
Assemble: span0,
Follow: follow,
Progedit: progedit,
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}

View File

@ -109,6 +109,7 @@ package obj
import (
"bufio"
"cmd/internal/sys"
"fmt"
"log"
"path/filepath"
@ -556,7 +557,7 @@ func (w *objWriter) writeSymDebug(s *LSym) {
} else if r.Type == R_TLS_LE {
name = "TLS"
}
if ctxt.Arch.Thechar == '5' || ctxt.Arch.Thechar == '9' {
if ctxt.Arch.InFamily(sys.ARM, sys.PPC64) {
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(int64(r.Add)))
} else {
fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, int64(r.Add))

View File

@ -100,7 +100,7 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
}
if started != 0 {
addvarint(ctxt, dst, uint32((p.Pc-pc)/int64(ctxt.Arch.Minlc)))
addvarint(ctxt, dst, uint32((p.Pc-pc)/int64(ctxt.Arch.MinLC)))
pc = p.Pc
}
@ -120,7 +120,7 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
if ctxt.Debugpcln != 0 {
fmt.Fprintf(ctxt.Bso, "%6x done\n", uint64(int64(func_.Text.Pc)+func_.Size))
}
addvarint(ctxt, dst, uint32((func_.Size-pc)/int64(ctxt.Arch.Minlc)))
addvarint(ctxt, dst, uint32((func_.Size-pc)/int64(ctxt.Arch.MinLC)))
addvarint(ctxt, dst, 0) // terminator
}

View File

@ -31,7 +31,7 @@ package ppc64
import (
"cmd/internal/obj"
"encoding/binary"
"cmd/internal/sys"
"fmt"
"math"
)
@ -592,7 +592,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.As = AMOVD
q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG
q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3
@ -827,9 +827,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.As = AMOVD
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
if ctxt.Cursym.Cfunc {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
@ -1181,27 +1181,17 @@ loop:
}
var Linkppc64 = obj.LinkArch{
ByteOrder: binary.BigEndian,
Name: "ppc64",
Thechar: '9',
Arch: sys.ArchPPC64,
Preprocess: preprocess,
Assemble: span9,
Follow: follow,
Progedit: progedit,
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}
var Linkppc64le = obj.LinkArch{
ByteOrder: binary.LittleEndian,
Name: "ppc64le",
Thechar: '9',
Arch: sys.ArchPPC64LE,
Preprocess: preprocess,
Assemble: span9,
Follow: follow,
Progedit: progedit,
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}

View File

@ -31,7 +31,7 @@ package s390x
import (
"cmd/internal/obj"
"encoding/binary"
"cmd/internal/sys"
"fmt"
"math"
)
@ -460,7 +460,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.As = AMOVD
q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG
q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3
@ -664,9 +664,9 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
p.As = AMOVD
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
if ctxt.Cursym.Cfunc {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
@ -999,15 +999,10 @@ var unaryDst = map[obj.As]bool{
}
var Links390x = obj.LinkArch{
ByteOrder: binary.BigEndian,
Name: "s390x",
Thechar: 'z',
Arch: sys.ArchS390X,
Preprocess: preprocess,
Assemble: spanz,
Follow: follow,
Progedit: progedit,
UnaryDst: unaryDst,
Minlc: 2,
Ptrsize: 8,
Regsize: 8,
}

View File

@ -32,6 +32,7 @@
package obj
import (
"cmd/internal/sys"
"log"
"os"
"path/filepath"
@ -100,7 +101,7 @@ func Linknew(arch *LinkArch) *Link {
}
// On arm, record goarm.
if ctxt.Arch.Thechar == '5' {
if ctxt.Arch.Family == sys.ARM {
ctxt.Goarm = Getgoarm()
}

View File

@ -1754,7 +1754,7 @@ func naclpad(ctxt *obj.Link, s *obj.LSym, c int32, pad int32) int32 {
}
func spadjop(ctxt *obj.Link, p *obj.Prog, l, q obj.As) obj.As {
if p.Mode != 64 || ctxt.Arch.Ptrsize == 4 {
if p.Mode != 64 || ctxt.Arch.PtrSize == 4 {
return l
}
return q

View File

@ -32,7 +32,7 @@ package x86
import (
"cmd/internal/obj"
"encoding/binary"
"cmd/internal/sys"
"fmt"
"log"
"math"
@ -49,7 +49,7 @@ func CanUse1InsnTLS(ctxt *obj.Link) bool {
return true
}
if ctxt.Arch.Regsize == 4 {
if ctxt.Arch.RegSize == 4 {
switch ctxt.Headtype {
case obj.Hlinux,
obj.Hnacl,
@ -75,7 +75,7 @@ func CanUse1InsnTLS(ctxt *obj.Link) bool {
func progedit(ctxt *obj.Link, p *obj.Prog) {
// Maintain information about code generation mode.
if ctxt.Mode == 0 {
ctxt.Mode = ctxt.Arch.Regsize * 8
ctxt.Mode = ctxt.Arch.RegSize * 8
}
p.Mode = int8(ctxt.Mode)
@ -207,7 +207,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
}
// Rewrite MOVL/MOVQ $XXX(FP/SP) as LEAL/LEAQ.
if p.From.Type == obj.TYPE_ADDR && (ctxt.Arch.Thechar == '6' || p.From.Name != obj.NAME_EXTERN && p.From.Name != obj.NAME_STATIC) {
if p.From.Type == obj.TYPE_ADDR && (ctxt.Arch.Family == sys.AMD64 || p.From.Name != obj.NAME_EXTERN && p.From.Name != obj.NAME_STATIC) {
switch p.As {
case AMOVL:
p.As = ALEAL
@ -614,7 +614,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// Make room for to save a base pointer. If autoffset == 0,
// this might do something special like a tail jump to
// another function, so in that case we omit this.
bpsize = ctxt.Arch.Ptrsize
bpsize = ctxt.Arch.PtrSize
autoffset += int32(bpsize)
p.To.Offset += int64(bpsize)
@ -656,7 +656,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
}
if autoffset != 0 {
if autoffset%int32(ctxt.Arch.Regsize) != 0 {
if autoffset%int32(ctxt.Arch.RegSize) != 0 {
ctxt.Diag("unaligned stack size %d", autoffset)
}
p = obj.Appendp(ctxt, p)
@ -671,10 +671,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p = obj.Appendp(ctxt, p)
p.As = obj.ANOP
p.Spadj = int32(-ctxt.Arch.Ptrsize)
p.Spadj = int32(-ctxt.Arch.PtrSize)
p = obj.Appendp(ctxt, p)
p.As = obj.ANOP
p.Spadj = int32(ctxt.Arch.Ptrsize)
p.Spadj = int32(ctxt.Arch.PtrSize)
}
deltasp := autoffset
@ -724,7 +724,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.As = AMOVQ
p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_CX
p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic
p.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_BX
if ctxt.Headtype == obj.Hnacl && p.Mode == 64 {
@ -757,7 +757,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.As = ALEAQ
p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_SP
p.From.Offset = int64(autoffset) + int64(ctxt.Arch.Regsize)
p.From.Offset = int64(autoffset) + int64(ctxt.Arch.RegSize)
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_DI
if ctxt.Headtype == obj.Hnacl || p.Mode == 32 {
@ -935,7 +935,7 @@ func indir_cx(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
// Returns last new instruction.
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
p.As = AMOVQ
if ctxt.Arch.Ptrsize == 4 {
if ctxt.Arch.PtrSize == 4 {
p.As = AMOVL
}
p.From.Type = obj.TYPE_MEM
@ -984,9 +984,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32) *ob
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SP
indir_cx(ctxt, p, &p.To)
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
if ctxt.Cursym.Cfunc {
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
} else if framesize <= obj.StackBig {
// large stack: SP-framesize <= stackguard-StackSmall
@ -1006,9 +1006,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32) *ob
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_AX
indir_cx(ctxt, p, &p.To)
p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
if ctxt.Cursym.Cfunc {
p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
} else {
// Such a large stack we need to protect against wraparound.
@ -1030,9 +1030,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32) *ob
p.As = mov
indir_cx(ctxt, p, &p.From)
p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
if ctxt.Cursym.Cfunc {
p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_SI
@ -1402,43 +1402,28 @@ var unaryDst = map[obj.As]bool{
}
var Linkamd64 = obj.LinkArch{
ByteOrder: binary.LittleEndian,
Name: "amd64",
Thechar: '6',
Arch: sys.ArchAMD64,
Preprocess: preprocess,
Assemble: span6,
Follow: follow,
Progedit: progedit,
UnaryDst: unaryDst,
Minlc: 1,
Ptrsize: 8,
Regsize: 8,
}
var Linkamd64p32 = obj.LinkArch{
ByteOrder: binary.LittleEndian,
Name: "amd64p32",
Thechar: '6',
Arch: sys.ArchAMD64P32,
Preprocess: preprocess,
Assemble: span6,
Follow: follow,
Progedit: progedit,
UnaryDst: unaryDst,
Minlc: 1,
Ptrsize: 4,
Regsize: 8,
}
var Link386 = obj.LinkArch{
ByteOrder: binary.LittleEndian,
Name: "386",
Thechar: '8',
Arch: sys.Arch386,
Preprocess: preprocess,
Assemble: span6,
Follow: follow,
Progedit: progedit,
UnaryDst: unaryDst,
Minlc: 1,
Ptrsize: 4,
Regsize: 4,
}

View File

@ -0,0 +1,145 @@
// Copyright 2016 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.
package sys
import "encoding/binary"
// ArchFamily represents an architecture family.
type ArchFamily byte
const (
AMD64 ArchFamily = '6'
ARM ArchFamily = '5'
ARM64 ArchFamily = '7'
I386 ArchFamily = '8'
MIPS64 ArchFamily = '0'
PPC64 ArchFamily = '9'
S390X ArchFamily = 'z'
)
// Arch represents an individual architecture.
type Arch struct {
Name string
Family ArchFamily
ByteOrder binary.ByteOrder
IntSize int
PtrSize int
RegSize int
MinLC int
}
// HasFamily reports whether a is a member of any of the specified
// architecture families.
func (a *Arch) InFamily(xs ...ArchFamily) bool {
for _, x := range xs {
if a.Family == x {
return true
}
}
return false
}
var Arch386 = &Arch{
Name: "386",
Family: I386,
ByteOrder: binary.LittleEndian,
IntSize: 4,
PtrSize: 4,
RegSize: 4,
MinLC: 1,
}
var ArchAMD64 = &Arch{
Name: "amd64",
Family: AMD64,
ByteOrder: binary.LittleEndian,
IntSize: 8,
PtrSize: 8,
RegSize: 8,
MinLC: 1,
}
var ArchAMD64P32 = &Arch{
Name: "amd64p32",
Family: AMD64,
ByteOrder: binary.LittleEndian,
IntSize: 4,
PtrSize: 4,
RegSize: 8,
MinLC: 1,
}
var ArchARM = &Arch{
Name: "arm",
Family: ARM,
ByteOrder: binary.LittleEndian,
IntSize: 4,
PtrSize: 4,
RegSize: 4,
MinLC: 4,
}
var ArchARM64 = &Arch{
Name: "arm64",
Family: ARM64,
ByteOrder: binary.LittleEndian,
IntSize: 8,
PtrSize: 8,
RegSize: 8,
MinLC: 4,
}
var ArchMIPS64 = &Arch{
Name: "mips64",
Family: MIPS64,
ByteOrder: binary.BigEndian,
IntSize: 8,
PtrSize: 8,
RegSize: 8,
MinLC: 4,
}
var ArchMIPS64LE = &Arch{
Name: "mips64le",
Family: MIPS64,
ByteOrder: binary.LittleEndian,
IntSize: 8,
PtrSize: 8,
RegSize: 8,
MinLC: 4,
}
var ArchPPC64 = &Arch{
Name: "ppc64",
Family: PPC64,
ByteOrder: binary.BigEndian,
IntSize: 8,
PtrSize: 8,
RegSize: 8,
MinLC: 4,
}
var ArchPPC64LE = &Arch{
Name: "ppc64le",
Family: PPC64,
ByteOrder: binary.LittleEndian,
IntSize: 8,
PtrSize: 8,
RegSize: 8,
MinLC: 4,
}
var ArchS390X = &Arch{
Name: "s390x",
Family: S390X,
ByteOrder: binary.BigEndian,
IntSize: 8,
PtrSize: 8,
RegSize: 8,
MinLC: 2,
}

View File

@ -285,7 +285,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
return
}
if ld.HEADTYPE == obj.Hdarwin && s.Size == int64(ld.Thearch.Ptrsize) && r.Off == 0 {
if ld.HEADTYPE == obj.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 {
// Mach-O relocations are a royal pain to lay out.
// They use a compact stateful bytecode representation
// that is too much bother to deal with.

View File

@ -31,16 +31,11 @@
package amd64
const (
thechar = '6'
MaxAlign = 32 // max data alignment
MinAlign = 1 // min data alignment
FuncAlign = 16
)
const (
MINLC = 1
)
/* Used by ../internal/ld/dwarf.go */
const (
DWARFREGSP = 7

View File

@ -32,6 +32,7 @@ package amd64
import (
"cmd/internal/obj"
"cmd/internal/sys"
"cmd/link/internal/ld"
"fmt"
"log"
@ -45,20 +46,14 @@ func Main() {
}
func linkarchinit() {
ld.Thestring = "amd64"
ld.Thelinkarch = &ld.Linkamd64
ld.SysArch = sys.ArchAMD64
if obj.Getgoarch() == "amd64p32" {
ld.Thelinkarch = &ld.Linkamd64p32
ld.SysArch = sys.ArchAMD64P32
}
ld.Thearch.Thechar = thechar
ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Regsize = ld.Thelinkarch.Regsize
ld.Thearch.Funcalign = FuncAlign
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minalign = MinAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR

View File

@ -63,11 +63,9 @@ package arm
// THE SOFTWARE.
const (
thechar = '5'
MaxAlign = 8 // max data alignment
MinAlign = 1 // min data alignment
FuncAlign = 4 // single-instruction alignment
MINLC = 4
)
/* Used by ../internal/ld/dwarf.go */

View File

@ -32,6 +32,7 @@ package arm
import (
"cmd/internal/obj"
"cmd/internal/sys"
"cmd/link/internal/ld"
"fmt"
"log"
@ -45,17 +46,11 @@ func Main() {
}
func linkarchinit() {
ld.Thestring = "arm"
ld.Thelinkarch = &ld.Linkarm
ld.SysArch = sys.ArchARM
ld.Thearch.Thechar = thechar
ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Regsize = ld.Thelinkarch.Regsize
ld.Thearch.Funcalign = FuncAlign
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minalign = MinAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR

View File

@ -375,7 +375,7 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
}
// The TCB is two pointers. This is not documented anywhere, but is
// de facto part of the ABI.
v := r.Sym.Value + int64(2*ld.Thearch.Ptrsize)
v := r.Sym.Value + int64(2*ld.SysArch.PtrSize)
if v < 0 || v >= 32678 {
ld.Diag("TLS offset out of range %d", v)
}

View File

@ -62,11 +62,9 @@ package arm64
// THE SOFTWARE.
const (
thechar = '7'
MaxAlign = 32 // max data alignment
MinAlign = 1 // min data alignment
FuncAlign = 8
MINLC = 4
)
/* Used by ../internal/ld/dwarf.go */

View File

@ -32,6 +32,7 @@ package arm64
import (
"cmd/internal/obj"
"cmd/internal/sys"
"cmd/link/internal/ld"
"fmt"
"log"
@ -45,17 +46,11 @@ func Main() {
}
func linkarchinit() {
ld.Thestring = obj.Getgoarch()
ld.Thelinkarch = &ld.Linkarm64
ld.SysArch = sys.ArchARM64
ld.Thearch.Thechar = thechar
ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Regsize = ld.Thelinkarch.Regsize
ld.Thearch.Funcalign = FuncAlign
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minalign = MinAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR

View File

@ -1,97 +0,0 @@
// Copyright 2015 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.
package ld
import "encoding/binary"
var Linkarm = LinkArch{
ByteOrder: binary.LittleEndian,
Name: "arm",
Thechar: '5',
Minlc: 4,
Ptrsize: 4,
Regsize: 4,
}
var Linkarm64 = LinkArch{
ByteOrder: binary.LittleEndian,
Name: "arm64",
Thechar: '7',
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}
var Linkamd64 = LinkArch{
ByteOrder: binary.LittleEndian,
Name: "amd64",
Thechar: '6',
Minlc: 1,
Ptrsize: 8,
Regsize: 8,
}
var Linkamd64p32 = LinkArch{
ByteOrder: binary.LittleEndian,
Name: "amd64p32",
Thechar: '6',
Minlc: 1,
Ptrsize: 4,
Regsize: 8,
}
var Link386 = LinkArch{
ByteOrder: binary.LittleEndian,
Name: "386",
Thechar: '8',
Minlc: 1,
Ptrsize: 4,
Regsize: 4,
}
var Linkppc64 = LinkArch{
ByteOrder: binary.BigEndian,
Name: "ppc64",
Thechar: '9',
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}
var Linkppc64le = LinkArch{
ByteOrder: binary.LittleEndian,
Name: "ppc64le",
Thechar: '9',
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}
var Linkmips64 = LinkArch{
ByteOrder: binary.BigEndian,
Name: "mips64",
Thechar: '0',
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}
var Linkmips64le = LinkArch{
ByteOrder: binary.LittleEndian,
Name: "mips64le",
Thechar: '0',
Minlc: 4,
Ptrsize: 8,
Regsize: 8,
}
var Links390x = LinkArch{
ByteOrder: binary.BigEndian,
Name: "s390x",
Thechar: 'z',
Minlc: 2,
Ptrsize: 8,
Regsize: 8,
}

View File

@ -34,6 +34,7 @@ package ld
import (
"cmd/internal/gcprog"
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
"log"
"os"
@ -121,7 +122,7 @@ func Adduint64(ctxt *Link, s *LSym, v uint64) int64 {
}
func adduint(ctxt *Link, s *LSym, v uint64) int64 {
return adduintxx(ctxt, s, v, Thearch.Intsize)
return adduintxx(ctxt, s, v, SysArch.IntSize)
}
func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 {
@ -138,12 +139,12 @@ func Addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
}
s.Attr |= AttrReachable
i := s.Size
s.Size += int64(ctxt.Arch.Ptrsize)
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.Siz = uint8(ctxt.Arch.PtrSize)
r.Type = obj.R_ADDR
r.Add = add
return i + int64(r.Siz)
@ -163,7 +164,7 @@ func Addpcrelplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 {
r.Add = add
r.Type = obj.R_PCREL
r.Siz = 4
if Thearch.Thechar == 'z' {
if SysArch.Family == sys.S390X {
r.Variant = RV_390_DBL
}
return i + int64(r.Siz)
@ -178,15 +179,15 @@ func setaddrplus(ctxt *Link, s *LSym, off int64, t *LSym, add int64) int64 {
s.Type = obj.SDATA
}
s.Attr |= AttrReachable
if off+int64(ctxt.Arch.Ptrsize) > s.Size {
s.Size = off + int64(ctxt.Arch.Ptrsize)
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.Siz = uint8(ctxt.Arch.PtrSize)
r.Type = obj.R_ADDR
r.Add = add
return off + int64(r.Siz)
@ -202,12 +203,12 @@ func addsize(ctxt *Link, s *LSym, t *LSym) int64 {
}
s.Attr |= AttrReachable
i := s.Size
s.Size += int64(ctxt.Arch.Ptrsize)
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.Siz = uint8(ctxt.Arch.PtrSize)
r.Type = obj.R_SIZE
return i + int64(r.Siz)
}
@ -356,7 +357,7 @@ func relocsym(s *LSym) {
// We need to be able to reference dynimport symbols when linking against
// shared libraries, and Solaris needs it always
if HEADTYPE != obj.Hsolaris && r.Sym != nil && r.Sym.Type == obj.SDYNIMPORT && !DynlinkingGo() {
if !(Thearch.Thechar == '9' && Linkmode == LinkExternal && r.Sym.Name == ".TOC.") {
if !(SysArch.Family == sys.PPC64 && Linkmode == LinkExternal && r.Sym.Name == ".TOC.") {
Diag("unhandled relocation for %s (type %d rtype %d)", r.Sym.Name, r.Sym.Type, r.Type)
}
}
@ -365,7 +366,7 @@ func relocsym(s *LSym) {
}
// TODO(mundaym): remove this special case - see issue 14218.
if Thearch.Thechar == 'z' {
if SysArch.Family == sys.S390X {
switch r.Type {
case obj.R_PCRELDBL:
r.Type = obj.R_PCREL
@ -394,7 +395,7 @@ func relocsym(s *LSym) {
}
case obj.R_TLS_LE:
isAndroidX86 := goos == "android" && (Thearch.Thechar == '6' || Thearch.Thechar == '8')
isAndroidX86 := goos == "android" && (SysArch.InFamily(sys.AMD64, sys.I386))
if Linkmode == LinkExternal && Iself && HEADTYPE != obj.Hopenbsd && !isAndroidX86 {
r.Done = 0
@ -404,13 +405,13 @@ func relocsym(s *LSym) {
r.Xsym = r.Sym
r.Xadd = r.Add
o = 0
if Thearch.Thechar != '6' {
if SysArch.Family != sys.AMD64 {
o = r.Add
}
break
}
if Iself && Thearch.Thechar == '5' {
if Iself && SysArch.Family == sys.ARM {
// On ELF ARM, the thread pointer is 8 bytes before
// the start of the thread-local data block, so add 8
// to the actual TLS offset (r->sym->value).
@ -428,7 +429,7 @@ func relocsym(s *LSym) {
}
case obj.R_TLS_IE:
isAndroidX86 := goos == "android" && (Thearch.Thechar == '6' || Thearch.Thechar == '8')
isAndroidX86 := goos == "android" && (SysArch.InFamily(sys.AMD64, sys.I386))
if Linkmode == LinkExternal && Iself && HEADTYPE != obj.Hopenbsd && !isAndroidX86 {
r.Done = 0
@ -438,7 +439,7 @@ func relocsym(s *LSym) {
r.Xsym = r.Sym
r.Xadd = r.Add
o = 0
if Thearch.Thechar != '6' {
if SysArch.Family != sys.AMD64 {
o = r.Add
}
break
@ -465,7 +466,7 @@ func relocsym(s *LSym) {
o = r.Xadd
if Iself {
if Thearch.Thechar == '6' {
if SysArch.Family == sys.AMD64 {
o = 0
}
} else if HEADTYPE == obj.Hdarwin {
@ -475,10 +476,10 @@ func relocsym(s *LSym) {
// The workaround is that on arm64 don't ever add symaddr to o and always use
// extern relocation by requiring rs->dynid >= 0.
if rs.Type != obj.SHOSTOBJ {
if Thearch.Thechar == '7' && rs.Dynid < 0 {
if SysArch.Family == sys.ARM64 && rs.Dynid < 0 {
Diag("R_ADDR reloc to %s+%d is not supported on darwin/arm64", rs.Name, o)
}
if Thearch.Thechar != '7' {
if SysArch.Family != sys.ARM64 {
o += Symaddr(rs)
}
}
@ -498,7 +499,7 @@ func relocsym(s *LSym) {
// fail at runtime. See https://golang.org/issue/7980.
// Instead of special casing only amd64, we treat this as an error on all
// 64-bit architectures so as to be future-proof.
if int32(o) < 0 && Thearch.Ptrsize > 4 && siz == 4 {
if int32(o) < 0 && SysArch.PtrSize > 4 && siz == 4 {
Diag("non-pc-relative relocation address is too big: %#x (%#x + %#x)", uint64(o), Symaddr(r.Sym), r.Add)
errorexit()
}
@ -515,7 +516,7 @@ func relocsym(s *LSym) {
r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr)
o = r.Xadd
rs = r.Xsym
if Iself && Thearch.Thechar == '6' {
if Iself && SysArch.Family == sys.AMD64 {
o = 0
}
break
@ -544,7 +545,7 @@ func relocsym(s *LSym) {
o = r.Xadd
if Iself {
if Thearch.Thechar == '6' {
if SysArch.Family == sys.AMD64 {
o = 0
}
} else if HEADTYPE == obj.Hdarwin {
@ -556,7 +557,7 @@ func relocsym(s *LSym) {
} else {
o += int64(r.Siz)
}
} else if HEADTYPE == obj.Hwindows && Thearch.Thechar == '6' { // only amd64 needs PCREL
} else if HEADTYPE == obj.Hwindows && SysArch.Family == sys.AMD64 { // only amd64 needs PCREL
// PE/COFF's PC32 relocation uses the address after the relocated
// bytes as the base. Compensate by skewing the addend.
o += int64(r.Siz)
@ -675,7 +676,7 @@ func dynrelocsym(s *LSym) {
r.Add = int64(targ.Plt)
// jmp *addr
if Thearch.Thechar == '8' {
if SysArch.Family == sys.I386 {
Adduint8(Ctxt, rel, 0xff)
Adduint8(Ctxt, rel, 0x25)
Addaddr(Ctxt, rel, targ)
@ -982,7 +983,7 @@ func addstrdata(name string, value string) {
s.Attr |= AttrDuplicateOK
reachable := s.Attr.Reachable()
Addaddr(Ctxt, s, sp)
adduintxx(Ctxt, s, uint64(len(value)), Thearch.Ptrsize)
adduintxx(Ctxt, s, uint64(len(value)), SysArch.PtrSize)
// addstring, addaddr, etc., mark the symbols as reachable.
// In this case that is not necessarily true, so stick to what
@ -1128,7 +1129,7 @@ func (p *GCProg) writeByte(x byte) {
}
func (p *GCProg) End(size int64) {
p.w.ZeroUntil(size / int64(Thearch.Ptrsize))
p.w.ZeroUntil(size / int64(SysArch.PtrSize))
p.w.End()
if debugGCProg {
fmt.Fprintf(os.Stderr, "ld: end GCProg\n")
@ -1144,7 +1145,7 @@ func (p *GCProg) AddSym(s *LSym) {
return
}
ptrsize := int64(Thearch.Ptrsize)
ptrsize := int64(SysArch.PtrSize)
nptr := decodetype_ptrdata(typ) / ptrsize
if debugGCProg {
@ -1532,7 +1533,7 @@ func dodata() {
if s != nil && s.Type == obj.STLSBSS {
if Iself && (Linkmode == LinkExternal || Debug['d'] == 0) && HEADTYPE != obj.Hopenbsd {
sect = addsection(&Segdata, ".tbss", 06)
sect.Align = int32(Thearch.Ptrsize)
sect.Align = int32(SysArch.PtrSize)
sect.Vaddr = 0
} else {
sect = nil

View File

@ -6,6 +6,7 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
"strings"
"unicode"
@ -227,7 +228,7 @@ func (d *deadcodepass) markMethod(m methodref) {
func (d *deadcodepass) init() {
var names []string
if Thearch.Thechar == '5' {
if SysArch.Family == sys.ARM {
// mark some functions that are only referenced after linker code editing
if d.ctxt.Goarm == 5 {
names = append(names, "_sfloat")

View File

@ -7,6 +7,7 @@ package ld
import (
"bytes"
"cmd/internal/obj"
"cmd/internal/sys"
"debug/elf"
"fmt"
)
@ -46,39 +47,39 @@ func decode_inuxi(p []byte, sz int) uint64 {
}
}
func commonsize() int { return 6*Thearch.Ptrsize + 8 } // runtime._type
func structfieldSize() int { return 3 * Thearch.Ptrsize } // runtime.structfield
func uncommonSize() int { return 2*Thearch.Ptrsize + 2*Thearch.Intsize } // runtime.uncommontype
func commonsize() int { return 6*SysArch.PtrSize + 8 } // runtime._type
func structfieldSize() int { return 3 * SysArch.PtrSize } // runtime.structfield
func uncommonSize() int { return 2*SysArch.PtrSize + 2*SysArch.IntSize } // runtime.uncommontype
// Type.commonType.kind
func decodetype_kind(s *LSym) uint8 {
return uint8(s.P[2*Thearch.Ptrsize+7] & obj.KindMask) // 0x13 / 0x1f
return uint8(s.P[2*SysArch.PtrSize+7] & obj.KindMask) // 0x13 / 0x1f
}
// Type.commonType.kind
func decodetype_noptr(s *LSym) uint8 {
return uint8(s.P[2*Thearch.Ptrsize+7] & obj.KindNoPointers) // 0x13 / 0x1f
return uint8(s.P[2*SysArch.PtrSize+7] & obj.KindNoPointers) // 0x13 / 0x1f
}
// Type.commonType.kind
func decodetype_usegcprog(s *LSym) uint8 {
return uint8(s.P[2*Thearch.Ptrsize+7] & obj.KindGCProg) // 0x13 / 0x1f
return uint8(s.P[2*SysArch.PtrSize+7] & obj.KindGCProg) // 0x13 / 0x1f
}
// Type.commonType.size
func decodetype_size(s *LSym) int64 {
return int64(decode_inuxi(s.P, Thearch.Ptrsize)) // 0x8 / 0x10
return int64(decode_inuxi(s.P, SysArch.PtrSize)) // 0x8 / 0x10
}
// Type.commonType.ptrdata
func decodetype_ptrdata(s *LSym) int64 {
return int64(decode_inuxi(s.P[Thearch.Ptrsize:], Thearch.Ptrsize)) // 0x8 / 0x10
return int64(decode_inuxi(s.P[SysArch.PtrSize:], SysArch.PtrSize)) // 0x8 / 0x10
}
// Type.commonType.tflag
func decodetype_hasUncommon(s *LSym) bool {
const tflagUncommon = 1 // see ../../../../reflect/type.go:/^type.tflag
return s.P[2*Thearch.Ptrsize+4]&tflagUncommon != 0
return s.P[2*SysArch.PtrSize+4]&tflagUncommon != 0
}
// Find the elf.Section of a given shared library that contains a given address.
@ -112,11 +113,11 @@ func decodetype_gcprog(s *LSym) []byte {
Exitf("cannot find gcprog for %s", s.Name)
return nil
}
return decode_reloc_sym(s, 2*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize)).P
return decode_reloc_sym(s, 2*int32(SysArch.PtrSize)+8+1*int32(SysArch.PtrSize)).P
}
func decodetype_gcprog_shlib(s *LSym) uint64 {
if Thearch.Thechar == '7' {
if SysArch.Family == sys.ARM64 {
for _, shlib := range Ctxt.Shlibs {
if shlib.Path == s.File {
return shlib.gcdata_addresses[s]
@ -124,7 +125,7 @@ func decodetype_gcprog_shlib(s *LSym) uint64 {
}
return 0
}
return decode_inuxi(s.P[2*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize):], Thearch.Ptrsize)
return decode_inuxi(s.P[2*int32(SysArch.PtrSize)+8+1*int32(SysArch.PtrSize):], SysArch.PtrSize)
}
func decodetype_gcmask(s *LSym) []byte {
@ -133,14 +134,14 @@ func decodetype_gcmask(s *LSym) []byte {
ptrdata := decodetype_ptrdata(s)
sect := findShlibSection(s.File, addr)
if sect != nil {
r := make([]byte, ptrdata/int64(Thearch.Ptrsize))
r := make([]byte, ptrdata/int64(SysArch.PtrSize))
sect.ReadAt(r, int64(addr-sect.Addr))
return r
}
Exitf("cannot find gcmask for %s", s.Name)
return nil
}
mask := decode_reloc_sym(s, 2*int32(Thearch.Ptrsize)+8+1*int32(Thearch.Ptrsize))
mask := decode_reloc_sym(s, 2*int32(SysArch.PtrSize)+8+1*int32(SysArch.PtrSize))
return mask.P
}
@ -150,7 +151,7 @@ func decodetype_arrayelem(s *LSym) *LSym {
}
func decodetype_arraylen(s *LSym) int64 {
return int64(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Ptrsize))
return int64(decode_inuxi(s.P[commonsize()+2*SysArch.PtrSize:], SysArch.PtrSize))
}
// Type.PtrType.elem
@ -164,7 +165,7 @@ func decodetype_mapkey(s *LSym) *LSym {
}
func decodetype_mapvalue(s *LSym) *LSym {
return decode_reloc_sym(s, int32(commonsize())+int32(Thearch.Ptrsize)) // 0x20 / 0x38
return decode_reloc_sym(s, int32(commonsize())+int32(SysArch.PtrSize)) // 0x20 / 0x38
}
// Type.ChanType.elem
@ -188,13 +189,13 @@ func decodetype_funcoutcount(s *LSym) int {
func decodetype_funcintype(s *LSym, i int) *LSym {
uadd := commonsize() + 4
if Thearch.Ptrsize == 8 {
if SysArch.PtrSize == 8 {
uadd += 4
}
if decodetype_hasUncommon(s) {
uadd += uncommonSize()
}
return decode_reloc_sym(s, int32(uadd+i*Thearch.Ptrsize))
return decode_reloc_sym(s, int32(uadd+i*SysArch.PtrSize))
}
func decodetype_funcouttype(s *LSym, i int) *LSym {
@ -203,11 +204,11 @@ func decodetype_funcouttype(s *LSym, i int) *LSym {
// Type.StructType.fields.Slice::length
func decodetype_structfieldcount(s *LSym) int {
return int(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Intsize))
return int(decode_inuxi(s.P[commonsize()+2*SysArch.PtrSize:], SysArch.IntSize))
}
func decodetype_structfieldarrayoff(s *LSym, i int) int {
off := commonsize() + 2*Thearch.Ptrsize + 2*Thearch.Intsize
off := commonsize() + 2*SysArch.PtrSize + 2*SysArch.IntSize
if decodetype_hasUncommon(s) {
off += uncommonSize()
}
@ -224,7 +225,7 @@ func decodetype_stringptr(s *LSym, off int) string {
if r == nil { // shouldn't happen.
return ""
}
strlen := int64(decode_inuxi(s.P[Thearch.Ptrsize:], Thearch.Intsize))
strlen := int64(decode_inuxi(s.P[SysArch.PtrSize:], SysArch.IntSize))
return string(r.Sym.P[r.Add : r.Add+strlen])
}
@ -248,17 +249,17 @@ func decodetype_structfieldname(s *LSym, i int) string {
func decodetype_structfieldtype(s *LSym, i int) *LSym {
off := decodetype_structfieldarrayoff(s, i)
return decode_reloc_sym(s, int32(off+Thearch.Ptrsize))
return decode_reloc_sym(s, int32(off+SysArch.PtrSize))
}
func decodetype_structfieldoffs(s *LSym, i int) int64 {
off := decodetype_structfieldarrayoff(s, i)
return int64(decode_inuxi(s.P[off+2*Thearch.Ptrsize:], Thearch.Intsize))
return int64(decode_inuxi(s.P[off+2*SysArch.PtrSize:], SysArch.IntSize))
}
// InterfaceType.methods.length
func decodetype_ifacemethodcount(s *LSym) int64 {
return int64(decode_inuxi(s.P[commonsize()+2*Thearch.Ptrsize:], Thearch.Intsize))
return int64(decode_inuxi(s.P[commonsize()+2*SysArch.PtrSize:], SysArch.IntSize))
}
// methodsig is a fully qualified typed method signature, like
@ -288,7 +289,7 @@ func decode_methodsig(s *LSym, off, size, count int) []methodsig {
var methods []methodsig
for i := 0; i < count; i++ {
buf.WriteString(decodetype_name(s, off))
mtypSym := decode_reloc_sym(s, int32(off+Thearch.Ptrsize))
mtypSym := decode_reloc_sym(s, int32(off+SysArch.PtrSize))
buf.WriteRune('(')
inCount := decodetype_funcincount(mtypSym)
@ -319,7 +320,7 @@ func decodetype_ifacemethods(s *LSym) []methodsig {
if decodetype_kind(s)&kindMask != kindInterface {
panic(fmt.Sprintf("symbol %q is not an interface", s.Name))
}
r := decode_reloc(s, int32(commonsize()+Thearch.Ptrsize))
r := decode_reloc(s, int32(commonsize()+SysArch.PtrSize))
if r == nil {
return nil
}
@ -328,7 +329,7 @@ func decodetype_ifacemethods(s *LSym) []methodsig {
}
off := int(r.Add) // array of reflect.imethod values
numMethods := int(decodetype_ifacemethodcount(s))
sizeofIMethod := 2 * Thearch.Ptrsize
sizeofIMethod := 2 * SysArch.PtrSize
return decode_methodsig(s, off, sizeofIMethod, numMethods)
}
@ -339,31 +340,31 @@ func decodetype_methods(s *LSym) []methodsig {
off := commonsize() // reflect.rtype
switch decodetype_kind(s) & kindMask {
case kindStruct: // reflect.structType
off += 2*Thearch.Ptrsize + 2*Thearch.Intsize
off += 2*SysArch.PtrSize + 2*SysArch.IntSize
case kindPtr: // reflect.ptrType
off += Thearch.Ptrsize
off += SysArch.PtrSize
case kindFunc: // reflect.funcType
off += Thearch.Ptrsize // 4 bytes, pointer aligned
off += SysArch.PtrSize // 4 bytes, pointer aligned
case kindSlice: // reflect.sliceType
off += Thearch.Ptrsize
off += SysArch.PtrSize
case kindArray: // reflect.arrayType
off += 3 * Thearch.Ptrsize
off += 3 * SysArch.PtrSize
case kindChan: // reflect.chanType
off += 2 * Thearch.Ptrsize
off += 2 * SysArch.PtrSize
case kindMap: // reflect.mapType
off += 4*Thearch.Ptrsize + 8
off += 4*SysArch.PtrSize + 8
case kindInterface: // reflect.interfaceType
off += Thearch.Ptrsize + 2*Thearch.Intsize
off += SysArch.PtrSize + 2*SysArch.IntSize
default:
// just Sizeof(rtype)
}
numMethods := int(decode_inuxi(s.P[off+2*Thearch.Ptrsize:], Thearch.Intsize))
r := decode_reloc(s, int32(off+Thearch.Ptrsize))
numMethods := int(decode_inuxi(s.P[off+2*SysArch.PtrSize:], SysArch.IntSize))
r := decode_reloc(s, int32(off+SysArch.PtrSize))
if r.Sym != s {
panic(fmt.Sprintf("method slice pointer in %s leads to a different symbol %s", s, r.Sym))
}
off = int(r.Add) // array of reflect.method values
sizeofMethod := 4 * Thearch.Ptrsize // sizeof reflect.method in program
sizeofMethod := 4 * SysArch.PtrSize // sizeof reflect.method in program
return decode_methodsig(s, off, sizeofMethod, numMethods)
}

View File

@ -39,7 +39,7 @@ var gdbscript string
* Basic I/O
*/
func addrput(s *LSym, addr int64) {
switch Thearch.Ptrsize {
switch SysArch.PtrSize {
case 4:
Adduint32(Ctxt, s, uint32(addr))
@ -569,7 +569,7 @@ func adddwarfref(ctxt *Link, s *LSym, t *LSym, size int) int64 {
default:
Diag("invalid size %d in adddwarfref\n", size)
fallthrough
case Thearch.Ptrsize:
case SysArch.PtrSize:
result = Addaddr(ctxt, s, t)
case 4:
result = addaddrplus4(ctxt, s, t, 0)
@ -599,7 +599,7 @@ func putattr(s *LSym, abbrev int, form int, cls int, value int64, data interface
case DW_FORM_block1: // block
if cls == DW_CLS_ADDRESS {
Adduint8(Ctxt, s, uint8(1+Thearch.Ptrsize))
Adduint8(Ctxt, s, uint8(1+SysArch.PtrSize))
Adduint8(Ctxt, s, DW_OP_addr)
Addaddr(Ctxt, s, data.(*LSym))
break
@ -682,14 +682,14 @@ func putattr(s *LSym, abbrev int, form int, cls int, value int64, data interface
case DW_FORM_ref_addr: // reference to a DIE in the .info section
if data == nil {
Diag("dwarf: null reference in %d", abbrev)
if Thearch.Ptrsize == 8 {
if SysArch.PtrSize == 8 {
Adduint64(Ctxt, s, 0) // invalid dwarf, gdb will complain.
} else {
Adduint32(Ctxt, s, 0) // invalid dwarf, gdb will complain.
}
} else {
dsym := data.(*LSym)
adddwarfref(Ctxt, s, dsym, Thearch.Ptrsize)
adddwarfref(Ctxt, s, dsym, SysArch.PtrSize)
}
case DW_FORM_ref1, // reference within the compilation unit
@ -1161,11 +1161,11 @@ func synthesizemaptypes(die *DWDie) {
// compute size info like hashmap.c does.
indirect_key, indirect_val := false, false
if keysize > MaxKeySize {
keysize = int64(Thearch.Ptrsize)
keysize = int64(SysArch.PtrSize)
indirect_key = true
}
if valsize > MaxValSize {
valsize = int64(Thearch.Ptrsize)
valsize = int64(SysArch.PtrSize)
indirect_val = true
}
@ -1212,13 +1212,13 @@ func synthesizemaptypes(die *DWDie) {
fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "overflow", 0)
newrefattr(fld, DW_AT_type, defptrto(dwhb.sym))
newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
if Thearch.Regsize > Thearch.Ptrsize {
if SysArch.RegSize > SysArch.PtrSize {
fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad", 0)
newrefattr(fld, DW_AT_type, mustFind("uintptr"))
newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(Thearch.Ptrsize))
newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(SysArch.PtrSize))
}
newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize+BucketSize*int64(keysize)+BucketSize*int64(valsize)+int64(Thearch.Regsize), 0)
newattr(dwhb, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize+BucketSize*int64(keysize)+BucketSize*int64(valsize)+int64(SysArch.RegSize), 0)
})
// Construct hash<K,V>
@ -1481,7 +1481,7 @@ func writelines(prev *LSym) *LSym {
headerend = ls.Size
Adduint8(Ctxt, ls, 0) // start extended opcode
uleb128put(ls, 1+int64(Thearch.Ptrsize))
uleb128put(ls, 1+int64(SysArch.PtrSize))
Adduint8(Ctxt, ls, DW_LNE_set_address)
pc := s.Value
@ -1555,7 +1555,7 @@ func writelines(prev *LSym) *LSym {
dt = DW_ABRV_AUTO
offs = int64(a.Aoffset)
if !haslinkregister() {
offs -= int64(Thearch.Ptrsize)
offs -= int64(SysArch.PtrSize)
}
case obj.A_PARAM:
@ -1667,7 +1667,7 @@ func writeframes(prev *LSym) *LSym {
if haslinkregister() {
uleb128put(fs, int64(0)) // offset
} else {
uleb128put(fs, int64(Thearch.Ptrsize)) // offset
uleb128put(fs, int64(SysArch.PtrSize)) // offset
}
Adduint8(Ctxt, fs, DW_CFA_offset_extended)
@ -1675,7 +1675,7 @@ func writeframes(prev *LSym) *LSym {
if haslinkregister() {
uleb128put(fs, int64(0)/DATAALIGNMENTFACTOR) // at cfa - 0
} else {
uleb128put(fs, int64(-Thearch.Ptrsize)/DATAALIGNMENTFACTOR) // at cfa - x*4
uleb128put(fs, int64(-SysArch.PtrSize)/DATAALIGNMENTFACTOR) // at cfa - x*4
}
// 4 is to exclude the length field.
@ -1713,10 +1713,10 @@ func writeframes(prev *LSym) *LSym {
if haslinkregister() {
deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
} else {
deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(Thearch.Ptrsize)+int64(pcsp.value))
deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(SysArch.PtrSize)+int64(pcsp.value))
}
}
pad := int(Rnd(int64(len(deltaBuf)), int64(Thearch.Ptrsize))) - len(deltaBuf)
pad := int(Rnd(int64(len(deltaBuf)), int64(SysArch.PtrSize))) - len(deltaBuf)
deltaBuf = append(deltaBuf, zeros[:pad]...)
// Emit the FDE header, Section 6.4.1.
@ -1724,7 +1724,7 @@ func writeframes(prev *LSym) *LSym {
// 4 bytes: Pointer to the CIE above, at offset 0
// ptrsize: initial location
// ptrsize: address range
Adduint32(Ctxt, fs, uint32(4+2*Thearch.Ptrsize+len(deltaBuf))) // length (excludes itself)
Adduint32(Ctxt, fs, uint32(4+2*SysArch.PtrSize+len(deltaBuf))) // length (excludes itself)
if Linkmode == LinkExternal {
adddwarfref(Ctxt, fs, framesec, 4)
} else {
@ -1771,7 +1771,7 @@ func writeinfo(prev *LSym) *LSym {
// debug_abbrev_offset (*)
adddwarfref(Ctxt, s, abbrevsym, 4)
Adduint8(Ctxt, s, uint8(Thearch.Ptrsize)) // address_size
Adduint8(Ctxt, s, uint8(SysArch.PtrSize)) // address_size
prev = putdie(prev, compunit)
cusize := s.Size - 4 // exclude the length field.
@ -1848,7 +1848,7 @@ func writearanges(prev *LSym) *LSym {
s.Type = obj.SDWARFSECT
// The first tuple is aligned to a multiple of the size of a single tuple
// (twice the size of an address)
headersize := int(Rnd(4+2+4+1+1, int64(Thearch.Ptrsize*2))) // don't count unit_length field itself
headersize := int(Rnd(4+2+4+1+1, int64(SysArch.PtrSize*2))) // don't count unit_length field itself
for compunit := dwroot.child; compunit != nil; compunit = compunit.link {
b := getattr(compunit, DW_AT_low_pc)
@ -1861,13 +1861,13 @@ func writearanges(prev *LSym) *LSym {
}
// Write .debug_aranges Header + entry (sec 6.1.2)
unitlength := uint32(headersize) + 4*uint32(Thearch.Ptrsize) - 4
unitlength := uint32(headersize) + 4*uint32(SysArch.PtrSize) - 4
Adduint32(Ctxt, s, unitlength) // unit_length (*)
Adduint16(Ctxt, s, 2) // dwarf version (appendix F)
adddwarfref(Ctxt, s, compunit.sym, 4)
Adduint8(Ctxt, s, uint8(Thearch.Ptrsize)) // address_size
Adduint8(Ctxt, s, uint8(SysArch.PtrSize)) // address_size
Adduint8(Ctxt, s, 0) // segment_size
padding := headersize - (4 + 2 + 4 + 1 + 1)
for i := 0; i < padding; i++ {
@ -1940,7 +1940,7 @@ func dwarfgeneratedebugsyms() {
die := newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size
newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0)
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(Thearch.Ptrsize), 0)
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, int64(SysArch.PtrSize), 0)
newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, obj.KindUintptr, 0)
// Prototypes needed for type synthesis.

View File

@ -6,6 +6,7 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"crypto/sha1"
"encoding/binary"
"encoding/hex"
@ -866,25 +867,23 @@ var buildinfo []byte
func Elfinit() {
Iself = true
switch Thearch.Thechar {
case '0', '6', '7', '9', 'z':
if SysArch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.S390X) {
elfRelType = ".rela"
default:
} else {
elfRelType = ".rel"
}
switch Thearch.Thechar {
switch SysArch.Family {
// 64-bit architectures
case '9', 'z':
case sys.PPC64, sys.S390X:
if Ctxt.Arch.ByteOrder == binary.BigEndian {
ehdr.flags = 1 /* Version 1 ABI */
} else {
ehdr.flags = 2 /* Version 2 ABI */
}
fallthrough
case '0', '6', '7':
if Thearch.Thechar == '0' {
case sys.AMD64, sys.ARM64, sys.MIPS64:
if SysArch.Family == sys.MIPS64 {
ehdr.flags = 0x20000000 /* MIPS 3 */
}
elf64 = true
@ -897,7 +896,7 @@ func Elfinit() {
// we use EABI on both linux/arm and freebsd/arm.
// 32-bit architectures
case '5':
case sys.ARM:
// we use EABI on both linux/arm and freebsd/arm.
if HEADTYPE == obj.Hlinux || HEADTYPE == obj.Hfreebsd {
// We set a value here that makes no indication of which
@ -911,7 +910,6 @@ func Elfinit() {
ehdr.flags = 0x5000002 // has entry point, Version5 EABI
}
fallthrough
default:
ehdr.phoff = ELF32HDRSIZE
/* Must be be ELF32HDRSIZE: first PHdr must follow ELF header */
@ -1432,7 +1430,7 @@ func elfdynhash() {
}
// s390x (ELF64) hash table entries are 8 bytes
if Thearch.Thechar == 'z' {
if SysArch.Family == sys.S390X {
Adduint64(Ctxt, s, uint64(nbucket))
Adduint64(Ctxt, s, uint64(nsym))
for i := 0; i < nbucket; i++ {
@ -1660,15 +1658,15 @@ func elfshreloc(sect *Section) *ElfShdr {
sh := elfshname(elfRelType + sect.Name)
sh.type_ = uint32(typ)
sh.entsize = uint64(Thearch.Regsize) * 2
sh.entsize = uint64(SysArch.RegSize) * 2
if typ == SHT_RELA {
sh.entsize += uint64(Thearch.Regsize)
sh.entsize += uint64(SysArch.RegSize)
}
sh.link = uint32(elfshname(".symtab").shnum)
sh.info = uint32(sect.Elfsect.shnum)
sh.off = sect.Reloff
sh.size = sect.Rellen
sh.addralign = uint64(Thearch.Regsize)
sh.addralign = uint64(SysArch.RegSize)
return sh
}
@ -1872,7 +1870,7 @@ func doelf() {
Addstring(shstrtab, ".interp")
Addstring(shstrtab, ".hash")
Addstring(shstrtab, ".got")
if Thearch.Thechar == '9' {
if SysArch.Family == sys.PPC64 {
Addstring(shstrtab, ".glink")
}
Addstring(shstrtab, ".got.plt")
@ -1919,7 +1917,7 @@ func doelf() {
s.Type = obj.SELFGOT // writable
/* ppc64 glink resolver */
if Thearch.Thechar == '9' {
if SysArch.Family == sys.PPC64 {
s := Linklookup(Ctxt, ".glink", 0)
s.Attr |= AttrReachable
s.Type = obj.SELFRXSECT
@ -1938,7 +1936,7 @@ func doelf() {
s = Linklookup(Ctxt, ".plt", 0)
s.Attr |= AttrReachable
if Thearch.Thechar == '9' {
if SysArch.Family == sys.PPC64 {
// In the ppc64 ABI, .plt is a data section
// written by the dynamic linker.
s.Type = obj.SELFSECT
@ -1993,15 +1991,15 @@ func doelf() {
Elfwritedynent(s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
}
if Thearch.Thechar == '9' {
if SysArch.Family == sys.PPC64 {
elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".plt", 0))
} else if Thearch.Thechar == 'z' {
} else if SysArch.Family == sys.S390X {
elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".got", 0))
} else {
elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".got.plt", 0))
}
if Thearch.Thechar == '9' {
if SysArch.Family == sys.PPC64 {
Elfwritedynent(s, DT_PPC64_OPT, 0)
}
@ -2080,22 +2078,22 @@ func Asmbelfsetup() {
func Asmbelf(symo int64) {
eh := getElfEhdr()
switch Thearch.Thechar {
switch SysArch.Family {
default:
Exitf("unknown architecture in asmbelf: %v", Thearch.Thechar)
case '0':
Exitf("unknown architecture in asmbelf: %v", SysArch.Family)
case sys.MIPS64:
eh.machine = EM_MIPS
case '5':
case sys.ARM:
eh.machine = EM_ARM
case '6':
case sys.AMD64:
eh.machine = EM_X86_64
case '7':
case sys.ARM64:
eh.machine = EM_AARCH64
case '8':
case sys.I386:
eh.machine = EM_386
case '9':
case sys.PPC64:
eh.machine = EM_PPC64
case 'z':
case sys.S390X:
eh.machine = EM_S390
}
@ -2251,7 +2249,7 @@ func Asmbelf(symo int64) {
} else {
sh.entsize = ELF32SYMSIZE
}
sh.addralign = uint64(Thearch.Regsize)
sh.addralign = uint64(SysArch.RegSize)
sh.link = uint32(elfshname(".dynstr").shnum)
// sh->info = index of first non-local symbol (number of local symbols)
@ -2275,7 +2273,7 @@ func Asmbelf(symo int64) {
sh = elfshname(".gnu.version_r")
sh.type_ = SHT_GNU_VERNEED
sh.flags = SHF_ALLOC
sh.addralign = uint64(Thearch.Regsize)
sh.addralign = uint64(SysArch.RegSize)
sh.info = uint32(elfverneed)
sh.link = uint32(elfshname(".dynstr").shnum)
shsym(sh, Linklookup(Ctxt, ".gnu.version_r", 0))
@ -2286,7 +2284,7 @@ func Asmbelf(symo int64) {
sh.type_ = SHT_RELA
sh.flags = SHF_ALLOC
sh.entsize = ELF64RELASIZE
sh.addralign = uint64(Thearch.Regsize)
sh.addralign = uint64(SysArch.RegSize)
sh.link = uint32(elfshname(".dynsym").shnum)
sh.info = uint32(elfshname(".plt").shnum)
shsym(sh, Linklookup(Ctxt, ".rela.plt", 0))
@ -2350,15 +2348,15 @@ func Asmbelf(symo int64) {
sh := elfshname(".got")
sh.type_ = SHT_PROGBITS
sh.flags = SHF_ALLOC + SHF_WRITE
sh.entsize = uint64(Thearch.Regsize)
sh.addralign = uint64(Thearch.Regsize)
sh.entsize = uint64(SysArch.RegSize)
sh.addralign = uint64(SysArch.RegSize)
shsym(sh, Linklookup(Ctxt, ".got", 0))
sh = elfshname(".got.plt")
sh.type_ = SHT_PROGBITS
sh.flags = SHF_ALLOC + SHF_WRITE
sh.entsize = uint64(Thearch.Regsize)
sh.addralign = uint64(Thearch.Regsize)
sh.entsize = uint64(SysArch.RegSize)
sh.addralign = uint64(SysArch.RegSize)
shsym(sh, Linklookup(Ctxt, ".got.plt", 0))
}
@ -2366,7 +2364,7 @@ func Asmbelf(symo int64) {
sh.type_ = SHT_HASH
sh.flags = SHF_ALLOC
sh.entsize = 4
sh.addralign = uint64(Thearch.Regsize)
sh.addralign = uint64(SysArch.RegSize)
sh.link = uint32(elfshname(".dynsym").shnum)
shsym(sh, Linklookup(Ctxt, ".hash", 0))
@ -2375,8 +2373,8 @@ func Asmbelf(symo int64) {
sh.type_ = SHT_DYNAMIC
sh.flags = SHF_ALLOC + SHF_WRITE
sh.entsize = 2 * uint64(Thearch.Regsize)
sh.addralign = uint64(Thearch.Regsize)
sh.entsize = 2 * uint64(SysArch.RegSize)
sh.addralign = uint64(SysArch.RegSize)
sh.link = uint32(elfshname(".dynstr").shnum)
shsym(sh, Linklookup(Ctxt, ".dynamic", 0))
ph := newElfPhdr()
@ -2402,7 +2400,7 @@ func Asmbelf(symo int64) {
ph.type_ = PT_TLS
ph.flags = PF_R
ph.memsz = tlssize
ph.align = uint64(Thearch.Regsize)
ph.align = uint64(SysArch.RegSize)
}
}
}
@ -2411,12 +2409,12 @@ func Asmbelf(symo int64) {
ph := newElfPhdr()
ph.type_ = PT_GNU_STACK
ph.flags = PF_W + PF_R
ph.align = uint64(Thearch.Regsize)
ph.align = uint64(SysArch.RegSize)
ph = newElfPhdr()
ph.type_ = PT_PAX_FLAGS
ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
ph.align = uint64(Thearch.Regsize)
ph.align = uint64(SysArch.RegSize)
}
elfobj:
@ -2476,8 +2474,8 @@ elfobj:
sh.type_ = SHT_SYMTAB
sh.off = uint64(symo)
sh.size = uint64(Symsize)
sh.addralign = uint64(Thearch.Regsize)
sh.entsize = 8 + 2*uint64(Thearch.Regsize)
sh.addralign = uint64(SysArch.RegSize)
sh.entsize = 8 + 2*uint64(SysArch.RegSize)
sh.link = uint32(elfshname(".strtab").shnum)
sh.info = uint32(elfglobalsymndx)
@ -2600,7 +2598,7 @@ func Elfadddynsym(ctxt *Link, s *LSym) {
/* size of object */
Adduint64(ctxt, d, uint64(s.Size))
if Thearch.Thechar == '6' && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
if SysArch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
Elfwritedynent(Linklookup(ctxt, ".dynamic", 0), DT_NEEDED, uint64(Addstring(Linklookup(ctxt, ".dynstr", 0), s.Dynimplib)))
}
} else {
@ -2628,9 +2626,9 @@ func Elfadddynsym(ctxt *Link, s *LSym) {
t := STB_GLOBAL << 4
// TODO(mwhudson): presumably the behaviour should actually be the same on both arm and 386.
if Thearch.Thechar == '8' && s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
if SysArch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
t |= STT_FUNC
} else if Thearch.Thechar == '5' && s.Attr.CgoExportDynamic() && s.Type&obj.SMASK == obj.STEXT {
} else if SysArch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&obj.SMASK == obj.STEXT {
t |= STT_FUNC
} else {
t |= STT_OBJECT

View File

@ -3,6 +3,7 @@ package ld
import (
"bytes"
"cmd/internal/obj"
"cmd/internal/sys"
"encoding/binary"
"fmt"
"io"
@ -546,47 +547,48 @@ func ldelf(f *obj.Biobuf, pkg string, length int64, pn string) {
return
}
switch Thearch.Thechar {
switch SysArch.Family {
default:
Diag("%s: elf %s unimplemented", pn, Thestring)
Diag("%s: elf %s unimplemented", pn, SysArch.Name)
return
case '0':
case sys.MIPS64:
if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
Diag("%s: elf object but not mips64", pn)
return
}
case '5':
case sys.ARM:
if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
Diag("%s: elf object but not arm", pn)
return
}
case '6':
case sys.AMD64:
if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
Diag("%s: elf object but not amd64", pn)
return
}
case '7':
case sys.ARM64:
if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
Diag("%s: elf object but not arm64", pn)
return
}
case '8':
case sys.I386:
if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
Diag("%s: elf object but not 386", pn)
return
}
case '9':
case sys.PPC64:
if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
Diag("%s: elf object but not ppc64", pn)
return
}
case 'z':
case sys.S390X:
if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
Diag("%s: elf object but not s390x", pn)
return
@ -1056,7 +1058,7 @@ func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) {
}
case ElfSymBindLocal:
if Thearch.Thechar == '5' && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
// binutils for arm generate these mapping
// symbols, ignore these
break
@ -1127,7 +1129,9 @@ func (x rbyoff) Less(i, j int) bool {
}
func reltype(pn string, elftype int, siz *uint8) int {
switch uint32(Thearch.Thechar) | uint32(elftype)<<24 {
// TODO(mdempsky): Remove dependency on ArchFamily char values.
switch uint32(SysArch.Family) | uint32(elftype)<<24 {
default:
Diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
fallthrough

View File

@ -2,6 +2,7 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"encoding/binary"
"fmt"
"log"
@ -471,18 +472,18 @@ func ldmacho(f *obj.Biobuf, pkg string, length int64, pn string) {
m.length = length
m.name = pn
switch Thearch.Thechar {
switch SysArch.Family {
default:
Diag("%s: mach-o %s unimplemented", pn, Thestring)
Diag("%s: mach-o %s unimplemented", pn, SysArch.Name)
return
case '6':
case sys.AMD64:
if e != binary.LittleEndian || m.cputype != LdMachoCpuAmd64 {
Diag("%s: mach-o object but not amd64", pn)
return
}
case '8':
case sys.I386:
if e != binary.LittleEndian || m.cputype != LdMachoCpu386 {
Diag("%s: mach-o object but not 386", pn)
return
@ -724,10 +725,9 @@ func ldmacho(f *obj.Biobuf, pkg string, length int64, pn string) {
rp = &r[rpi]
rel = &sect.rel[j]
if rel.scattered != 0 {
if Thearch.Thechar != '8' {
if SysArch.Family != sys.I386 {
// mach-o only uses scattered relocation on 32-bit platforms
Diag("unexpected scattered relocation")
continue
}
@ -821,7 +821,7 @@ func ldmacho(f *obj.Biobuf, pkg string, length int64, pn string) {
rp.Off = int32(rel.addr)
// Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
if Thearch.Thechar == '6' && rel.extrn == 0 && rel.type_ == 1 {
if SysArch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == 1 {
// Calculate the addend as the offset into the section.
//
// The rip-relative offset stored in the object file is encoded
@ -847,7 +847,7 @@ func ldmacho(f *obj.Biobuf, pkg string, length int64, pn string) {
// For i386 Mach-O PC-relative, the addend is written such that
// it *is* the PC being subtracted. Use that to make
// it match our version of PC-relative.
if rel.pcrel != 0 && Thearch.Thechar == '8' {
if rel.pcrel != 0 && SysArch.Family == sys.I386 {
rp.Add += int64(rp.Off) + int64(rp.Siz)
}
if rel.extrn == 0 {
@ -866,7 +866,7 @@ func ldmacho(f *obj.Biobuf, pkg string, length int64, pn string) {
// include that information in the addend.
// We only care about the delta from the
// section base.
if Thearch.Thechar == '8' {
if SysArch.Family == sys.I386 {
rp.Add -= int64(c.seg.sect[rel.symnum-1].addr)
}
} else {

View File

@ -6,6 +6,7 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"encoding/binary"
"fmt"
"log"
@ -492,7 +493,7 @@ func readpesym(peobj *PeObj, i int, y **PeSym) (err error) {
if strings.HasPrefix(name, "__imp_") {
name = name[6:] // __imp_Name => Name
}
if Thearch.Thechar == '8' && name[0] == '_' {
if SysArch.Family == sys.I386 && name[0] == '_' {
name = name[1:] // _Name => Name
}
}

View File

@ -34,6 +34,7 @@ import (
"bufio"
"bytes"
"cmd/internal/obj"
"cmd/internal/sys"
"crypto/sha1"
"debug/elf"
"encoding/binary"
@ -82,14 +83,9 @@ import (
// THE SOFTWARE.
type Arch struct {
Thechar int
Ptrsize int
Intsize int
Regsize int
Funcalign int
Maxalign int
Minalign int
Minlc int
Dwarfregsp int
Dwarfreglr int
Linuxdynld string
@ -191,8 +187,7 @@ func UseRelro() bool {
}
var (
Thestring string
Thelinkarch *LinkArch
SysArch *sys.Arch
outfile string
dynexp []*LSym
dynlib []string
@ -509,7 +504,7 @@ func loadlib() {
}
loadinternal("runtime")
if Thearch.Thechar == '5' {
if SysArch.Family == sys.ARM {
loadinternal("math")
}
if flag_race != 0 {
@ -562,7 +557,7 @@ func loadlib() {
// dependency problems when compiling natively (external linking requires
// runtime/cgo, runtime/cgo requires cmd/cgo, but cmd/cgo needs to be
// compiled using external linking.)
if (Thearch.Thechar == '5' || Thearch.Thechar == '7') && HEADTYPE == obj.Hdarwin && iscgo {
if SysArch.InFamily(sys.ARM, sys.ARM64) && HEADTYPE == obj.Hdarwin && iscgo {
Linkmode = LinkExternal
}
@ -621,7 +616,7 @@ func loadlib() {
// a variable to hold g in assembly (currently only intel).
if tlsg.Type == 0 {
tlsg.Type = obj.STLSBSS
tlsg.Size = int64(Thearch.Ptrsize)
tlsg.Size = int64(SysArch.PtrSize)
} else if tlsg.Type != obj.SDYNIMPORT {
Diag("internal error: runtime declared tlsg variable %d", tlsg.Type)
}
@ -639,7 +634,7 @@ func loadlib() {
// In addition, on ARM, the runtime depends on the linker
// recording the value of GOARM.
if Thearch.Thechar == '5' {
if SysArch.Family == sys.ARM {
s := Linklookup(Ctxt, "runtime.goarm", 0)
s.Type = obj.SRODATA
@ -1226,7 +1221,7 @@ func hostlink() {
if Debug['s'] == 0 && debug_s == 0 && HEADTYPE == obj.Hdarwin {
// Skip combining dwarf on arm.
if Thearch.Thechar != '5' && Thearch.Thechar != '7' {
if !SysArch.InFamily(sys.ARM, sys.ARM64) {
dsym := filepath.Join(tmpdir, "go.dwarf")
if out, err := exec.Command("dsymutil", "-f", outfile, "-o", dsym).CombinedOutput(); err != nil {
Ctxt.Cursym = nil
@ -1254,14 +1249,14 @@ func hostlink() {
// hostlinkArchArgs returns arguments to pass to the external linker
// based on the architecture.
func hostlinkArchArgs() []string {
switch Thearch.Thechar {
case '8':
switch SysArch.Family {
case sys.I386:
return []string{"-m32"}
case '6', '9', 'z':
case sys.AMD64, sys.PPC64, sys.S390X:
return []string{"-m64"}
case '5':
case sys.ARM:
return []string{"-marm"}
case '7':
case sys.ARM64:
// nothing needed
}
return nil
@ -1306,10 +1301,10 @@ func ldobj(f *obj.Biobuf, pkg string, length int64, pn string, file string, when
if !strings.HasPrefix(line, "go object ") {
if strings.HasSuffix(pn, ".go") {
Exitf("%cl: input %s is not .%c file (use %cg to compile .go files)", Thearch.Thechar, pn, Thearch.Thechar, Thearch.Thechar)
Exitf("%cl: input %s is not .%c file (use %cg to compile .go files)", SysArch.Family, pn, SysArch.Family, SysArch.Family)
}
if line == Thestring {
if line == SysArch.Name {
// old header format: just $GOOS
Diag("%s: stale object file", pn)
return nil
@ -1500,12 +1495,12 @@ func ldshlibsyms(shlib string) {
// the type data.
if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
lsym.P = readelfsymboldata(f, &elfsym)
gcdata_locations[elfsym.Value+2*uint64(Thearch.Ptrsize)+8+1*uint64(Thearch.Ptrsize)] = lsym
gcdata_locations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym
}
}
}
gcdata_addresses := make(map[*LSym]uint64)
if Thearch.Thechar == '7' {
if SysArch.Family == sys.ARM64 {
for _, sect := range f.Sections {
if sect.Type == elf.SHT_RELA {
var rela elf.Rela64
@ -1565,8 +1560,8 @@ func mywhatsys() {
goos = obj.Getgoos()
goarch = obj.Getgoarch()
if !strings.HasPrefix(goarch, Thestring) {
log.Fatalf("cannot use %cc with GOARCH=%s", Thearch.Thechar, goarch)
if !strings.HasPrefix(goarch, SysArch.Name) {
log.Fatalf("cannot use %cc with GOARCH=%s", SysArch.Family, goarch)
}
}
@ -1608,7 +1603,7 @@ func addsection(seg *Segment, name string, rwx int) *Section {
sect.Rwx = uint8(rwx)
sect.Name = name
sect.Seg = seg
sect.Align = int32(Thearch.Ptrsize) // everything is at least pointer-aligned
sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned
*l = sect
return sect
}
@ -1652,7 +1647,7 @@ func callsize() int {
if haslinkregister() {
return 0
}
return Thearch.Regsize
return SysArch.RegSize
}
func dostkcheck() {
@ -1986,7 +1981,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype)
// NOTE(ality): acid can't produce a stack trace without .frame symbols
put(nil, ".frame", 'm', int64(s.Locals)+int64(Thearch.Ptrsize), 0, 0, nil)
put(nil, ".frame", 'm', int64(s.Locals)+int64(SysArch.PtrSize), 0, 0, nil)
for _, a := range s.Autom {
// Emit a or p according to actual offset, even if label is wrong.
@ -1999,7 +1994,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
if a.Name == obj.A_PARAM {
off = a.Aoffset
} else {
off = a.Aoffset - int32(Thearch.Ptrsize)
off = a.Aoffset - int32(SysArch.PtrSize)
}
// FP
@ -2009,8 +2004,8 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
}
// SP
if off <= int32(-Thearch.Ptrsize) {
put(nil, a.Asym.Name, 'a', -(int64(off) + int64(Thearch.Ptrsize)), 0, 0, a.Gotype)
if off <= int32(-SysArch.PtrSize) {
put(nil, a.Asym.Name, 'a', -(int64(off) + int64(SysArch.PtrSize)), 0, 0, a.Gotype)
continue
}
}

View File

@ -32,8 +32,8 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"debug/elf"
"encoding/binary"
"fmt"
)
@ -161,11 +161,9 @@ type Shlib struct {
}
type Link struct {
Thechar int32
Thestring string
Goarm int32
Headtype int
Arch *LinkArch
Arch *sys.Arch
Debugvlog int32
Bso *obj.Biobuf
Windows int32
@ -196,15 +194,15 @@ type Link struct {
// 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.Thechar {
case '6', '8':
switch ctxt.Arch.Family {
case sys.AMD64, sys.I386:
return 0
case '9':
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)
return int64(4 * ctxt.Arch.PtrSize)
default:
return int64(ctxt.Arch.Ptrsize)
return int64(ctxt.Arch.PtrSize)
}
}
@ -213,15 +211,6 @@ func (l *Link) IncVersion() {
l.Hash = append(l.Hash, make(map[string]*LSym))
}
type LinkArch struct {
ByteOrder binary.ByteOrder
Name string
Thechar int
Minlc int
Ptrsize int
Regsize int
}
type Library struct {
Objref string
Srcref string

View File

@ -6,6 +6,7 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"sort"
"strings"
)
@ -131,15 +132,7 @@ var nsortsym int
var load_budget int = INITIAL_MACHO_HEADR - 2*1024
func Machoinit() {
switch Thearch.Thechar {
// 64-bit architectures
case '6', '7', '9':
macho64 = true
// 32-bit architectures
default:
break
}
macho64 = SysArch.RegSize == 8
}
func getMachoHdr() *MachoHdr {
@ -356,8 +349,8 @@ func machoshbits(mseg *MachoSeg, sect *Section, segname string) {
buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
var msect *MachoSect
if sect.Rwx&1 == 0 && segname != "__DWARF" && (Thearch.Thechar == '7' || // arm64
(Thearch.Thechar == '6' && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive))) { // amd64
if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 ||
(SysArch.Family == sys.AMD64 && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive))) {
// Darwin external linker on arm64 and on amd64 in c-shared/c-archive buildmode
// complains about absolute relocs in __TEXT, so if the section is not
// executable, put it in __DATA segment.
@ -422,23 +415,23 @@ func Asmbmacho() {
va := INITTEXT - int64(HEADR)
mh := getMachoHdr()
switch Thearch.Thechar {
switch SysArch.Family {
default:
Exitf("unknown macho architecture: %v", Thearch.Thechar)
Exitf("unknown macho architecture: %v", SysArch.Family)
case '5':
case sys.ARM:
mh.cpu = MACHO_CPU_ARM
mh.subcpu = MACHO_SUBCPU_ARMV7
case '6':
case sys.AMD64:
mh.cpu = MACHO_CPU_AMD64
mh.subcpu = MACHO_SUBCPU_X86
case '7':
case sys.ARM64:
mh.cpu = MACHO_CPU_ARM64
mh.subcpu = MACHO_SUBCPU_ARM64_ALL
case '8':
case sys.I386:
mh.cpu = MACHO_CPU_386
mh.subcpu = MACHO_SUBCPU_X86
}
@ -449,7 +442,7 @@ func Asmbmacho() {
ms = newMachoSeg("", 40)
ms.fileoffset = Segtext.Fileoff
if Thearch.Thechar == '5' || Buildmode == BuildmodeCArchive {
if SysArch.Family == sys.ARM || Buildmode == BuildmodeCArchive {
ms.filesize = Segdata.Fileoff + Segdata.Filelen - Segtext.Fileoff
} else {
ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
@ -511,31 +504,31 @@ func Asmbmacho() {
}
if Linkmode != LinkExternal {
switch Thearch.Thechar {
switch SysArch.Family {
default:
Exitf("unknown macho architecture: %v", Thearch.Thechar)
Exitf("unknown macho architecture: %v", SysArch.Family)
case '5':
case sys.ARM:
ml := newMachoLoad(5, 17+2) /* unix thread */
ml.data[0] = 1 /* thread type */
ml.data[1] = 17 /* word count */
ml.data[2+15] = uint32(Entryvalue()) /* start pc */
case '6':
case sys.AMD64:
ml := newMachoLoad(5, 42+2) /* unix thread */
ml.data[0] = 4 /* thread type */
ml.data[1] = 42 /* word count */
ml.data[2+32] = uint32(Entryvalue()) /* start pc */
ml.data[2+32+1] = uint32(Entryvalue() >> 32)
case '7':
case sys.ARM64:
ml := newMachoLoad(5, 68+2) /* unix thread */
ml.data[0] = 6 /* thread type */
ml.data[1] = 68 /* word count */
ml.data[2+64] = uint32(Entryvalue()) /* start pc */
ml.data[2+64+1] = uint32(Entryvalue() >> 32)
case '8':
case sys.I386:
ml := newMachoLoad(5, 16+2) /* unix thread */
ml.data[0] = 1 /* thread type */
ml.data[1] = 16 /* word count */
@ -546,7 +539,6 @@ func Asmbmacho() {
if Debug['d'] == 0 {
// must match domacholink below
s1 := Linklookup(Ctxt, ".machosymtab", 0)
s2 := Linklookup(Ctxt, ".linkedit.plt", 0)
s3 := Linklookup(Ctxt, ".linkedit.got", 0)
s4 := Linklookup(Ctxt, ".machosymstr", 0)
@ -729,7 +721,7 @@ func machosymtab() {
Adduint8(Ctxt, symtab, 0x01) // type N_EXT, external symbol
Adduint8(Ctxt, symtab, 0) // no section
Adduint16(Ctxt, symtab, 0) // desc
adduintxx(Ctxt, symtab, 0, Thearch.Ptrsize) // no value
adduintxx(Ctxt, symtab, 0, SysArch.PtrSize) // no value
} else {
if s.Attr.CgoExport() {
Adduint8(Ctxt, symtab, 0x0f)
@ -747,7 +739,7 @@ func machosymtab() {
Adduint8(Ctxt, symtab, uint8(o.Sect.Extnum))
}
Adduint16(Ctxt, symtab, 0) // desc
adduintxx(Ctxt, symtab, uint64(Symaddr(s)), Thearch.Ptrsize)
adduintxx(Ctxt, symtab, uint64(Symaddr(s)), SysArch.PtrSize)
}
}
}

View File

@ -93,7 +93,7 @@ func pciterinit(ctxt *Link, it *Pciter, d *Pcdata) {
it.value = -1
it.start = 1
it.done = 0
it.pcscale = uint32(ctxt.Arch.Minlc)
it.pcscale = uint32(ctxt.Arch.MinLC)
pciternext(it)
}
@ -242,12 +242,12 @@ func pclntab() {
}
pclntabNfunc = nfunc
Symgrow(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize)+int64(Thearch.Ptrsize)+4)
Symgrow(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize)+4)
setuint32(Ctxt, ftab, 0, 0xfffffffb)
setuint8(Ctxt, ftab, 6, uint8(Thearch.Minlc))
setuint8(Ctxt, ftab, 7, uint8(Thearch.Ptrsize))
setuintxx(Ctxt, ftab, 8, uint64(nfunc), int64(Thearch.Ptrsize))
pclntabPclntabOffset = int32(8 + Thearch.Ptrsize)
setuint8(Ctxt, ftab, 6, uint8(SysArch.MinLC))
setuint8(Ctxt, ftab, 7, uint8(SysArch.PtrSize))
setuintxx(Ctxt, ftab, 8, uint64(nfunc), int64(SysArch.PtrSize))
pclntabPclntabOffset = int32(8 + SysArch.PtrSize)
nfunc = 0
var last *LSym
@ -272,16 +272,16 @@ func pclntab() {
}
funcstart = int32(len(ftab.P))
funcstart += int32(-len(ftab.P)) & (int32(Thearch.Ptrsize) - 1)
funcstart += int32(-len(ftab.P)) & (int32(SysArch.PtrSize) - 1)
setaddr(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize), Ctxt.Cursym)
setuintxx(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize)+int64(Thearch.Ptrsize), uint64(funcstart), int64(Thearch.Ptrsize))
setaddr(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), Ctxt.Cursym)
setuintxx(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint64(funcstart), int64(SysArch.PtrSize))
// fixed size of struct, checked below
off = funcstart
end = funcstart + int32(Thearch.Ptrsize) + 3*4 + 5*4 + int32(len(pcln.Pcdata))*4 + int32(len(pcln.Funcdata))*int32(Thearch.Ptrsize)
if len(pcln.Funcdata) > 0 && (end&int32(Thearch.Ptrsize-1) != 0) {
end = funcstart + int32(SysArch.PtrSize) + 3*4 + 5*4 + int32(len(pcln.Pcdata))*4 + int32(len(pcln.Funcdata))*int32(SysArch.PtrSize)
if len(pcln.Funcdata) > 0 && (end&int32(SysArch.PtrSize-1) != 0) {
end += 4
}
Symgrow(Ctxt, ftab, int64(end))
@ -330,25 +330,25 @@ func pclntab() {
// funcdata, must be pointer-aligned and we're only int32-aligned.
// Missing funcdata will be 0 (nil pointer).
if len(pcln.Funcdata) > 0 {
if off&int32(Thearch.Ptrsize-1) != 0 {
if off&int32(SysArch.PtrSize-1) != 0 {
off += 4
}
for i = 0; i < int32(len(pcln.Funcdata)); i++ {
if pcln.Funcdata[i] == nil {
setuintxx(Ctxt, ftab, int64(off)+int64(Thearch.Ptrsize)*int64(i), uint64(pcln.Funcdataoff[i]), int64(Thearch.Ptrsize))
setuintxx(Ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), uint64(pcln.Funcdataoff[i]), int64(SysArch.PtrSize))
} else {
// TODO: Dedup.
funcdata_bytes += pcln.Funcdata[i].Size
setaddrplus(Ctxt, ftab, int64(off)+int64(Thearch.Ptrsize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
setaddrplus(Ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
}
}
off += int32(len(pcln.Funcdata)) * int32(Thearch.Ptrsize)
off += int32(len(pcln.Funcdata)) * int32(SysArch.PtrSize)
}
if off != end {
Diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, len(pcln.Pcdata), len(pcln.Funcdata), Thearch.Ptrsize)
Diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, len(pcln.Pcdata), len(pcln.Funcdata), SysArch.PtrSize)
errorexit()
}
@ -357,14 +357,14 @@ func pclntab() {
pclntabLastFunc = last
// Final entry of table is just end pc.
setaddrplus(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize), last, last.Size)
setaddrplus(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), last, last.Size)
// Start file table.
start := int32(len(ftab.P))
start += int32(-len(ftab.P)) & (int32(Thearch.Ptrsize) - 1)
start += int32(-len(ftab.P)) & (int32(SysArch.PtrSize) - 1)
pclntabFiletabOffset = start
setuint32(Ctxt, ftab, 8+int64(Thearch.Ptrsize)+int64(nfunc)*2*int64(Thearch.Ptrsize)+int64(Thearch.Ptrsize), uint32(start))
setuint32(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint32(start))
Symgrow(Ctxt, ftab, int64(start)+(int64(Ctxt.Nhistfile)+1)*4)
setuint32(Ctxt, ftab, int64(start), uint32(Ctxt.Nhistfile))

View File

@ -6,6 +6,7 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"encoding/binary"
"fmt"
"os"
@ -419,9 +420,9 @@ func chksectseg(h *IMAGE_SECTION_HEADER, s *Segment) {
func Peinit() {
var l int
switch Thearch.Thechar {
switch SysArch.Family {
// 64-bit architectures
case '6':
case sys.AMD64:
pe64 = 1
l = binary.Size(&oh64)
@ -506,7 +507,7 @@ func initdynimport() *Dll {
if err != nil {
Diag("failed to parse stdcall decoration: %v", err)
}
m.argsize *= Thearch.Ptrsize
m.argsize *= SysArch.PtrSize
s.Extname = s.Extname[:i]
}
@ -520,10 +521,10 @@ func initdynimport() *Dll {
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
m.s.Type = obj.SDATA
Symgrow(Ctxt, m.s, int64(Thearch.Ptrsize))
Symgrow(Ctxt, m.s, int64(SysArch.PtrSize))
dynName := m.s.Extname
// only windows/386 requires stdcall decoration
if Thearch.Thechar == '8' && m.argsize >= 0 {
if SysArch.Family == sys.I386 && m.argsize >= 0 {
dynName += fmt.Sprintf("@%d", m.argsize)
}
dynSym := Linklookup(Ctxt, dynName, 0)
@ -532,7 +533,7 @@ func initdynimport() *Dll {
r := Addrel(m.s)
r.Sym = dynSym
r.Off = 0
r.Siz = uint8(Thearch.Ptrsize)
r.Siz = uint8(SysArch.PtrSize)
r.Type = obj.R_ADDR
}
}
@ -546,10 +547,10 @@ func initdynimport() *Dll {
m.s.Sub = dynamic.Sub
dynamic.Sub = m.s
m.s.Value = dynamic.Size
dynamic.Size += int64(Thearch.Ptrsize)
dynamic.Size += int64(SysArch.PtrSize)
}
dynamic.Size += int64(Thearch.Ptrsize)
dynamic.Size += int64(SysArch.PtrSize)
}
}
@ -946,7 +947,7 @@ func writePESymTableRecords() int {
}
// only windows/386 requires underscore prefix on external symbols
if Thearch.Thechar == '8' &&
if SysArch.Family == sys.I386 &&
Linkmode == LinkExternal &&
(s.Type != obj.SDYNIMPORT || s.Attr.CgoExport()) &&
s.Name == s.Extname &&
@ -1002,7 +1003,7 @@ func writePESymTableRecords() int {
for d := dr; d != nil; d = d.next {
for m := d.ms; m != nil; m = m.next {
s := m.s.R[0].Xsym
put(s, s.Name, 'U', 0, int64(Thearch.Ptrsize), 0, nil)
put(s, s.Name, 'U', 0, int64(SysArch.PtrSize), 0, nil)
}
}
@ -1129,12 +1130,12 @@ func addinitarray() (c *IMAGE_SECTION_HEADER) {
}
func Asmbpe() {
switch Thearch.Thechar {
switch SysArch.Family {
default:
Exitf("unknown PE architecture: %v", Thearch.Thechar)
case '6':
Exitf("unknown PE architecture: %v", SysArch.Family)
case sys.AMD64:
fh.Machine = IMAGE_FILE_MACHINE_AMD64
case '8':
case sys.I386:
fh.Machine = IMAGE_FILE_MACHINE_I386
}

View File

@ -32,6 +32,7 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"flag"
"fmt"
"os"
@ -44,9 +45,7 @@ var (
)
func Ldmain() {
Ctxt = linknew(Thelinkarch)
Ctxt.Thechar = int32(Thearch.Thechar)
Ctxt.Thestring = Thestring
Ctxt = linknew(SysArch)
Ctxt.Diag = Diag
Ctxt.Bso = &Bso
@ -70,7 +69,7 @@ func Ldmain() {
}
}
if Thearch.Thechar == '6' && obj.Getgoos() == "plan9" {
if SysArch.Family == sys.AMD64 && obj.Getgoos() == "plan9" {
obj.Flagcount("8", "use 64-bit addresses in symbol table", &Debug['8'])
}
obj.Flagfn1("B", "add an ELF NT_GNU_BUILD_ID `note` when using ELF", addbuildinfo)
@ -107,7 +106,7 @@ func Ldmain() {
obj.Flagcount("race", "enable race detector", &flag_race)
obj.Flagcount("s", "disable symbol table", &Debug['s'])
var flagShared int
if Thearch.Thechar == '5' || Thearch.Thechar == '6' {
if SysArch.InFamily(sys.ARM, sys.AMD64) {
obj.Flagcount("shared", "generate shared object (implies -linkmode external)", &flagShared)
}
obj.Flagstr("tmpdir", "use `directory` for temporary files", &tmpdir)

View File

@ -33,6 +33,7 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"log"
"strconv"
)
@ -55,7 +56,7 @@ var headers = []struct {
{"windowsgui", obj.Hwindows},
}
func linknew(arch *LinkArch) *Link {
func linknew(arch *sys.Arch) *Link {
ctxt := &Link{
Hash: []map[string]*LSym{
// preallocate about 2mb for hash of
@ -98,33 +99,33 @@ func linknew(arch *LinkArch) *Link {
obj.Hdragonfly,
obj.Hsolaris:
if obj.Getgoos() == "android" {
switch ctxt.Arch.Thechar {
case '6':
switch ctxt.Arch.Family {
case sys.AMD64:
// Android/amd64 constant - offset from 0(FS) to our TLS slot.
// Explained in src/runtime/cgo/gcc_android_*.c
ctxt.Tlsoffset = 0x1d0
case '8':
case sys.I386:
// Android/386 constant - offset from 0(GS) to our TLS slot.
ctxt.Tlsoffset = 0xf8
default:
ctxt.Tlsoffset = -1 * ctxt.Arch.Ptrsize
ctxt.Tlsoffset = -1 * ctxt.Arch.PtrSize
}
} else {
ctxt.Tlsoffset = -1 * ctxt.Arch.Ptrsize
ctxt.Tlsoffset = -1 * ctxt.Arch.PtrSize
}
case obj.Hnacl:
switch ctxt.Arch.Thechar {
switch ctxt.Arch.Family {
default:
log.Fatalf("unknown thread-local storage offset for nacl/%s", ctxt.Arch.Name)
case '5':
case sys.ARM:
ctxt.Tlsoffset = 0
case '6':
case sys.AMD64:
ctxt.Tlsoffset = 0
case '8':
case sys.I386:
ctxt.Tlsoffset = -8
}
@ -133,26 +134,26 @@ func linknew(arch *LinkArch) *Link {
* Explained in src/runtime/cgo/gcc_darwin_*.c.
*/
case obj.Hdarwin:
switch ctxt.Arch.Thechar {
switch ctxt.Arch.Family {
default:
log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name)
case '5':
case sys.ARM:
ctxt.Tlsoffset = 0 // dummy value, not needed
case '6':
case sys.AMD64:
ctxt.Tlsoffset = 0x8a0
case '7':
case sys.ARM64:
ctxt.Tlsoffset = 0 // dummy value, not needed
case '8':
case sys.I386:
ctxt.Tlsoffset = 0x468
}
}
// On arm, record goarm.
if ctxt.Arch.Thechar == '5' {
if ctxt.Arch.Family == sys.ARM {
ctxt.Goarm = obj.Getgoarm()
}

View File

@ -32,6 +32,7 @@ package ld
import (
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
"path/filepath"
"strings"
@ -160,7 +161,7 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
if x.Type&obj.SHIDDEN != 0 {
other = STV_HIDDEN
}
if (Buildmode == BuildmodePIE || DynlinkingGo()) && Thearch.Thechar == '9' && type_ == STT_FUNC && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
if (Buildmode == BuildmodePIE || DynlinkingGo()) && SysArch.Family == sys.PPC64 && type_ == STT_FUNC && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
// On ppc64 the top three bits of the st_other field indicate how
// many instructions separate the global and local entry points. In
// our case it is two instructions, indicated by the value 3.
@ -229,7 +230,7 @@ func putplan9sym(x *LSym, s string, t int, addr int64, size int64, ver int, go_
'Z',
'm':
l := 4
if HEADTYPE == obj.Hplan9 && Thearch.Thechar == '6' && Debug['8'] == 0 {
if HEADTYPE == obj.Hplan9 && SysArch.Family == sys.AMD64 && Debug['8'] == 0 {
Lputb(uint32(addr >> 32))
l = 8
}

View File

@ -32,6 +32,7 @@ package mips64
import (
"cmd/internal/obj"
"cmd/internal/sys"
"cmd/link/internal/ld"
"encoding/binary"
"fmt"
@ -82,8 +83,8 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
// the first instruction is always at the lower address, this is endian neutral;
// but note that o1 and o2 should still use the target endian.
o1 := ld.Thelinkarch.ByteOrder.Uint32(s.P[r.Off:])
o2 := ld.Thelinkarch.ByteOrder.Uint32(s.P[r.Off+4:])
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
o2 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off+4:])
o1 = o1&0xffff0000 | uint32(t>>16)&0xffff
o2 = o2&0xffff0000 | uint32(t)&0xffff
@ -99,7 +100,7 @@ func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
obj.R_JMPMIPS:
// Low 26 bits = (S + A) >> 2
t := ld.Symaddr(r.Sym) + r.Add
o1 := ld.Thelinkarch.ByteOrder.Uint32(s.P[r.Off:])
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
*val = int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000)
return 0
}
@ -214,7 +215,7 @@ func asmb() {
default:
case obj.Hplan9: /* plan 9 */
magic := uint32(4*18*18 + 7)
if ld.Thestring == "mips64le" {
if ld.SysArch == sys.ArchMIPS64LE {
magic = uint32(4*26*26 + 7)
}
ld.Thearch.Lput(uint32(magic)) /* magic */

View File

@ -62,11 +62,9 @@ package mips64
// THE SOFTWARE.
const (
thechar = '0'
MaxAlign = 32 // max data alignment
MinAlign = 1 // min data alignment
FuncAlign = 8
MINLC = 4
)
/* Used by ../internal/ld/dwarf.go */

View File

@ -32,6 +32,7 @@ package mips64
import (
"cmd/internal/obj"
"cmd/internal/sys"
"cmd/link/internal/ld"
"fmt"
"log"
@ -45,21 +46,15 @@ func Main() {
}
func linkarchinit() {
ld.Thestring = obj.Getgoarch()
if ld.Thestring == "mips64le" {
ld.Thelinkarch = &ld.Linkmips64le
if obj.Getgoarch() == "mips64le" {
ld.SysArch = sys.ArchMIPS64LE
} else {
ld.Thelinkarch = &ld.Linkmips64
ld.SysArch = sys.ArchMIPS64
}
ld.Thearch.Thechar = thechar
ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Regsize = ld.Thelinkarch.Regsize
ld.Thearch.Funcalign = FuncAlign
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minalign = MinAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR
@ -72,7 +67,7 @@ func linkarchinit() {
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
if ld.Thelinkarch == &ld.Linkmips64le {
if ld.SysArch == sys.ArchMIPS64LE {
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl

View File

@ -62,11 +62,9 @@ package ppc64
// THE SOFTWARE.
const (
thechar = '9'
MaxAlign = 32 // max data alignment
MinAlign = 1 // min data alignment
FuncAlign = 8
MINLC = 4
)
/* Used by ../internal/ld/dwarf.go */

View File

@ -32,6 +32,7 @@ package ppc64
import (
"cmd/internal/obj"
"cmd/internal/sys"
"cmd/link/internal/ld"
"fmt"
"log"
@ -45,21 +46,15 @@ func Main() {
}
func linkarchinit() {
ld.Thestring = obj.Getgoarch()
if ld.Thestring == "ppc64le" {
ld.Thelinkarch = &ld.Linkppc64le
if obj.Getgoarch() == "ppc64le" {
ld.SysArch = sys.ArchPPC64LE
} else {
ld.Thelinkarch = &ld.Linkppc64
ld.SysArch = sys.ArchPPC64
}
ld.Thearch.Thechar = thechar
ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Regsize = ld.Thelinkarch.Regsize
ld.Thearch.Funcalign = FuncAlign
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minalign = MinAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR
@ -72,7 +67,7 @@ func linkarchinit() {
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
if ld.Thelinkarch == &ld.Linkppc64le {
if ld.SysArch == sys.ArchPPC64LE {
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
@ -150,7 +145,7 @@ func archinit() {
}
case obj.Hlinux: /* ppc64 elf */
if ld.Thestring == "ppc64" {
if ld.SysArch == sys.ArchPPC64 {
ld.Debug['d'] = 1 // TODO(austin): ELF ABI v1 not supported yet
}
ld.Elfinit()

View File

@ -62,14 +62,9 @@ package s390x
// THE SOFTWARE.
const (
thechar = 'z'
PtrSize = 8
IntSize = 8
RegSize = 8
MaxAlign = 32 // max data alignment
MinAlign = 2 // min data alignment
FuncAlign = 16
MINLC = 2
)
/* Used by ../internal/ld/dwarf.go */

View File

@ -32,6 +32,7 @@ package s390x
import (
"cmd/internal/obj"
"cmd/internal/sys"
"cmd/link/internal/ld"
"fmt"
)
@ -44,17 +45,11 @@ func Main() {
}
func linkarchinit() {
ld.Thestring = obj.Getgoarch()
ld.Thelinkarch = &ld.Links390x
ld.SysArch = sys.ArchS390X
ld.Thearch.Thechar = thechar
ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Regsize = ld.Thelinkarch.Regsize
ld.Thearch.Funcalign = FuncAlign
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minalign = MinAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR

View File

@ -292,7 +292,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
return
}
if ld.HEADTYPE == obj.Hdarwin && s.Size == PtrSize && r.Off == 0 {
if ld.HEADTYPE == obj.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 {
// Mach-O relocations are a royal pain to lay out.
// They use a compact stateful bytecode representation
// that is too much bother to deal with.
@ -317,7 +317,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
return
}
if ld.HEADTYPE == obj.Hwindows && s.Size == PtrSize {
if ld.HEADTYPE == obj.Hwindows && s.Size == int64(ld.SysArch.PtrSize) {
// nothing to do, the relocation will be laid out in pereloc1
return
}

View File

@ -31,12 +31,9 @@
package x86
const (
thechar = '8'
PtrSize = 4
MaxAlign = 32 // max data alignment
MinAlign = 1 // min data alignment
FuncAlign = 16
MINLC = 1
)
/* Used by ../internal/ld/dwarf.go */

View File

@ -32,6 +32,7 @@ package x86
import (
"cmd/internal/obj"
"cmd/internal/sys"
"cmd/link/internal/ld"
"fmt"
"log"
@ -45,17 +46,11 @@ func Main() {
}
func linkarchinit() {
ld.Thestring = "386"
ld.Thelinkarch = &ld.Link386
ld.SysArch = sys.Arch386
ld.Thearch.Thechar = thechar
ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize
ld.Thearch.Regsize = ld.Thelinkarch.Regsize
ld.Thearch.Funcalign = FuncAlign
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minalign = MinAlign
ld.Thearch.Minlc = MINLC
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR