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 (
"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 {
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
}

View file

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

View file

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

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