mirror of
https://github.com/golang/go
synced 2024-11-19 03:04:42 -07:00
cmd/internal/ld, cmd/6l: external linking for windows/amd64
Change-Id: I2d2ea233f976aab3f356f9b508cdd246d5013e30 Signed-off-by: Shenghou Ma <minux@golang.org> Reviewed-on: https://go-review.googlesource.com/7534 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
484d9399de
commit
e7df053977
@ -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) {
|
|||||||
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 {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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) {
|
|||||||
} 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 {
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user