github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/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) bool { 236 ld.Thearch.Vput(uint64(sectoff)) 237 238 elfsym := r.Xsym.ElfsymForReloc() 239 switch r.Type { 240 default: 241 return false 242 case objabi.R_TLS_LE: 243 switch r.Siz { 244 default: 245 return false 246 case 4: 247 // WARNING - silently ignored by linker in ELF64 248 ld.Thearch.Vput(ld.R_390_TLS_LE32 | uint64(elfsym)<<32) 249 case 8: 250 // WARNING - silently ignored by linker in ELF32 251 ld.Thearch.Vput(ld.R_390_TLS_LE64 | uint64(elfsym)<<32) 252 } 253 case objabi.R_TLS_IE: 254 switch r.Siz { 255 default: 256 return false 257 case 4: 258 ld.Thearch.Vput(ld.R_390_TLS_IEENT | uint64(elfsym)<<32) 259 } 260 case objabi.R_ADDR: 261 switch r.Siz { 262 default: 263 return false 264 case 4: 265 ld.Thearch.Vput(ld.R_390_32 | uint64(elfsym)<<32) 266 case 8: 267 ld.Thearch.Vput(ld.R_390_64 | uint64(elfsym)<<32) 268 } 269 case objabi.R_GOTPCREL: 270 if r.Siz == 4 { 271 ld.Thearch.Vput(ld.R_390_GOTENT | uint64(elfsym)<<32) 272 } else { 273 return false 274 } 275 case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL: 276 elfrel := ld.R_390_NONE 277 isdbl := r.Variant&ld.RV_TYPE_MASK == ld.RV_390_DBL 278 // TODO(mundaym): all DBL style relocations should be 279 // signalled using the variant - see issue 14218. 280 switch r.Type { 281 case objabi.R_PCRELDBL, objabi.R_CALL: 282 isdbl = true 283 } 284 if r.Xsym.Type == ld.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == objabi.R_CALL) { 285 if isdbl { 286 switch r.Siz { 287 case 2: 288 elfrel = ld.R_390_PLT16DBL 289 case 4: 290 elfrel = ld.R_390_PLT32DBL 291 } 292 } else { 293 switch r.Siz { 294 case 4: 295 elfrel = ld.R_390_PLT32 296 case 8: 297 elfrel = ld.R_390_PLT64 298 } 299 } 300 } else { 301 if isdbl { 302 switch r.Siz { 303 case 2: 304 elfrel = ld.R_390_PC16DBL 305 case 4: 306 elfrel = ld.R_390_PC32DBL 307 } 308 } else { 309 switch r.Siz { 310 case 2: 311 elfrel = ld.R_390_PC16 312 case 4: 313 elfrel = ld.R_390_PC32 314 case 8: 315 elfrel = ld.R_390_PC64 316 } 317 } 318 } 319 if elfrel == ld.R_390_NONE { 320 return false // unsupported size/dbl combination 321 } 322 ld.Thearch.Vput(uint64(elfrel) | uint64(elfsym)<<32) 323 } 324 325 ld.Thearch.Vput(uint64(r.Xadd)) 326 return true 327 } 328 329 func elfsetupplt(ctxt *ld.Link) { 330 plt := ctxt.Syms.Lookup(".plt", 0) 331 got := ctxt.Syms.Lookup(".got", 0) 332 if plt.Size == 0 { 333 // stg %r1,56(%r15) 334 ld.Adduint8(ctxt, plt, 0xe3) 335 ld.Adduint8(ctxt, plt, 0x10) 336 ld.Adduint8(ctxt, plt, 0xf0) 337 ld.Adduint8(ctxt, plt, 0x38) 338 ld.Adduint8(ctxt, plt, 0x00) 339 ld.Adduint8(ctxt, plt, 0x24) 340 // larl %r1,_GLOBAL_OFFSET_TABLE_ 341 ld.Adduint8(ctxt, plt, 0xc0) 342 ld.Adduint8(ctxt, plt, 0x10) 343 ld.Addpcrelplus(ctxt, plt, got, 6) 344 // mvc 48(8,%r15),8(%r1) 345 ld.Adduint8(ctxt, plt, 0xd2) 346 ld.Adduint8(ctxt, plt, 0x07) 347 ld.Adduint8(ctxt, plt, 0xf0) 348 ld.Adduint8(ctxt, plt, 0x30) 349 ld.Adduint8(ctxt, plt, 0x10) 350 ld.Adduint8(ctxt, plt, 0x08) 351 // lg %r1,16(%r1) 352 ld.Adduint8(ctxt, plt, 0xe3) 353 ld.Adduint8(ctxt, plt, 0x10) 354 ld.Adduint8(ctxt, plt, 0x10) 355 ld.Adduint8(ctxt, plt, 0x10) 356 ld.Adduint8(ctxt, plt, 0x00) 357 ld.Adduint8(ctxt, plt, 0x04) 358 // br %r1 359 ld.Adduint8(ctxt, plt, 0x07) 360 ld.Adduint8(ctxt, plt, 0xf1) 361 // nopr %r0 362 ld.Adduint8(ctxt, plt, 0x07) 363 ld.Adduint8(ctxt, plt, 0x00) 364 // nopr %r0 365 ld.Adduint8(ctxt, plt, 0x07) 366 ld.Adduint8(ctxt, plt, 0x00) 367 // nopr %r0 368 ld.Adduint8(ctxt, plt, 0x07) 369 ld.Adduint8(ctxt, plt, 0x00) 370 371 // assume got->size == 0 too 372 ld.Addaddrplus(ctxt, got, ctxt.Syms.Lookup(".dynamic", 0), 0) 373 374 ld.Adduint64(ctxt, got, 0) 375 ld.Adduint64(ctxt, got, 0) 376 } 377 } 378 379 func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) bool { 380 return false 381 } 382 383 func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool { 384 if ld.Linkmode == ld.LinkExternal { 385 return false 386 } 387 388 switch r.Type { 389 case objabi.R_CONST: 390 *val = r.Add 391 return true 392 case objabi.R_GOTOFF: 393 *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)) 394 return true 395 } 396 397 return false 398 } 399 400 func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { 401 switch r.Variant & ld.RV_TYPE_MASK { 402 default: 403 ld.Errorf(s, "unexpected relocation variant %d", r.Variant) 404 return t 405 406 case ld.RV_NONE: 407 return t 408 409 case ld.RV_390_DBL: 410 if (t & 1) != 0 { 411 ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value) 412 } 413 return t >> 1 414 } 415 } 416 417 func addpltsym(ctxt *ld.Link, s *ld.Symbol) { 418 if s.Plt >= 0 { 419 return 420 } 421 422 ld.Adddynsym(ctxt, s) 423 424 if ld.Iself { 425 plt := ctxt.Syms.Lookup(".plt", 0) 426 got := ctxt.Syms.Lookup(".got", 0) 427 rela := ctxt.Syms.Lookup(".rela.plt", 0) 428 if plt.Size == 0 { 429 elfsetupplt(ctxt) 430 } 431 // larl %r1,_GLOBAL_OFFSET_TABLE_+index 432 433 ld.Adduint8(ctxt, plt, 0xc0) 434 ld.Adduint8(ctxt, plt, 0x10) 435 ld.Addpcrelplus(ctxt, plt, got, got.Size+6) // need variant? 436 437 // add to got: pointer to current pos in plt 438 ld.Addaddrplus(ctxt, got, plt, plt.Size+8) // weird but correct 439 // lg %r1,0(%r1) 440 ld.Adduint8(ctxt, plt, 0xe3) 441 ld.Adduint8(ctxt, plt, 0x10) 442 ld.Adduint8(ctxt, plt, 0x10) 443 ld.Adduint8(ctxt, plt, 0x00) 444 ld.Adduint8(ctxt, plt, 0x00) 445 ld.Adduint8(ctxt, plt, 0x04) 446 // br %r1 447 ld.Adduint8(ctxt, plt, 0x07) 448 ld.Adduint8(ctxt, plt, 0xf1) 449 // basr %r1,%r0 450 ld.Adduint8(ctxt, plt, 0x0d) 451 ld.Adduint8(ctxt, plt, 0x10) 452 // lgf %r1,12(%r1) 453 ld.Adduint8(ctxt, plt, 0xe3) 454 ld.Adduint8(ctxt, plt, 0x10) 455 ld.Adduint8(ctxt, plt, 0x10) 456 ld.Adduint8(ctxt, plt, 0x0c) 457 ld.Adduint8(ctxt, plt, 0x00) 458 ld.Adduint8(ctxt, plt, 0x14) 459 // jg .plt 460 ld.Adduint8(ctxt, plt, 0xc0) 461 ld.Adduint8(ctxt, plt, 0xf4) 462 463 ld.Adduint32(ctxt, plt, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation 464 //.plt index 465 ld.Adduint32(ctxt, plt, uint32(rela.Size)) // rela size before current entry 466 467 // rela 468 ld.Addaddrplus(ctxt, rela, got, got.Size-8) 469 470 ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_JMP_SLOT)) 471 ld.Adduint64(ctxt, rela, 0) 472 473 s.Plt = int32(plt.Size - 32) 474 475 } else { 476 ld.Errorf(s, "addpltsym: unsupported binary format") 477 } 478 } 479 480 func addgotsym(ctxt *ld.Link, s *ld.Symbol) { 481 if s.Got >= 0 { 482 return 483 } 484 485 ld.Adddynsym(ctxt, s) 486 got := ctxt.Syms.Lookup(".got", 0) 487 s.Got = int32(got.Size) 488 ld.Adduint64(ctxt, got, 0) 489 490 if ld.Iself { 491 rela := ctxt.Syms.Lookup(".rela", 0) 492 ld.Addaddrplus(ctxt, rela, got, int64(s.Got)) 493 ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT)) 494 ld.Adduint64(ctxt, rela, 0) 495 } else { 496 ld.Errorf(s, "addgotsym: unsupported binary format") 497 } 498 } 499 500 func asmb(ctxt *ld.Link) { 501 if ctxt.Debugvlog != 0 { 502 ctxt.Logf("%5.2f asmb\n", ld.Cputime()) 503 } 504 505 if ld.Iself { 506 ld.Asmbelfsetup() 507 } 508 509 sect := ld.Segtext.Sections[0] 510 ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 511 ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 512 for _, sect = range ld.Segtext.Sections[1:] { 513 ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 514 ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 515 } 516 517 if ld.Segrodata.Filelen > 0 { 518 if ctxt.Debugvlog != 0 { 519 ctxt.Logf("%5.2f rodatblk\n", ld.Cputime()) 520 } 521 ld.Cseek(int64(ld.Segrodata.Fileoff)) 522 ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen)) 523 } 524 if ld.Segrelrodata.Filelen > 0 { 525 if ctxt.Debugvlog != 0 { 526 ctxt.Logf("%5.2f rodatblk\n", ld.Cputime()) 527 } 528 ld.Cseek(int64(ld.Segrelrodata.Fileoff)) 529 ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen)) 530 } 531 532 if ctxt.Debugvlog != 0 { 533 ctxt.Logf("%5.2f datblk\n", ld.Cputime()) 534 } 535 536 ld.Cseek(int64(ld.Segdata.Fileoff)) 537 ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen)) 538 539 ld.Cseek(int64(ld.Segdwarf.Fileoff)) 540 ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen)) 541 542 /* output symbol table */ 543 ld.Symsize = 0 544 545 ld.Lcsize = 0 546 symo := uint32(0) 547 if !*ld.FlagS { 548 if !ld.Iself { 549 ld.Errorf(nil, "unsupported executable format") 550 } 551 if ctxt.Debugvlog != 0 { 552 ctxt.Logf("%5.2f sym\n", ld.Cputime()) 553 } 554 symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) 555 symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound))) 556 557 ld.Cseek(int64(symo)) 558 if ctxt.Debugvlog != 0 { 559 ctxt.Logf("%5.2f elfsym\n", ld.Cputime()) 560 } 561 ld.Asmelfsym(ctxt) 562 ld.Cflush() 563 ld.Cwrite(ld.Elfstrdat) 564 565 if ctxt.Debugvlog != 0 { 566 ctxt.Logf("%5.2f dwarf\n", ld.Cputime()) 567 } 568 569 if ld.Linkmode == ld.LinkExternal { 570 ld.Elfemitreloc(ctxt) 571 } 572 } 573 574 if ctxt.Debugvlog != 0 { 575 ctxt.Logf("%5.2f header\n", ld.Cputime()) 576 } 577 ld.Cseek(0) 578 switch ld.Headtype { 579 default: 580 ld.Errorf(nil, "unsupported operating system") 581 case objabi.Hlinux: 582 ld.Asmbelf(ctxt, int64(symo)) 583 } 584 585 ld.Cflush() 586 if *ld.FlagC { 587 fmt.Printf("textsize=%d\n", ld.Segtext.Filelen) 588 fmt.Printf("datsize=%d\n", ld.Segdata.Filelen) 589 fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen) 590 fmt.Printf("symsize=%d\n", ld.Symsize) 591 fmt.Printf("lcsize=%d\n", ld.Lcsize) 592 fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize)) 593 } 594 }