...

Source file src/pkg/cmd/link/internal/s390x/asm.go

     1	// Inferno utils/5l/asm.c
     2	// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
     3	//
     4	//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5	//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6	//	Portions Copyright © 1997-1999 Vita Nuova Limited
     7	//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8	//	Portions Copyright © 2004,2006 Bruce Ellis
     9	//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10	//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11	//	Portions Copyright © 2009 The Go Authors. All rights reserved.
    12	//
    13	// Permission is hereby granted, free of charge, to any person obtaining a copy
    14	// of this software and associated documentation files (the "Software"), to deal
    15	// in the Software without restriction, including without limitation the rights
    16	// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17	// copies of the Software, and to permit persons to whom the Software is
    18	// furnished to do so, subject to the following conditions:
    19	//
    20	// The above copyright notice and this permission notice shall be included in
    21	// all copies or substantial portions of the Software.
    22	//
    23	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24	// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25	// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26	// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27	// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28	// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29	// THE SOFTWARE.
    30	
    31	package s390x
    32	
    33	import (
    34		"cmd/internal/objabi"
    35		"cmd/internal/sys"
    36		"cmd/link/internal/ld"
    37		"cmd/link/internal/sym"
    38		"debug/elf"
    39		"fmt"
    40	)
    41	
    42	// gentext generates assembly to append the local moduledata to the global
    43	// moduledata linked list at initialization time. This is only done if the runtime
    44	// is in a different module.
    45	//
    46	// <go.link.addmoduledata>:
    47	// 	larl  %r2, <local.moduledata>
    48	// 	jg    <runtime.addmoduledata@plt>
    49	//	undef
    50	//
    51	// The job of appending the moduledata is delegated to runtime.addmoduledata.
    52	func gentext(ctxt *ld.Link) {
    53		if !ctxt.DynlinkingGo() {
    54			return
    55		}
    56		addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
    57		if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
    58			// we're linking a module containing the runtime -> no need for
    59			// an init function
    60			return
    61		}
    62		addmoduledata.Attr |= sym.AttrReachable
    63		initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
    64		initfunc.Type = sym.STEXT
    65		initfunc.Attr |= sym.AttrLocal
    66		initfunc.Attr |= sym.AttrReachable
    67	
    68		// larl %r2, <local.moduledata>
    69		initfunc.AddUint8(0xc0)
    70		initfunc.AddUint8(0x20)
    71		lmd := initfunc.AddRel()
    72		lmd.InitExt()
    73		lmd.Off = int32(initfunc.Size)
    74		lmd.Siz = 4
    75		lmd.Sym = ctxt.Moduledata
    76		lmd.Type = objabi.R_PCREL
    77		lmd.Variant = sym.RV_390_DBL
    78		lmd.Add = 2 + int64(lmd.Siz)
    79		initfunc.AddUint32(ctxt.Arch, 0)
    80	
    81		// jg <runtime.addmoduledata[@plt]>
    82		initfunc.AddUint8(0xc0)
    83		initfunc.AddUint8(0xf4)
    84		rel := initfunc.AddRel()
    85		rel.InitExt()
    86		rel.Off = int32(initfunc.Size)
    87		rel.Siz = 4
    88		rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
    89		rel.Type = objabi.R_CALL
    90		rel.Variant = sym.RV_390_DBL
    91		rel.Add = 2 + int64(rel.Siz)
    92		initfunc.AddUint32(ctxt.Arch, 0)
    93	
    94		// undef (for debugging)
    95		initfunc.AddUint32(ctxt.Arch, 0)
    96		if ctxt.BuildMode == ld.BuildModePlugin {
    97			ctxt.Textp = append(ctxt.Textp, addmoduledata)
    98		}
    99		ctxt.Textp = append(ctxt.Textp, initfunc)
   100		initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
   101		initarray_entry.Attr |= sym.AttrLocal
   102		initarray_entry.Attr |= sym.AttrReachable
   103		initarray_entry.Type = sym.SINITARR
   104		initarray_entry.AddAddr(ctxt.Arch, initfunc)
   105	}
   106	
   107	func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
   108		targ := r.Sym
   109		r.InitExt()
   110	
   111		switch r.Type {
   112		default:
   113			if r.Type >= objabi.ElfRelocOffset {
   114				ld.Errorf(s, "unexpected relocation type %d", r.Type)
   115				return false
   116			}
   117	
   118			// Handle relocations found in ELF object files.
   119		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_12),
   120			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT12):
   121			ld.Errorf(s, "s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-objabi.ElfRelocOffset)
   122			return false
   123	
   124		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_8),
   125			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_16),
   126			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_32),
   127			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_64):
   128			if targ.Type == sym.SDYNIMPORT {
   129				ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
   130			}
   131			r.Type = objabi.R_ADDR
   132			return true
   133	
   134		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC16),
   135			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC32),
   136			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC64):
   137			if targ.Type == sym.SDYNIMPORT {
   138				ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name)
   139			}
   140			// TODO(mwhudson): the test of VisibilityHidden here probably doesn't make
   141			// sense and should be removed when someone has thought about it properly.
   142			if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
   143				ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
   144			}
   145			r.Type = objabi.R_PCREL
   146			r.Add += int64(r.Siz)
   147			return true
   148	
   149		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT16),
   150			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT32),
   151			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOT64):
   152			ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
   153			return true
   154	
   155		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT16DBL),
   156			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT32DBL):
   157			r.Type = objabi.R_PCREL
   158			r.Variant = sym.RV_390_DBL
   159			r.Add += int64(r.Siz)
   160			if targ.Type == sym.SDYNIMPORT {
   161				addpltsym(ctxt, targ)
   162				r.Sym = ctxt.Syms.Lookup(".plt", 0)
   163				r.Add += int64(targ.Plt())
   164			}
   165			return true
   166	
   167		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT32),
   168			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PLT64):
   169			r.Type = objabi.R_PCREL
   170			r.Add += int64(r.Siz)
   171			if targ.Type == sym.SDYNIMPORT {
   172				addpltsym(ctxt, targ)
   173				r.Sym = ctxt.Syms.Lookup(".plt", 0)
   174				r.Add += int64(targ.Plt())
   175			}
   176			return true
   177	
   178		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_COPY):
   179			ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
   180			return false
   181	
   182		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GLOB_DAT):
   183			ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
   184			return false
   185	
   186		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_JMP_SLOT):
   187			ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
   188			return false
   189	
   190		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_RELATIVE):
   191			ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-objabi.ElfRelocOffset)
   192			return false
   193	
   194		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTOFF):
   195			if targ.Type == sym.SDYNIMPORT {
   196				ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
   197			}
   198			r.Type = objabi.R_GOTOFF
   199			return true
   200	
   201		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPC):
   202			r.Type = objabi.R_PCREL
   203			r.Sym = ctxt.Syms.Lookup(".got", 0)
   204			r.Add += int64(r.Siz)
   205			return true
   206	
   207		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC16DBL),
   208			objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_PC32DBL):
   209			r.Type = objabi.R_PCREL
   210			r.Variant = sym.RV_390_DBL
   211			r.Add += int64(r.Siz)
   212			if targ.Type == sym.SDYNIMPORT {
   213				ld.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name)
   214			}
   215			return true
   216	
   217		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPCDBL):
   218			r.Type = objabi.R_PCREL
   219			r.Variant = sym.RV_390_DBL
   220			r.Sym = ctxt.Syms.Lookup(".got", 0)
   221			r.Add += int64(r.Siz)
   222			return true
   223	
   224		case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTENT):
   225			addgotsym(ctxt, targ)
   226	
   227			r.Type = objabi.R_PCREL
   228			r.Variant = sym.RV_390_DBL
   229			r.Sym = ctxt.Syms.Lookup(".got", 0)
   230			r.Add += int64(targ.Got())
   231			r.Add += int64(r.Siz)
   232			return true
   233		}
   234		// Handle references to ELF symbols from our own object files.
   235		if targ.Type != sym.SDYNIMPORT {
   236			return true
   237		}
   238	
   239		return false
   240	}
   241	
   242	func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
   243		ctxt.Out.Write64(uint64(sectoff))
   244	
   245		elfsym := r.Xsym.ElfsymForReloc()
   246		switch r.Type {
   247		default:
   248			return false
   249		case objabi.R_TLS_LE:
   250			switch r.Siz {
   251			default:
   252				return false
   253			case 4:
   254				// WARNING - silently ignored by linker in ELF64
   255				ctxt.Out.Write64(uint64(elf.R_390_TLS_LE32) | uint64(elfsym)<<32)
   256			case 8:
   257				// WARNING - silently ignored by linker in ELF32
   258				ctxt.Out.Write64(uint64(elf.R_390_TLS_LE64) | uint64(elfsym)<<32)
   259			}
   260		case objabi.R_TLS_IE:
   261			switch r.Siz {
   262			default:
   263				return false
   264			case 4:
   265				ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32)
   266			}
   267		case objabi.R_ADDR:
   268			switch r.Siz {
   269			default:
   270				return false
   271			case 4:
   272				ctxt.Out.Write64(uint64(elf.R_390_32) | uint64(elfsym)<<32)
   273			case 8:
   274				ctxt.Out.Write64(uint64(elf.R_390_64) | uint64(elfsym)<<32)
   275			}
   276		case objabi.R_GOTPCREL:
   277			if r.Siz == 4 {
   278				ctxt.Out.Write64(uint64(elf.R_390_GOTENT) | uint64(elfsym)<<32)
   279			} else {
   280				return false
   281			}
   282		case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL:
   283			elfrel := elf.R_390_NONE
   284			isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL
   285			// TODO(mundaym): all DBL style relocations should be
   286			// signalled using the variant - see issue 14218.
   287			switch r.Type {
   288			case objabi.R_PCRELDBL, objabi.R_CALL:
   289				isdbl = true
   290			}
   291			if r.Xsym.Type == sym.SDYNIMPORT && (r.Xsym.ElfType() == elf.STT_FUNC || r.Type == objabi.R_CALL) {
   292				if isdbl {
   293					switch r.Siz {
   294					case 2:
   295						elfrel = elf.R_390_PLT16DBL
   296					case 4:
   297						elfrel = elf.R_390_PLT32DBL
   298					}
   299				} else {
   300					switch r.Siz {
   301					case 4:
   302						elfrel = elf.R_390_PLT32
   303					case 8:
   304						elfrel = elf.R_390_PLT64
   305					}
   306				}
   307			} else {
   308				if isdbl {
   309					switch r.Siz {
   310					case 2:
   311						elfrel = elf.R_390_PC16DBL
   312					case 4:
   313						elfrel = elf.R_390_PC32DBL
   314					}
   315				} else {
   316					switch r.Siz {
   317					case 2:
   318						elfrel = elf.R_390_PC16
   319					case 4:
   320						elfrel = elf.R_390_PC32
   321					case 8:
   322						elfrel = elf.R_390_PC64
   323					}
   324				}
   325			}
   326			if elfrel == elf.R_390_NONE {
   327				return false // unsupported size/dbl combination
   328			}
   329			ctxt.Out.Write64(uint64(elfrel) | uint64(elfsym)<<32)
   330		}
   331	
   332		ctxt.Out.Write64(uint64(r.Xadd))
   333		return true
   334	}
   335	
   336	func elfsetupplt(ctxt *ld.Link) {
   337		plt := ctxt.Syms.Lookup(".plt", 0)
   338		got := ctxt.Syms.Lookup(".got", 0)
   339		if plt.Size == 0 {
   340			// stg     %r1,56(%r15)
   341			plt.AddUint8(0xe3)
   342			plt.AddUint8(0x10)
   343			plt.AddUint8(0xf0)
   344			plt.AddUint8(0x38)
   345			plt.AddUint8(0x00)
   346			plt.AddUint8(0x24)
   347			// larl    %r1,_GLOBAL_OFFSET_TABLE_
   348			plt.AddUint8(0xc0)
   349			plt.AddUint8(0x10)
   350			plt.AddPCRelPlus(ctxt.Arch, got, 6)
   351			// mvc     48(8,%r15),8(%r1)
   352			plt.AddUint8(0xd2)
   353			plt.AddUint8(0x07)
   354			plt.AddUint8(0xf0)
   355			plt.AddUint8(0x30)
   356			plt.AddUint8(0x10)
   357			plt.AddUint8(0x08)
   358			// lg      %r1,16(%r1)
   359			plt.AddUint8(0xe3)
   360			plt.AddUint8(0x10)
   361			plt.AddUint8(0x10)
   362			plt.AddUint8(0x10)
   363			plt.AddUint8(0x00)
   364			plt.AddUint8(0x04)
   365			// br      %r1
   366			plt.AddUint8(0x07)
   367			plt.AddUint8(0xf1)
   368			// nopr    %r0
   369			plt.AddUint8(0x07)
   370			plt.AddUint8(0x00)
   371			// nopr    %r0
   372			plt.AddUint8(0x07)
   373			plt.AddUint8(0x00)
   374			// nopr    %r0
   375			plt.AddUint8(0x07)
   376			plt.AddUint8(0x00)
   377	
   378			// assume got->size == 0 too
   379			got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
   380	
   381			got.AddUint64(ctxt.Arch, 0)
   382			got.AddUint64(ctxt.Arch, 0)
   383		}
   384	}
   385	
   386	func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
   387		return false
   388	}
   389	
   390	func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
   391		if ctxt.LinkMode == ld.LinkExternal {
   392			return val, false
   393		}
   394	
   395		switch r.Type {
   396		case objabi.R_CONST:
   397			return r.Add, true
   398		case objabi.R_GOTOFF:
   399			return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true
   400		}
   401	
   402		return val, false
   403	}
   404	
   405	func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
   406		switch r.Variant & sym.RV_TYPE_MASK {
   407		default:
   408			ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
   409			return t
   410	
   411		case sym.RV_NONE:
   412			return t
   413	
   414		case sym.RV_390_DBL:
   415			if (t & 1) != 0 {
   416				ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
   417			}
   418			return t >> 1
   419		}
   420	}
   421	
   422	func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
   423		if s.Plt() >= 0 {
   424			return
   425		}
   426	
   427		ld.Adddynsym(ctxt, s)
   428	
   429		if ctxt.IsELF {
   430			plt := ctxt.Syms.Lookup(".plt", 0)
   431			got := ctxt.Syms.Lookup(".got", 0)
   432			rela := ctxt.Syms.Lookup(".rela.plt", 0)
   433			if plt.Size == 0 {
   434				elfsetupplt(ctxt)
   435			}
   436			// larl    %r1,_GLOBAL_OFFSET_TABLE_+index
   437	
   438			plt.AddUint8(0xc0)
   439			plt.AddUint8(0x10)
   440			plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant?
   441	
   442			// add to got: pointer to current pos in plt
   443			got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct
   444			// lg      %r1,0(%r1)
   445			plt.AddUint8(0xe3)
   446			plt.AddUint8(0x10)
   447			plt.AddUint8(0x10)
   448			plt.AddUint8(0x00)
   449			plt.AddUint8(0x00)
   450			plt.AddUint8(0x04)
   451			// br      %r1
   452			plt.AddUint8(0x07)
   453			plt.AddUint8(0xf1)
   454			// basr    %r1,%r0
   455			plt.AddUint8(0x0d)
   456			plt.AddUint8(0x10)
   457			// lgf     %r1,12(%r1)
   458			plt.AddUint8(0xe3)
   459			plt.AddUint8(0x10)
   460			plt.AddUint8(0x10)
   461			plt.AddUint8(0x0c)
   462			plt.AddUint8(0x00)
   463			plt.AddUint8(0x14)
   464			// jg .plt
   465			plt.AddUint8(0xc0)
   466			plt.AddUint8(0xf4)
   467	
   468			plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation
   469			//.plt index
   470			plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry
   471	
   472			// rela
   473			rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
   474	
   475			rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT)))
   476			rela.AddUint64(ctxt.Arch, 0)
   477	
   478			s.SetPlt(int32(plt.Size - 32))
   479	
   480		} else {
   481			ld.Errorf(s, "addpltsym: unsupported binary format")
   482		}
   483	}
   484	
   485	func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
   486		if s.Got() >= 0 {
   487			return
   488		}
   489	
   490		ld.Adddynsym(ctxt, s)
   491		got := ctxt.Syms.Lookup(".got", 0)
   492		s.SetGot(int32(got.Size))
   493		got.AddUint64(ctxt.Arch, 0)
   494	
   495		if ctxt.IsELF {
   496			rela := ctxt.Syms.Lookup(".rela", 0)
   497			rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
   498			rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT)))
   499			rela.AddUint64(ctxt.Arch, 0)
   500		} else {
   501			ld.Errorf(s, "addgotsym: unsupported binary format")
   502		}
   503	}
   504	
   505	func asmb(ctxt *ld.Link) {
   506		if ctxt.Debugvlog != 0 {
   507			ctxt.Logf("%5.2f asmb\n", ld.Cputime())
   508		}
   509	
   510		if ctxt.IsELF {
   511			ld.Asmbelfsetup()
   512		}
   513	
   514		sect := ld.Segtext.Sections[0]
   515		ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
   516		ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
   517		for _, sect = range ld.Segtext.Sections[1:] {
   518			ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
   519			ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
   520		}
   521	
   522		if ld.Segrodata.Filelen > 0 {
   523			if ctxt.Debugvlog != 0 {
   524				ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
   525			}
   526			ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
   527			ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
   528		}
   529		if ld.Segrelrodata.Filelen > 0 {
   530			if ctxt.Debugvlog != 0 {
   531				ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
   532			}
   533			ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
   534			ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
   535		}
   536	
   537		if ctxt.Debugvlog != 0 {
   538			ctxt.Logf("%5.2f datblk\n", ld.Cputime())
   539		}
   540	
   541		ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
   542		ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
   543	
   544		ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
   545		ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
   546	}
   547	
   548	func asmb2(ctxt *ld.Link) {
   549		/* output symbol table */
   550		ld.Symsize = 0
   551	
   552		ld.Lcsize = 0
   553		symo := uint32(0)
   554		if !*ld.FlagS {
   555			if !ctxt.IsELF {
   556				ld.Errorf(nil, "unsupported executable format")
   557			}
   558			if ctxt.Debugvlog != 0 {
   559				ctxt.Logf("%5.2f sym\n", ld.Cputime())
   560			}
   561			symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
   562			symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
   563	
   564			ctxt.Out.SeekSet(int64(symo))
   565			if ctxt.Debugvlog != 0 {
   566				ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
   567			}
   568			ld.Asmelfsym(ctxt)
   569			ctxt.Out.Flush()
   570			ctxt.Out.Write(ld.Elfstrdat)
   571	
   572			if ctxt.Debugvlog != 0 {
   573				ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
   574			}
   575	
   576			if ctxt.LinkMode == ld.LinkExternal {
   577				ld.Elfemitreloc(ctxt)
   578			}
   579		}
   580	
   581		if ctxt.Debugvlog != 0 {
   582			ctxt.Logf("%5.2f header\n", ld.Cputime())
   583		}
   584		ctxt.Out.SeekSet(0)
   585		switch ctxt.HeadType {
   586		default:
   587			ld.Errorf(nil, "unsupported operating system")
   588		case objabi.Hlinux:
   589			ld.Asmbelf(ctxt, int64(symo))
   590		}
   591	
   592		ctxt.Out.Flush()
   593		if *ld.FlagC {
   594			fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
   595			fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
   596			fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
   597			fmt.Printf("symsize=%d\n", ld.Symsize)
   598			fmt.Printf("lcsize=%d\n", ld.Lcsize)
   599			fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
   600		}
   601	}
   602	

View as plain text