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