Commit 9f5d0bff authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle Committed by Ian Lance Taylor

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: default avatarIan Lance Taylor <iant@golang.org>
parent c661cb01
...@@ -33,6 +33,7 @@ package main ...@@ -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 { ...@@ -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) { ...@@ -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 ...@@ -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 ...@@ -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
......
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