Commit 5d95de20 authored by David Crawshaw's avatar David Crawshaw

cmd/link: remove SysArch global variable

For #22095

Change-Id: I9d1f0d93f8fd701a24af826dc903eea2bc235de2
Reviewed-on: https://go-review.googlesource.com/67317
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 0a7ef31d
......@@ -32,6 +32,7 @@ package amd64
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"debug/elf"
"log"
......@@ -102,7 +103,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
switch r.Type {
default:
if r.Type >= 256 {
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(r.Type))
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
return false
}
......@@ -330,7 +331,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
return true
}
if ld.Headtype == objabi.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 {
if ld.Headtype == objabi.Hdarwin && s.Size == int64(ctxt.Arch.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.
......@@ -422,14 +423,14 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
return true
}
func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL {
if rs.Dynid < 0 {
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
return false
}
......@@ -438,7 +439,7 @@ func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
return false
}
}
......@@ -485,13 +486,13 @@ func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
return true
}
func pereloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func pereloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
if rs.Dynid < 0 {
ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
return false
}
......
......@@ -37,42 +37,46 @@ import (
"fmt"
)
func Init() {
ld.SysArch = sys.ArchAMD64
func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchAMD64
if objabi.GOARCH == "amd64p32" {
ld.SysArch = sys.ArchAMD64P32
}
ld.Thearch.Funcalign = funcAlign
ld.Thearch.Maxalign = maxAlign
ld.Thearch.Minalign = minAlign
ld.Thearch.Dwarfregsp = dwarfRegSP
ld.Thearch.Dwarfreglr = dwarfRegLR
ld.Thearch.Adddynrel = adddynrel
ld.Thearch.Archinit = archinit
ld.Thearch.Archreloc = archreloc
ld.Thearch.Archrelocvariant = archrelocvariant
ld.Thearch.Asmb = asmb
ld.Thearch.Elfreloc1 = elfreloc1
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
ld.Thearch.PEreloc1 = pereloc1
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
ld.Thearch.Append16 = ld.Append16l
ld.Thearch.Append32 = ld.Append32l
ld.Thearch.Append64 = ld.Append64l
ld.Thearch.TLSIEtoLE = tlsIEtoLE
ld.Thearch.Linuxdynld = "/lib64/ld-linux-x86-64.so.2"
ld.Thearch.Freebsddynld = "/libexec/ld-elf.so.1"
ld.Thearch.Openbsddynld = "/usr/libexec/ld.so"
ld.Thearch.Netbsddynld = "/libexec/ld.elf_so"
ld.Thearch.Dragonflydynld = "/usr/libexec/ld-elf.so.2"
ld.Thearch.Solarisdynld = "/lib/amd64/ld.so.1"
arch = sys.ArchAMD64P32
}
theArch := ld.Arch{
Funcalign: funcAlign,
Maxalign: maxAlign,
Minalign: minAlign,
Dwarfregsp: dwarfRegSP,
Dwarfreglr: dwarfRegLR,
Adddynrel: adddynrel,
Archinit: archinit,
Archreloc: archreloc,
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Elfreloc1: elfreloc1,
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
PEreloc1: pereloc1,
Lput: ld.Lputl,
Wput: ld.Wputl,
Vput: ld.Vputl,
Append16: ld.Append16l,
Append32: ld.Append32l,
Append64: ld.Append64l,
TLSIEtoLE: tlsIEtoLE,
Linuxdynld: "/lib64/ld-linux-x86-64.so.2",
Freebsddynld: "/libexec/ld-elf.so.1",
Openbsddynld: "/usr/libexec/ld.so",
Netbsddynld: "/libexec/ld.elf_so",
Dragonflydynld: "/usr/libexec/ld-elf.so.2",
Solarisdynld: "/lib/amd64/ld.so.1",
}
return arch, theArch
}
func archinit(ctxt *ld.Link) {
......@@ -94,8 +98,6 @@ func archinit(ctxt *ld.Link) {
}
case objabi.Hdarwin: /* apple MACH */
ld.Machoinit()
ld.HEADR = ld.INITIAL_MACHO_HEADR
if *ld.FlagRound == -1 {
*ld.FlagRound = 4096
......
......@@ -32,6 +32,7 @@ package arm
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"fmt"
"log"
......@@ -118,7 +119,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
switch r.Type {
default:
if r.Type >= 256 {
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(r.Type))
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
return false
}
......@@ -320,7 +321,7 @@ func elfsetupplt(ctxt *ld.Link) {
}
}
func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
......@@ -357,7 +358,7 @@ func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_CALLARM {
if rs.Dynid < 0 {
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
return false
}
......@@ -366,7 +367,7 @@ func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
return false
}
}
......@@ -461,11 +462,11 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
if immrot(uint32(offset)) == 0 {
ld.Errorf(s, "odd offset in dynlink direct call: %v+%d", r.Sym, offset)
}
gentrampdyn(tramp, r.Sym, int64(offset))
gentrampdyn(ctxt.Arch, tramp, r.Sym, int64(offset))
} else if ld.Buildmode == ld.BuildmodeCArchive || ld.Buildmode == ld.BuildmodeCShared || ld.Buildmode == ld.BuildmodePIE {
gentramppic(tramp, r.Sym, int64(offset))
gentramppic(ctxt.Arch, tramp, r.Sym, int64(offset))
} else {
gentramp(tramp, r.Sym, int64(offset))
gentramp(ctxt.Arch, tramp, r.Sym, int64(offset))
}
}
// modify reloc to point to tramp, which will be resolved later
......@@ -474,21 +475,21 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
r.Done = false
}
default:
ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, ld.RelocName(r.Type))
ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
}
}
// generate a trampoline to target+offset
func gentramp(tramp, target *ld.Symbol, offset int64) {
func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
tramp.Size = 12 // 3 instructions
tramp.P = make([]byte, tramp.Size)
t := ld.Symaddr(target) + int64(offset)
o1 := uint32(0xe5900000 | 11<<12 | 15<<16) // MOVW (R15), R11 // R15 is actual pc + 8
o2 := uint32(0xe12fff10 | 11) // JMP (R11)
o3 := uint32(t) // WORD $target
ld.SysArch.ByteOrder.PutUint32(tramp.P, o1)
ld.SysArch.ByteOrder.PutUint32(tramp.P[4:], o2)
ld.SysArch.ByteOrder.PutUint32(tramp.P[8:], o3)
arch.ByteOrder.PutUint32(tramp.P, o1)
arch.ByteOrder.PutUint32(tramp.P[4:], o2)
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
if ld.Linkmode == ld.LinkExternal {
r := ld.Addrel(tramp)
......@@ -501,17 +502,17 @@ func gentramp(tramp, target *ld.Symbol, offset int64) {
}
// generate a trampoline to target+offset in position independent code
func gentramppic(tramp, target *ld.Symbol, offset int64) {
func gentramppic(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
tramp.Size = 16 // 4 instructions
tramp.P = make([]byte, tramp.Size)
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 4) // MOVW 4(R15), R11 // R15 is actual pc + 8
o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
o3 := uint32(0xe12fff10 | 11) // JMP (R11)
o4 := uint32(0) // WORD $(target-pc) // filled in with relocation
ld.SysArch.ByteOrder.PutUint32(tramp.P, o1)
ld.SysArch.ByteOrder.PutUint32(tramp.P[4:], o2)
ld.SysArch.ByteOrder.PutUint32(tramp.P[8:], o3)
ld.SysArch.ByteOrder.PutUint32(tramp.P[12:], o4)
arch.ByteOrder.PutUint32(tramp.P, o1)
arch.ByteOrder.PutUint32(tramp.P[4:], o2)
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
r := ld.Addrel(tramp)
r.Off = 12
......@@ -522,7 +523,7 @@ func gentramppic(tramp, target *ld.Symbol, offset int64) {
}
// generate a trampoline to target+offset in dynlink mode (using GOT)
func gentrampdyn(tramp, target *ld.Symbol, offset int64) {
func gentrampdyn(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
tramp.Size = 20 // 5 instructions
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 8) // MOVW 8(R15), R11 // R15 is actual pc + 8
o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
......@@ -539,13 +540,13 @@ func gentrampdyn(tramp, target *ld.Symbol, offset int64) {
o1 = uint32(0xe5900000 | 11<<12 | 15<<16 | 12) // MOVW 12(R15), R11
}
tramp.P = make([]byte, tramp.Size)
ld.SysArch.ByteOrder.PutUint32(tramp.P, o1)
ld.SysArch.ByteOrder.PutUint32(tramp.P[4:], o2)
ld.SysArch.ByteOrder.PutUint32(tramp.P[8:], o3)
ld.SysArch.ByteOrder.PutUint32(tramp.P[12:], o4)
ld.SysArch.ByteOrder.PutUint32(tramp.P[16:], o5)
arch.ByteOrder.PutUint32(tramp.P, o1)
arch.ByteOrder.PutUint32(tramp.P[4:], o2)
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
arch.ByteOrder.PutUint32(tramp.P[16:], o5)
if offset != 0 {
ld.SysArch.ByteOrder.PutUint32(tramp.P[20:], o6)
arch.ByteOrder.PutUint32(tramp.P[20:], o6)
}
r := ld.Addrel(tramp)
......
......@@ -37,38 +37,42 @@ import (
"fmt"
)
func Init() {
ld.SysArch = sys.ArchARM
func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchARM
ld.Thearch.Funcalign = funcAlign
ld.Thearch.Maxalign = maxAlign
ld.Thearch.Minalign = minAlign
ld.Thearch.Dwarfregsp = dwarfRegSP
ld.Thearch.Dwarfreglr = dwarfRegLR
theArch := ld.Arch{
Funcalign: funcAlign,
Maxalign: maxAlign,
Minalign: minAlign,
Dwarfregsp: dwarfRegSP,
Dwarfreglr: dwarfRegLR,
ld.Thearch.Adddynrel = adddynrel
ld.Thearch.Archinit = archinit
ld.Thearch.Archreloc = archreloc
ld.Thearch.Archrelocvariant = archrelocvariant
ld.Thearch.Trampoline = trampoline
ld.Thearch.Asmb = asmb
ld.Thearch.Elfreloc1 = elfreloc1
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
ld.Thearch.Append16 = ld.Append16l
ld.Thearch.Append32 = ld.Append32l
ld.Thearch.Append64 = ld.Append64l
Adddynrel: adddynrel,
Archinit: archinit,
Archreloc: archreloc,
Archrelocvariant: archrelocvariant,
Trampoline: trampoline,
Asmb: asmb,
Elfreloc1: elfreloc1,
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
Lput: ld.Lputl,
Wput: ld.Wputl,
Vput: ld.Vputl,
Append16: ld.Append16l,
Append32: ld.Append32l,
Append64: ld.Append64l,
ld.Thearch.Linuxdynld = "/lib/ld-linux.so.3" // 2 for OABI, 3 for EABI
ld.Thearch.Freebsddynld = "/usr/libexec/ld-elf.so.1"
ld.Thearch.Openbsddynld = "/usr/libexec/ld.so"
ld.Thearch.Netbsddynld = "/libexec/ld.elf_so"
ld.Thearch.Dragonflydynld = "XXX"
ld.Thearch.Solarisdynld = "XXX"
Linuxdynld: "/lib/ld-linux.so.3", // 2 for OABI, 3 for EABI
Freebsddynld: "/usr/libexec/ld-elf.so.1",
Openbsddynld: "/usr/libexec/ld.so",
Netbsddynld: "/libexec/ld.elf_so",
Dragonflydynld: "XXX",
Solarisdynld: "XXX",
}
return arch, theArch
}
func archinit(ctxt *ld.Link) {
......@@ -123,7 +127,6 @@ func archinit(ctxt *ld.Link) {
case objabi.Hdarwin: /* apple MACH */
*ld.FlagW = true // disable DWARF generation
ld.Machoinit()
ld.HEADR = ld.INITIAL_MACHO_HEADR
if *ld.FlagTextAddr == -1 {
*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
......
......@@ -32,6 +32,7 @@ package arm64
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"encoding/binary"
"fmt"
......@@ -142,7 +143,7 @@ func elfsetupplt(ctxt *ld.Link) {
return
}
func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
......@@ -152,7 +153,7 @@ func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
// UNSIGNED relocation at all.
if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 || r.Type == objabi.R_ADDR {
if rs.Dynid < 0 {
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
return false
}
......@@ -161,7 +162,7 @@ func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
return false
}
}
......@@ -348,7 +349,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
}
// 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.SysArch.PtrSize)
v := r.Sym.Value + int64(2*ctxt.Arch.PtrSize)
if v < 0 || v >= 32678 {
ld.Errorf(s, "TLS offset out of range %d", v)
}
......
......@@ -37,38 +37,42 @@ import (
"fmt"
)
func Init() {
ld.SysArch = sys.ArchARM64
func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchARM64
ld.Thearch.Funcalign = funcAlign
ld.Thearch.Maxalign = maxAlign
ld.Thearch.Minalign = minAlign
ld.Thearch.Dwarfregsp = dwarfRegSP
ld.Thearch.Dwarfreglr = dwarfRegLR
theArch := ld.Arch{
Funcalign: funcAlign,
Maxalign: maxAlign,
Minalign: minAlign,
Dwarfregsp: dwarfRegSP,
Dwarfreglr: dwarfRegLR,
ld.Thearch.Adddynrel = adddynrel
ld.Thearch.Archinit = archinit
ld.Thearch.Archreloc = archreloc
ld.Thearch.Archrelocvariant = archrelocvariant
ld.Thearch.Asmb = asmb
ld.Thearch.Elfreloc1 = elfreloc1
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
ld.Thearch.Append16 = ld.Append16l
ld.Thearch.Append32 = ld.Append32l
ld.Thearch.Append64 = ld.Append64l
Adddynrel: adddynrel,
Archinit: archinit,
Archreloc: archreloc,
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Elfreloc1: elfreloc1,
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
Lput: ld.Lputl,
Wput: ld.Wputl,
Vput: ld.Vputl,
Append16: ld.Append16l,
Append32: ld.Append32l,
Append64: ld.Append64l,
ld.Thearch.Linuxdynld = "/lib/ld-linux-aarch64.so.1"
Linuxdynld: "/lib/ld-linux-aarch64.so.1",
ld.Thearch.Freebsddynld = "XXX"
ld.Thearch.Openbsddynld = "XXX"
ld.Thearch.Netbsddynld = "XXX"
ld.Thearch.Dragonflydynld = "XXX"
ld.Thearch.Solarisdynld = "XXX"
Freebsddynld: "XXX",
Openbsddynld: "XXX",
Netbsddynld: "XXX",
Dragonflydynld: "XXX",
Solarisdynld: "XXX",
}
return arch, theArch
}
func archinit(ctxt *ld.Link) {
......@@ -104,7 +108,6 @@ func archinit(ctxt *ld.Link) {
case objabi.Hdarwin: /* apple MACH */
*ld.FlagW = true // disable DWARF generation
ld.Machoinit()
ld.HEADR = ld.INITIAL_MACHO_HEADR
if *ld.FlagTextAddr == -1 {
*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
......
......@@ -178,7 +178,7 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) {
case "android":
return true, "android"
case "darwin":
if SysArch.InFamily(sys.ARM, sys.ARM64) {
if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
return true, "iOS"
}
}
......@@ -191,7 +191,7 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) {
// https://golang.org/issue/10373
// https://golang.org/issue/14449
// https://golang.org/issue/21961
if iscgo && SysArch.InFamily(sys.ARM64, sys.MIPS64, sys.MIPS, sys.PPC64) {
if iscgo && ctxt.Arch.InFamily(sys.ARM64, sys.MIPS64, sys.MIPS, sys.PPC64) {
return true, objabi.GOARCH + " does not support internal cgo"
}
......
This diff is collapsed.
......@@ -199,7 +199,7 @@ func (d *deadcodepass) markMethod(m methodref) {
func (d *deadcodepass) init() {
var names []string
if SysArch.Family == sys.ARM {
if d.ctxt.Arch.Family == sys.ARM {
// mark some functions that are only referenced after linker code editing
names = append(names, "runtime.read_tls_fallback")
}
......@@ -221,7 +221,7 @@ func (d *deadcodepass) init() {
} else {
// The external linker refers main symbol directly.
if Linkmode == LinkExternal && (Buildmode == BuildmodeExe || Buildmode == BuildmodePIE) {
if Headtype == objabi.Hwindows && SysArch.Family == sys.I386 {
if Headtype == objabi.Hwindows && d.ctxt.Arch.Family == sys.I386 {
*flagEntrySymbol = "_main"
} else {
*flagEntrySymbol = "main"
......@@ -275,7 +275,7 @@ func (d *deadcodepass) flood() {
// later will give a better error than deadcode.
continue
}
if decodetypeKind(s)&kindMask == kindInterface {
if decodetypeKind(d.ctxt.Arch, s)&kindMask == kindInterface {
for _, sig := range decodeIfaceMethods(d.ctxt.Arch, s) {
if d.ctxt.Debugvlog > 1 {
d.ctxt.Logf("reached iface method: %s\n", sig)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -528,9 +528,9 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
return
}
switch SysArch.Family {
switch ctxt.Arch.Family {
default:
Errorf(nil, "%s: elf %s unimplemented", pn, SysArch.Name)
Errorf(nil, "%s: elf %s unimplemented", pn, ctxt.Arch.Name)
return
case sys.MIPS:
......@@ -1051,7 +1051,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, loc
}
case ElfSymBindLocal:
if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
if ctxt.Arch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
// binutils for arm generate these mapping
// symbols, ignore these
break
......@@ -1134,7 +1134,7 @@ func relSize(ctxt *Link, pn string, elftype uint32) uint8 {
S390X = uint32(sys.S390X)
)
switch uint32(SysArch.Family) | elftype<<24 {
switch uint32(ctxt.Arch.Family) | elftype<<24 {
default:
Errorf(nil, "%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
fallthrough
......
......@@ -480,9 +480,9 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
m.length = length
m.name = pn
switch SysArch.Family {
switch ctxt.Arch.Family {
default:
Errorf(nil, "%s: mach-o %s unimplemented", pn, SysArch.Name)
Errorf(nil, "%s: mach-o %s unimplemented", pn, ctxt.Arch.Name)
return
case sys.AMD64:
......@@ -731,7 +731,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
rp = &r[rpi]
rel = &sect.rel[j]
if rel.scattered != 0 {
if SysArch.Family != sys.I386 {
if ctxt.Arch.Family != sys.I386 {
// mach-o only uses scattered relocation on 32-bit platforms
Errorf(s, "unexpected scattered relocation")
continue
......@@ -827,7 +827,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
rp.Off = int32(rel.addr)
// Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
if SysArch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_SIGNED {
if ctxt.Arch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_SIGNED {
// Calculate the addend as the offset into the section.
//
// The rip-relative offset stored in the object file is encoded
......@@ -852,7 +852,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
// An unsigned internal relocation has a value offset
// by the section address.
if SysArch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_UNSIGNED {
if ctxt.Arch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_UNSIGNED {
secaddr = c.seg.sect[rel.symnum-1].addr
rp.Add -= int64(secaddr)
}
......@@ -860,7 +860,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, 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 && SysArch.Family == sys.I386 {
if rel.pcrel != 0 && ctxt.Arch.Family == sys.I386 {
rp.Add += int64(rp.Off) + int64(rp.Siz)
}
if rel.extrn == 0 {
......@@ -879,7 +879,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
// include that information in the addend.
// We only care about the delta from the
// section base.
if SysArch.Family == sys.I386 {
if ctxt.Arch.Family == sys.I386 {
rp.Add -= int64(c.seg.sect[rel.symnum-1].addr)
}
} else {
......
......@@ -404,7 +404,7 @@ func readpesym(ctxt *Link, f *pe.File, sym *pe.COFFSymbol, sectsyms map[*pe.Sect
if strings.HasPrefix(name, "__imp_") {
name = name[6:] // __imp_Name => Name
}
if SysArch.Family == sys.I386 && name[0] == '_' {
if ctxt.Arch.Family == sys.I386 && name[0] == '_' {
name = name[1:] // _Name => Name
}
}
......
......@@ -105,8 +105,8 @@ type Arch struct {
Elfreloc1 func(*Link, *Reloc, int64) bool
Elfsetupplt func(*Link)
Gentext func(*Link)
Machoreloc1 func(*Symbol, *Reloc, int64) bool
PEreloc1 func(*Symbol, *Reloc, int64) bool
Machoreloc1 func(*sys.Arch, *Symbol, *Reloc, int64) bool
PEreloc1 func(*sys.Arch, *Symbol, *Reloc, int64) bool
Wput func(uint16)
Lput func(uint32)
Vput func(uint64)
......@@ -188,7 +188,6 @@ func UseRelro() bool {
}
var (
SysArch *sys.Arch
dynexp []*Symbol
dynlib []string
ldflag []string
......@@ -379,7 +378,7 @@ func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
if *flagExtld == "" {
*flagExtld = "gcc"
}
args := hostlinkArchArgs()
args := hostlinkArchArgs(ctxt.Arch)
args = append(args, cmd)
if ctxt.Debugvlog != 0 {
ctxt.Logf("%s %v\n", *flagExtld, args)
......@@ -413,7 +412,7 @@ func (ctxt *Link) loadlib() {
}
loadinternal(ctxt, "runtime")
if SysArch.Family == sys.ARM {
if ctxt.Arch.Family == sys.ARM {
loadinternal(ctxt, "math")
}
if *flagRace {
......@@ -457,7 +456,7 @@ func (ctxt *Link) loadlib() {
*FlagTextAddr = 0
}
if Linkmode == LinkExternal && SysArch.Family == sys.PPC64 {
if Linkmode == LinkExternal && ctxt.Arch.Family == sys.PPC64 {
toc := ctxt.Syms.Lookup(".TOC.", 0)
toc.Type = SDYNIMPORT
}
......@@ -503,7 +502,7 @@ func (ctxt *Link) loadlib() {
// a variable to hold g in assembly (currently only intel).
if tlsg.Type == 0 {
tlsg.Type = STLSBSS
tlsg.Size = int64(SysArch.PtrSize)
tlsg.Size = int64(ctxt.Arch.PtrSize)
} else if tlsg.Type != SDYNIMPORT {
Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
}
......@@ -527,7 +526,7 @@ func (ctxt *Link) loadlib() {
// In addition, on ARM, the runtime depends on the linker
// recording the value of GOARM.
if SysArch.Family == sys.ARM {
if ctxt.Arch.Family == sys.ARM {
s := ctxt.Syms.Lookup("runtime.goarm", 0)
s.Type = SRODATA
s.Size = 0
......@@ -639,7 +638,7 @@ func (ctxt *Link) loadlib() {
}
}
if SysArch == sys.Arch386 {
if ctxt.Arch == sys.Arch386 {
if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
got.Type = SDYNIMPORT
......@@ -1082,7 +1081,7 @@ func (l *Link) hostlink() {
var argv []string
argv = append(argv, *flagExtld)
argv = append(argv, hostlinkArchArgs()...)
argv = append(argv, hostlinkArchArgs(l.Arch)...)
if !*FlagS && !debug_s {
argv = append(argv, "-gdwarf-2")
......@@ -1100,7 +1099,7 @@ func (l *Link) hostlink() {
if l.DynlinkingGo() {
argv = append(argv, "-Wl,-flat_namespace")
}
if Buildmode == BuildmodeExe && !SysArch.InFamily(sys.ARM64) {
if Buildmode == BuildmodeExe && !l.Arch.InFamily(sys.ARM64) {
argv = append(argv, "-Wl,-no_pie")
}
case objabi.Hopenbsd:
......@@ -1129,7 +1128,7 @@ func (l *Link) hostlink() {
case BuildmodeCShared:
if Headtype == objabi.Hdarwin {
argv = append(argv, "-dynamiclib")
if SysArch.Family != sys.AMD64 {
if l.Arch.Family != sys.AMD64 {
argv = append(argv, "-Wl,-read_only_relocs,suppress")
}
} else {
......@@ -1169,7 +1168,7 @@ func (l *Link) hostlink() {
// from the beginning of the section (like STYPE).
argv = append(argv, "-Wl,-znocopyreloc")
if SysArch.InFamily(sys.ARM, sys.ARM64) {
if l.Arch.InFamily(sys.ARM, sys.ARM64) {
// On ARM, the GNU linker will generate COPY relocations
// even with -znocopyreloc set.
// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
......@@ -1335,7 +1334,7 @@ func (l *Link) hostlink() {
if !*FlagS && !*FlagW && !debug_s && Headtype == objabi.Hdarwin {
// Skip combining dwarf on arm.
if !SysArch.InFamily(sys.ARM, sys.ARM64) {
if !l.Arch.InFamily(sys.ARM, sys.ARM64) {
dsym := filepath.Join(*flagTmpdir, "go.dwarf")
if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
......@@ -1359,8 +1358,8 @@ func (l *Link) hostlink() {
// hostlinkArchArgs returns arguments to pass to the external linker
// based on the architecture.
func hostlinkArchArgs() []string {
switch SysArch.Family {
func hostlinkArchArgs(arch *sys.Arch) []string {
switch arch.Family {
case sys.I386:
return []string{"-m32"}
case sys.AMD64, sys.PPC64, sys.S390X:
......@@ -1417,7 +1416,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *Library, length int64, pn string, fil
return nil
}
if line == SysArch.Name {
if line == ctxt.Arch.Name {
// old header format: just $GOOS
Errorf(nil, "%s: stale object file", pn)
return nil
......@@ -1633,12 +1632,12 @@ func ldshlibsyms(ctxt *Link, shlib string) {
// the type data.
if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
lsym.P = readelfsymboldata(ctxt, f, &elfsym)
gcdataLocations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym
gcdataLocations[elfsym.Value+2*uint64(ctxt.Arch.PtrSize)+8+1*uint64(ctxt.Arch.PtrSize)] = lsym
}
}
}
gcdataAddresses := make(map[*Symbol]uint64)
if SysArch.Family == sys.ARM64 {
if ctxt.Arch.Family == sys.ARM64 {
for _, sect := range f.Sections {
if sect.Type == elf.SHT_RELA {
var rela elf.Rela64
......@@ -1666,12 +1665,12 @@ func ldshlibsyms(ctxt *Link, shlib string) {
ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses})
}
func addsection(seg *Segment, name string, rwx int) *Section {
func addsection(arch *sys.Arch, seg *Segment, name string, rwx int) *Section {
sect := new(Section)
sect.Rwx = uint8(rwx)
sect.Name = name
sect.Seg = seg
sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned
sect.Align = int32(arch.PtrSize) // everything is at least pointer-aligned
seg.Sections = append(seg.Sections, sect)
return sect
}
......@@ -1715,7 +1714,7 @@ func callsize(ctxt *Link) int {
if haslinkregister(ctxt) {
return 0
}
return SysArch.RegSize
return ctxt.Arch.RegSize
}
func (ctxt *Link) dostkcheck() {
......@@ -2077,7 +2076,7 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
locals = s.FuncInfo.Locals
}
// NOTE(ality): acid can't produce a stack trace without .frame symbols
put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(SysArch.PtrSize), nil)
put(ctxt, nil, ".frame", FrameSym, int64(locals)+int64(ctxt.Arch.PtrSize), nil)
if s.FuncInfo == nil {
continue
......@@ -2093,7 +2092,7 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
if a.Name == objabi.A_PARAM {
off = a.Aoffset
} else {
off = a.Aoffset - int32(SysArch.PtrSize)
off = a.Aoffset - int32(ctxt.Arch.PtrSize)
}
// FP
......@@ -2103,8 +2102,8 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
}
// SP
if off <= int32(-SysArch.PtrSize) {
put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(SysArch.PtrSize)), a.Gotype)
if off <= int32(-ctxt.Arch.PtrSize) {
put(ctxt, nil, a.Asym.Name, AutoSym, -(int64(off) + int64(ctxt.Arch.PtrSize)), a.Gotype)
continue
}
// Otherwise, off is addressing the saved program counter.
......
......@@ -331,14 +331,14 @@ const (
RV_TYPE_MASK RelocVariant = RV_CHECK_OVERFLOW - 1
)
func RelocName(r objabi.RelocType) string {
func RelocName(arch *sys.Arch, r objabi.RelocType) string {
// We didn't have some relocation types at Go1.4.
// Uncomment code when we include those in bootstrap code.
switch {
case r >= 512: // Mach-O
// nr := (r - 512)>>1
// switch SysArch.Family {
// switch ctxt.Arch.Family {
// case sys.AMD64:
// return macho.RelocTypeX86_64(nr).String()
// case sys.ARM:
......@@ -352,7 +352,7 @@ func RelocName(r objabi.RelocType) string {
// }
case r >= 256: // ELF
nr := r - 256
switch SysArch.Family {
switch arch.Family {
case sys.AMD64:
return elf.R_X86_64(nr).String()
case sys.ARM:
......
......@@ -148,8 +148,6 @@ const (
// Mach-O file writing
// http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
var macho64 bool
var machohdr MachoHdr
var load []MachoLoad
......@@ -183,16 +181,12 @@ var nsortsym int
// up about 1300 bytes; we overestimate that as 2k.
var loadBudget int = INITIAL_MACHO_HEADR - 2*1024
func Machoinit() {
macho64 = SysArch.RegSize == 8
}
func getMachoHdr() *MachoHdr {
return &machohdr
}
func newMachoLoad(type_ uint32, ndata uint32) *MachoLoad {
if macho64 && (ndata&1 != 0) {
func newMachoLoad(arch *sys.Arch, type_ uint32, ndata uint32) *MachoLoad {
if arch.PtrSize == 8 && (ndata&1 != 0) {
ndata++
}
......@@ -235,14 +229,14 @@ var dylib []string
var linkoff int64
func machowrite() int {
func machowrite(arch *sys.Arch) int {
o1 := coutbuf.Offset()
loadsize := 4 * 4 * ndebug
for i := 0; i < len(load); i++ {
loadsize += 4 * (len(load[i].data) + 2)
}
if macho64 {
if arch.PtrSize == 8 {
loadsize += 18 * 4 * nseg
loadsize += 20 * 4 * nsect
} else {
......@@ -250,7 +244,7 @@ func machowrite() int {
loadsize += 17 * 4 * nsect
}
if macho64 {
if arch.PtrSize == 8 {
Thearch.Lput(MH_MAGIC_64)
} else {
Thearch.Lput(MH_MAGIC)
......@@ -269,13 +263,13 @@ func machowrite() int {
} else {
Thearch.Lput(0) /* flags */
}
if macho64 {
if arch.PtrSize == 8 {
Thearch.Lput(0) /* reserved */
}
for i := 0; i < nseg; i++ {
s := &seg[i]
if macho64 {
if arch.PtrSize == 8 {
Thearch.Lput(LC_SEGMENT_64)
Thearch.Lput(72 + 80*s.nsect)
strnput(s.name, 16)
......@@ -303,7 +297,7 @@ func machowrite() int {
for j := uint32(0); j < s.nsect; j++ {
t := &s.sect[j]
if macho64 {
if arch.PtrSize == 8 {
strnput(t.name, 16)
strnput(t.segname, 16)
Thearch.Vput(t.addr)
......@@ -406,9 +400,9 @@ func machoshbits(ctxt *Link, mseg *MachoSeg, sect *Section, segname string) {
buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
var msect *MachoSect
if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 ||
(SysArch.Family == sys.AMD64 && Buildmode != BuildmodeExe) ||
(SysArch.Family == sys.ARM && Buildmode != BuildmodeExe)) {
if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 ||
(ctxt.Arch.Family == sys.AMD64 && Buildmode != BuildmodeExe) ||
(ctxt.Arch.Family == sys.ARM && Buildmode != BuildmodeExe)) {
// Darwin external linker on arm64 and on amd64 and arm in c-shared/c-archive buildmode
// complains about absolute relocs in __TEXT, so if the section is not
// executable, put it in __DATA segment.
......@@ -471,9 +465,9 @@ func Asmbmacho(ctxt *Link) {
va := *FlagTextAddr - int64(HEADR)
mh := getMachoHdr()
switch SysArch.Family {
switch ctxt.Arch.Family {
default:
Exitf("unknown macho architecture: %v", SysArch.Family)
Exitf("unknown macho architecture: %v", ctxt.Arch.Family)
case sys.ARM:
mh.cpu = MACHO_CPU_ARM
......@@ -498,7 +492,7 @@ func Asmbmacho(ctxt *Link) {
ms = newMachoSeg("", 40)
ms.fileoffset = Segtext.Fileoff
if SysArch.Family == sys.ARM || Buildmode == BuildmodeCArchive {
if ctxt.Arch.Family == sys.ARM || Buildmode == BuildmodeCArchive {
ms.filesize = Segdata.Fileoff + Segdata.Filelen - Segtext.Fileoff
} else {
ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
......@@ -560,32 +554,32 @@ func Asmbmacho(ctxt *Link) {
}
if Linkmode != LinkExternal {
switch SysArch.Family {
switch ctxt.Arch.Family {
default:
Exitf("unknown macho architecture: %v", SysArch.Family)
Exitf("unknown macho architecture: %v", ctxt.Arch.Family)
case sys.ARM:
ml := newMachoLoad(LC_UNIXTHREAD, 17+2)
ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 17+2)
ml.data[0] = 1 /* thread type */
ml.data[1] = 17 /* word count */
ml.data[2+15] = uint32(Entryvalue(ctxt)) /* start pc */
case sys.AMD64:
ml := newMachoLoad(LC_UNIXTHREAD, 42+2)
ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 42+2)
ml.data[0] = 4 /* thread type */
ml.data[1] = 42 /* word count */
ml.data[2+32] = uint32(Entryvalue(ctxt)) /* start pc */
ml.data[2+32+1] = uint32(Entryvalue(ctxt) >> 32)
case sys.ARM64:
ml := newMachoLoad(LC_UNIXTHREAD, 68+2)
ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 68+2)
ml.data[0] = 6 /* thread type */
ml.data[1] = 68 /* word count */
ml.data[2+64] = uint32(Entryvalue(ctxt)) /* start pc */
ml.data[2+64+1] = uint32(Entryvalue(ctxt) >> 32)
case sys.I386:
ml := newMachoLoad(LC_UNIXTHREAD, 16+2)
ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 16+2)
ml.data[0] = 1 /* thread type */
ml.data[1] = 16 /* word count */
ml.data[2+10] = uint32(Entryvalue(ctxt)) /* start pc */
......@@ -609,7 +603,7 @@ func Asmbmacho(ctxt *Link) {
ms.prot2 = 3
}
ml := newMachoLoad(LC_SYMTAB, 4)
ml := newMachoLoad(ctxt.Arch, LC_SYMTAB, 4)
ml.data[0] = uint32(linkoff) /* symoff */
ml.data[1] = uint32(nsortsym) /* nsyms */
ml.data[2] = uint32(linkoff + s1.Size + s2.Size + s3.Size) /* stroff */
......@@ -618,12 +612,12 @@ func Asmbmacho(ctxt *Link) {
machodysymtab(ctxt)
if Linkmode != LinkExternal {
ml := newMachoLoad(LC_LOAD_DYLINKER, 6)
ml := newMachoLoad(ctxt.Arch, LC_LOAD_DYLINKER, 6)
ml.data[0] = 12 /* offset to string */
stringtouint32(ml.data[1:], "/usr/lib/dyld")
for i := 0; i < len(dylib); i++ {
ml = newMachoLoad(LC_LOAD_DYLIB, 4+(uint32(len(dylib[i]))+1+7)/8*2)
ml = newMachoLoad(ctxt.Arch, LC_LOAD_DYLIB, 4+(uint32(len(dylib[i]))+1+7)/8*2)
ml.data[0] = 24 /* offset of string from beginning of load */
ml.data[1] = 0 /* time stamp */
ml.data[2] = 0 /* version */
......@@ -642,12 +636,12 @@ func Asmbmacho(ctxt *Link) {
// and we can assume OS X.
//
// See golang.org/issues/12941.
ml := newMachoLoad(LC_VERSION_MIN_MACOSX, 2)
ml := newMachoLoad(ctxt.Arch, LC_VERSION_MIN_MACOSX, 2)
ml.data[0] = 10<<16 | 7<<8 | 0<<0 // OS X version 10.7.0
ml.data[1] = 10<<16 | 7<<8 | 0<<0 // SDK 10.7.0
}
a := machowrite()
a := machowrite(ctxt.Arch)
if int32(a) > HEADR {
Exitf("HEADR too small: %d > %d", a, HEADR)
}
......@@ -790,7 +784,7 @@ func machosymtab(ctxt *Link) {
Adduint8(ctxt, symtab, 0x01) // type N_EXT, external symbol
Adduint8(ctxt, symtab, 0) // no section
Adduint16(ctxt, symtab, 0) // desc
adduintxx(ctxt, symtab, 0, SysArch.PtrSize) // no value
adduintxx(ctxt, symtab, 0, ctxt.Arch.PtrSize) // no value
} else {
if s.Attr.CgoExport() || export {
Adduint8(ctxt, symtab, 0x0f)
......@@ -808,13 +802,13 @@ func machosymtab(ctxt *Link) {
Adduint8(ctxt, symtab, uint8(o.Sect.Extnum))
}
Adduint16(ctxt, symtab, 0) // desc
adduintxx(ctxt, symtab, uint64(Symaddr(s)), SysArch.PtrSize)
adduintxx(ctxt, symtab, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
}
}
}
func machodysymtab(ctxt *Link) {
ml := newMachoLoad(LC_DYSYMTAB, 18)
ml := newMachoLoad(ctxt.Arch, LC_DYSYMTAB, 18)
n := 0
ml.data[0] = uint32(n) /* ilocalsym */
......@@ -930,10 +924,10 @@ func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
continue
}
if !r.Xsym.Attr.Reachable() {
Errorf(sym, "unreachable reloc %d (%s) target %v", r.Type, RelocName(r.Type), r.Xsym.Name)
Errorf(sym, "unreachable reloc %d (%s) target %v", r.Type, RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
}
if !Thearch.Machoreloc1(sym, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) {
Errorf(sym, "unsupported obj reloc %d (%s)/%d to %s", r.Type, RelocName(r.Type), r.Siz, r.Sym.Name)
if !Thearch.Machoreloc1(ctxt.Arch, sym, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) {
Errorf(sym, "unsupported obj reloc %d (%s)/%d to %s", r.Type, RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
}
}
}
......
......@@ -100,8 +100,9 @@ var (
)
// Main is the main entry point for the linker code.
func Main() {
ctxt := linknew(SysArch)
func Main(arch *sys.Arch, theArch Arch) {
Thearch = theArch
ctxt := linknew(arch)
ctxt.Bso = bufio.NewWriter(os.Stdout)
// For testing behavior of go command when tools crash silently.
......@@ -114,7 +115,7 @@ func Main() {
}
// TODO(matloob): define these above and then check flag values here
if SysArch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
if ctxt.Arch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
flag.BoolVar(&Flag8, "8", false, "use 64-bit addresses in symbol table")
}
objabi.Flagfn1("B", "add an ELF NT_GNU_BUILD_ID `note` when using ELF", addbuildinfo)
......
......@@ -226,12 +226,12 @@ func (ctxt *Link) pclntab() {
}
pclntabNfunc = nfunc
Symgrow(ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize)+4)
Symgrow(ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize)+4)
setuint32(ctxt, ftab, 0, 0xfffffffb)
setuint8(ctxt, ftab, 6, uint8(SysArch.MinLC))
setuint8(ctxt, ftab, 7, uint8(SysArch.PtrSize))
setuint8(ctxt, ftab, 6, uint8(ctxt.Arch.MinLC))
setuint8(ctxt, ftab, 7, uint8(ctxt.Arch.PtrSize))
setuint(ctxt, ftab, 8, uint64(nfunc))
pclntabPclntabOffset = int32(8 + SysArch.PtrSize)
pclntabPclntabOffset = int32(8 + ctxt.Arch.PtrSize)
funcnameoff := make(map[string]int32)
nameToOffset := func(name string) int32 {
......@@ -279,10 +279,10 @@ func (ctxt *Link) pclntab() {
}
funcstart := int32(len(ftab.P))
funcstart += int32(-len(ftab.P)) & (int32(SysArch.PtrSize) - 1)
funcstart += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
setaddr(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), s)
setuint(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint64(funcstart))
setaddr(ctxt, ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), s)
setuint(ctxt, ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint64(funcstart))
// Write runtime._func. Keep in sync with ../../../../runtime/runtime2.go:/_func
// and package debug/gosym.
......@@ -290,8 +290,8 @@ func (ctxt *Link) pclntab() {
// fixed size of struct, checked below
off := funcstart
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 := funcstart + int32(ctxt.Arch.PtrSize) + 3*4 + 5*4 + int32(len(pcln.Pcdata))*4 + int32(len(pcln.Funcdata))*int32(ctxt.Arch.PtrSize)
if len(pcln.Funcdata) > 0 && (end&int32(ctxt.Arch.PtrSize-1) != 0) {
end += 4
}
Symgrow(ftab, int64(end))
......@@ -370,25 +370,25 @@ func (ctxt *Link) 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(SysArch.PtrSize-1) != 0 {
if off&int32(ctxt.Arch.PtrSize-1) != 0 {
off += 4
}
for i := 0; i < len(pcln.Funcdata); i++ {
if pcln.Funcdata[i] == nil {
setuint(ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), uint64(pcln.Funcdataoff[i]))
setuint(ctxt, ftab, int64(off)+int64(ctxt.Arch.PtrSize)*int64(i), uint64(pcln.Funcdataoff[i]))
} else {
// TODO: Dedup.
funcdataBytes += pcln.Funcdata[i].Size
setaddrplus(ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
setaddrplus(ctxt, ftab, int64(off)+int64(ctxt.Arch.PtrSize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
}
}
off += int32(len(pcln.Funcdata)) * int32(SysArch.PtrSize)
off += int32(len(pcln.Funcdata)) * int32(ctxt.Arch.PtrSize)
}
if off != end {
Errorf(s, "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)
Errorf(s, "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), ctxt.Arch.PtrSize)
errorexit()
}
......@@ -397,14 +397,14 @@ func (ctxt *Link) pclntab() {
pclntabLastFunc = last
// Final entry of table is just end pc.
setaddrplus(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), last, last.Size)
setaddrplus(ctxt, ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), last, last.Size)
// Start file table.
start := int32(len(ftab.P))
start += int32(-len(ftab.P)) & (int32(SysArch.PtrSize) - 1)
start += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
pclntabFiletabOffset = start
setuint32(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint32(start))
setuint32(ctxt, ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint32(start))
Symgrow(ftab, int64(start)+(int64(len(ctxt.Filesyms))+1)*4)
setuint32(ctxt, ftab, int64(start), uint32(len(ctxt.Filesyms)+1))
......
......@@ -517,7 +517,7 @@ func (f *peFile) emitRelocations(ctxt *Link) {
if r.Xsym.Dynid < 0 {
Errorf(sym, "reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
}
if !Thearch.PEreloc1(sym, r, int64(uint64(sym.Value+int64(r.Off))-base)) {
if !Thearch.PEreloc1(ctxt.Arch, sym, r, int64(uint64(sym.Value+int64(r.Off))-base)) {
Errorf(sym, "unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
}
relocs++
......@@ -636,7 +636,7 @@ func (f *peFile) writeSymbols(ctxt *Link) {
}
// Only windows/386 requires underscore prefix on external symbols.
if SysArch.Family == sys.I386 &&
if ctxt.Arch.Family == sys.I386 &&
Linkmode == LinkExternal &&
(s.Type == SHOSTOBJ || s.Attr.CgoExport()) {
s.Name = "_" + s.Name
......@@ -705,12 +705,12 @@ func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) {
}
// writeFileHeader writes COFF file header for peFile f.
func (f *peFile) writeFileHeader() {
func (f *peFile) writeFileHeader(arch *sys.Arch) {
var fh pe.FileHeader
switch SysArch.Family {
switch arch.Family {
default:
Exitf("unknown PE architecture: %v", SysArch.Family)
Exitf("unknown PE architecture: %v", arch.Family)
case sys.AMD64:
fh.Machine = IMAGE_FILE_MACHINE_AMD64
case sys.I386:
......@@ -865,7 +865,7 @@ var pefile peFile
func Peinit(ctxt *Link) {
var l int
switch SysArch.Family {
switch ctxt.Arch.Family {
// 64-bit architectures
case sys.AMD64:
pe64 = 1
......@@ -923,7 +923,7 @@ func pewrite(ctxt *Link) {
strnput("PE", 4)
}
pefile.writeFileHeader()
pefile.writeFileHeader(ctxt.Arch)
pefile.writeOptionalHeader(ctxt)
......@@ -976,7 +976,7 @@ func initdynimport(ctxt *Link) *Dll {
if err != nil {
Errorf(s, "failed to parse stdcall decoration: %v", err)
}
m.argsize *= SysArch.PtrSize
m.argsize *= ctxt.Arch.PtrSize
s.Extname = s.Extname[:i]
}
......@@ -990,10 +990,10 @@ func initdynimport(ctxt *Link) *Dll {
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
m.s.Type = SDATA
Symgrow(m.s, int64(SysArch.PtrSize))
Symgrow(m.s, int64(ctxt.Arch.PtrSize))
dynName := m.s.Extname
// only windows/386 requires stdcall decoration
if SysArch.Family == sys.I386 && m.argsize >= 0 {
if ctxt.Arch.Family == sys.I386 && m.argsize >= 0 {
dynName += fmt.Sprintf("@%d", m.argsize)
}
dynSym := ctxt.Syms.Lookup(dynName, 0)
......@@ -1002,7 +1002,7 @@ func initdynimport(ctxt *Link) *Dll {
r := Addrel(m.s)
r.Sym = dynSym
r.Off = 0
r.Siz = uint8(SysArch.PtrSize)
r.Siz = uint8(ctxt.Arch.PtrSize)
r.Type = objabi.R_ADDR
}
}
......@@ -1016,10 +1016,10 @@ func initdynimport(ctxt *Link) *Dll {
m.s.Sub = dynamic.Sub
dynamic.Sub = m.s
m.s.Value = dynamic.Size
dynamic.Size += int64(SysArch.PtrSize)
dynamic.Size += int64(ctxt.Arch.PtrSize)
}
dynamic.Size += int64(SysArch.PtrSize)
dynamic.Size += int64(ctxt.Arch.PtrSize)
}
}
......@@ -1285,9 +1285,9 @@ func addpersrc(ctxt *Link) {
}
func Asmbpe(ctxt *Link) {
switch SysArch.Family {
switch ctxt.Arch.Family {
default:
Exitf("unknown PE architecture: %v", SysArch.Family)
Exitf("unknown PE architecture: %v", ctxt.Arch.Family)
case sys.AMD64, sys.I386:
}
......
......@@ -147,7 +147,7 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S
if x.Type&SHIDDEN != 0 {
other = STV_HIDDEN
}
if SysArch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
if ctxt.Arch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && 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.
......@@ -225,7 +225,7 @@ func putplan9sym(ctxt *Link, x *Symbol, s string, typ SymbolType, addr int64, go
case AutoSym, ParamSym, FrameSym:
l := 4
if Headtype == objabi.Hplan9 && SysArch.Family == sys.AMD64 && !Flag8 {
if Headtype == objabi.Hplan9 && ctxt.Arch.Family == sys.AMD64 && !Flag8 {
Lputb(uint32(addr >> 32))
l = 8
}
......@@ -313,7 +313,7 @@ func textsectionmap(ctxt *Link) uint32 {
break
}
}
Symgrow(t, 3*nsections*int64(SysArch.PtrSize))
Symgrow(t, 3*nsections*int64(ctxt.Arch.PtrSize))
off := int64(0)
n := 0
......
......@@ -27,7 +27,7 @@ func (ctxt *Link) typelink() {
typelinks := byTypeStr{}
for _, s := range ctxt.Syms.Allsym {
if s.Attr.Reachable() && s.Attr.MakeTypelink() {
typelinks = append(typelinks, typelinkSortKey{decodetypeStr(s), s})
typelinks = append(typelinks, typelinkSortKey{decodetypeStr(ctxt.Arch, s), s})
}
}
sort.Sort(typelinks)
......
......@@ -32,6 +32,7 @@ package mips
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"fmt"
"log"
......@@ -75,12 +76,12 @@ func elfsetupplt(ctxt *ld.Link) {
return
}
func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
return false
}
func applyrel(r *ld.Reloc, s *ld.Symbol, val *int64, t int64) {
o := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
func applyrel(arch *sys.Arch, r *ld.Reloc, s *ld.Symbol, val *int64, t int64) {
o := arch.ByteOrder.Uint32(s.P[r.Off:])
switch r.Type {
case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
*val = int64(o&0xffff0000 | uint32(t)&0xffff)
......@@ -111,13 +112,13 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
ld.Errorf(s, "missing section for %s", rs.Name)
}
r.Xsym = rs
applyrel(r, s, val, r.Xadd)
applyrel(ctxt.Arch, r, s, val, r.Xadd)
return true
case objabi.R_ADDRMIPSTLS, objabi.R_CALLMIPS, objabi.R_JMPMIPS:
r.Done = false
r.Xsym = r.Sym
r.Xadd = r.Add
applyrel(r, s, val, r.Add)
applyrel(ctxt.Arch, r, s, val, r.Add)
return true
}
}
......@@ -131,7 +132,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
return true
case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSU:
t := ld.Symaddr(r.Sym) + r.Add
applyrel(r, s, val, t)
applyrel(ctxt.Arch, r, s, val, t)
return true
case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
t := ld.Symaddr(r.Sym) + r.Add
......@@ -145,7 +146,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
}
applyrel(r, s, val, t)
applyrel(ctxt.Arch, r, s, val, t)
return true
case objabi.R_ADDRMIPSTLS:
// thread pointer is at 0x7000 offset from the start of TLS data area
......@@ -153,7 +154,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
if t < -32768 || t >= 32678 {
ld.Errorf(s, "TLS offset out of range %d", t)
}
applyrel(r, s, val, t)
applyrel(ctxt.Arch, r, s, val, t)
return true
}
......
......@@ -37,53 +37,55 @@ import (
"fmt"
)
// Reading object files.
func Init() {
func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchMIPS
if objabi.GOARCH == "mipsle" {
ld.SysArch = sys.ArchMIPSLE
} else {
ld.SysArch = sys.ArchMIPS
arch = sys.ArchMIPSLE
}
ld.Thearch.Funcalign = FuncAlign
ld.Thearch.Maxalign = MaxAlign
ld.Thearch.Minalign = MinAlign
ld.Thearch.Dwarfregsp = DWARFREGSP
ld.Thearch.Dwarfreglr = DWARFREGLR
theArch := ld.Arch{
Funcalign: FuncAlign,
Maxalign: MaxAlign,
Minalign: MinAlign,
Dwarfregsp: DWARFREGSP,
Dwarfreglr: DWARFREGLR,
ld.Thearch.Adddynrel = adddynrel
ld.Thearch.Archinit = archinit
ld.Thearch.Archreloc = archreloc
ld.Thearch.Archrelocvariant = archrelocvariant
ld.Thearch.Asmb = asmb
ld.Thearch.Elfreloc1 = elfreloc1
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
if ld.SysArch == sys.ArchMIPSLE {
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
ld.Thearch.Append16 = ld.Append16l
ld.Thearch.Append32 = ld.Append32l
ld.Thearch.Append64 = ld.Append64l
} else {
ld.Thearch.Lput = ld.Lputb
ld.Thearch.Wput = ld.Wputb
ld.Thearch.Vput = ld.Vputb
ld.Thearch.Append16 = ld.Append16b
ld.Thearch.Append32 = ld.Append32b
ld.Thearch.Append64 = ld.Append64b
Adddynrel: adddynrel,
Archinit: archinit,
Archreloc: archreloc,
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Elfreloc1: elfreloc1,
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
Linuxdynld: "/lib/ld.so.1",
Freebsddynld: "XXX",
Openbsddynld: "XXX",
Netbsddynld: "XXX",
Dragonflydynld: "XXX",
Solarisdynld: "XXX",
}
ld.Thearch.Linuxdynld = "/lib/ld.so.1"
if arch == sys.ArchMIPSLE {
theArch.Lput = ld.Lputl
theArch.Wput = ld.Wputl
theArch.Vput = ld.Vputl
theArch.Append16 = ld.Append16l
theArch.Append32 = ld.Append32l
theArch.Append64 = ld.Append64l
} else {
theArch.Lput = ld.Lputb
theArch.Wput = ld.Wputb
theArch.Vput = ld.Vputb
theArch.Append16 = ld.Append16b
theArch.Append32 = ld.Append32b
theArch.Append64 = ld.Append64b
}
ld.Thearch.Freebsddynld = "XXX"
ld.Thearch.Openbsddynld = "XXX"
ld.Thearch.Netbsddynld = "XXX"
ld.Thearch.Dragonflydynld = "XXX"
ld.Thearch.Solarisdynld = "XXX"
return arch, theArch
}
func archinit(ctxt *ld.Link) {
......
......@@ -93,7 +93,7 @@ func elfsetupplt(ctxt *ld.Link) {
return
}
func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
return false
}
......@@ -140,7 +140,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
case objabi.R_ADDRMIPS,
objabi.R_ADDRMIPSU:
t := ld.Symaddr(r.Sym) + r.Add
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
if r.Type == objabi.R_ADDRMIPS {
*val = int64(o1&0xffff0000 | uint32(t)&0xffff)
} else {
......@@ -153,14 +153,14 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
if t < -32768 || t >= 32678 {
ld.Errorf(s, "TLS offset out of range %d", t)
}
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
*val = int64(o1&0xffff0000 | uint32(t)&0xffff)
return true
case objabi.R_CALLMIPS,
objabi.R_JMPMIPS:
// Low 26 bits = (S + A) >> 2
t := ld.Symaddr(r.Sym) + r.Add
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
o1 := ctxt.Arch.ByteOrder.Uint32(s.P[r.Off:])
*val = int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000)
return true
}
......@@ -272,7 +272,7 @@ func asmb(ctxt *ld.Link) {
default:
case objabi.Hplan9: /* plan 9 */
magic := uint32(4*18*18 + 7)
if ld.SysArch == sys.ArchMIPS64LE {
if ctxt.Arch == sys.ArchMIPS64LE {
magic = uint32(4*26*26 + 7)
}
ld.Thearch.Lput(magic) /* magic */
......
......@@ -37,51 +37,52 @@ import (
"fmt"
)
func Init() {
func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchMIPS64
if objabi.GOARCH == "mips64le" {
ld.SysArch = sys.ArchMIPS64LE
} else {
ld.SysArch = sys.ArchMIPS64
arch = sys.ArchMIPS64LE
}
ld.Thearch.Funcalign = funcAlign
ld.Thearch.Maxalign = maxAlign
ld.Thearch.Minalign = minAlign
ld.Thearch.Dwarfregsp = dwarfRegSP
ld.Thearch.Dwarfreglr = dwarfRegLR
theArch := ld.Arch{
Funcalign: funcAlign,
Maxalign: maxAlign,
Minalign: minAlign,
Dwarfregsp: dwarfRegSP,
Dwarfreglr: dwarfRegLR,
Adddynrel: adddynrel,
Archinit: archinit,
Archreloc: archreloc,
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Elfreloc1: elfreloc1,
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
ld.Thearch.Adddynrel = adddynrel
ld.Thearch.Archinit = archinit
ld.Thearch.Archreloc = archreloc
ld.Thearch.Archrelocvariant = archrelocvariant
ld.Thearch.Asmb = asmb
ld.Thearch.Elfreloc1 = elfreloc1
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
if ld.SysArch == sys.ArchMIPS64LE {
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
ld.Thearch.Append16 = ld.Append16l
ld.Thearch.Append32 = ld.Append32l
ld.Thearch.Append64 = ld.Append64l
Linuxdynld: "/lib64/ld64.so.1",
Freebsddynld: "XXX",
Openbsddynld: "XXX",
Netbsddynld: "XXX",
Dragonflydynld: "XXX",
Solarisdynld: "XXX",
}
if arch == sys.ArchMIPS64LE {
theArch.Lput = ld.Lputl
theArch.Wput = ld.Wputl
theArch.Vput = ld.Vputl
theArch.Append16 = ld.Append16l
theArch.Append32 = ld.Append32l
theArch.Append64 = ld.Append64l
} else {
ld.Thearch.Lput = ld.Lputb
ld.Thearch.Wput = ld.Wputb
ld.Thearch.Vput = ld.Vputb
ld.Thearch.Append16 = ld.Append16b
ld.Thearch.Append32 = ld.Append32b
ld.Thearch.Append64 = ld.Append64b
theArch.Lput = ld.Lputb
theArch.Wput = ld.Wputb
theArch.Vput = ld.Vputb
theArch.Append16 = ld.Append16b
theArch.Append32 = ld.Append32b
theArch.Append64 = ld.Append64b
}
ld.Thearch.Linuxdynld = "/lib64/ld64.so.1"
ld.Thearch.Freebsddynld = "XXX"
ld.Thearch.Openbsddynld = "XXX"
ld.Thearch.Netbsddynld = "XXX"
ld.Thearch.Dragonflydynld = "XXX"
ld.Thearch.Solarisdynld = "XXX"
return arch, theArch
}
func archinit(ctxt *ld.Link) {
......
......@@ -32,6 +32,7 @@ package ppc64
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"encoding/binary"
"fmt"
......@@ -262,7 +263,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
switch r.Type {
default:
if r.Type >= 256 {
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(r.Type))
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
return false
}
......@@ -447,7 +448,7 @@ func elfsetupplt(ctxt *ld.Link) {
}
}
func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
return false
}
......@@ -570,7 +571,7 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
ld.Errorf(s, "unexpected trampoline for shared or dynamic linking\n")
} else {
ctxt.AddTramp(tramp)
gentramp(tramp, r.Sym, int64(r.Add))
gentramp(ctxt.Arch, tramp, r.Sym, int64(r.Add))
}
}
r.Sym = tramp
......@@ -578,11 +579,11 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
r.Done = false
}
default:
ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, ld.RelocName(r.Type))
ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
}
}
func gentramp(tramp, target *ld.Symbol, offset int64) {
func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
// Used for default build mode for an executable
// Address of the call target is generated using
// relocation and doesn't depend on r2 (TOC).
......@@ -612,10 +613,10 @@ func gentramp(tramp, target *ld.Symbol, offset int64) {
}
o3 := uint32(0x7fe903a6) // mtctr r31
o4 := uint32(0x4e800420) // bctr
ld.SysArch.ByteOrder.PutUint32(tramp.P, o1)
ld.SysArch.ByteOrder.PutUint32(tramp.P[4:], o2)
ld.SysArch.ByteOrder.PutUint32(tramp.P[8:], o3)
ld.SysArch.ByteOrder.PutUint32(tramp.P[12:], o4)
arch.ByteOrder.PutUint32(tramp.P, o1)
arch.ByteOrder.PutUint32(tramp.P[4:], o2)
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
}
func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
......
......@@ -37,53 +37,57 @@ import (
"fmt"
)
func Init() {
func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchPPC64
if objabi.GOARCH == "ppc64le" {
ld.SysArch = sys.ArchPPC64LE
} else {
ld.SysArch = sys.ArchPPC64
arch = sys.ArchPPC64LE
}
ld.Thearch.Funcalign = funcAlign
ld.Thearch.Maxalign = maxAlign
ld.Thearch.Minalign = minAlign
ld.Thearch.Dwarfregsp = dwarfRegSP
ld.Thearch.Dwarfreglr = dwarfRegLR
theArch := ld.Arch{
Funcalign: funcAlign,
Maxalign: maxAlign,
Minalign: minAlign,
Dwarfregsp: dwarfRegSP,
Dwarfreglr: dwarfRegLR,
ld.Thearch.Adddynrel = adddynrel
ld.Thearch.Archinit = archinit
ld.Thearch.Archreloc = archreloc
ld.Thearch.Archrelocvariant = archrelocvariant
ld.Thearch.Asmb = asmb
ld.Thearch.Elfreloc1 = elfreloc1
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Trampoline = trampoline
ld.Thearch.Machoreloc1 = machoreloc1
if ld.SysArch == sys.ArchPPC64LE {
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
ld.Thearch.Append16 = ld.Append16l
ld.Thearch.Append32 = ld.Append32l
ld.Thearch.Append64 = ld.Append64l
} else {
ld.Thearch.Lput = ld.Lputb
ld.Thearch.Wput = ld.Wputb
ld.Thearch.Vput = ld.Vputb
ld.Thearch.Append16 = ld.Append16b
ld.Thearch.Append32 = ld.Append32b
ld.Thearch.Append64 = ld.Append64b
Adddynrel: adddynrel,
Archinit: archinit,
Archreloc: archreloc,
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Elfreloc1: elfreloc1,
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Trampoline: trampoline,
Machoreloc1: machoreloc1,
// TODO(austin): ABI v1 uses /usr/lib/ld.so.1,
Linuxdynld: "/lib64/ld64.so.1",
Freebsddynld: "XXX",
Openbsddynld: "XXX",
Netbsddynld: "XXX",
Dragonflydynld: "XXX",
Solarisdynld: "XXX",
}
// TODO(austin): ABI v1 uses /usr/lib/ld.so.1
ld.Thearch.Linuxdynld = "/lib64/ld64.so.1"
if arch == sys.ArchPPC64LE {
theArch.Lput = ld.Lputl
theArch.Wput = ld.Wputl
theArch.Vput = ld.Vputl
theArch.Append16 = ld.Append16l
theArch.Append32 = ld.Append32l
theArch.Append64 = ld.Append64l
} else {
theArch.Lput = ld.Lputb
theArch.Wput = ld.Wputb
theArch.Vput = ld.Vputb
theArch.Append16 = ld.Append16b
theArch.Append32 = ld.Append32b
theArch.Append64 = ld.Append64b
}
ld.Thearch.Freebsddynld = "XXX"
ld.Thearch.Openbsddynld = "XXX"
ld.Thearch.Netbsddynld = "XXX"
ld.Thearch.Dragonflydynld = "XXX"
ld.Thearch.Solarisdynld = "XXX"
return arch, theArch
}
func archinit(ctxt *ld.Link) {
......@@ -105,7 +109,7 @@ func archinit(ctxt *ld.Link) {
}
case objabi.Hlinux: /* ppc64 elf */
if ld.SysArch == sys.ArchPPC64 {
if ctxt.Arch == sys.ArchPPC64 {
*ld.FlagD = true // TODO(austin): ELF ABI v1 not supported yet
}
ld.Elfinit(ctxt)
......
......@@ -32,6 +32,7 @@ package s390x
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"debug/elf"
"fmt"
......@@ -376,7 +377,7 @@ func elfsetupplt(ctxt *ld.Link) {
}
}
func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
return false
}
......
......@@ -37,39 +37,43 @@ import (
"fmt"
)
func Init() {
ld.SysArch = sys.ArchS390X
func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchS390X
ld.Thearch.Funcalign = funcAlign
ld.Thearch.Maxalign = maxAlign
ld.Thearch.Minalign = minAlign
ld.Thearch.Dwarfregsp = dwarfRegSP
ld.Thearch.Dwarfreglr = dwarfRegLR
theArch := ld.Arch{
Funcalign: funcAlign,
Maxalign: maxAlign,
Minalign: minAlign,
Dwarfregsp: dwarfRegSP,
Dwarfreglr: dwarfRegLR,
ld.Thearch.Adddynrel = adddynrel
ld.Thearch.Archinit = archinit
ld.Thearch.Archreloc = archreloc
ld.Thearch.Archrelocvariant = archrelocvariant
ld.Thearch.Asmb = asmb // in asm.go
ld.Thearch.Elfreloc1 = elfreloc1
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
ld.Thearch.Lput = ld.Lputb
ld.Thearch.Wput = ld.Wputb
ld.Thearch.Vput = ld.Vputb
ld.Thearch.Append16 = ld.Append16b
ld.Thearch.Append32 = ld.Append32b
ld.Thearch.Append64 = ld.Append64b
Adddynrel: adddynrel,
Archinit: archinit,
Archreloc: archreloc,
Archrelocvariant: archrelocvariant,
Asmb: asmb, // in asm.go
Elfreloc1: elfreloc1,
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
Lput: ld.Lputb,
Wput: ld.Wputb,
Vput: ld.Vputb,
Append16: ld.Append16b,
Append32: ld.Append32b,
Append64: ld.Append64b,
ld.Thearch.Linuxdynld = "/lib64/ld64.so.1"
Linuxdynld: "/lib64/ld64.so.1",
// not relevant for s390x
ld.Thearch.Freebsddynld = "XXX"
ld.Thearch.Openbsddynld = "XXX"
ld.Thearch.Netbsddynld = "XXX"
ld.Thearch.Dragonflydynld = "XXX"
ld.Thearch.Solarisdynld = "XXX"
Freebsddynld: "XXX",
Openbsddynld: "XXX",
Netbsddynld: "XXX",
Dragonflydynld: "XXX",
Solarisdynld: "XXX",
}
return arch, theArch
}
func archinit(ctxt *ld.Link) {
......
......@@ -32,6 +32,7 @@ package x86
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"log"
)
......@@ -170,7 +171,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
switch r.Type {
default:
if r.Type >= 256 {
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(r.Type))
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
return false
}
......@@ -311,7 +312,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
return true
}
if ld.Headtype == objabi.Hdarwin && s.Size == int64(ld.SysArch.PtrSize) && r.Off == 0 {
if ld.Headtype == objabi.Hdarwin && s.Size == int64(ctxt.Arch.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.
......@@ -398,14 +399,14 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
return true
}
func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
if rs.Type == ld.SHOSTOBJ {
if rs.Dynid < 0 {
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
return false
}
......@@ -414,7 +415,7 @@ func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
return false
}
}
......@@ -448,13 +449,13 @@ func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
return true
}
func pereloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func pereloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
if rs.Dynid < 0 {
ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(r.Type), rs.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
return false
}
......
......@@ -37,37 +37,41 @@ import (
"fmt"
)
func Init() {
ld.SysArch = sys.Arch386
ld.Thearch.Funcalign = funcAlign
ld.Thearch.Maxalign = maxAlign
ld.Thearch.Minalign = minAlign
ld.Thearch.Dwarfregsp = dwarfRegSP
ld.Thearch.Dwarfreglr = dwarfRegLR
ld.Thearch.Adddynrel = adddynrel
ld.Thearch.Archinit = archinit
ld.Thearch.Archreloc = archreloc
ld.Thearch.Archrelocvariant = archrelocvariant
ld.Thearch.Asmb = asmb
ld.Thearch.Elfreloc1 = elfreloc1
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
ld.Thearch.PEreloc1 = pereloc1
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
ld.Thearch.Append16 = ld.Append16l
ld.Thearch.Append32 = ld.Append32l
ld.Thearch.Append64 = ld.Append64l
ld.Thearch.Linuxdynld = "/lib/ld-linux.so.2"
ld.Thearch.Freebsddynld = "/usr/libexec/ld-elf.so.1"
ld.Thearch.Openbsddynld = "/usr/libexec/ld.so"
ld.Thearch.Netbsddynld = "/usr/libexec/ld.elf_so"
ld.Thearch.Solarisdynld = "/lib/ld.so.1"
func Init() (*sys.Arch, ld.Arch) {
arch := sys.Arch386
theArch := ld.Arch{
Funcalign: funcAlign,
Maxalign: maxAlign,
Minalign: minAlign,
Dwarfregsp: dwarfRegSP,
Dwarfreglr: dwarfRegLR,
Adddynrel: adddynrel,
Archinit: archinit,
Archreloc: archreloc,
Archrelocvariant: archrelocvariant,
Asmb: asmb,
Elfreloc1: elfreloc1,
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
PEreloc1: pereloc1,
Lput: ld.Lputl,
Wput: ld.Wputl,
Vput: ld.Vputl,
Append16: ld.Append16l,
Append32: ld.Append32l,
Append64: ld.Append64l,
Linuxdynld: "/lib/ld-linux.so.2",
Freebsddynld: "/usr/libexec/ld-elf.so.1",
Openbsddynld: "/usr/libexec/ld.so",
Netbsddynld: "/usr/libexec/ld.elf_so",
Solarisdynld: "/lib/ld.so.1",
}
return arch, theArch
}
func archinit(ctxt *ld.Link) {
......@@ -89,8 +93,6 @@ func archinit(ctxt *ld.Link) {
}
case objabi.Hdarwin: /* apple MACH */
ld.Machoinit()
ld.HEADR = ld.INITIAL_MACHO_HEADR
if *ld.FlagTextAddr == -1 {
*ld.FlagTextAddr = 4096 + int64(ld.HEADR)
......
......@@ -6,6 +6,7 @@ package main
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/amd64"
"cmd/link/internal/arm"
"cmd/link/internal/arm64"
......@@ -26,7 +27,7 @@ import (
//
// Before any argument parsing is done, the Init function of relevant
// architecture package is called. The only job done in Init is
// configuration of the ld.Thearch and ld.SysArch variables.
// configuration of the architecture-specific variables.
//
// Then control flow passes to ld.Main, which parses flags, makes
// some configuration decisions, and then gives the architecture
......@@ -34,26 +35,29 @@ import (
// via the ld.Thearch.Archinit function.
func main() {
var arch *sys.Arch
var theArch ld.Arch
switch objabi.GOARCH {
default:
fmt.Fprintf(os.Stderr, "link: unknown architecture %q\n", objabi.GOARCH)
os.Exit(2)
case "386":
x86.Init()
arch, theArch = x86.Init()
case "amd64", "amd64p32":
amd64.Init()
arch, theArch = amd64.Init()
case "arm":
arm.Init()
arch, theArch = arm.Init()
case "arm64":
arm64.Init()
arch, theArch = arm64.Init()
case "mips", "mipsle":
mips.Init()
arch, theArch = mips.Init()
case "mips64", "mips64le":
mips64.Init()
arch, theArch = mips64.Init()
case "ppc64", "ppc64le":
ppc64.Init()
arch, theArch = ppc64.Init()
case "s390x":
s390x.Init()
arch, theArch = s390x.Init()
}
ld.Main()
ld.Main(arch, theArch)
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment