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 {
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) 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,6 +32,7 @@ package ld ...@@ -32,6 +32,7 @@ package ld
import ( import (
"cmd/internal/obj" "cmd/internal/obj"
"debug/elf"
"encoding/binary" "encoding/binary"
) )
...@@ -52,6 +53,10 @@ type LSym struct { ...@@ -52,6 +53,10 @@ type LSym struct {
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