]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/6l, cmd/internal/ld: handle R_PCREL to function in other shared library
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Tue, 5 May 2015 04:10:12 +0000 (16:10 +1200)
committerIan Lance Taylor <iant@golang.org>
Wed, 6 May 2015 00:17:23 +0000 (00:17 +0000)
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>
src/cmd/6l/asm.go
src/cmd/internal/ld/lib.go
src/cmd/internal/ld/link.go
src/cmd/internal/ld/symtab.go

index deaeb82d39f20f1c1a99e587b1d2b637d3f544ff..4df8ac719645ec630855b1dd3fe50dbdb2dd7d0f 100644 (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 {
-                       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
                }
index cdf2dcaccb26c0c50d7e098c555657e1881d02d0..184175e02648c4c5c3713d9b82fda20f0bb2f417 100644 (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)
index 52390e741d2493c8c8c45742aa492357705fa1d2..03da52a98150b71fbd2924ad20454516241f9e50 100644 (file)
@@ -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
index 31baba010b265b5cea6c060dacc37c0c0d2c6300..d6e79dc00fddbf985251e4a76cd49526c4e285e6 100644 (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