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 (a] 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 (a] 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(ctxt *ld.Link) { 51 if !ctxt.DynlinkingGo() { 52 return 53 } 54 addmoduledata := ctxt.Syms.Lookup("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 := ctxt.Syms.Lookup("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(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 = obj.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 = obj.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 93 ctxt.Textp = append(ctxt.Textp, initfunc) 94 initarray_entry := ctxt.Syms.Lookup("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(ctxt, initarray_entry, initfunc) 99 } 100 101 func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool { 102 targ := r.Sym 103 104 switch r.Type { 105 default: 106 if r.Type >= 256 { 107 ld.Errorf(s, "unexpected relocation type %d", r.Type) 108 return false 109 } 110 111 // Handle relocations found in ELF object files. 112 case 256 + ld.R_390_12, 113 256 + ld.R_390_GOT12: 114 ld.Errorf(s, "s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256) 115 return false 116 117 case 256 + ld.R_390_8, 118 256 + ld.R_390_16, 119 256 + ld.R_390_32, 120 256 + ld.R_390_64: 121 if targ.Type == obj.SDYNIMPORT { 122 ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name) 123 } 124 r.Type = obj.R_ADDR 125 return true 126 127 case 256 + ld.R_390_PC16, 128 256 + ld.R_390_PC32, 129 256 + ld.R_390_PC64: 130 if targ.Type == obj.SDYNIMPORT { 131 ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name) 132 } 133 if targ.Type == 0 || targ.Type == obj.SXREF { 134 ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name) 135 } 136 r.Type = obj.R_PCREL 137 r.Add += int64(r.Siz) 138 return true 139 140 case 256 + ld.R_390_GOT16, 141 256 + ld.R_390_GOT32, 142 256 + ld.R_390_GOT64: 143 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 144 return true 145 146 case 256 + ld.R_390_PLT16DBL, 147 256 + ld.R_390_PLT32DBL: 148 r.Type = obj.R_PCREL 149 r.Variant = ld.RV_390_DBL 150 r.Add += int64(r.Siz) 151 if targ.Type == obj.SDYNIMPORT { 152 addpltsym(ctxt, targ) 153 r.Sym = ctxt.Syms.Lookup(".plt", 0) 154 r.Add += int64(targ.Plt) 155 } 156 return true 157 158 case 256 + ld.R_390_PLT32, 159 256 + ld.R_390_PLT64: 160 r.Type = obj.R_PCREL 161 r.Add += int64(r.Siz) 162 if targ.Type == obj.SDYNIMPORT { 163 addpltsym(ctxt, targ) 164 r.Sym = ctxt.Syms.Lookup(".plt", 0) 165 r.Add += int64(targ.Plt) 166 } 167 return true 168 169 case 256 + ld.R_390_COPY: 170 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 171 return false 172 173 case 256 + ld.R_390_GLOB_DAT: 174 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 175 return false 176 177 case 256 + ld.R_390_JMP_SLOT: 178 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 179 return false 180 181 case 256 + ld.R_390_RELATIVE: 182 ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) 183 return false 184 185 case 256 + ld.R_390_GOTOFF: 186 if targ.Type == obj.SDYNIMPORT { 187 ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name) 188 } 189 r.Type = obj.R_GOTOFF 190 return true 191 192 case 256 + ld.R_390_GOTPC: 193 r.Type = obj.R_PCREL 194 r.Sym = ctxt.Syms.Lookup(".got", 0) 195 r.Add += int64(r.Siz) 196 return true 197 198 case 256 + ld.R_390_PC16DBL, 199 256 + ld.R_390_PC32DBL: 200 r.Type = obj.R_PCREL 201 r.Variant = ld.RV_390_DBL 202 r.Add += int64(r.Siz) 203 if targ.Type == obj.SDYNIMPORT { 204 ld.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name) 205 } 206 return true 207 208 case 256 + ld.R_390_GOTPCDBL: 209 r.Type = obj.R_PCREL 210 r.Variant = ld.RV_390_DBL 211 r.Sym = ctxt.Syms.Lookup(".got", 0) 212 r.Add += int64(r.Siz) 213 return true 214 215 case 256 + ld.R_390_GOTENT: 216 addgotsym(ctxt, targ) 217 218 r.Type = obj.R_PCREL 219 r.Variant = ld.RV_390_DBL 220 r.Sym = ctxt.Syms.Lookup(".got", 0) 221 r.Add += int64(targ.Got) 222 r.Add += int64(r.Siz) 223 return true 224 } 225 // Handle references to ELF symbols from our own object files. 226 if targ.Type != obj.SDYNIMPORT { 227 return true 228 } 229 230 return false 231 } 232 233 func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int { 234 ld.Thearch.Vput(uint64(sectoff)) 235 236 elfsym := r.Xsym.ElfsymForReloc() 237 switch r.Type { 238 default: 239 return -1 240 241 case obj.R_TLS_LE: 242 switch r.Siz { 243 default: 244 return -1 245 case 4: 246 // WARNING - silently ignored by linker in ELF64 247 ld.Thearch.Vput(ld.R_390_TLS_LE32 | uint64(elfsym)<<32) 248 case 8: 249 // WARNING - silently ignored by linker in ELF32 250 ld.Thearch.Vput(ld.R_390_TLS_LE64 | uint64(elfsym)<<32) 251 } 252 253 case obj.R_TLS_IE: 254 switch r.Siz { 255 default: 256 return -1 257 case 4: 258 ld.Thearch.Vput(ld.R_390_TLS_IEENT | uint64(elfsym)<<32) 259 } 260 261 case obj.R_ADDR: 262 switch r.Siz { 263 default: 264 return -1 265 case 4: 266 ld.Thearch.Vput(ld.R_390_32 | uint64(elfsym)<<32) 267 case 8: 268 ld.Thearch.Vput(ld.R_390_64 | uint64(elfsym)<<32) 269 } 270 271 case obj.R_GOTPCREL: 272 if r.Siz == 4 { 273 ld.Thearch.Vput(ld.R_390_GOTENT | uint64(elfsym)<<32) 274 } else { 275 return -1 276 } 277 278 case obj.R_PCREL, obj.R_PCRELDBL, obj.R_CALL: 279 elfrel := ld.R_390_NONE 280 isdbl := r.Variant&ld.RV_TYPE_MASK == ld.RV_390_DBL 281 // TODO(mundaym): all DBL style relocations should be 282 // signalled using the variant - see issue 14218. 283 switch r.Type { 284 case obj.R_PCRELDBL, obj.R_CALL: 285 isdbl = true 286 } 287 if r.Xsym.Type == obj.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == obj.R_CALL) { 288 if isdbl { 289 switch r.Siz { 290 case 2: 291 elfrel = ld.R_390_PLT16DBL 292 case 4: 293 elfrel = ld.R_390_PLT32DBL 294 } 295 } else { 296 switch r.Siz { 297 case 4: 298 elfrel = ld.R_390_PLT32 299 case 8: 300 elfrel = ld.R_390_PLT64 301 } 302 } 303 } else { 304 if isdbl { 305 switch r.Siz { 306 case 2: 307 elfrel = ld.R_390_PC16DBL 308 case 4: 309 elfrel = ld.R_390_PC32DBL 310 } 311 } else { 312 switch r.Siz { 313 case 2: 314 elfrel = ld.R_390_PC16 315 case 4: 316 elfrel = ld.R_390_PC32 317 case 8: 318 elfrel = ld.R_390_PC64 319 } 320 } 321 } 322 if elfrel == ld.R_390_NONE { 323 return -1 // unsupported size/dbl combination 324 } 325 ld.Thearch.Vput(uint64(elfrel) | uint64(elfsym)<<32) 326 } 327 328 ld.Thearch.Vput(uint64(r.Xadd)) 329 return 0 330 } 331 332 func elfsetupplt(ctxt *ld.Link) { 333 plt := ctxt.Syms.Lookup(".plt", 0) 334 got := ctxt.Syms.Lookup(".got", 0) 335 if plt.Size == 0 { 336 // stg %r1,56(%r15) 337 ld.Adduint8(ctxt, plt, 0xe3) 338 ld.Adduint8(ctxt, plt, 0x10) 339 ld.Adduint8(ctxt, plt, 0xf0) 340 ld.Adduint8(ctxt, plt, 0x38) 341 ld.Adduint8(ctxt, plt, 0x00) 342 ld.Adduint8(ctxt, plt, 0x24) 343 // larl %r1,_GLOBAL_OFFSET_TABLE_ 344 ld.Adduint8(ctxt, plt, 0xc0) 345 ld.Adduint8(ctxt, plt, 0x10) 346 ld.Addpcrelplus(ctxt, plt, got, 6) 347 // mvc 48(8,%r15),8(%r1) 348 ld.Adduint8(ctxt, plt, 0xd2) 349 ld.Adduint8(ctxt, plt, 0x07) 350 ld.Adduint8(ctxt, plt, 0xf0) 351 ld.Adduint8(ctxt, plt, 0x30) 352 ld.Adduint8(ctxt, plt, 0x10) 353 ld.Adduint8(ctxt, plt, 0x08) 354 // lg %r1,16(%r1) 355 ld.Adduint8(ctxt, plt, 0xe3) 356 ld.Adduint8(ctxt, plt, 0x10) 357 ld.Adduint8(ctxt, plt, 0x10) 358 ld.Adduint8(ctxt, plt, 0x10) 359 ld.Adduint8(ctxt, plt, 0x00) 360 ld.Adduint8(ctxt, plt, 0x04) 361 // br %r1 362 ld.Adduint8(ctxt, plt, 0x07) 363 ld.Adduint8(ctxt, plt, 0xf1) 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 // nopr %r0 371 ld.Adduint8(ctxt, plt, 0x07) 372 ld.Adduint8(ctxt, plt, 0x00) 373 374 // assume got->size == 0 too 375 ld.Addaddrplus(ctxt, got, ctxt.Syms.Lookup(".dynamic", 0), 0) 376 377 ld.Adduint64(ctxt, got, 0) 378 ld.Adduint64(ctxt, got, 0) 379 } 380 } 381 382 func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int { 383 return -1 384 } 385 386 func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int { 387 if ld.Linkmode == ld.LinkExternal { 388 return -1 389 } 390 391 switch r.Type { 392 case obj.R_CONST: 393 *val = r.Add 394 return 0 395 396 case obj.R_GOTOFF: 397 *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0)) 398 return 0 399 } 400 401 return -1 402 } 403 404 func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 { 405 switch r.Variant & ld.RV_TYPE_MASK { 406 default: 407 ld.Errorf(s, "unexpected relocation variant %d", r.Variant) 408 return t 409 410 case ld.RV_NONE: 411 return t 412 413 case ld.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 *ld.Symbol) { 422 if s.Plt >= 0 { 423 return 424 } 425 426 ld.Adddynsym(ctxt, s) 427 428 if ld.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 ld.Adduint8(ctxt, plt, 0xc0) 438 ld.Adduint8(ctxt, plt, 0x10) 439 ld.Addpcrelplus(ctxt, plt, got, got.Size+6) // need variant? 440 441 // add to got: pointer to current pos in plt 442 ld.Addaddrplus(ctxt, got, plt, plt.Size+8) // weird but correct 443 // lg %r1,0(%r1) 444 ld.Adduint8(ctxt, plt, 0xe3) 445 ld.Adduint8(ctxt, plt, 0x10) 446 ld.Adduint8(ctxt, plt, 0x10) 447 ld.Adduint8(ctxt, plt, 0x00) 448 ld.Adduint8(ctxt, plt, 0x00) 449 ld.Adduint8(ctxt, plt, 0x04) 450 // br %r1 451 ld.Adduint8(ctxt, plt, 0x07) 452 ld.Adduint8(ctxt, plt, 0xf1) 453 // basr %r1,%r0 454 ld.Adduint8(ctxt, plt, 0x0d) 455 ld.Adduint8(ctxt, plt, 0x10) 456 // lgf %r1,12(%r1) 457 ld.Adduint8(ctxt, plt, 0xe3) 458 ld.Adduint8(ctxt, plt, 0x10) 459 ld.Adduint8(ctxt, plt, 0x10) 460 ld.Adduint8(ctxt, plt, 0x0c) 461 ld.Adduint8(ctxt, plt, 0x00) 462 ld.Adduint8(ctxt, plt, 0x14) 463 // jg .plt 464 ld.Adduint8(ctxt, plt, 0xc0) 465 ld.Adduint8(ctxt, plt, 0xf4) 466 467 ld.Adduint32(ctxt, plt, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation 468 //.plt index 469 ld.Adduint32(ctxt, plt, uint32(rela.Size)) // rela size before current entry 470 471 // rela 472 ld.Addaddrplus(ctxt, rela, got, got.Size-8) 473 474 ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_JMP_SLOT)) 475 ld.Adduint64(ctxt, rela, 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 *ld.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 ld.Adduint64(ctxt, got, 0) 493 494 if ld.Iself { 495 rela := ctxt.Syms.Lookup(".rela", 0) 496 ld.Addaddrplus(ctxt, rela, got, int64(s.Got)) 497 ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT)) 498 ld.Adduint64(ctxt, rela, 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", obj.Cputime()) 507 } 508 509 if ld.Iself { 510 ld.Asmbelfsetup() 511 } 512 513 sect := ld.Segtext.Sect 514 ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff)) 515 ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length)) 516 for sect = sect.Next; sect != nil; sect = sect.Next { 517 ld.Cseek(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", obj.Cputime()) 524 } 525 ld.Cseek(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", obj.Cputime()) 531 } 532 ld.Cseek(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", obj.Cputime()) 538 } 539 540 ld.Cseek(int64(ld.Segdata.Fileoff)) 541 ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen)) 542 543 ld.Cseek(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 !ld.Iself { 553 ld.Errorf(nil, "unsupported executable format") 554 } 555 if ctxt.Debugvlog != 0 { 556 ctxt.Logf("%5.2f sym\n", obj.Cputime()) 557 } 558 symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen) 559 symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound))) 560 561 ld.Cseek(int64(symo)) 562 if ctxt.Debugvlog != 0 { 563 ctxt.Logf("%5.2f elfsym\n", obj.Cputime()) 564 } 565 ld.Asmelfsym(ctxt) 566 ld.Cflush() 567 ld.Cwrite(ld.Elfstrdat) 568 569 if ctxt.Debugvlog != 0 { 570 ctxt.Logf("%5.2f dwarf\n", obj.Cputime()) 571 } 572 573 if ld.Linkmode == ld.LinkExternal { 574 ld.Elfemitreloc(ctxt) 575 } 576 } 577 578 if ctxt.Debugvlog != 0 { 579 ctxt.Logf("%5.2f header\n", obj.Cputime()) 580 } 581 ld.Cseek(0) 582 switch ld.Headtype { 583 default: 584 ld.Errorf(nil, "unsupported operating system") 585 case obj.Hlinux: 586 ld.Asmbelf(ctxt, int64(symo)) 587 } 588 589 ld.Cflush() 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 } 599