cmd: add new common architecture representation

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

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

Passes toolstash/buildall.

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

View file

@ -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