mirror of
https://github.com/golang/go
synced 2024-11-18 16:34:51 -07:00
cmd/6l, cmd/internal/ld: handle R_PCREL to function in other shared library
An ELF linker handles a PC-relative reference to an STT_FUNC defined in a shared library by building a PLT entry and referring to that, so do the same in 6l. Fixes #10690 Change-Id: I061a96fd4400d957e301d0ac86760ce256910e1d Reviewed-on: https://go-review.googlesource.com/9711 Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
c661cb01f7
commit
9f5d0bff41
@ -33,6 +33,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"cmd/internal/ld"
|
"cmd/internal/ld"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
"debug/elf"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
@ -381,7 +382,11 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
|||||||
|
|
||||||
case obj.R_PCREL:
|
case obj.R_PCREL:
|
||||||
if r.Siz == 4 {
|
if r.Siz == 4 {
|
||||||
ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
|
if r.Xsym.Type == obj.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC {
|
||||||
|
ld.Thearch.Vput(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
|
||||||
|
} else {
|
||||||
|
ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
@ -1197,6 +1197,7 @@ func ldshlibsyms(shlib string) {
|
|||||||
s.Name, shlib, lsym.File)
|
s.Name, shlib, lsym.File)
|
||||||
}
|
}
|
||||||
lsym.Type = obj.SDYNIMPORT
|
lsym.Type = obj.SDYNIMPORT
|
||||||
|
lsym.ElfType = elf.ST_TYPE(s.Info)
|
||||||
lsym.File = libpath
|
lsym.File = libpath
|
||||||
if strings.HasPrefix(lsym.Name, "type.") {
|
if strings.HasPrefix(lsym.Name, "type.") {
|
||||||
data := make([]byte, s.Size)
|
data := make([]byte, s.Size)
|
||||||
|
@ -32,26 +32,31 @@ package ld
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
"debug/elf"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LSym struct {
|
type LSym struct {
|
||||||
Name string
|
Name string
|
||||||
Extname string
|
Extname string
|
||||||
Type int16
|
Type int16
|
||||||
Version int16
|
Version int16
|
||||||
Dupok uint8
|
Dupok uint8
|
||||||
Cfunc uint8
|
Cfunc uint8
|
||||||
External uint8
|
External uint8
|
||||||
Nosplit uint8
|
Nosplit uint8
|
||||||
Reachable bool
|
Reachable bool
|
||||||
Cgoexport uint8
|
Cgoexport uint8
|
||||||
Special uint8
|
Special uint8
|
||||||
Stkcheck uint8
|
Stkcheck uint8
|
||||||
Hide uint8
|
Hide uint8
|
||||||
Leaf uint8
|
Leaf uint8
|
||||||
Localentry uint8
|
Localentry uint8
|
||||||
Onlist uint8
|
Onlist uint8
|
||||||
|
// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
|
||||||
|
// is not set for symbols defined by the packages being linked or by symbols
|
||||||
|
// read by ldelf (and so is left as elf.STT_NOTYPE).
|
||||||
|
ElfType elf.SymType
|
||||||
Dynid int32
|
Dynid int32
|
||||||
Plt int32
|
Plt int32
|
||||||
Got int32
|
Got int32
|
||||||
|
@ -106,10 +106,9 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
|
|||||||
type_ = STT_OBJECT
|
type_ = STT_OBJECT
|
||||||
|
|
||||||
case 'U':
|
case 'U':
|
||||||
type_ = STT_NOTYPE
|
// ElfType is only set for symbols read from Go shared libraries, but
|
||||||
if x == Ctxt.Tlsg {
|
// for other symbols it is left as STT_NOTYPE which is fine.
|
||||||
type_ = STT_TLS
|
type_ = int(x.ElfType)
|
||||||
}
|
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
type_ = STT_TLS
|
type_ = STT_TLS
|
||||||
|
Loading…
Reference in New Issue
Block a user