From 29a6149e67a9c382938ffb40102fb989a0a6db48 Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Sat, 19 Mar 2016 00:23:17 -0400 Subject: [PATCH] cmd/link/internal/s390x: add s390x support Supports basic internal linking, external linking and shared library linking. Change-Id: Ic9693dd94df561b0f9df9880009b1e8ab9d59b92 Reviewed-on: https://go-review.googlesource.com/20879 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Michael Hudson-Doyle --- src/cmd/dist/buildtool.go | 1 + src/cmd/link/internal/s390x/asm.go | 598 +++++++++++++++++++++++++++++ src/cmd/link/internal/s390x/l.go | 79 ++++ src/cmd/link/internal/s390x/obj.go | 119 ++++++ 4 files changed, 797 insertions(+) create mode 100644 src/cmd/link/internal/s390x/asm.go create mode 100644 src/cmd/link/internal/s390x/l.go create mode 100644 src/cmd/link/internal/s390x/obj.go diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go index 59ba610b2a..df9d9f3eeb 100644 --- a/src/cmd/dist/buildtool.go +++ b/src/cmd/dist/buildtool.go @@ -53,6 +53,7 @@ var bootstrapDirs = []string{ "link/internal/ld", "link/internal/mips64", "link/internal/ppc64", + "link/internal/s390x", "link/internal/x86", } diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go new file mode 100644 index 0000000000..75a8206174 --- /dev/null +++ b/src/cmd/link/internal/s390x/asm.go @@ -0,0 +1,598 @@ +// Inferno utils/5l/asm.c +// http://code.google.com/p/inferno-os/source/browse/utils/5l/asm.c +// +// 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 +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// 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 ( + "cmd/internal/obj" + "cmd/link/internal/ld" + "debug/elf" + "fmt" +) + +// 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. +// +// : +// larl %r2, +// jg +// undef +// +// The job of appending the moduledata is delegated to runtime.addmoduledata. +func gentext() { + if !ld.DynlinkingGo() { + return + } + addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) + if addmoduledata.Type == obj.STEXT { + // we're linking a module containing the runtime -> no need for + // an init function + return + } + addmoduledata.Attr |= ld.AttrReachable + initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0) + initfunc.Type = obj.STEXT + initfunc.Attr |= ld.AttrLocal + initfunc.Attr |= ld.AttrReachable + + // larl %r2, + ld.Adduint8(ld.Ctxt, initfunc, 0xc0) + ld.Adduint8(ld.Ctxt, initfunc, 0x20) + lmd := ld.Addrel(initfunc) + lmd.Off = int32(initfunc.Size) + lmd.Siz = 4 + lmd.Sym = ld.Ctxt.Moduledata + lmd.Type = obj.R_PCREL + lmd.Variant = ld.RV_390_DBL + lmd.Add = 2 + int64(lmd.Siz) + ld.Adduint32(ld.Ctxt, initfunc, 0) + + // jg + ld.Adduint8(ld.Ctxt, initfunc, 0xc0) + ld.Adduint8(ld.Ctxt, initfunc, 0xf4) + rel := ld.Addrel(initfunc) + rel.Off = int32(initfunc.Size) + rel.Siz = 4 + rel.Sym = ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) + rel.Type = obj.R_CALL + rel.Variant = ld.RV_390_DBL + rel.Add = 2 + int64(rel.Siz) + ld.Adduint32(ld.Ctxt, initfunc, 0) + + // undef (for debugging) + ld.Adduint32(ld.Ctxt, initfunc, 0) + + if ld.Ctxt.Etextp != nil { + ld.Ctxt.Etextp.Next = initfunc + } else { + ld.Ctxt.Textp = initfunc + } + ld.Ctxt.Etextp = initfunc + initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0) + initarray_entry.Attr |= ld.AttrLocal + initarray_entry.Attr |= ld.AttrReachable + initarray_entry.Type = obj.SINITARR + ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) +} + +func adddynrel(s *ld.LSym, r *ld.Reloc) { + targ := r.Sym + ld.Ctxt.Cursym = s + + switch r.Type { + default: + if r.Type >= 256 { + ld.Diag("unexpected relocation type %d", r.Type) + return + } + + // Handle relocations found in ELF object files. + case 256 + ld.R_390_12, + 256 + ld.R_390_GOT12: + ld.Diag("s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256) + return + + case 256 + ld.R_390_8, + 256 + ld.R_390_16, + 256 + ld.R_390_32, + 256 + ld.R_390_64: + if targ.Type == obj.SDYNIMPORT { + ld.Diag("unexpected R_390_nn relocation for dynamic symbol %s", targ.Name) + } + r.Type = obj.R_ADDR + return + + case 256 + ld.R_390_PC16, + 256 + ld.R_390_PC32, + 256 + ld.R_390_PC64: + if targ.Type == obj.SDYNIMPORT { + ld.Diag("unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name) + } + if targ.Type == 0 || targ.Type == obj.SXREF { + ld.Diag("unknown symbol %s in pcrel", targ.Name) + } + r.Type = obj.R_PCREL + r.Add += int64(r.Siz) + return + + case 256 + ld.R_390_GOT16, + 256 + ld.R_390_GOT32, + 256 + ld.R_390_GOT64: + ld.Diag("unimplemented S390x relocation: %v", r.Type-256) + return + + case 256 + ld.R_390_PLT16DBL, + 256 + ld.R_390_PLT32DBL: + r.Type = obj.R_PCREL + r.Variant = ld.RV_390_DBL + r.Add += int64(r.Siz) + if targ.Type == obj.SDYNIMPORT { + addpltsym(ld.Ctxt, targ) + r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) + r.Add += int64(targ.Plt) + } + return + + case 256 + ld.R_390_PLT32, + 256 + ld.R_390_PLT64: + r.Type = obj.R_PCREL + r.Add += int64(r.Siz) + if targ.Type == obj.SDYNIMPORT { + addpltsym(ld.Ctxt, targ) + r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) + r.Add += int64(targ.Plt) + } + return + + case 256 + ld.R_390_COPY: + ld.Diag("unimplemented S390x relocation: %v", r.Type-256) + + case 256 + ld.R_390_GLOB_DAT: + ld.Diag("unimplemented S390x relocation: %v", r.Type-256) + + case 256 + ld.R_390_JMP_SLOT: + ld.Diag("unimplemented S390x relocation: %v", r.Type-256) + + case 256 + ld.R_390_RELATIVE: + ld.Diag("unimplemented S390x relocation: %v", r.Type-256) + + case 256 + ld.R_390_GOTOFF: + if targ.Type == obj.SDYNIMPORT { + ld.Diag("unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name) + } + r.Type = obj.R_GOTOFF + return + + case 256 + ld.R_390_GOTPC: + r.Type = obj.R_PCREL + r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) + r.Add += int64(r.Siz) + return + + case 256 + ld.R_390_PC16DBL, + 256 + ld.R_390_PC32DBL: + r.Type = obj.R_PCREL + r.Variant = ld.RV_390_DBL + r.Add += int64(r.Siz) + if targ.Type == obj.SDYNIMPORT { + ld.Diag("unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name) + } + return + + case 256 + ld.R_390_GOTPCDBL: + r.Type = obj.R_PCREL + r.Variant = ld.RV_390_DBL + r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) + r.Add += int64(r.Siz) + return + + case 256 + ld.R_390_GOTENT: + addgotsym(targ) + + r.Type = obj.R_PCREL + r.Variant = ld.RV_390_DBL + r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) + r.Add += int64(targ.Got) + r.Add += int64(r.Siz) + return + } + // Handle references to ELF symbols from our own object files. + if targ.Type != obj.SDYNIMPORT { + return + } + + ld.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type) +} + +func elfreloc1(r *ld.Reloc, sectoff int64) int { + ld.Thearch.Vput(uint64(sectoff)) + + elfsym := r.Xsym.ElfsymForReloc() + switch r.Type { + default: + return -1 + + case obj.R_TLS_LE: + switch r.Siz { + default: + return -1 + case 4: + // WARNING - silently ignored by linker in ELF64 + ld.Thearch.Vput(ld.R_390_TLS_LE32 | uint64(elfsym)<<32) + case 8: + // WARNING - silently ignored by linker in ELF32 + ld.Thearch.Vput(ld.R_390_TLS_LE64 | uint64(elfsym)<<32) + } + + case obj.R_TLS_IE: + switch r.Siz { + default: + return -1 + case 4: + ld.Thearch.Vput(ld.R_390_TLS_IEENT | uint64(elfsym)<<32) + } + + case obj.R_ADDR: + switch r.Siz { + default: + return -1 + case 4: + ld.Thearch.Vput(ld.R_390_32 | uint64(elfsym)<<32) + case 8: + ld.Thearch.Vput(ld.R_390_64 | uint64(elfsym)<<32) + } + + case obj.R_GOTPCREL: + if r.Siz == 4 { + ld.Thearch.Vput(ld.R_390_GOTENT | uint64(elfsym)<<32) + } else { + return -1 + } + + case obj.R_PCREL, obj.R_PCRELDBL, obj.R_CALL: + elfrel := ld.R_390_NONE + isdbl := r.Variant&ld.RV_TYPE_MASK == ld.RV_390_DBL + // TODO(mundaym): all DBL style relocations should be + // signalled using the variant - see issue 14218. + switch r.Type { + case obj.R_PCRELDBL, obj.R_CALL: + isdbl = true + } + if r.Xsym.Type == obj.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == obj.R_CALL) { + if isdbl { + switch r.Siz { + case 2: + elfrel = ld.R_390_PLT16DBL + case 4: + elfrel = ld.R_390_PLT32DBL + } + } else { + switch r.Siz { + case 4: + elfrel = ld.R_390_PLT32 + case 8: + elfrel = ld.R_390_PLT64 + } + } + } else { + if isdbl { + switch r.Siz { + case 2: + elfrel = ld.R_390_PC16DBL + case 4: + elfrel = ld.R_390_PC32DBL + } + } else { + switch r.Siz { + case 2: + elfrel = ld.R_390_PC16 + case 4: + elfrel = ld.R_390_PC32 + case 8: + elfrel = ld.R_390_PC64 + } + } + } + if elfrel == ld.R_390_NONE { + return -1 // unsupported size/dbl combination + } + ld.Thearch.Vput(uint64(elfrel) | uint64(elfsym)<<32) + } + + ld.Thearch.Vput(uint64(r.Xadd)) + return 0 +} + +func elfsetupplt() { + plt := ld.Linklookup(ld.Ctxt, ".plt", 0) + got := ld.Linklookup(ld.Ctxt, ".got", 0) + if plt.Size == 0 { + // stg %r1,56(%r15) + ld.Adduint8(ld.Ctxt, plt, 0xe3) + ld.Adduint8(ld.Ctxt, plt, 0x10) + ld.Adduint8(ld.Ctxt, plt, 0xf0) + ld.Adduint8(ld.Ctxt, plt, 0x38) + ld.Adduint8(ld.Ctxt, plt, 0x00) + ld.Adduint8(ld.Ctxt, plt, 0x24) + // larl %r1,_GLOBAL_OFFSET_TABLE_ + ld.Adduint8(ld.Ctxt, plt, 0xc0) + ld.Adduint8(ld.Ctxt, plt, 0x10) + ld.Addpcrelplus(ld.Ctxt, plt, got, 6) + // mvc 48(8,%r15),8(%r1) + ld.Adduint8(ld.Ctxt, plt, 0xd2) + ld.Adduint8(ld.Ctxt, plt, 0x07) + ld.Adduint8(ld.Ctxt, plt, 0xf0) + ld.Adduint8(ld.Ctxt, plt, 0x30) + ld.Adduint8(ld.Ctxt, plt, 0x10) + ld.Adduint8(ld.Ctxt, plt, 0x08) + // lg %r1,16(%r1) + ld.Adduint8(ld.Ctxt, plt, 0xe3) + ld.Adduint8(ld.Ctxt, plt, 0x10) + ld.Adduint8(ld.Ctxt, plt, 0x10) + ld.Adduint8(ld.Ctxt, plt, 0x10) + ld.Adduint8(ld.Ctxt, plt, 0x00) + ld.Adduint8(ld.Ctxt, plt, 0x04) + // br %r1 + ld.Adduint8(ld.Ctxt, plt, 0x07) + ld.Adduint8(ld.Ctxt, plt, 0xf1) + // nopr %r0 + ld.Adduint8(ld.Ctxt, plt, 0x07) + ld.Adduint8(ld.Ctxt, plt, 0x00) + // nopr %r0 + ld.Adduint8(ld.Ctxt, plt, 0x07) + ld.Adduint8(ld.Ctxt, plt, 0x00) + // nopr %r0 + ld.Adduint8(ld.Ctxt, plt, 0x07) + ld.Adduint8(ld.Ctxt, plt, 0x00) + + // assume got->size == 0 too + ld.Addaddrplus(ld.Ctxt, got, ld.Linklookup(ld.Ctxt, ".dynamic", 0), 0) + + ld.Adduint64(ld.Ctxt, got, 0) + ld.Adduint64(ld.Ctxt, got, 0) + } +} + +func machoreloc1(r *ld.Reloc, sectoff int64) int { + return -1 +} + +func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int { + if ld.Linkmode == ld.LinkExternal { + return -1 + } + + switch r.Type { + case obj.R_CONST: + *val = r.Add + return 0 + + case obj.R_GOTOFF: + *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0)) + return 0 + } + + return -1 +} + +func archrelocvariant(r *ld.Reloc, s *ld.LSym, t int64) int64 { + switch r.Variant & ld.RV_TYPE_MASK { + default: + ld.Diag("unexpected relocation variant %d", r.Variant) + return t + + case ld.RV_NONE: + return t + + case ld.RV_390_DBL: + if (t & 1) != 0 { + ld.Diag("%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value) + } + return t >> 1 + } +} + +func addpltsym(ctxt *ld.Link, s *ld.LSym) { + if s.Plt >= 0 { + return + } + + ld.Adddynsym(ctxt, s) + + if ld.Iself { + plt := ld.Linklookup(ctxt, ".plt", 0) + got := ld.Linklookup(ctxt, ".got", 0) + rela := ld.Linklookup(ctxt, ".rela.plt", 0) + if plt.Size == 0 { + elfsetupplt() + } + // larl %r1,_GLOBAL_OFFSET_TABLE_+index + + ld.Adduint8(ctxt, plt, 0xc0) + ld.Adduint8(ctxt, plt, 0x10) + ld.Addpcrelplus(ctxt, plt, got, got.Size+6) // need variant? + + // add to got: pointer to current pos in plt + ld.Addaddrplus(ctxt, got, plt, plt.Size+8) // weird but correct + // lg %r1,0(%r1) + ld.Adduint8(ctxt, plt, 0xe3) + ld.Adduint8(ctxt, plt, 0x10) + ld.Adduint8(ctxt, plt, 0x10) + ld.Adduint8(ctxt, plt, 0x00) + ld.Adduint8(ctxt, plt, 0x00) + ld.Adduint8(ctxt, plt, 0x04) + // br %r1 + ld.Adduint8(ctxt, plt, 0x07) + ld.Adduint8(ctxt, plt, 0xf1) + // basr %r1,%r0 + ld.Adduint8(ctxt, plt, 0x0d) + ld.Adduint8(ctxt, plt, 0x10) + // lgf %r1,12(%r1) + ld.Adduint8(ctxt, plt, 0xe3) + ld.Adduint8(ctxt, plt, 0x10) + ld.Adduint8(ctxt, plt, 0x10) + ld.Adduint8(ctxt, plt, 0x0c) + ld.Adduint8(ctxt, plt, 0x00) + ld.Adduint8(ctxt, plt, 0x14) + // jg .plt + ld.Adduint8(ctxt, plt, 0xc0) + ld.Adduint8(ctxt, plt, 0xf4) + + ld.Adduint32(ctxt, plt, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation + //.plt index + ld.Adduint32(ctxt, plt, uint32(rela.Size)) // rela size before current entry + + // rela + ld.Addaddrplus(ctxt, rela, got, got.Size-8) + + ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_JMP_SLOT)) + ld.Adduint64(ctxt, rela, 0) + + s.Plt = int32(plt.Size - 32) + + } else { + ld.Diag("addpltsym: unsupported binary format") + } +} + +func addgotsym(s *ld.LSym) { + if s.Got >= 0 { + return + } + + ld.Adddynsym(ld.Ctxt, s) + got := ld.Linklookup(ld.Ctxt, ".got", 0) + s.Got = int32(got.Size) + ld.Adduint64(ld.Ctxt, got, 0) + + if ld.Iself { + rela := ld.Linklookup(ld.Ctxt, ".rela", 0) + ld.Addaddrplus(ld.Ctxt, rela, got, int64(s.Got)) + ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT)) + ld.Adduint64(ld.Ctxt, rela, 0) + } else { + ld.Diag("addgotsym: unsupported binary format") + } +} + +func asmb() { + if ld.Debug['v'] != 0 { + fmt.Fprintf(&ld.Bso, "%5.2f asmb\n", obj.Cputime()) + } + ld.Bso.Flush() + + if ld.Iself { + ld.Asmbelfsetup() + } + + sect := ld.Segtext.Sect + ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) + ld.Codeblk(int64(sect.Vaddr), int64(sect.Length)) + for sect = sect.Next; sect != nil; sect = sect.Next { + ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) + ld.Datblk(int64(sect.Vaddr), int64(sect.Length)) + } + + if ld.Segrodata.Filelen > 0 { + if ld.Debug['v'] != 0 { + fmt.Fprintf(&ld.Bso, "%5.2f rodatblk\n", obj.Cputime()) + } + ld.Bso.Flush() + + ld.Cseek(int64(ld.Segrodata.Fileoff)) + ld.Datblk(int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) + } + + if ld.Debug['v'] != 0 { + fmt.Fprintf(&ld.Bso, "%5.2f datblk\n", obj.Cputime()) + } + ld.Bso.Flush() + + ld.Cseek(int64(ld.Segdata.Fileoff)) + ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen)) + + /* output symbol table */ + ld.Symsize = 0 + + ld.Lcsize = 0 + symo := uint32(0) + if ld.Debug['s'] == 0 { + if !ld.Iself { + ld.Diag("unsupported executable format") + } + if ld.Debug['v'] != 0 { + fmt.Fprintf(&ld.Bso, "%5.2f sym\n", obj.Cputime()) + } + ld.Bso.Flush() + symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen) + symo = uint32(ld.Rnd(int64(symo), int64(ld.INITRND))) + + ld.Cseek(int64(symo)) + if ld.Debug['v'] != 0 { + fmt.Fprintf(&ld.Bso, "%5.2f elfsym\n", obj.Cputime()) + } + ld.Asmelfsym() + ld.Cflush() + ld.Cwrite(ld.Elfstrdat) + + if ld.Debug['v'] != 0 { + fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime()) + } + ld.Dwarfemitdebugsections() + + if ld.Linkmode == ld.LinkExternal { + ld.Elfemitreloc() + } + } + + ld.Ctxt.Cursym = nil + if ld.Debug['v'] != 0 { + fmt.Fprintf(&ld.Bso, "%5.2f header\n", obj.Cputime()) + } + ld.Bso.Flush() + ld.Cseek(0) + switch ld.HEADTYPE { + default: + ld.Diag("unsupported operating system") + case obj.Hlinux: + ld.Asmbelf(int64(symo)) + } + + ld.Cflush() + if ld.Debug['c'] != 0 { + 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)) + } +} diff --git a/src/cmd/link/internal/s390x/l.go b/src/cmd/link/internal/s390x/l.go new file mode 100644 index 0000000000..839a9849c8 --- /dev/null +++ b/src/cmd/link/internal/s390x/l.go @@ -0,0 +1,79 @@ +// Inferno utils/5l/asm.c +// http://code.google.com/p/inferno-os/source/browse/utils/5l/asm.c +// +// 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 +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// 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 + +// Writing object files. + +// cmd/9l/l.h from Vita Nuova. +// +// 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-2008 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-2008 Lucent Technologies Inc. and others +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// 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. + +const ( + thechar = 'z' + PtrSize = 8 + IntSize = 8 + RegSize = 8 + MaxAlign = 32 // max data alignment + MinAlign = 2 // min data alignment + FuncAlign = 16 + MINLC = 2 +) + +/* Used by ../internal/ld/dwarf.go */ +const ( + DWARFREGSP = 15 + DWARFREGLR = 14 +) diff --git a/src/cmd/link/internal/s390x/obj.go b/src/cmd/link/internal/s390x/obj.go new file mode 100644 index 0000000000..ef88d22bbd --- /dev/null +++ b/src/cmd/link/internal/s390x/obj.go @@ -0,0 +1,119 @@ +// Inferno utils/5l/obj.c +// http://code.google.com/p/inferno-os/source/browse/utils/5l/obj.c +// +// 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 +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// 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 ( + "cmd/internal/obj" + "cmd/link/internal/ld" + "fmt" +) + +// Reading object files. + +func Main() { + linkarchinit() + ld.Ldmain() +} + +func linkarchinit() { + ld.Thestring = obj.Getgoarch() + ld.Thelinkarch = &ld.Links390x + + ld.Thearch.Thechar = thechar + ld.Thearch.Ptrsize = ld.Thelinkarch.Ptrsize + ld.Thearch.Intsize = ld.Thelinkarch.Ptrsize + ld.Thearch.Regsize = ld.Thelinkarch.Regsize + ld.Thearch.Funcalign = FuncAlign + ld.Thearch.Maxalign = MaxAlign + ld.Thearch.Minalign = MinAlign + ld.Thearch.Minlc = MINLC + ld.Thearch.Dwarfregsp = DWARFREGSP + ld.Thearch.Dwarfreglr = DWARFREGLR + + ld.Thearch.Adddynrel = adddynrel + ld.Thearch.Archinit = archinit + ld.Thearch.Archreloc = archreloc + ld.Thearch.Archrelocvariant = archrelocvariant + ld.Thearch.Asmb = asmb // in asm.go + ld.Thearch.Elfreloc1 = elfreloc1 + ld.Thearch.Elfsetupplt = elfsetupplt + ld.Thearch.Gentext = gentext + ld.Thearch.Machoreloc1 = machoreloc1 + ld.Thearch.Lput = ld.Lputb + ld.Thearch.Wput = ld.Wputb + ld.Thearch.Vput = ld.Vputb + ld.Thearch.Append16 = ld.Append16b + ld.Thearch.Append32 = ld.Append32b + ld.Thearch.Append64 = ld.Append64b + + ld.Thearch.Linuxdynld = "/lib64/ld64.so.1" + + // not relevant for s390x + ld.Thearch.Freebsddynld = "XXX" + ld.Thearch.Openbsddynld = "XXX" + ld.Thearch.Netbsddynld = "XXX" + ld.Thearch.Dragonflydynld = "XXX" + ld.Thearch.Solarisdynld = "XXX" +} + +func archinit() { + // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when + // Go was built; see ../../make.bash. + if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" { + ld.Linkmode = ld.LinkInternal + } + + if ld.Buildmode == ld.BuildmodeCArchive || ld.Buildmode == ld.BuildmodeCShared || ld.DynlinkingGo() { + ld.Linkmode = ld.LinkExternal + } + + switch ld.HEADTYPE { + default: + ld.Exitf("unknown -H option: %v", ld.HEADTYPE) + + case obj.Hlinux: // s390x ELF + ld.Elfinit() + ld.HEADR = ld.ELFRESERVE + if ld.INITTEXT == -1 { + ld.INITTEXT = 0x10000 + int64(ld.HEADR) + } + if ld.INITDAT == -1 { + ld.INITDAT = 0 + } + if ld.INITRND == -1 { + ld.INITRND = 0x10000 + } + } + + if ld.INITDAT != 0 && ld.INITRND != 0 { + fmt.Printf("warning: -D0x%x is ignored because of -R0x%x\n", uint64(ld.INITDAT), uint32(ld.INITRND)) + } +} -- 2.48.1