github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/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) (int64, bool) { 388 if ctxt.LinkMode == ld.LinkExternal { 389 return val, false 390 } 391 392 switch r.Type { 393 case objabi.R_CONST: 394 return r.Add, true 395 case objabi.R_GOTOFF: 396 return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)), true 397 } 398 399 return val, false 400 } 401 402 func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 { 403 switch r.Variant & sym.RV_TYPE_MASK { 404 default: 405 ld.Errorf(s, "unexpected relocation variant %d", r.Variant) 406 return t 407 408 case sym.RV_NONE: 409 return t 410 411 case sym.RV_390_DBL: 412 if (t & 1) != 0 { 413 ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value) 414 } 415 return t >> 1 416 } 417 } 418 419 func addpltsym(ctxt *ld.Link, s *sym.Symbol) { 420 if s.Plt() >= 0 { 421 return 422 } 423 424 ld.Adddynsym(ctxt, s) 425 426 if ctxt.IsELF { 427 plt := ctxt.Syms.Lookup(".plt", 0) 428 got := ctxt.Syms.Lookup(".got", 0) 429 rela := ctxt.Syms.Lookup(".rela.plt", 0) 430 if plt.Size == 0 { 431 elfsetupplt(ctxt) 432 } 433 // larl %r1,_GLOBAL_OFFSET_TABLE_+index 434 435 plt.AddUint8(0xc0) 436 plt.AddUint8(0x10) 437 plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant? 438 439 // add to got: pointer to current pos in plt 440 got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct 441 // lg %r1,0(%r1) 442 plt.AddUint8(0xe3) 443 plt.AddUint8(0x10) 444 plt.AddUint8(0x10) 445 plt.AddUint8(0x00) 446 plt.AddUint8(0x00) 447 plt.AddUint8(0x04) 448 // br %r1 449 plt.AddUint8(0x07) 450 plt.AddUint8(0xf1) 451 // basr %r1,%r0 452 plt.AddUint8(0x0d) 453 plt.AddUint8(0x10) 454 // lgf %r1,12(%r1) 455 plt.AddUint8(0xe3) 456 plt.AddUint8(0x10) 457 plt.AddUint8(0x10) 458 plt.AddUint8(0x0c) 459 plt.AddUint8(0x00) 460 plt.AddUint8(0x14) 461 // jg .plt 462 plt.AddUint8(0xc0) 463 plt.AddUint8(0xf4) 464 465 plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation 466 //.plt index 467 plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry 468 469 // rela 470 rela.AddAddrPlus(ctxt.Arch, got, got.Size-8) 471 472 rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT))) 473 rela.AddUint64(ctxt.Arch, 0) 474 475 s.SetPlt(int32(plt.Size - 32)) 476 477 } else { 478 ld.Errorf(s, "addpltsym: unsupported binary format") 479 } 480 } 481 482 func addgotsym(ctxt *ld.Link, s *sym.Symbol) { 483 if s.Got() >= 0 { 484 return 485 } 486 487 ld.Adddynsym(ctxt, s) 488 got := ctxt.Syms.Lookup(".got", 0) 489 s.SetGot(int32(got.Size)) 490 got.AddUint64(ctxt.Arch, 0) 491 492 if ctxt.IsELF { 493 rela := ctxt.Syms.Lookup(".rela", 0) 494 rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got())) 495 rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT))) 496 rela.AddUint64(ctxt.Arch, 0) 497 } else { 498 ld.Errorf(s, "addgotsym: unsupported binary format") 499 } 500 } 501 502 func asmb(ctxt *ld.Link) { 503 if ctxt.Debugvlog != 0 { 504 ctxt.Logf("%5.2f asmb\n", ld.Cputime()) 505 } 506 507 if ctxt.IsELF { 508 ld.Asmbelfsetup() 509 } 510 511 sect := ld.Segtext.Sections[0] 512 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 513 ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 514 for _, sect = range ld.Segtext.Sections[1:] { 515 ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 516 ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 517 } 518 519 if ld.Segrodata.Filelen > 0 { 520 if ctxt.Debugvlog != 0 { 521 ctxt.Logf("%5.2f rodatblk\n", ld.Cputime()) 522 } 523 ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff)) 524 ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) 525 } 526 if ld.Segrelrodata.Filelen > 0 { 527 if ctxt.Debugvlog != 0 { 528 ctxt.Logf("%5.2f rodatblk\n", ld.Cputime()) 529 } 530 ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff)) 531 ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen)) 532 } 533 534 if ctxt.Debugvlog != 0 { 535 ctxt.Logf("%5.2f datblk\n", ld.Cputime()) 536 } 537 538 ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff)) 539 ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen)) 540 541 ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff)) 542 ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) 543 544 /* output symbol table */ 545 ld.Symsize = 0 546 547 ld.Lcsize = 0 548 symo := uint32(0) 549 if !*ld.FlagS { 550 if !ctxt.IsELF { 551 ld.Errorf(nil, "unsupported executable format") 552 } 553 if ctxt.Debugvlog != 0 { 554 ctxt.Logf("%5.2f sym\n", ld.Cputime()) 555 } 556 symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) 557 symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound))) 558 559 ctxt.Out.SeekSet(int64(symo)) 560 if ctxt.Debugvlog != 0 { 561 ctxt.Logf("%5.2f elfsym\n", ld.Cputime()) 562 } 563 ld.Asmelfsym(ctxt) 564 ctxt.Out.Flush() 565 ctxt.Out.Write(ld.Elfstrdat) 566 567 if ctxt.Debugvlog != 0 { 568 ctxt.Logf("%5.2f dwarf\n", ld.Cputime()) 569 } 570 571 if ctxt.LinkMode == ld.LinkExternal { 572 ld.Elfemitreloc(ctxt) 573 } 574 } 575 576 if ctxt.Debugvlog != 0 { 577 ctxt.Logf("%5.2f header\n", ld.Cputime()) 578 } 579 ctxt.Out.SeekSet(0) 580 switch ctxt.HeadType { 581 default: 582 ld.Errorf(nil, "unsupported operating system") 583 case objabi.Hlinux: 584 ld.Asmbelf(ctxt, int64(symo)) 585 } 586 587 ctxt.Out.Flush() 588 if *ld.FlagC { 589 fmt.Printf("textsize=%d\n", ld.Segtext.Filelen) 590 fmt.Printf("datsize=%d\n", ld.Segdata.Filelen) 591 fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen) 592 fmt.Printf("symsize=%d\n", ld.Symsize) 593 fmt.Printf("lcsize=%d\n", ld.Lcsize) 594 fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize)) 595 } 596 }