1
0
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:
Michael Hudson-Doyle 2015-05-05 16:10:12 +12:00 committed by Ian Lance Taylor
parent c661cb01f7
commit 9f5d0bff41
4 changed files with 31 additions and 21 deletions

View File

@ -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
} }

View File

@ -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)

View File

@ -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

View File

@ -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