blob: 27edbcb22ddb22cb919bebaab85240c45e3eaa7e [file] [log] [blame]
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ld
import (
"cmd/internal/objabi"
"cmd/link/internal/loader"
"cmd/link/internal/sym"
)
// Temporary dumping around for sym.Symbol version of helper
// functions in xcoff.go, still being used for some archs/oses.
// FIXME: get rid of this file when dodata() is completely
// converted.
// xcoffUpdateOuterSize stores the size of outer symbols in order to have it
// in the symbol table.
func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) {
if size == 0 {
return
}
switch stype {
default:
Errorf(nil, "unknown XCOFF outer symbol for type %s", stype.String())
case sym.SRODATA, sym.SRODATARELRO, sym.SFUNCTAB, sym.SSTRING:
// Nothing to do
case sym.STYPERELRO:
if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) {
// runtime.types size must be removed, as it's a real symbol.
outerSymSize["typerel.*"] = size - ctxt.Syms.ROLookup("runtime.types", 0).Size
return
}
fallthrough
case sym.STYPE:
if !ctxt.DynlinkingGo() {
// runtime.types size must be removed, as it's a real symbol.
outerSymSize["type.*"] = size - ctxt.Syms.ROLookup("runtime.types", 0).Size
}
case sym.SGOSTRING:
outerSymSize["go.string.*"] = size
case sym.SGOFUNC:
if !ctxt.DynlinkingGo() {
outerSymSize["go.func.*"] = size
}
case sym.SGOFUNCRELRO:
outerSymSize["go.funcrel.*"] = size
case sym.SGCBITS:
outerSymSize["runtime.gcbits.*"] = size
case sym.SITABLINK:
outerSymSize["runtime.itablink"] = size
}
}
// Xcoffadddynrel adds a dynamic relocation in a XCOFF file.
// This relocation will be made by the loader.
func Xcoffadddynrel(target *Target, ldr *loader.Loader, s *sym.Symbol, r *sym.Reloc) bool {
if target.IsExternal() {
return true
}
if s.Type <= sym.SPCLNTAB {
Errorf(s, "cannot have a relocation to %s in a text section symbol", r.Sym.Name)
return false
}
xldr := &xcoffLoaderReloc{
sym: s,
roff: r.Off,
}
switch r.Type {
default:
Errorf(s, "unexpected .loader relocation to symbol: %s (type: %s)", r.Sym.Name, r.Type.String())
return false
case objabi.R_ADDR:
if s.Type == sym.SXCOFFTOC && r.Sym.Type == sym.SDYNIMPORT {
// Imported symbol relocation
for i, dynsym := range xfile.loaderSymbols {
if ldr.Syms[dynsym.sym].Name == r.Sym.Name {
xldr.symndx = int32(i + 3) // +3 because of 3 section symbols
break
}
}
} else if s.Type == sym.SDATA || s.Type == sym.SNOPTRDATA || s.Type == sym.SBUILDINFO || s.Type == sym.SXCOFFTOC {
switch r.Sym.Sect.Seg {
default:
Errorf(s, "unknown segment for .loader relocation with symbol %s", r.Sym.Name)
case &Segtext:
case &Segrodata:
xldr.symndx = 0 // .text
case &Segdata:
if r.Sym.Type == sym.SBSS || r.Sym.Type == sym.SNOPTRBSS {
xldr.symndx = 2 // .bss
} else {
xldr.symndx = 1 // .data
}
}
} else {
Errorf(s, "unexpected type for .loader relocation R_ADDR for symbol %s: %s to %s", r.Sym.Name, s.Type, r.Sym.Type)
return false
}
xldr.rtype = 0x3F<<8 + XCOFF_R_POS
}
xfile.loaderReloc = append(xfile.loaderReloc, xldr)
return true
}