github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/link/internal/s390x/asm.go (about) 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 "github.com/gagliardetto/golang-go/cmd/internal/objabi" 35 "github.com/gagliardetto/golang-go/cmd/internal/sys" 36 "github.com/gagliardetto/golang-go/cmd/link/internal/ld" 37 "github.com/gagliardetto/golang-go/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.IsELF { 507 ld.Asmbelfsetup() 508 } 509 510 sect := ld.Segtext.Sections[0] 511 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 512 ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 513 for _, sect = range ld.Segtext.Sections[1:] { 514 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 515 ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 516 } 517 518 if ld.Segrodata.Filelen > 0 { 519 ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff)) 520 ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) 521 } 522 if ld.Segrelrodata.Filelen > 0 { 523 ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff)) 524 ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen)) 525 } 526 527 ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff)) 528 ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen)) 529 530 ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff)) 531 ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) 532 } 533 534 func asmb2(ctxt *ld.Link) { 535 /* output symbol table */ 536 ld.Symsize = 0 537 538 ld.Lcsize = 0 539 symo := uint32(0) 540 if !*ld.FlagS { 541 if !ctxt.IsELF { 542 ld.Errorf(nil, "unsupported executable format") 543 } 544 symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) 545 symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound))) 546 547 ctxt.Out.SeekSet(int64(symo)) 548 ld.Asmelfsym(ctxt) 549 ctxt.Out.Flush() 550 ctxt.Out.Write(ld.Elfstrdat) 551 552 if ctxt.LinkMode == ld.LinkExternal { 553 ld.Elfemitreloc(ctxt) 554 } 555 } 556 557 ctxt.Out.SeekSet(0) 558 switch ctxt.HeadType { 559 default: 560 ld.Errorf(nil, "unsupported operating system") 561 case objabi.Hlinux: 562 ld.Asmbelf(ctxt, int64(symo)) 563 } 564 565 ctxt.Out.Flush() 566 if *ld.FlagC { 567 fmt.Printf("textsize=%d\n", ld.Segtext.Filelen) 568 fmt.Printf("datsize=%d\n", ld.Segdata.Filelen) 569 fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen) 570 fmt.Printf("symsize=%d\n", ld.Symsize) 571 fmt.Printf("lcsize=%d\n", ld.Lcsize) 572 fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize)) 573 } 574 }