Commit f55b2a11 authored by Shenghou Ma's avatar Shenghou Ma Committed by Minux Ma

cmd/internal/ld, cmd/7l: external linking support for linux/arm64

Based on Michael Hudson-Doyle's patch:
https://github.com/4ad/go/commit/b735215ee41b4237ec393d4669f6f55d4b27babc

Change-Id: I309e3df7608b9eef9339196fdc50dedf5f9439f0
Reviewed-on: https://go-review.googlesource.com/8437Reviewed-by: default avatarAram Hăvărneanu <aram@mgk.ro>
Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent a50b24c6
...@@ -66,8 +66,33 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) { ...@@ -66,8 +66,33 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
} }
func elfreloc1(r *ld.Reloc, sectoff int64) int { func elfreloc1(r *ld.Reloc, sectoff int64) int {
// TODO(minux) ld.Thearch.Vput(uint64(sectoff))
return -1
elfsym := r.Xsym.Elfsym
switch r.Type {
default:
return -1
case ld.R_ADDR:
switch r.Siz {
case 4:
ld.Thearch.Vput(ld.R_AARCH64_ABS32 | uint64(elfsym)<<32)
case 8:
ld.Thearch.Vput(ld.R_AARCH64_ABS64 | uint64(elfsym)<<32)
default:
return -1
}
case ld.R_CALLARM64:
if r.Siz != 4 {
return -1
}
ld.Thearch.Vput(ld.R_AARCH64_CALL26 | uint64(elfsym)<<32)
}
ld.Thearch.Vput(uint64(r.Xadd))
return 0
} }
func elfsetupplt() { func elfsetupplt() {
...@@ -81,8 +106,18 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -81,8 +106,18 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int { func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
if ld.Linkmode == ld.LinkExternal { if ld.Linkmode == ld.LinkExternal {
// TODO(minux): translate R_CALLARM64 into standard ELF relocation. switch r.Type {
return -1 default:
return -1
case ld.R_CALLARM64:
r.Done = 0
r.Xsym = r.Sym
*val = int64(0xfc000000 & uint32(r.Add))
r.Xadd = int64((uint32(r.Add) &^ 0xfc000000) * 4)
r.Add = 0
return 0
}
} }
switch r.Type { switch r.Type {
...@@ -108,7 +143,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 { ...@@ -108,7 +143,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 {
} }
func adddynsym(ctxt *ld.Link, s *ld.LSym) { func adddynsym(ctxt *ld.Link, s *ld.LSym) {
log.Fatalf("adddynsym not implemented") // TODO(minux): implement when needed.
} }
func adddynlib(lib string) { func adddynlib(lib string) {
......
...@@ -96,6 +96,8 @@ func archinit() { ...@@ -96,6 +96,8 @@ func archinit() {
if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" { if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" {
log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE))) log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE)))
} }
case ld.Hlinux:
break
} }
switch ld.HEADTYPE { switch ld.HEADTYPE {
......
...@@ -2367,12 +2367,13 @@ func dwarfaddshstrings(shstrtab *LSym) { ...@@ -2367,12 +2367,13 @@ func dwarfaddshstrings(shstrtab *LSym) {
elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str") elfstrdbg[ElfStrDebugStr] = Addstring(shstrtab, ".debug_str")
elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts") elfstrdbg[ElfStrGDBScripts] = Addstring(shstrtab, ".debug_gdb_scripts")
if Linkmode == LinkExternal { if Linkmode == LinkExternal {
if Thearch.Thechar == '6' || Thearch.Thechar == '9' { switch Thearch.Thechar {
case '6', '7', '9':
elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info") elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rela.debug_info")
elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges") elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rela.debug_aranges")
elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line") elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rela.debug_line")
elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame") elfstrdbg[ElfStrRelDebugFrame] = Addstring(shstrtab, ".rela.debug_frame")
} else { default:
elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info") elfstrdbg[ElfStrRelDebugInfo] = Addstring(shstrtab, ".rel.debug_info")
elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges") elfstrdbg[ElfStrRelDebugAranges] = Addstring(shstrtab, ".rel.debug_aranges")
elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line") elfstrdbg[ElfStrRelDebugLine] = Addstring(shstrtab, ".rel.debug_line")
...@@ -2419,9 +2420,10 @@ func dwarfaddelfsectionsyms() { ...@@ -2419,9 +2420,10 @@ func dwarfaddelfsectionsyms() {
func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) { func dwarfaddelfrelocheader(elfstr int, shdata *ElfShdr, off int64, size int64) {
sh := newElfShdr(elfstrdbg[elfstr]) sh := newElfShdr(elfstrdbg[elfstr])
if Thearch.Thechar == '6' || Thearch.Thechar == '9' { switch Thearch.Thechar {
case '6', '7', '9':
sh.type_ = SHT_RELA sh.type_ = SHT_RELA
} else { default:
sh.type_ = SHT_REL sh.type_ = SHT_REL
} }
......
...@@ -1489,10 +1489,11 @@ func elfshreloc(sect *Section) *ElfShdr { ...@@ -1489,10 +1489,11 @@ func elfshreloc(sect *Section) *ElfShdr {
var prefix string var prefix string
var typ int var typ int
if Thearch.Thechar == '6' || Thearch.Thechar == '9' { switch Thearch.Thechar {
case '6', '7', '9':
prefix = ".rela" prefix = ".rela"
typ = SHT_RELA typ = SHT_RELA
} else { default:
prefix = ".rel" prefix = ".rel"
typ = SHT_REL typ = SHT_REL
} }
...@@ -1657,9 +1658,10 @@ func doelf() { ...@@ -1657,9 +1658,10 @@ func doelf() {
if Flag_shared != 0 { if Flag_shared != 0 {
Addstring(shstrtab, ".init_array") Addstring(shstrtab, ".init_array")
if Thearch.Thechar == '6' || Thearch.Thechar == '9' { switch Thearch.Thechar {
case '6', '7', '9':
Addstring(shstrtab, ".rela.init_array") Addstring(shstrtab, ".rela.init_array")
} else { default:
Addstring(shstrtab, ".rel.init_array") Addstring(shstrtab, ".rel.init_array")
} }
} }
...@@ -1683,10 +1685,11 @@ func doelf() { ...@@ -1683,10 +1685,11 @@ func doelf() {
Addstring(shstrtab, ".dynamic") Addstring(shstrtab, ".dynamic")
Addstring(shstrtab, ".dynsym") Addstring(shstrtab, ".dynsym")
Addstring(shstrtab, ".dynstr") Addstring(shstrtab, ".dynstr")
if Thearch.Thechar == '6' || Thearch.Thechar == '9' { switch Thearch.Thechar {
case '6', '7', '9':
Addstring(shstrtab, ".rela") Addstring(shstrtab, ".rela")
Addstring(shstrtab, ".rela.plt") Addstring(shstrtab, ".rela.plt")
} else { default:
Addstring(shstrtab, ".rel") Addstring(shstrtab, ".rel")
Addstring(shstrtab, ".rel.plt") Addstring(shstrtab, ".rel.plt")
} }
...@@ -1700,9 +1703,10 @@ func doelf() { ...@@ -1700,9 +1703,10 @@ func doelf() {
s.Type = SELFROSECT s.Type = SELFROSECT
s.Reachable = true s.Reachable = true
if Thearch.Thechar == '6' || Thearch.Thechar == '9' { switch Thearch.Thechar {
case '6', '7', '9':
s.Size += ELF64SYMSIZE s.Size += ELF64SYMSIZE
} else { default:
s.Size += ELF32SYMSIZE s.Size += ELF32SYMSIZE
} }
...@@ -1791,9 +1795,10 @@ func doelf() { ...@@ -1791,9 +1795,10 @@ func doelf() {
elfwritedynentsym(s, DT_HASH, Linklookup(Ctxt, ".hash", 0)) elfwritedynentsym(s, DT_HASH, Linklookup(Ctxt, ".hash", 0))
elfwritedynentsym(s, DT_SYMTAB, Linklookup(Ctxt, ".dynsym", 0)) elfwritedynentsym(s, DT_SYMTAB, Linklookup(Ctxt, ".dynsym", 0))
if Thearch.Thechar == '6' || Thearch.Thechar == '9' { switch Thearch.Thechar {
case '6', '7', '9':
Elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE) Elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE)
} else { default:
Elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE) Elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE)
} }
elfwritedynentsym(s, DT_STRTAB, Linklookup(Ctxt, ".dynstr", 0)) elfwritedynentsym(s, DT_STRTAB, Linklookup(Ctxt, ".dynstr", 0))
......
...@@ -711,6 +711,9 @@ func hostlink() { ...@@ -711,6 +711,9 @@ func hostlink() {
case '5': case '5':
argv = append(argv, "-marm") argv = append(argv, "-marm")
case '7':
// nothing needed
} }
if Debug['s'] == 0 && debug_s == 0 { if Debug['s'] == 0 && debug_s == 0 {
......
...@@ -167,11 +167,9 @@ func putelfsectionsym(s *LSym, shndx int) { ...@@ -167,11 +167,9 @@ func putelfsectionsym(s *LSym, shndx int) {
func putelfsymshndx(sympos int64, shndx int) { func putelfsymshndx(sympos int64, shndx int) {
here := Cpos() here := Cpos()
switch Thearch.Thechar { if elf64 != 0 {
case '6':
Cseek(sympos + 6) Cseek(sympos + 6)
} else {
default:
Cseek(sympos + 14) Cseek(sympos + 14)
} }
......
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