mirror of https://github.com/golang/go.git
cmd/link: always resolve functions locally when linking dynamically
When dynamically linking, we want references to functions defined in this module to always be to the function object, not to the PLT. We force this by writing an additional local symbol for every global function symbol and making all relocations against the global symbol refer to this local symbol instead. This is approximately equivalent to the ELF linker -Bsymbolic-functions option, but that is buggy on several platforms. Change-Id: Ie6983eb4d1947f8543736fd349f9a90df3cce91a Reviewed-on: https://go-review.googlesource.com/16436 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
ab7e82ef3b
commit
c34fb3cfc6
|
|
@ -323,7 +323,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
|||
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||
ld.Thearch.Vput(uint64(sectoff))
|
||||
|
||||
elfsym := r.Xsym.Elfsym
|
||||
elfsym := r.Xsym.ElfsymForReloc()
|
||||
switch r.Type {
|
||||
default:
|
||||
return -1
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
|||
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||
ld.Thearch.Lput(uint32(sectoff))
|
||||
|
||||
elfsym := r.Xsym.Elfsym
|
||||
elfsym := r.Xsym.ElfsymForReloc()
|
||||
switch r.Type {
|
||||
default:
|
||||
return -1
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
|||
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||
ld.Thearch.Vput(uint64(sectoff))
|
||||
|
||||
elfsym := r.Xsym.Elfsym
|
||||
elfsym := r.Xsym.ElfsymForReloc()
|
||||
switch r.Type {
|
||||
default:
|
||||
return -1
|
||||
|
|
|
|||
|
|
@ -1615,7 +1615,7 @@ func elfrelocsect(sect *Section, first *LSym) {
|
|||
continue
|
||||
}
|
||||
|
||||
if r.Xsym.Elfsym == 0 {
|
||||
if r.Xsym.ElfsymForReloc() == 0 {
|
||||
Diag("reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
|
||||
}
|
||||
if Thearch.Elfreloc1(r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
|
||||
|
|
|
|||
|
|
@ -1031,14 +1031,6 @@ func hostlink() {
|
|||
argv = append(argv, "-shared", "-Wl,-z,nodelete")
|
||||
}
|
||||
case BuildmodeShared:
|
||||
// TODO(mwhudson): unless you do this, dynamic relocations fill
|
||||
// out the findfunctab table and for some reason shared libraries
|
||||
// and the executable both define a main function and putting the
|
||||
// address of executable's main into the shared libraries
|
||||
// findfunctab violates the assumptions of the runtime. TBH, I
|
||||
// think we may well end up wanting to use -Bsymbolic here
|
||||
// anyway.
|
||||
argv = append(argv, "-Wl,-Bsymbolic-functions")
|
||||
if UseRelro() {
|
||||
argv = append(argv, "-Wl,-z,relro")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ type LSym struct {
|
|||
Got int32
|
||||
Align int32
|
||||
Elfsym int32
|
||||
LocalElfsym int32
|
||||
Args int32
|
||||
Locals int32
|
||||
Value int64
|
||||
|
|
@ -92,6 +93,16 @@ func (s *LSym) String() string {
|
|||
return fmt.Sprintf("%s<%d>", s.Name, s.Version)
|
||||
}
|
||||
|
||||
func (s *LSym) ElfsymForReloc() int32 {
|
||||
// If putelfsym created a local version of this symbol, use that in all
|
||||
// relocations.
|
||||
if s.LocalElfsym != 0 {
|
||||
return s.LocalElfsym
|
||||
} else {
|
||||
return s.Elfsym
|
||||
}
|
||||
}
|
||||
|
||||
type Reloc struct {
|
||||
Off int32
|
||||
Siz uint8
|
||||
|
|
|
|||
|
|
@ -155,11 +155,6 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
|
|||
bind = STB_LOCAL
|
||||
}
|
||||
|
||||
if bind != elfbind {
|
||||
return
|
||||
}
|
||||
|
||||
off := putelfstr(s)
|
||||
if Linkmode == LinkExternal && elfshnum != SHN_UNDEF {
|
||||
addr -= int64(xo.Sect.Vaddr)
|
||||
}
|
||||
|
|
@ -167,7 +162,24 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
|
|||
if x.Type&obj.SHIDDEN != 0 {
|
||||
other = STV_HIDDEN
|
||||
}
|
||||
putelfsyment(off, addr, size, bind<<4|type_&0xf, elfshnum, other)
|
||||
|
||||
if DynlinkingGo() && bind == STB_GLOBAL && elfbind == STB_LOCAL && x.Type == obj.STEXT {
|
||||
// When dynamically linking, we want references to functions defined
|
||||
// in this module to always be to the function object, not to the
|
||||
// PLT. We force this by writing an additional local symbol for every
|
||||
// global function symbol and making all relocations against the
|
||||
// global symbol refer to this local symbol instead (see
|
||||
// (*LSym).ElfsymForReloc). This is approximately equivalent to the
|
||||
// ELF linker -Bsymbolic-functions option, but that is buggy on
|
||||
// several platforms.
|
||||
putelfsyment(putelfstr("local."+s), addr, size, STB_LOCAL<<4|type_&0xf, elfshnum, other)
|
||||
x.LocalElfsym = int32(numelfsym)
|
||||
numelfsym++
|
||||
} else if bind != elfbind {
|
||||
return
|
||||
}
|
||||
|
||||
putelfsyment(putelfstr(s), addr, size, bind<<4|type_&0xf, elfshnum, other)
|
||||
x.Elfsym = int32(numelfsym)
|
||||
numelfsym++
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
|||
func elfreloc1(r *ld.Reloc, sectoff int64) int {
|
||||
ld.Thearch.Lput(uint32(sectoff))
|
||||
|
||||
elfsym := r.Xsym.Elfsym
|
||||
elfsym := r.Xsym.ElfsymForReloc()
|
||||
switch r.Type {
|
||||
default:
|
||||
return -1
|
||||
|
|
|
|||
Loading…
Reference in New Issue