2016-03-19 00:23:17 -04:00
|
|
|
// Inferno utils/5l/asm.c
|
2016-08-28 17:04:46 -07:00
|
|
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
|
2016-03-19 00:23:17 -04:00
|
|
|
//
|
|
|
|
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
|
|
|
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
|
|
|
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
|
|
|
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
|
|
|
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
|
|
|
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
|
|
|
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
2016-04-10 14:32:26 -07:00
|
|
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
2016-03-19 00:23:17 -04:00
|
|
|
//
|
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
|
//
|
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
|
//
|
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
|
// THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
package s390x
|
|
|
|
|
|
|
|
|
|
import (
|
2017-04-18 12:53:25 -07:00
|
|
|
"cmd/internal/objabi"
|
2017-09-30 21:10:49 +00:00
|
|
|
"cmd/internal/sys"
|
2016-03-19 00:23:17 -04:00
|
|
|
"cmd/link/internal/ld"
|
2020-03-11 12:12:41 -04:00
|
|
|
"cmd/link/internal/loader"
|
2017-10-04 17:54:04 -04:00
|
|
|
"cmd/link/internal/sym"
|
2016-03-19 00:23:17 -04:00
|
|
|
"debug/elf"
|
|
|
|
|
"fmt"
|
2020-03-20 12:24:35 -04:00
|
|
|
"sync"
|
2016-03-19 00:23:17 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// gentext generates assembly to append the local moduledata to the global
|
|
|
|
|
// moduledata linked list at initialization time. This is only done if the runtime
|
|
|
|
|
// is in a different module.
|
|
|
|
|
//
|
|
|
|
|
// <go.link.addmoduledata>:
|
|
|
|
|
// larl %r2, <local.moduledata>
|
|
|
|
|
// jg <runtime.addmoduledata@plt>
|
|
|
|
|
// undef
|
|
|
|
|
//
|
|
|
|
|
// The job of appending the moduledata is delegated to runtime.addmoduledata.
|
2020-04-02 07:47:12 -04:00
|
|
|
func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
|
|
|
|
|
initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
|
|
|
|
|
if initfunc == nil {
|
2016-03-19 00:23:17 -04:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// larl %r2, <local.moduledata>
|
2017-09-30 15:06:44 +00:00
|
|
|
initfunc.AddUint8(0xc0)
|
|
|
|
|
initfunc.AddUint8(0x20)
|
2020-04-02 07:47:12 -04:00
|
|
|
initfunc.AddSymRef(ctxt.Arch, ctxt.Moduledata2, 6, objabi.R_PCREL, 4)
|
|
|
|
|
r1 := initfunc.Relocs()
|
|
|
|
|
ldr.SetRelocVariant(initfunc.Sym(), r1.Count()-1, sym.RV_390_DBL)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
|
|
|
|
// jg <runtime.addmoduledata[@plt]>
|
2017-09-30 15:06:44 +00:00
|
|
|
initfunc.AddUint8(0xc0)
|
|
|
|
|
initfunc.AddUint8(0xf4)
|
2020-04-02 07:47:12 -04:00
|
|
|
initfunc.AddSymRef(ctxt.Arch, addmoduledata, 6, objabi.R_CALL, 4)
|
|
|
|
|
r2 := initfunc.Relocs()
|
|
|
|
|
ldr.SetRelocVariant(initfunc.Sym(), r2.Count()-1, sym.RV_390_DBL)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
|
|
|
|
// undef (for debugging)
|
2017-09-30 15:06:44 +00:00
|
|
|
initfunc.AddUint32(ctxt.Arch, 0)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-24 17:56:24 -04:00
|
|
|
func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r *loader.Reloc2, rIdx int) bool {
|
|
|
|
|
targ := r.Sym()
|
|
|
|
|
var targType sym.SymKind
|
|
|
|
|
if targ != 0 {
|
|
|
|
|
targType = ldr.SymType(targ)
|
|
|
|
|
}
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2020-04-24 17:56:24 -04:00
|
|
|
switch r.Type() {
|
2016-03-19 00:23:17 -04:00
|
|
|
default:
|
2020-04-24 17:56:24 -04:00
|
|
|
if r.Type() >= objabi.ElfRelocOffset {
|
|
|
|
|
ldr.Errorf(s, "unexpected relocation type %d", r.Type())
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle relocations found in ELF object files.
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_12),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT12):
|
2020-04-24 17:56:24 -04:00
|
|
|
ldr.Errorf(s, "s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type()-objabi.ElfRelocOffset)
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_8),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_16),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_32),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_64):
|
2020-04-24 17:56:24 -04:00
|
|
|
if targType == sym.SDYNIMPORT {
|
|
|
|
|
ldr.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", ldr.SymName(targ))
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2020-04-24 17:56:24 -04:00
|
|
|
|
|
|
|
|
su := ldr.MakeSymbolUpdater(s)
|
|
|
|
|
su.SetRelocType(rIdx, objabi.R_ADDR)
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC16),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC32),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC64):
|
2020-04-24 17:56:24 -04:00
|
|
|
if targType == sym.SDYNIMPORT {
|
|
|
|
|
ldr.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", ldr.SymName(targ))
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2017-04-28 12:43:06 +12:00
|
|
|
// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
|
|
|
|
|
// sense and should be removed when someone has thought about it properly.
|
2020-04-24 17:56:24 -04:00
|
|
|
if (targType == 0 || targType == sym.SXREF) && !ldr.AttrVisibilityHidden(targ) {
|
|
|
|
|
ldr.Errorf(s, "unknown symbol %s in pcrel", ldr.SymName(targ))
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2020-04-24 17:56:24 -04:00
|
|
|
su := ldr.MakeSymbolUpdater(s)
|
|
|
|
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
|
|
|
|
su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT16),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT32),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT64):
|
2020-04-24 17:56:24 -04:00
|
|
|
ldr.Errorf(s, "unimplemented S390x relocation: %v", r.Type()-objabi.ElfRelocOffset)
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT16DBL),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT32DBL):
|
2020-04-24 17:56:24 -04:00
|
|
|
su := ldr.MakeSymbolUpdater(s)
|
|
|
|
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
|
|
|
|
ldr.SetRelocVariant(s, rIdx, sym.RV_390_DBL)
|
|
|
|
|
su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
|
|
|
|
|
if targType == sym.SDYNIMPORT {
|
|
|
|
|
addpltsym2(target, ldr, syms, targ)
|
|
|
|
|
r.SetSym(syms.PLT2)
|
|
|
|
|
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT32),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT64):
|
2020-04-24 17:56:24 -04:00
|
|
|
su := ldr.MakeSymbolUpdater(s)
|
|
|
|
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
|
|
|
|
su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
|
|
|
|
|
if targType == sym.SDYNIMPORT {
|
|
|
|
|
addpltsym2(target, ldr, syms, targ)
|
|
|
|
|
r.SetSym(syms.PLT2)
|
|
|
|
|
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_COPY):
|
2020-04-24 17:56:24 -04:00
|
|
|
ldr.Errorf(s, "unimplemented S390x relocation: %v", r.Type()-objabi.ElfRelocOffset)
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GLOB_DAT):
|
2020-04-24 17:56:24 -04:00
|
|
|
ldr.Errorf(s, "unimplemented S390x relocation: %v", r.Type()-objabi.ElfRelocOffset)
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_JMP_SLOT):
|
2020-04-24 17:56:24 -04:00
|
|
|
ldr.Errorf(s, "unimplemented S390x relocation: %v", r.Type()-objabi.ElfRelocOffset)
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_RELATIVE):
|
2020-04-24 17:56:24 -04:00
|
|
|
ldr.Errorf(s, "unimplemented S390x relocation: %v", r.Type()-objabi.ElfRelocOffset)
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTOFF):
|
2020-04-24 17:56:24 -04:00
|
|
|
if targType == sym.SDYNIMPORT {
|
|
|
|
|
ldr.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", ldr.SymName(targ))
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2020-04-24 17:56:24 -04:00
|
|
|
su := ldr.MakeSymbolUpdater(s)
|
|
|
|
|
su.SetRelocType(rIdx, objabi.R_GOTOFF)
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPC):
|
2020-04-24 17:56:24 -04:00
|
|
|
su := ldr.MakeSymbolUpdater(s)
|
|
|
|
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
|
|
|
|
r.SetSym(syms.GOT2)
|
|
|
|
|
su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC16DBL),
|
|
|
|
|
objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC32DBL):
|
2020-04-24 17:56:24 -04:00
|
|
|
su := ldr.MakeSymbolUpdater(s)
|
|
|
|
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
|
|
|
|
ldr.SetRelocVariant(s, rIdx, sym.RV_390_DBL)
|
|
|
|
|
su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
|
|
|
|
|
if targType == sym.SDYNIMPORT {
|
|
|
|
|
ldr.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", ldr.SymName(targ))
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPCDBL):
|
2020-04-24 17:56:24 -04:00
|
|
|
su := ldr.MakeSymbolUpdater(s)
|
|
|
|
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
|
|
|
|
ldr.SetRelocVariant(s, rIdx, sym.RV_390_DBL)
|
|
|
|
|
r.SetSym(syms.GOT2)
|
|
|
|
|
su.SetRelocAdd(rIdx, r.Add()+int64(r.Siz()))
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTENT):
|
2020-04-24 17:56:24 -04:00
|
|
|
addgotsym2(target, ldr, syms, targ)
|
|
|
|
|
su := ldr.MakeSymbolUpdater(s)
|
|
|
|
|
su.SetRelocType(rIdx, objabi.R_PCREL)
|
|
|
|
|
ldr.SetRelocVariant(s, rIdx, sym.RV_390_DBL)
|
|
|
|
|
r.SetSym(syms.GOT2)
|
|
|
|
|
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ))+int64(r.Siz()))
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
// Handle references to ELF symbols from our own object files.
|
2020-04-24 17:56:24 -04:00
|
|
|
if targType != sym.SDYNIMPORT {
|
2016-09-05 23:49:53 -04:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
2016-09-05 23:49:53 -04:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write64(uint64(sectoff))
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2020-04-28 10:51:40 -04:00
|
|
|
elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
|
2016-03-19 00:23:17 -04:00
|
|
|
switch r.Type {
|
|
|
|
|
default:
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_TLS_LE:
|
2016-03-19 00:23:17 -04:00
|
|
|
switch r.Siz {
|
|
|
|
|
default:
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
case 4:
|
|
|
|
|
// WARNING - silently ignored by linker in ELF64
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write64(uint64(elf.R_390_TLS_LE32) | uint64(elfsym)<<32)
|
2016-03-19 00:23:17 -04:00
|
|
|
case 8:
|
|
|
|
|
// WARNING - silently ignored by linker in ELF32
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write64(uint64(elf.R_390_TLS_LE64) | uint64(elfsym)<<32)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_TLS_IE:
|
2016-03-19 00:23:17 -04:00
|
|
|
switch r.Siz {
|
|
|
|
|
default:
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
case 4:
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_ADDR:
|
2016-03-19 00:23:17 -04:00
|
|
|
switch r.Siz {
|
|
|
|
|
default:
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
case 4:
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write64(uint64(elf.R_390_32) | uint64(elfsym)<<32)
|
2016-03-19 00:23:17 -04:00
|
|
|
case 8:
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write64(uint64(elf.R_390_64) | uint64(elfsym)<<32)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_GOTPCREL:
|
2016-03-19 00:23:17 -04:00
|
|
|
if r.Siz == 4 {
|
2017-10-06 16:01:02 -04:00
|
|
|
ctxt.Out.Write64(uint64(elf.R_390_GOTENT) | uint64(elfsym)<<32)
|
2016-03-19 00:23:17 -04:00
|
|
|
} else {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel := elf.R_390_NONE
|
2017-10-04 17:54:04 -04:00
|
|
|
isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL
|
2016-03-19 00:23:17 -04:00
|
|
|
// TODO(mundaym): all DBL style relocations should be
|
|
|
|
|
// signalled using the variant - see issue 14218.
|
|
|
|
|
switch r.Type {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_PCRELDBL, objabi.R_CALL:
|
2016-03-19 00:23:17 -04:00
|
|
|
isdbl = true
|
|
|
|
|
}
|
2018-07-18 10:19:35 -04:00
|
|
|
if r.Xsym.Type == sym.SDYNIMPORT && (r.Xsym.ElfType() == elf.STT_FUNC || r.Type == objabi.R_CALL) {
|
2016-03-19 00:23:17 -04:00
|
|
|
if isdbl {
|
|
|
|
|
switch r.Siz {
|
|
|
|
|
case 2:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel = elf.R_390_PLT16DBL
|
2016-03-19 00:23:17 -04:00
|
|
|
case 4:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel = elf.R_390_PLT32DBL
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
switch r.Siz {
|
|
|
|
|
case 4:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel = elf.R_390_PLT32
|
2016-03-19 00:23:17 -04:00
|
|
|
case 8:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel = elf.R_390_PLT64
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if isdbl {
|
|
|
|
|
switch r.Siz {
|
|
|
|
|
case 2:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel = elf.R_390_PC16DBL
|
2016-03-19 00:23:17 -04:00
|
|
|
case 4:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel = elf.R_390_PC32DBL
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
switch r.Siz {
|
|
|
|
|
case 2:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel = elf.R_390_PC16
|
2016-03-19 00:23:17 -04:00
|
|
|
case 4:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel = elf.R_390_PC32
|
2016-03-19 00:23:17 -04:00
|
|
|
case 8:
|
2017-10-06 16:01:02 -04:00
|
|
|
elfrel = elf.R_390_PC64
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-06 16:01:02 -04:00
|
|
|
if elfrel == elf.R_390_NONE {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false // unsupported size/dbl combination
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write64(uint64(elfrel) | uint64(elfsym)<<32)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write64(uint64(r.Xadd))
|
2017-08-27 22:00:00 +09:00
|
|
|
return true
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
2020-03-11 12:12:41 -04:00
|
|
|
func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
|
|
|
|
|
if plt.Size() == 0 {
|
2016-03-19 00:23:17 -04:00
|
|
|
// stg %r1,56(%r15)
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xe3)
|
|
|
|
|
plt.AddUint8(0x10)
|
|
|
|
|
plt.AddUint8(0xf0)
|
|
|
|
|
plt.AddUint8(0x38)
|
|
|
|
|
plt.AddUint8(0x00)
|
|
|
|
|
plt.AddUint8(0x24)
|
2016-03-19 00:23:17 -04:00
|
|
|
// larl %r1,_GLOBAL_OFFSET_TABLE_
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xc0)
|
|
|
|
|
plt.AddUint8(0x10)
|
2020-03-11 22:24:01 -04:00
|
|
|
plt.AddSymRef(ctxt.Arch, got.Sym(), 6, objabi.R_PCRELDBL, 4)
|
2016-03-19 00:23:17 -04:00
|
|
|
// mvc 48(8,%r15),8(%r1)
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xd2)
|
|
|
|
|
plt.AddUint8(0x07)
|
|
|
|
|
plt.AddUint8(0xf0)
|
|
|
|
|
plt.AddUint8(0x30)
|
|
|
|
|
plt.AddUint8(0x10)
|
|
|
|
|
plt.AddUint8(0x08)
|
2016-03-19 00:23:17 -04:00
|
|
|
// lg %r1,16(%r1)
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xe3)
|
|
|
|
|
plt.AddUint8(0x10)
|
|
|
|
|
plt.AddUint8(0x10)
|
|
|
|
|
plt.AddUint8(0x10)
|
|
|
|
|
plt.AddUint8(0x00)
|
|
|
|
|
plt.AddUint8(0x04)
|
2016-03-19 00:23:17 -04:00
|
|
|
// br %r1
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x07)
|
|
|
|
|
plt.AddUint8(0xf1)
|
2016-03-19 00:23:17 -04:00
|
|
|
// nopr %r0
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x07)
|
|
|
|
|
plt.AddUint8(0x00)
|
2016-03-19 00:23:17 -04:00
|
|
|
// nopr %r0
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x07)
|
|
|
|
|
plt.AddUint8(0x00)
|
2016-03-19 00:23:17 -04:00
|
|
|
// nopr %r0
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x07)
|
|
|
|
|
plt.AddUint8(0x00)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
|
|
|
|
// assume got->size == 0 too
|
2020-03-11 12:12:41 -04:00
|
|
|
got.AddAddrPlus(ctxt.Arch, dynamic, 0)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
got.AddUint64(ctxt.Arch, 0)
|
|
|
|
|
got.AddUint64(ctxt.Arch, 0)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
|
2017-08-27 22:00:00 +09:00
|
|
|
return false
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
2020-02-24 21:06:21 -05:00
|
|
|
func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
|
2020-02-24 21:04:50 -05:00
|
|
|
if target.IsExternal() {
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return val, false
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch r.Type {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_CONST:
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return r.Add, true
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.R_GOTOFF:
|
2020-02-24 21:06:21 -05:00
|
|
|
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(syms.GOT), true
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
cmd/link: fewer allocs in ld.Arch.Archreloc
Archreloc had this signature:
func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
The last *int64 argument is used as out parameter.
Passed valus could be allocated on stack, but escape analysis
fails here, leading to high number of unwanted allocs.
If instead 4th arg is passed by value, and modified values is returned,
no problems with allocations arise:
func(*Link, *sym.Reloc, *sym.Symbol, int64) (int64, bool)
There are 2 benefits:
1. code becomes more readable.
2. less allocations.
For linking "hello world" example from net/http:
name old time/op new time/op delta
Linker-4 530ms ± 2% 520ms ± 2% -1.83% (p=0.001 n=17+16)
It's top 1 in alloc_objects from memprofile:
flat flat% sum% cum cum%
229379 33.05% 33.05% 229379 33.05% cmd/link/internal/ld.relocsym
...
list relocsym:
229379 229379 (flat, cum) 33.05% of Total
229379 229379 183: var o int64
After the patch, ~230k of int64 allocs (~ 1.75mb) removed.
Passes toolshash-check (toolstash cmp).
Change-Id: I25504fe27967bcff70c4b7338790f3921d15473d
Reviewed-on: https://go-review.googlesource.com/113637
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-17 19:50:29 +03:00
|
|
|
return val, false
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
2020-02-24 21:06:21 -05:00
|
|
|
func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
2017-10-04 17:54:04 -04:00
|
|
|
switch r.Variant & sym.RV_TYPE_MASK {
|
2016-03-19 00:23:17 -04:00
|
|
|
default:
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
|
2016-03-19 00:23:17 -04:00
|
|
|
return t
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
case sym.RV_NONE:
|
2016-03-19 00:23:17 -04:00
|
|
|
return t
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
case sym.RV_390_DBL:
|
2016-03-19 00:23:17 -04:00
|
|
|
if (t & 1) != 0 {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
return t >> 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-24 17:56:24 -04:00
|
|
|
func addpltsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
|
|
|
|
|
if ldr.SymPlt(s) >= 0 {
|
2016-03-19 00:23:17 -04:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-24 17:56:24 -04:00
|
|
|
ld.Adddynsym2(ldr, target, syms, s)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2020-03-04 17:25:01 -05:00
|
|
|
if target.IsElf() {
|
2020-04-24 17:56:24 -04:00
|
|
|
plt := ldr.MakeSymbolUpdater(syms.PLT2)
|
|
|
|
|
got := ldr.MakeSymbolUpdater(syms.GOT2)
|
|
|
|
|
rela := ldr.MakeSymbolUpdater(syms.RelaPLT2)
|
|
|
|
|
if plt.Size() == 0 {
|
2020-03-11 12:12:41 -04:00
|
|
|
panic("plt is not set up")
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
// larl %r1,_GLOBAL_OFFSET_TABLE_+index
|
|
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xc0)
|
|
|
|
|
plt.AddUint8(0x10)
|
2020-04-24 17:56:24 -04:00
|
|
|
plt.AddPCRelPlus(target.Arch, got.Sym(), got.Size()+6)
|
|
|
|
|
pltrelocs := plt.Relocs()
|
|
|
|
|
ldr.SetRelocVariant(plt.Sym(), pltrelocs.Count()-1, sym.RV_390_DBL)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
|
|
|
|
// add to got: pointer to current pos in plt
|
2020-04-24 17:56:24 -04:00
|
|
|
got.AddAddrPlus(target.Arch, plt.Sym(), plt.Size()+8) // weird but correct
|
2016-03-19 00:23:17 -04:00
|
|
|
// lg %r1,0(%r1)
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xe3)
|
|
|
|
|
plt.AddUint8(0x10)
|
|
|
|
|
plt.AddUint8(0x10)
|
|
|
|
|
plt.AddUint8(0x00)
|
|
|
|
|
plt.AddUint8(0x00)
|
|
|
|
|
plt.AddUint8(0x04)
|
2016-03-19 00:23:17 -04:00
|
|
|
// br %r1
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x07)
|
|
|
|
|
plt.AddUint8(0xf1)
|
2016-03-19 00:23:17 -04:00
|
|
|
// basr %r1,%r0
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0x0d)
|
|
|
|
|
plt.AddUint8(0x10)
|
2016-03-19 00:23:17 -04:00
|
|
|
// lgf %r1,12(%r1)
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xe3)
|
|
|
|
|
plt.AddUint8(0x10)
|
|
|
|
|
plt.AddUint8(0x10)
|
|
|
|
|
plt.AddUint8(0x0c)
|
|
|
|
|
plt.AddUint8(0x00)
|
|
|
|
|
plt.AddUint8(0x14)
|
2016-03-19 00:23:17 -04:00
|
|
|
// jg .plt
|
2017-09-30 15:06:44 +00:00
|
|
|
plt.AddUint8(0xc0)
|
|
|
|
|
plt.AddUint8(0xf4)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2020-04-24 17:56:24 -04:00
|
|
|
plt.AddUint32(target.Arch, uint32(-((plt.Size() - 2) >> 1))) // roll-your-own relocation
|
2016-03-19 00:23:17 -04:00
|
|
|
//.plt index
|
2020-04-24 17:56:24 -04:00
|
|
|
plt.AddUint32(target.Arch, uint32(rela.Size())) // rela size before current entry
|
2016-03-19 00:23:17 -04:00
|
|
|
|
|
|
|
|
// rela
|
2020-04-24 17:56:24 -04:00
|
|
|
rela.AddAddrPlus(target.Arch, got.Sym(), got.Size()-8)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2020-04-24 17:56:24 -04:00
|
|
|
sDynid := ldr.SymDynid(s)
|
|
|
|
|
rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(sDynid), uint32(elf.R_390_JMP_SLOT)))
|
2020-03-04 17:25:01 -05:00
|
|
|
rela.AddUint64(target.Arch, 0)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2020-04-24 17:56:24 -04:00
|
|
|
ldr.SetPlt(s, int32(plt.Size()-32))
|
2016-03-19 00:23:17 -04:00
|
|
|
|
|
|
|
|
} else {
|
2020-04-24 17:56:24 -04:00
|
|
|
ldr.Errorf(s, "addpltsym: unsupported binary format")
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-24 17:56:24 -04:00
|
|
|
func addgotsym2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
|
|
|
|
|
if ldr.SymGot(s) >= 0 {
|
2016-03-19 00:23:17 -04:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-24 17:56:24 -04:00
|
|
|
ld.Adddynsym2(ldr, target, syms, s)
|
|
|
|
|
got := ldr.MakeSymbolUpdater(syms.GOT2)
|
|
|
|
|
ldr.SetGot(s, int32(got.Size()))
|
2020-03-04 17:25:01 -05:00
|
|
|
got.AddUint64(target.Arch, 0)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2020-03-04 17:25:01 -05:00
|
|
|
if target.IsElf() {
|
2020-04-24 17:56:24 -04:00
|
|
|
rela := ldr.MakeSymbolUpdater(syms.Rela2)
|
|
|
|
|
rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s)))
|
|
|
|
|
rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_390_GLOB_DAT)))
|
2020-03-04 17:25:01 -05:00
|
|
|
rela.AddUint64(target.Arch, 0)
|
2016-03-19 00:23:17 -04:00
|
|
|
} else {
|
2020-04-24 17:56:24 -04:00
|
|
|
ldr.Errorf(s, "addgotsym: unsupported binary format")
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-28 09:53:29 -04:00
|
|
|
func asmb(ctxt *ld.Link, _ *loader.Loader) {
|
2017-10-07 13:43:38 -04:00
|
|
|
if ctxt.IsELF {
|
2016-09-20 15:57:53 +12:00
|
|
|
ld.Asmbelfsetup()
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
2020-03-20 12:24:35 -04:00
|
|
|
var wg sync.WaitGroup
|
2017-04-18 21:52:06 +12:00
|
|
|
sect := ld.Segtext.Sections[0]
|
2020-03-20 12:24:35 -04:00
|
|
|
offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
|
|
|
|
|
ld.WriteParallel(&wg, ld.Codeblk, ctxt, offset, sect.Vaddr, sect.Length)
|
|
|
|
|
|
|
|
|
|
for _, sect := range ld.Segtext.Sections[1:] {
|
|
|
|
|
offset := sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff
|
|
|
|
|
ld.WriteParallel(&wg, ld.Datblk, ctxt, offset, sect.Vaddr, sect.Length)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ld.Segrodata.Filelen > 0 {
|
2020-03-20 12:24:35 -04:00
|
|
|
ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrodata.Fileoff, ld.Segrodata.Vaddr, ld.Segrodata.Filelen)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2020-03-20 12:24:35 -04:00
|
|
|
|
2016-09-05 23:29:16 -04:00
|
|
|
if ld.Segrelrodata.Filelen > 0 {
|
2020-03-20 12:24:35 -04:00
|
|
|
ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segrelrodata.Fileoff, ld.Segrelrodata.Vaddr, ld.Segrelrodata.Filelen)
|
2016-09-05 23:29:16 -04:00
|
|
|
}
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2020-03-20 12:24:35 -04:00
|
|
|
ld.WriteParallel(&wg, ld.Datblk, ctxt, ld.Segdata.Fileoff, ld.Segdata.Vaddr, ld.Segdata.Filelen)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2020-03-20 12:24:35 -04:00
|
|
|
ld.WriteParallel(&wg, ld.Dwarfblk, ctxt, ld.Segdwarf.Fileoff, ld.Segdwarf.Vaddr, ld.Segdwarf.Filelen)
|
|
|
|
|
wg.Wait()
|
2019-04-03 22:41:48 -04:00
|
|
|
}
|
2016-03-14 09:23:04 -07:00
|
|
|
|
2019-04-03 22:41:48 -04:00
|
|
|
func asmb2(ctxt *ld.Link) {
|
2016-03-19 00:23:17 -04:00
|
|
|
/* output symbol table */
|
|
|
|
|
ld.Symsize = 0
|
|
|
|
|
|
|
|
|
|
ld.Lcsize = 0
|
|
|
|
|
symo := uint32(0)
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*ld.FlagS {
|
2017-10-07 13:43:38 -04:00
|
|
|
if !ctxt.IsELF {
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(nil, "unsupported executable format")
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
2016-03-14 09:23:04 -07:00
|
|
|
symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
|
2016-08-21 18:34:24 -04:00
|
|
|
symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(int64(symo))
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Asmelfsym(ctxt)
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.Write(ld.Elfstrdat)
|
2016-03-19 00:23:17 -04:00
|
|
|
|
2017-10-05 10:20:17 -04:00
|
|
|
if ctxt.LinkMode == ld.LinkExternal {
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Elfemitreloc(ctxt)
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-01 02:37:20 +00:00
|
|
|
ctxt.Out.SeekSet(0)
|
2017-10-07 13:49:44 -04:00
|
|
|
switch ctxt.HeadType {
|
2016-03-19 00:23:17 -04:00
|
|
|
default:
|
2016-09-17 09:39:33 -04:00
|
|
|
ld.Errorf(nil, "unsupported operating system")
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hlinux:
|
2016-08-19 22:40:38 -04:00
|
|
|
ld.Asmbelf(ctxt, int64(symo))
|
2016-03-19 00:23:17 -04:00
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
if *ld.FlagC {
|
2016-03-19 00:23:17 -04:00
|
|
|
fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
|
|
|
|
|
fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
|
|
|
|
|
fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
|
|
|
|
|
fmt.Printf("symsize=%d\n", ld.Symsize)
|
|
|
|
|
fmt.Printf("lcsize=%d\n", ld.Lcsize)
|
|
|
|
|
fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
|
|
|
|
|
}
|
|
|
|
|
}
|