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

cmd/internal/ld, cmd/6l: external linking for windows/amd64

Change-Id: I2d2ea233f976aab3f356f9b508cdd246d5013e30
Signed-off-by: default avatarShenghou Ma <minux@golang.org>
Reviewed-on: https://go-review.googlesource.com/7534Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 484d9399
...@@ -204,10 +204,16 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) { ...@@ -204,10 +204,16 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
switch r.Type { switch r.Type {
case ld.R_CALL, case ld.R_CALL,
ld.R_PCREL: ld.R_PCREL:
addpltsym(targ) if ld.HEADTYPE == ld.Hwindows {
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) // nothing to do, the relocation will be laid out in pereloc1
r.Add = int64(targ.Plt) return
return } else {
// for both ELF and Mach-O
addpltsym(targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0)
r.Add = int64(targ.Plt)
return
}
case ld.R_ADDR: case ld.R_ADDR:
if s.Type == ld.STEXT && ld.Iself { if s.Type == ld.STEXT && ld.Iself {
...@@ -262,6 +268,11 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) { ...@@ -262,6 +268,11 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
r.Type = 256 // ignore during relocsym r.Type = 256 // ignore during relocsym
return return
} }
if ld.HEADTYPE == ld.Hwindows {
// nothing to do, the relocation will be laid out in pereloc1
return
}
} }
ld.Ctxt.Cursym = s ld.Ctxt.Cursym = s
...@@ -393,6 +404,40 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -393,6 +404,40 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func pereloc1(r *ld.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
if rs.Dynid < 0 {
ld.Diag("reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type)
return false
}
ld.Thearch.Lput(uint32(sectoff))
ld.Thearch.Lput(uint32(rs.Dynid))
switch r.Type {
default:
return false
case ld.R_ADDR:
if r.Siz == 8 {
v = ld.IMAGE_REL_AMD64_ADDR64
} else {
v = ld.IMAGE_REL_AMD64_ADDR32
}
case ld.R_CALL,
ld.R_PCREL:
v = ld.IMAGE_REL_AMD64_REL32
}
ld.Thearch.Wput(uint16(v))
return true
}
func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int { func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
return -1 return -1
} }
......
...@@ -71,6 +71,7 @@ func linkarchinit() { ...@@ -71,6 +71,7 @@ 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
ld.Thearch.PEreloc1 = pereloc1
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
...@@ -110,7 +111,8 @@ func archinit() { ...@@ -110,7 +111,8 @@ func archinit() {
ld.Hnacl, ld.Hnacl,
ld.Hnetbsd, ld.Hnetbsd,
ld.Hopenbsd, ld.Hopenbsd,
ld.Hsolaris: ld.Hsolaris,
ld.Hwindows:
break break
} }
......
...@@ -499,8 +499,13 @@ func relocsym(s *LSym) { ...@@ -499,8 +499,13 @@ func relocsym(s *LSym) {
} else { } else {
o += int64(r.Siz) o += int64(r.Siz)
} }
} else if HEADTYPE == Hwindows { } else if HEADTYPE == Hwindows && Thearch.Thechar == '6' { // only amd64 needs PCREL
// nothing to do // PE/COFF's PC32 relocation uses the address after the relocated
// bytes as the base. Compensate by skewing the addend.
o += int64(r.Siz)
// GNU ld always add VirtualAddress of the .text section to the
// relocated address, compensate that.
o -= int64(s.Sect.(*Section).Vaddr - PEBASE)
} else { } else {
Diag("unhandled pcrel relocation for %s", headstring) Diag("unhandled pcrel relocation for %s", headstring)
} }
......
...@@ -532,7 +532,8 @@ func initdynimport() *Dll { ...@@ -532,7 +532,8 @@ func initdynimport() *Dll {
m.s.Type = SDATA m.s.Type = SDATA
Symgrow(Ctxt, m.s, int64(Thearch.Ptrsize)) Symgrow(Ctxt, m.s, int64(Thearch.Ptrsize))
dynName := m.s.Extname dynName := m.s.Extname
if m.argsize >= 0 { // only windows/386 requires stdcall decoration
if Thearch.Thechar == '8' && m.argsize >= 0 {
dynName += fmt.Sprintf("@%d", m.argsize) dynName += fmt.Sprintf("@%d", m.argsize)
} }
dynSym := Linklookup(Ctxt, dynName, 0) dynSym := Linklookup(Ctxt, dynName, 0)
...@@ -955,7 +956,8 @@ func addpesym(s *LSym, name string, type_ int, addr int64, size int64, ver int, ...@@ -955,7 +956,8 @@ func addpesym(s *LSym, name string, type_ int, addr int64, size int64, ver int,
} }
if coffsym != nil { if coffsym != nil {
if Linkmode == LinkExternal && (s.Type == SHOSTOBJ || s.Cgoexport != 0) && s.Name == s.Extname { // only windows/386 requires underscore prefix on external symbols
if Thearch.Thechar == '8' && Linkmode == LinkExternal && (s.Type == SHOSTOBJ || s.Cgoexport != 0) && s.Name == s.Extname {
s.Name = "_" + s.Name s.Name = "_" + s.Name
} }
cs := &coffsym[ncoffsym] cs := &coffsym[ncoffsym]
...@@ -963,7 +965,9 @@ func addpesym(s *LSym, name string, type_ int, addr int64, size int64, ver int, ...@@ -963,7 +965,9 @@ func addpesym(s *LSym, name string, type_ int, addr int64, size int64, ver int,
if len(s.Name) > 8 { if len(s.Name) > 8 {
cs.strtbloff = strtbladd(s.Name) cs.strtbloff = strtbladd(s.Name)
} }
if uint64(s.Value) >= Segdata.Vaddr+Segdata.Filelen && Linkmode == LinkExternal { // Note: although address of runtime.edata (type SDATA) is at the start of .bss section
// it still belongs to the .data section, not the .bss section.
if uint64(s.Value) >= Segdata.Vaddr+Segdata.Filelen && s.Type != SDATA && Linkmode == LinkExternal {
cs.value = int64(uint64(s.Value) - Segdata.Vaddr - Segdata.Filelen) cs.value = int64(uint64(s.Value) - Segdata.Vaddr - Segdata.Filelen)
cs.sect = bsssect cs.sect = bsssect
} else if uint64(s.Value) >= Segdata.Vaddr { } else if uint64(s.Value) >= Segdata.Vaddr {
......
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