github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/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 "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.Off = int32(initfunc.Size) 73 lmd.Siz = 4 74 lmd.Sym = ctxt.Moduledata 75 lmd.Type = objabi.R_PCREL 76 lmd.Variant = sym.RV_390_DBL 77 lmd.Add = 2 + int64(lmd.Siz) 78 initfunc.AddUint32(ctxt.Arch, 0) 79 80 // jg <runtime.addmoduledata[@plt]> 81 initfunc.AddUint8(0xc0) 82 initfunc.AddUint8(0xf4) 83 rel := initfunc.AddRel() 84 rel.Off = int32(initfunc.Size) 85 rel.Siz = 4 86 rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0) 87 rel.Type = objabi.R_CALL 88 rel.Variant = sym.RV_390_DBL 89 rel.Add = 2 + int64(rel.Siz) 90 initfunc.AddUint32(ctxt.Arch, 0) 91 92 // undef (for debugging) 93 initfunc.AddUint32(ctxt.Arch, 0) 94 if ctxt.BuildMode == ld.BuildModePlugin { 95 ctxt.Textp = append(ctxt.Textp, addmoduledata) 96 } 97 ctxt.Textp = append(ctxt.Textp, initfunc) 98 initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0) 99 initarray_entry.Attr |= sym.AttrLocal 100 initarray_entry.Attr |= sym.AttrReachable 101 initarray_entry.Type = sym.SINITARR 102 initarray_entry.AddAddr(ctxt.Arch, initfunc) 103 } 104 105 func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { 106 targ := r.Sym 107 108 switch r.Type { 109 default: 110 if r.Type >= 256 { 111 ld.Errorf(s, "unexpected relocation type %d", r.Type) 112 return false 113 } 114 115 // Handle relocations found in ELF object files. 116 case 256 + objabi.RelocType(elf.R_390_12), 117 256 + objabi.RelocType(elf.R_390_GOT12): 118 ld.Errorf(s, "s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256) 119 return false 120 121 case 256 + objabi.RelocType(elf.R_390_8), 122 256 + objabi.RelocType(elf.R_390_16), 123 256 + objabi.RelocType(elf.R_390_32), 124 256 + objabi.RelocType(elf.R_390_64): 125 if targ.Type == sym.SDYNIMPORT { 126 ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name) 127 } 128 r.Type = objabi.R_ADDR 129 return true 130 131 case 256 + objabi.RelocType(elf.R_390_PC16), 132 256 + objabi.RelocType(elf.R_390_PC32), 133 256 + objabi.RelocType(elf.R_390_PC64): 134 if targ.Type == sym.SDYNIMPORT { 135 ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name) 136 } 137 // TODO(mwhudson): the test of VisibilityHidden here probably doesn't make 138 // sense and should be removed when someone has thought about it properly. 139 if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() { 140 ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name) 141 } 142 r.Type = objabi.R_PCREL 143 r.Add += int64(r.Siz) 144 return true 145 146 case 256 + objabi.RelocType(elf.R_390_GOT16), 147 256 + objabi.RelocType(elf.R_390_GOT32), 148 256 + objabi.RelocType(elf.R_390_GOT64): 149 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 150 return true 151 152 case 256 + objabi.RelocType(elf.R_390_PLT16DBL), 153 256 + objabi.RelocType(elf.R_390_PLT32DBL): 154 r.Type = objabi.R_PCREL 155 r.Variant = sym.RV_390_DBL 156 r.Add += int64(r.Siz) 157 if targ.Type == sym.SDYNIMPORT { 158 addpltsym(ctxt, targ) 159 r.Sym = ctxt.Syms.Lookup(".plt", 0) 160 r.Add += int64(targ.Plt) 161 } 162 return true 163 164 case 256 + objabi.RelocType(elf.R_390_PLT32), 165 256 + objabi.RelocType(elf.R_390_PLT64): 166 r.Type = objabi.R_PCREL 167 r.Add += int64(r.Siz) 168 if targ.Type == sym.SDYNIMPORT { 169 addpltsym(ctxt, targ) 170 r.Sym = ctxt.Syms.Lookup(".plt", 0) 171 r.Add += int64(targ.Plt) 172 } 173 return true 174 175 case 256 + objabi.RelocType(elf.R_390_COPY): 176 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 177 return false 178 179 case 256 + objabi.RelocType(elf.R_390_GLOB_DAT): 180 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 181 return false 182 183 case 256 + objabi.RelocType(elf.R_390_JMP_SLOT): 184 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 185 return false 186 187 case 256 + objabi.RelocType(elf.R_390_RELATIVE): 188 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 189 return false 190 191 case 256 + objabi.RelocType(elf.R_390_GOTOFF): 192 if targ.Type == sym.SDYNIMPORT { 193 ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name) 194 } 195 r.Type = objabi.R_GOTOFF 196 return true 197 198 case 256 + objabi.RelocType(elf.R_390_GOTPC): 199 r.Type = objabi.R_PCREL 200 r.Sym = ctxt.Syms.Lookup(".got", 0) 201 r.Add += int64(r.Siz) 202 return true 203 204 case 256 + objabi.RelocType(elf.R_390_PC16DBL), 205 256 + objabi.RelocType(elf.R_390_PC32DBL): 206 r.Type = objabi.R_PCREL 207 r.Variant = sym.RV_390_DBL 208 r.Add += int64(r.Siz) 209 if targ.Type == sym.SDYNIMPORT { 210 ld.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name) 211 } 212 return true 213 214 case 256 + objabi.RelocType(elf.R_390_GOTPCDBL): 215 r.Type = objabi.R_PCREL 216 r.Variant = sym.RV_390_DBL 217 r.Sym = ctxt.Syms.Lookup(".got", 0) 218 r.Add += int64(r.Siz) 219 return true 220 221 case 256 + objabi.RelocType(elf.R_390_GOTENT): 222 addgotsym(ctxt, targ) 223 224 r.Type = objabi.R_PCREL 225 r.Variant = sym.RV_390_DBL 226 r.Sym = ctxt.Syms.Lookup(".got", 0) 227 r.Add += int64(targ.Got) 228 r.Add += int64(r.Siz) 229 return true 230 } 231 // Handle references to ELF symbols from our own object files. 232 if targ.Type != sym.SDYNIMPORT { 233 return true 234 } 235 236 return false 237 } 238 239 func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { 240 ctxt.Out.Write64(uint64(sectoff)) 241 242 elfsym := r.Xsym.ElfsymForReloc() 243 switch r.Type { 244 default: 245 return false 246 case objabi.R_TLS_LE: 247 switch r.Siz { 248 default: 249 return false 250 case 4: 251 // WARNING - silently ignored by linker in ELF64 252 ctxt.Out.Write64(uint64(elf.R_390_TLS_LE32) | uint64(elfsym)<<32) 253 case 8: 254 // WARNING - silently ignored by linker in ELF32 255 ctxt.Out.Write64(uint64(elf.R_390_TLS_LE64) | uint64(elfsym)<<32) 256 } 257 case objabi.R_TLS_IE: 258 switch r.Siz { 259 default: 260 return false 261 case 4: 262 ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32) 263 } 264 case objabi.R_ADDR: 265 switch r.Siz { 266 default: 267 return false 268 case 4: 269 ctxt.Out.Write64(uint64(elf.R_390_32) | uint64(elfsym)<<32) 270 case 8: 271 ctxt.Out.Write64(uint64(elf.R_390_64) | uint64(elfsym)<<32) 272 } 273 case objabi.R_GOTPCREL: 274 if r.Siz == 4 { 275 ctxt.Out.Write64(uint64(elf.R_390_GOTENT) | uint64(elfsym)<<32) 276 } else { 277 return false 278 } 279 case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL: 280 elfrel := elf.R_390_NONE 281 isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL 282 // TODO(mundaym): all DBL style relocations should be 283 // signalled using the variant - see issue 14218. 284 switch r.Type { 285 case objabi.R_PCRELDBL, objabi.R_CALL: 286 isdbl = true 287 } 288 if r.Xsym.Type == sym.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == objabi.R_CALL) { 289 if isdbl { 290 switch r.Siz { 291 case 2: 292 elfrel = elf.R_390_PLT16DBL 293 case 4: 294 elfrel = elf.R_390_PLT32DBL 295 } 296 } else { 297 switch r.Siz { 298 case 4: 299 elfrel = elf.R_390_PLT32 300 case 8: 301 elfrel = elf.R_390_PLT64 302 } 303 } 304 } else { 305 if isdbl { 306 switch r.Siz { 307 case 2: 308 elfrel = elf.R_390_PC16DBL 309 case 4: 310 elfrel = elf.R_390_PC32DBL 311 } 312 } else { 313 switch r.Siz { 314 case 2: 315 elfrel = elf.R_390_PC16 316 case 4: 317 elfrel = elf.R_390_PC32 318 case 8: 319 elfrel = elf.R_390_PC64 320 } 321 } 322 } 323 if elfrel == elf.R_390_NONE { 324 return false // unsupported size/dbl combination 325 } 326 ctxt.Out.Write64(uint64(elfrel) | uint64(elfsym)<<32) 327 } 328 329 ctxt.Out.Write64(uint64(r.Xadd)) 330 return true 331 } 332 333 func elfsetupplt(ctxt *ld.Link) { 334 plt := ctxt.Syms.Lookup(".plt", 0) 335 got := ctxt.Syms.Lookup(".got", 0) 336 if plt.Size == 0 { 337 // stg %r1,56(%r15) 338 plt.AddUint8(0xe3) 339 plt.AddUint8(0x10) 340 plt.AddUint8(0xf0) 341 plt.AddUint8(0x38) 342 plt.AddUint8(0x00) 343 plt.AddUint8(0x24) 344 // larl %r1,_GLOBAL_OFFSET_TABLE_ 345 plt.AddUint8(0xc0) 346 plt.AddUint8(0x10) 347 plt.AddPCRelPlus(ctxt.Arch, got, 6) 348 // mvc 48(8,%r15),8(%r1) 349 plt.AddUint8(0xd2) 350 plt.AddUint8(0x07) 351 plt.AddUint8(0xf0) 352 plt.AddUint8(0x30) 353 plt.AddUint8(0x10) 354 plt.AddUint8(0x08) 355 // lg %r1,16(%r1) 356 plt.AddUint8(0xe3) 357 plt.AddUint8(0x10) 358 plt.AddUint8(0x10) 359 plt.AddUint8(0x10) 360 plt.AddUint8(0x00) 361 plt.AddUint8(0x04) 362 // br %r1 363 plt.AddUint8(0x07) 364 plt.AddUint8(0xf1) 365 // nopr %r0 366 plt.AddUint8(0x07) 367 plt.AddUint8(0x00) 368 // nopr %r0 369 plt.AddUint8(0x07) 370 plt.AddUint8(0x00) 371 // nopr %r0 372 plt.AddUint8(0x07) 373 plt.AddUint8(0x00) 374 375 // assume got->size == 0 too 376 got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0) 377 378 got.AddUint64(ctxt.Arch, 0) 379 got.AddUint64(ctxt.Arch, 0) 380 } 381 } 382 383 func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { 384 return false 385 } 386 387 func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { 388 if ctxt.LinkMode == ld.LinkExternal { 389 return false 390 } 391 392 switch r.Type { 393 case objabi.R_CONST: 394 *val = r.Add 395 return true 396 case objabi.R_GOTOFF: 397 *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)) 398 return true 399 } 400 401 return false 402 } 403 404 func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { 405 switch r.Variant & sym.RV_TYPE_MASK { 406 default: 407 ld.Errorf(s, "unexpected relocation variant %d", r.Variant) 408 return t 409 410 case sym.RV_NONE: 411 return t 412 413 case sym.RV_390_DBL: 414 if (t & 1) != 0 { 415 ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value) 416 } 417 return t >> 1 418 } 419 } 420 421 func addpltsym(ctxt *ld.Link, s *sym.Symbol) { 422 if s.Plt >= 0 { 423 return 424 } 425 426 ld.Adddynsym(ctxt, s) 427 428 if ctxt.IsELF { 429 plt := ctxt.Syms.Lookup(".plt", 0) 430 got := ctxt.Syms.Lookup(".got", 0) 431 rela := ctxt.Syms.Lookup(".rela.plt", 0) 432 if plt.Size == 0 { 433 elfsetupplt(ctxt) 434 } 435 // larl %r1,_GLOBAL_OFFSET_TABLE_+index 436 437 plt.AddUint8(0xc0) 438 plt.AddUint8(0x10) 439 plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant? 440 441 // add to got: pointer to current pos in plt 442 got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct 443 // lg %r1,0(%r1) 444 plt.AddUint8(0xe3) 445 plt.AddUint8(0x10) 446 plt.AddUint8(0x10) 447 plt.AddUint8(0x00) 448 plt.AddUint8(0x00) 449 plt.AddUint8(0x04) 450 // br %r1 451 plt.AddUint8(0x07) 452 plt.AddUint8(0xf1) 453 // basr %r1,%r0 454 plt.AddUint8(0x0d) 455 plt.AddUint8(0x10) 456 // lgf %r1,12(%r1) 457 plt.AddUint8(0xe3) 458 plt.AddUint8(0x10) 459 plt.AddUint8(0x10) 460 plt.AddUint8(0x0c) 461 plt.AddUint8(0x00) 462 plt.AddUint8(0x14) 463 // jg .plt 464 plt.AddUint8(0xc0) 465 plt.AddUint8(0xf4) 466 467 plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation 468 //.plt index 469 plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry 470 471 // rela 472 rela.AddAddrPlus(ctxt.Arch, got, got.Size-8) 473 474 rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT))) 475 rela.AddUint64(ctxt.Arch, 0) 476 477 s.Plt = int32(plt.Size - 32) 478 479 } else { 480 ld.Errorf(s, "addpltsym: unsupported binary format") 481 } 482 } 483 484 func addgotsym(ctxt *ld.Link, s *sym.Symbol) { 485 if s.Got >= 0 { 486 return 487 } 488 489 ld.Adddynsym(ctxt, s) 490 got := ctxt.Syms.Lookup(".got", 0) 491 s.Got = int32(got.Size) 492 got.AddUint64(ctxt.Arch, 0) 493 494 if ctxt.IsELF { 495 rela := ctxt.Syms.Lookup(".rela", 0) 496 rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got)) 497 rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT))) 498 rela.AddUint64(ctxt.Arch, 0) 499 } else { 500 ld.Errorf(s, "addgotsym: unsupported binary format") 501 } 502 } 503 504 func asmb(ctxt *ld.Link) { 505 if ctxt.Debugvlog != 0 { 506 ctxt.Logf("%5.2f asmb\n", ld.Cputime()) 507 } 508 509 if ctxt.IsELF { 510 ld.Asmbelfsetup() 511 } 512 513 sect := ld.Segtext.Sections[0] 514 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 515 ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 516 for _, sect = range ld.Segtext.Sections[1:] { 517 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 518 ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 519 } 520 521 if ld.Segrodata.Filelen > 0 { 522 if ctxt.Debugvlog != 0 { 523 ctxt.Logf("%5.2f rodatblk\n", ld.Cputime()) 524 } 525 ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff)) 526 ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) 527 } 528 if ld.Segrelrodata.Filelen > 0 { 529 if ctxt.Debugvlog != 0 { 530 ctxt.Logf("%5.2f rodatblk\n", ld.Cputime()) 531 } 532 ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff)) 533 ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen)) 534 } 535 536 if ctxt.Debugvlog != 0 { 537 ctxt.Logf("%5.2f datblk\n", ld.Cputime()) 538 } 539 540 ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff)) 541 ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen)) 542 543 ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff)) 544 ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) 545 546 /* output symbol table */ 547 ld.Symsize = 0 548 549 ld.Lcsize = 0 550 symo := uint32(0) 551 if !*ld.FlagS { 552 if !ctxt.IsELF { 553 ld.Errorf(nil, "unsupported executable format") 554 } 555 if ctxt.Debugvlog != 0 { 556 ctxt.Logf("%5.2f sym\n", ld.Cputime()) 557 } 558 symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) 559 symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound))) 560 561 ctxt.Out.SeekSet(int64(symo)) 562 if ctxt.Debugvlog != 0 { 563 ctxt.Logf("%5.2f elfsym\n", ld.Cputime()) 564 } 565 ld.Asmelfsym(ctxt) 566 ctxt.Out.Flush() 567 ctxt.Out.Write(ld.Elfstrdat) 568 569 if ctxt.Debugvlog != 0 { 570 ctxt.Logf("%5.2f dwarf\n", ld.Cputime()) 571 } 572 573 if ctxt.LinkMode == ld.LinkExternal { 574 ld.Elfemitreloc(ctxt) 575 } 576 } 577 578 if ctxt.Debugvlog != 0 { 579 ctxt.Logf("%5.2f header\n", ld.Cputime()) 580 } 581 ctxt.Out.SeekSet(0) 582 switch ctxt.HeadType { 583 default: 584 ld.Errorf(nil, "unsupported operating system") 585 case objabi.Hlinux: 586 ld.Asmbelf(ctxt, int64(symo)) 587 } 588 589 ctxt.Out.Flush() 590 if *ld.FlagC { 591 fmt.Printf("textsize=%d\n", ld.Segtext.Filelen) 592 fmt.Printf("datsize=%d\n", ld.Segdata.Filelen) 593 fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen) 594 fmt.Printf("symsize=%d\n", ld.Symsize) 595 fmt.Printf("lcsize=%d\n", ld.Lcsize) 596 fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize)) 597 } 598 }