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:
parent
31cf1c1779
commit
c6e11fe037
@ -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])
|
||||
|
@ -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' {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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) &&
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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(®, Types[Tptr], n)
|
||||
Cgen(n, ®)
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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" {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
1
src/cmd/dist/buildtool.go
vendored
1
src/cmd/dist/buildtool.go
vendored
@ -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",
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
|
145
src/cmd/internal/sys/arch.go
Normal file
145
src/cmd/internal/sys/arch.go
Normal 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,
|
||||
}
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
}
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 = §.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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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()
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user