mirror of
https://github.com/golang/go
synced 2024-11-18 14:04:45 -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 (
|
||||
"cmd/internal/ld"
|
||||
"cmd/internal/obj"
|
||||
"debug/elf"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
@ -381,7 +382,11 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||
|
||||
case obj.R_PCREL:
|
||||
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 {
|
||||
return -1
|
||||
}
|
||||
|
@ -1197,6 +1197,7 @@ func ldshlibsyms(shlib string) {
|
||||
s.Name, shlib, lsym.File)
|
||||
}
|
||||
lsym.Type = obj.SDYNIMPORT
|
||||
lsym.ElfType = elf.ST_TYPE(s.Info)
|
||||
lsym.File = libpath
|
||||
if strings.HasPrefix(lsym.Name, "type.") {
|
||||
data := make([]byte, s.Size)
|
||||
|
@ -32,26 +32,31 @@ package ld
|
||||
|
||||
import (
|
||||
"cmd/internal/obj"
|
||||
"debug/elf"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
type LSym struct {
|
||||
Name string
|
||||
Extname string
|
||||
Type int16
|
||||
Version int16
|
||||
Dupok uint8
|
||||
Cfunc uint8
|
||||
External uint8
|
||||
Nosplit uint8
|
||||
Reachable bool
|
||||
Cgoexport uint8
|
||||
Special uint8
|
||||
Stkcheck uint8
|
||||
Hide uint8
|
||||
Leaf uint8
|
||||
Localentry uint8
|
||||
Onlist uint8
|
||||
Name string
|
||||
Extname string
|
||||
Type int16
|
||||
Version int16
|
||||
Dupok uint8
|
||||
Cfunc uint8
|
||||
External uint8
|
||||
Nosplit uint8
|
||||
Reachable bool
|
||||
Cgoexport uint8
|
||||
Special uint8
|
||||
Stkcheck uint8
|
||||
Hide uint8
|
||||
Leaf uint8
|
||||
Localentry 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
|
||||
Plt 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
|
||||
|
||||
case 'U':
|
||||
type_ = STT_NOTYPE
|
||||
if x == Ctxt.Tlsg {
|
||||
type_ = STT_TLS
|
||||
}
|
||||
// ElfType is only set for symbols read from Go shared libraries, but
|
||||
// for other symbols it is left as STT_NOTYPE which is fine.
|
||||
type_ = int(x.ElfType)
|
||||
|
||||
case 't':
|
||||
type_ = STT_TLS
|
||||
|
Loading…
Reference in New Issue
Block a user