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