Commit 3d1ce27b authored by Aram Hăvărneanu's avatar Aram Hăvărneanu

cmd/7l: add the ARM64 linker

Only internal linking without cgo is supported for now.

Change-Id: I91eb1572c1ccc805db62fc4c29080df98797d51a
Reviewed-on: https://go-review.googlesource.com/7048Reviewed-by: default avatarMinux Ma <minux@golang.org>
Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 18d9ddc3
This diff is collapsed.
......@@ -62,7 +62,7 @@ package main
// THE SOFTWARE.
const (
thechar = '9'
thechar = '7'
PtrSize = 8
IntSize = 8
RegSize = 8
......@@ -73,5 +73,5 @@ const (
/* Used by ../ld/dwarf.c */
const (
DWARFREGSP = 1
DWARFREGSP = 31
)
......@@ -46,11 +46,7 @@ func main() {
func linkarchinit() {
ld.Thestring = obj.Getgoarch()
if ld.Thestring == "ppc64le" {
ld.Thelinkarch = &ld.Linkppc64le
} else {
ld.Thelinkarch = &ld.Linkppc64
}
ld.Thelinkarch = &ld.Linkarm64
ld.Thearch.Thechar = thechar
ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize
......@@ -72,18 +68,11 @@ func linkarchinit() {
ld.Thearch.Elfsetupplt = elfsetupplt
ld.Thearch.Gentext = gentext
ld.Thearch.Machoreloc1 = machoreloc1
if ld.Thelinkarch == &ld.Linkppc64le {
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
} else {
ld.Thearch.Lput = ld.Lputb
ld.Thearch.Wput = ld.Wputb
ld.Thearch.Vput = ld.Vputb
}
ld.Thearch.Lput = ld.Lputl
ld.Thearch.Wput = ld.Wputl
ld.Thearch.Vput = ld.Vputl
// TODO(austin): ABI v1 uses /usr/lib/ld.so.1
ld.Thearch.Linuxdynld = "/lib64/ld64.so.1"
ld.Thearch.Linuxdynld = "/lib/ld-linux-aarch64.so.1"
ld.Thearch.Freebsddynld = "XXX"
ld.Thearch.Openbsddynld = "XXX"
......@@ -129,9 +118,7 @@ func archinit() {
}
case ld.Hlinux: /* ppc64 elf */
if ld.Thestring == "ppc64" {
ld.Debug['d'] = 1 // TODO(austin): ELF ABI v1 not supported yet
}
ld.Debug['d'] = 1 // TODO(aram): dynamic linking is not supported yet.
ld.Elfinit()
ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 {
......
......@@ -15,6 +15,15 @@ var Linkarm = LinkArch{
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",
......
......@@ -164,6 +164,7 @@ const (
EM_ST100 = 60
EM_TINYJ = 61
EM_X86_64 = 62
EM_AARCH64 = 183
EM_486 = 6
EM_MIPS_RS4_BE = 10
EM_ALPHA_STD = 41
......@@ -344,6 +345,9 @@ const (
R_X86_64_GOTTPOFF = 22
R_X86_64_TPOFF32 = 23
R_X86_64_COUNT = 24
R_AARCH64_ABS64 = 257
R_AARCH64_ABS32 = 258
R_AARCH64_CALL26 = 283
R_ALPHA_NONE = 0
R_ALPHA_REFLONG = 1
R_ALPHA_REFQUAD = 2
......@@ -757,8 +761,7 @@ func Elfinit() {
}
fallthrough
// fallthrough
case '6':
case '6', '7':
elf64 = 1
ehdr.phoff = ELF64HDRSIZE /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
......@@ -1367,14 +1370,15 @@ func elfdynhash() {
elfwritedynentsym(s, DT_VERSYM, Linklookup(Ctxt, ".gnu.version", 0))
}
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
switch Thearch.Thechar {
case '6', '7', '9':
sy := Linklookup(Ctxt, ".rela.plt", 0)
if sy.Size > 0 {
Elfwritedynent(s, DT_PLTREL, DT_RELA)
elfwritedynentsymsize(s, DT_PLTRELSZ, sy)
elfwritedynentsym(s, DT_JMPREL, sy)
}
} else {
default:
sy := Linklookup(Ctxt, ".rel.plt", 0)
if sy.Size > 0 {
Elfwritedynent(s, DT_PLTREL, DT_REL)
......@@ -1627,7 +1631,8 @@ func doelf() {
Debug['s'] = 0
Debug['d'] = 1
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
switch Thearch.Thechar {
case '6', '7', '9':
Addstring(shstrtab, ".rela.text")
Addstring(shstrtab, ".rela.rodata")
Addstring(shstrtab, ".rela.typelink")
......@@ -1635,7 +1640,8 @@ func doelf() {
Addstring(shstrtab, ".rela.gopclntab")
Addstring(shstrtab, ".rela.noptrdata")
Addstring(shstrtab, ".rela.data")
} else {
default:
Addstring(shstrtab, ".rel.text")
Addstring(shstrtab, ".rel.rodata")
Addstring(shstrtab, ".rel.typelink")
......@@ -1711,9 +1717,10 @@ func doelf() {
dynstr := s
/* relocation table */
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
switch Thearch.Thechar {
case '6', '7', '9':
s = Linklookup(Ctxt, ".rela", 0)
} else {
default:
s = Linklookup(Ctxt, ".rel", 0)
}
s.Reachable = true
......@@ -1755,9 +1762,10 @@ func doelf() {
Thearch.Elfsetupplt()
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
switch Thearch.Thechar {
case '6', '7', '9':
s = Linklookup(Ctxt, ".rela.plt", 0)
} else {
default:
s = Linklookup(Ctxt, ".rel.plt", 0)
}
s.Reachable = true
......@@ -1790,11 +1798,12 @@ func doelf() {
}
elfwritedynentsym(s, DT_STRTAB, Linklookup(Ctxt, ".dynstr", 0))
elfwritedynentsymsize(s, DT_STRSZ, Linklookup(Ctxt, ".dynstr", 0))
if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
switch Thearch.Thechar {
case '6', '7', '9':
elfwritedynentsym(s, DT_RELA, Linklookup(Ctxt, ".rela", 0))
elfwritedynentsymsize(s, DT_RELASZ, Linklookup(Ctxt, ".rela", 0))
Elfwritedynent(s, DT_RELAENT, ELF64RELASIZE)
} else {
default:
elfwritedynentsym(s, DT_REL, Linklookup(Ctxt, ".rel", 0))
elfwritedynentsymsize(s, DT_RELSZ, Linklookup(Ctxt, ".rel", 0))
Elfwritedynent(s, DT_RELENT, ELF32RELSIZE)
......@@ -1870,6 +1879,9 @@ func Asmbelf(symo int64) {
case '6':
eh.machine = EM_X86_64
case '7':
eh.machine = EM_AARCH64
case '8':
eh.machine = EM_386
......@@ -2033,7 +2045,8 @@ func Asmbelf(symo int64) {
switch eh.machine {
case EM_X86_64,
EM_PPC64:
EM_PPC64,
EM_AARCH64:
sh := elfshname(".rela.plt")
sh.type_ = SHT_RELA
sh.flags = SHF_ALLOC
......
......@@ -84,6 +84,7 @@ const (
ElfMachSH = 42
ElfMachSparc9 = 43
ElfMachAmd64 = 62
ElfMachArm64 = 183
)
const (
......@@ -432,6 +433,12 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
return
}
case '7':
if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
Diag("%s: elf object but not arm64", pn)
return
}
case '8':
if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
Diag("%s: elf object but not 386", pn)
......
......@@ -1064,7 +1064,7 @@ var (
// allow stack checks here.
func haslinkregister() bool {
return Thearch.Thechar == '5' || Thearch.Thechar == '9'
return Thearch.Thechar == '5' || Thearch.Thechar == '9' || Thearch.Thechar == '7'
}
func callsize() int {
......@@ -1183,6 +1183,7 @@ func stkcheck(up *Chain, depth int) int {
// Direct call.
case R_CALL,
R_CALLARM,
R_CALLARM64,
R_CALLPOWER:
ch.limit = int(int32(limit) - pcsp.value - int32(callsize()))
......
......@@ -219,6 +219,7 @@ const (
R_SIZE
R_CALL
R_CALLARM
R_CALLARM64
R_CALLIND
R_CALLPOWER
R_CONST
......
......@@ -58,6 +58,7 @@ func putelfstr(s string) int {
func putelfsyment(off int, addr int64, size int64, info int, shndx int, other int) {
switch Thearch.Thechar {
case '6',
'7',
'9':
Thearch.Lput(uint32(off))
Cput(uint8(info))
......
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