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