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