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
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
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
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 {
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")
}
Got int32
Align int32
Elfsym int32
+ LocalElfsym int32
Args int32
Locals int32
Value int64
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
bind = STB_LOCAL
}
- if bind != elfbind {
- return
- }
-
- off := putelfstr(s)
if Linkmode == LinkExternal && elfshnum != SHN_UNDEF {
addr -= int64(xo.Sect.Vaddr)
}
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++
}
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