github.com/alash3al/go@v0.0.0-20150827002835-d497eeb00540/src/cmd/link/internal/ld/lib.go (about) 1 // Inferno utils/8l/asm.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/8l/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 ld 32 33 import ( 34 "bufio" 35 "bytes" 36 "cmd/internal/obj" 37 "crypto/sha1" 38 "debug/elf" 39 "encoding/binary" 40 "fmt" 41 "io" 42 "io/ioutil" 43 "log" 44 "os" 45 "os/exec" 46 "path/filepath" 47 "runtime" 48 "strings" 49 ) 50 51 // Data layout and relocation. 52 53 // Derived from Inferno utils/6l/l.h 54 // http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h 55 // 56 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 57 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 58 // Portions Copyright © 1997-1999 Vita Nuova Limited 59 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 60 // Portions Copyright © 2004,2006 Bruce Ellis 61 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 62 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 63 // Portions Copyright © 2009 The Go Authors. All rights reserved. 64 // 65 // Permission is hereby granted, free of charge, to any person obtaining a copy 66 // of this software and associated documentation files (the "Software"), to deal 67 // in the Software without restriction, including without limitation the rights 68 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 69 // copies of the Software, and to permit persons to whom the Software is 70 // furnished to do so, subject to the following conditions: 71 // 72 // The above copyright notice and this permission notice shall be included in 73 // all copies or substantial portions of the Software. 74 // 75 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 76 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 77 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 78 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 79 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 80 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 81 // THE SOFTWARE. 82 83 type Arch struct { 84 Thechar int 85 Ptrsize int 86 Intsize int 87 Regsize int 88 Funcalign int 89 Maxalign int 90 Minlc int 91 Dwarfregsp int 92 Dwarfreglr int 93 Linuxdynld string 94 Freebsddynld string 95 Netbsddynld string 96 Openbsddynld string 97 Dragonflydynld string 98 Solarisdynld string 99 Adddynrel func(*LSym, *Reloc) 100 Archinit func() 101 Archreloc func(*Reloc, *LSym, *int64) int 102 Archrelocvariant func(*Reloc, *LSym, int64) int64 103 Asmb func() 104 Elfreloc1 func(*Reloc, int64) int 105 Elfsetupplt func() 106 Gentext func() 107 Machoreloc1 func(*Reloc, int64) int 108 PEreloc1 func(*Reloc, int64) bool 109 Lput func(uint32) 110 Wput func(uint16) 111 Vput func(uint64) 112 } 113 114 type Rpath struct { 115 set bool 116 val string 117 } 118 119 func (r *Rpath) Set(val string) error { 120 r.set = true 121 r.val = val 122 return nil 123 } 124 125 func (r *Rpath) String() string { 126 return r.val 127 } 128 129 var ( 130 Thearch Arch 131 datap *LSym 132 Debug [128]int 133 Lcsize int32 134 rpath Rpath 135 Spsize int32 136 Symsize int32 137 ) 138 139 // Terrible but standard terminology. 140 // A segment describes a block of file to load into memory. 141 // A section further describes the pieces of that block for 142 // use in debuggers and such. 143 144 const ( 145 MAXIO = 8192 146 MINFUNC = 16 // minimum size for a function 147 ) 148 149 type Segment struct { 150 Rwx uint8 // permission as usual unix bits (5 = r-x etc) 151 Vaddr uint64 // virtual address 152 Length uint64 // length in memory 153 Fileoff uint64 // file offset 154 Filelen uint64 // length on disk 155 Sect *Section 156 } 157 158 type Section struct { 159 Rwx uint8 160 Extnum int16 161 Align int32 162 Name string 163 Vaddr uint64 164 Length uint64 165 Next *Section 166 Seg *Segment 167 Elfsect *ElfShdr 168 Reloff uint64 169 Rellen uint64 170 } 171 172 // DynlinkingGo returns whether we are producing Go code that can live 173 // in separate shared libraries linked together at runtime. 174 func DynlinkingGo() bool { 175 return Buildmode == BuildmodeShared || Linkshared 176 } 177 178 var ( 179 Thestring string 180 Thelinkarch *LinkArch 181 outfile string 182 dynexp []*LSym 183 dynlib []string 184 ldflag []string 185 havedynamic int 186 Funcalign int 187 iscgo bool 188 elfglobalsymndx int 189 flag_installsuffix string 190 flag_race int 191 Buildmode BuildMode 192 Linkshared bool 193 tracksym string 194 interpreter string 195 tmpdir string 196 extld string 197 extldflags string 198 debug_s int // backup old value of debug['s'] 199 Ctxt *Link 200 HEADR int32 201 HEADTYPE int32 202 INITRND int32 203 INITTEXT int64 204 INITDAT int64 205 INITENTRY string /* entry point */ 206 nerrors int 207 Linkmode int 208 liveness int64 209 ) 210 211 // for dynexport field of LSym 212 const ( 213 CgoExportDynamic = 1 << 0 214 CgoExportStatic = 1 << 1 215 ) 216 217 var ( 218 Segtext Segment 219 Segrodata Segment 220 Segdata Segment 221 Segdwarf Segment 222 ) 223 224 /* set by call to mywhatsys() */ 225 226 /* whence for ldpkg */ 227 const ( 228 FileObj = 0 + iota 229 ArchiveObj 230 Pkgdef 231 ) 232 233 var ( 234 headstring string 235 // buffered output 236 Bso obj.Biobuf 237 ) 238 239 var coutbuf struct { 240 *bufio.Writer 241 f *os.File 242 } 243 244 const ( 245 // Whether to assume that the external linker is "gold" 246 // (http://sourceware.org/ml/binutils/2008-03/msg00162.html). 247 AssumeGoldLinker = 0 248 ) 249 250 const ( 251 symname = "__.GOSYMDEF" 252 pkgname = "__.PKGDEF" 253 ) 254 255 var ( 256 // Set if we see an object compiled by the host compiler that is not 257 // from a package that is known to support internal linking mode. 258 externalobj = false 259 goroot string 260 goarch string 261 goos string 262 theline string 263 ) 264 265 func Lflag(arg string) { 266 Ctxt.Libdir = append(Ctxt.Libdir, arg) 267 } 268 269 // A BuildMode indicates the sort of object we are building: 270 // "exe": build a main package and everything it imports into an executable. 271 // "c-shared": build a main package, plus all packages that it imports, into a 272 // single C shared library. The only callable symbols will be those functions 273 // marked as exported. 274 // "shared": combine all packages passed on the command line, and their 275 // dependencies, into a single shared library that will be used when 276 // building with the -linkshared option. 277 type BuildMode uint8 278 279 const ( 280 BuildmodeUnset BuildMode = iota 281 BuildmodeExe 282 BuildmodeCArchive 283 BuildmodeCShared 284 BuildmodeShared 285 ) 286 287 func (mode *BuildMode) Set(s string) error { 288 goos := obj.Getgoos() 289 goarch := obj.Getgoarch() 290 badmode := func() error { 291 return fmt.Errorf("buildmode %s not supported on %s/%s", s, goos, goarch) 292 } 293 switch s { 294 default: 295 return fmt.Errorf("invalid buildmode: %q", s) 296 case "exe": 297 *mode = BuildmodeExe 298 case "c-archive": 299 switch goos { 300 case "darwin", "linux": 301 default: 302 return badmode() 303 } 304 *mode = BuildmodeCArchive 305 case "c-shared": 306 if goarch != "amd64" && goarch != "arm" { 307 return badmode() 308 } 309 *mode = BuildmodeCShared 310 case "shared": 311 if goos != "linux" || goarch != "amd64" { 312 return badmode() 313 } 314 *mode = BuildmodeShared 315 } 316 return nil 317 } 318 319 func (mode *BuildMode) String() string { 320 switch *mode { 321 case BuildmodeUnset: 322 return "" // avoid showing a default in usage message 323 case BuildmodeExe: 324 return "exe" 325 case BuildmodeCArchive: 326 return "c-archive" 327 case BuildmodeCShared: 328 return "c-shared" 329 case BuildmodeShared: 330 return "shared" 331 } 332 return fmt.Sprintf("BuildMode(%d)", uint8(*mode)) 333 } 334 335 /* 336 * Unix doesn't like it when we write to a running (or, sometimes, 337 * recently run) binary, so remove the output file before writing it. 338 * On Windows 7, remove() can force a subsequent create() to fail. 339 * S_ISREG() does not exist on Plan 9. 340 */ 341 func mayberemoveoutfile() { 342 if fi, err := os.Lstat(outfile); err == nil && !fi.Mode().IsRegular() { 343 return 344 } 345 os.Remove(outfile) 346 } 347 348 func libinit() { 349 Funcalign = Thearch.Funcalign 350 mywhatsys() // get goroot, goarch, goos 351 352 // add goroot to the end of the libdir list. 353 suffix := "" 354 355 suffixsep := "" 356 if flag_installsuffix != "" { 357 suffixsep = "_" 358 suffix = flag_installsuffix 359 } else if flag_race != 0 { 360 suffixsep = "_" 361 suffix = "race" 362 } 363 364 Lflag(fmt.Sprintf("%s/pkg/%s_%s%s%s", goroot, goos, goarch, suffixsep, suffix)) 365 366 mayberemoveoutfile() 367 f, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775) 368 if err != nil { 369 Exitf("cannot create %s: %v", outfile, err) 370 } 371 372 coutbuf.Writer = bufio.NewWriter(f) 373 coutbuf.f = f 374 375 if INITENTRY == "" { 376 switch Buildmode { 377 case BuildmodeCShared, BuildmodeCArchive: 378 INITENTRY = fmt.Sprintf("_rt0_%s_%s_lib", goarch, goos) 379 case BuildmodeExe: 380 INITENTRY = fmt.Sprintf("_rt0_%s_%s", goarch, goos) 381 case BuildmodeShared: 382 // No INITENTRY for -buildmode=shared 383 default: 384 Diag("unknown INITENTRY for buildmode %v", Buildmode) 385 } 386 } 387 388 if !DynlinkingGo() { 389 Linklookup(Ctxt, INITENTRY, 0).Type = obj.SXREF 390 } 391 } 392 393 func Exitf(format string, a ...interface{}) { 394 fmt.Fprintf(os.Stderr, os.Args[0]+": "+format+"\n", a...) 395 if coutbuf.f != nil { 396 coutbuf.f.Close() 397 mayberemoveoutfile() 398 } 399 Exit(2) 400 } 401 402 func errorexit() { 403 if coutbuf.f != nil { 404 if nerrors != 0 { 405 Cflush() 406 } 407 // For rmtemp run at atexit time on Windows. 408 if err := coutbuf.f.Close(); err != nil { 409 Exitf("close: %v", err) 410 } 411 } 412 413 if nerrors != 0 { 414 if coutbuf.f != nil { 415 mayberemoveoutfile() 416 } 417 Exit(2) 418 } 419 420 Exit(0) 421 } 422 423 func loadinternal(name string) { 424 found := 0 425 for i := 0; i < len(Ctxt.Libdir); i++ { 426 if Linkshared { 427 shlibname := fmt.Sprintf("%s/%s.shlibname", Ctxt.Libdir[i], name) 428 if Debug['v'] != 0 { 429 fmt.Fprintf(&Bso, "searching for %s.a in %s\n", name, shlibname) 430 } 431 if obj.Access(shlibname, obj.AEXIST) >= 0 { 432 addlibpath(Ctxt, "internal", "internal", "", name, shlibname) 433 found = 1 434 break 435 } 436 } 437 pname := fmt.Sprintf("%s/%s.a", Ctxt.Libdir[i], name) 438 if Debug['v'] != 0 { 439 fmt.Fprintf(&Bso, "searching for %s.a in %s\n", name, pname) 440 } 441 if obj.Access(pname, obj.AEXIST) >= 0 { 442 addlibpath(Ctxt, "internal", "internal", pname, name, "") 443 found = 1 444 break 445 } 446 } 447 448 if found == 0 { 449 fmt.Fprintf(&Bso, "warning: unable to find %s.a\n", name) 450 } 451 } 452 453 func loadlib() { 454 switch Buildmode { 455 case BuildmodeCShared: 456 s := Linklookup(Ctxt, "runtime.islibrary", 0) 457 s.Dupok = 1 458 Adduint8(Ctxt, s, 1) 459 case BuildmodeCArchive: 460 s := Linklookup(Ctxt, "runtime.isarchive", 0) 461 s.Dupok = 1 462 Adduint8(Ctxt, s, 1) 463 } 464 465 loadinternal("runtime") 466 if Thearch.Thechar == '5' { 467 loadinternal("math") 468 } 469 if flag_race != 0 { 470 loadinternal("runtime/race") 471 } 472 473 var i int 474 for i = 0; i < len(Ctxt.Library); i++ { 475 if Debug['v'] > 1 { 476 fmt.Fprintf(&Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref) 477 } 478 iscgo = iscgo || Ctxt.Library[i].Pkg == "runtime/cgo" 479 if Ctxt.Library[i].Shlib != "" { 480 ldshlibsyms(Ctxt.Library[i].Shlib) 481 } else { 482 objfile(Ctxt.Library[i]) 483 } 484 } 485 486 if Linkmode == LinkAuto { 487 if iscgo && externalobj { 488 Linkmode = LinkExternal 489 } else { 490 Linkmode = LinkInternal 491 } 492 493 // Force external linking for android. 494 if goos == "android" { 495 Linkmode = LinkExternal 496 } 497 498 // cgo on Darwin must use external linking 499 // we can always use external linking, but then there will be circular 500 // dependency problems when compiling natively (external linking requires 501 // runtime/cgo, runtime/cgo requires cmd/cgo, but cmd/cgo needs to be 502 // compiled using external linking.) 503 if (Thearch.Thechar == '5' || Thearch.Thechar == '7') && HEADTYPE == obj.Hdarwin && iscgo { 504 Linkmode = LinkExternal 505 } 506 } 507 508 // cmd/7l doesn't support cgo internal linking 509 // This is https://golang.org/issue/10373. 510 if iscgo && goarch == "arm64" { 511 Linkmode = LinkExternal 512 } 513 514 if Linkmode == LinkExternal && !iscgo { 515 // This indicates a user requested -linkmode=external. 516 // The startup code uses an import of runtime/cgo to decide 517 // whether to initialize the TLS. So give it one. This could 518 // be handled differently but it's an unusual case. 519 loadinternal("runtime/cgo") 520 521 if i < len(Ctxt.Library) { 522 if Ctxt.Library[i].Shlib != "" { 523 ldshlibsyms(Ctxt.Library[i].Shlib) 524 } else { 525 if DynlinkingGo() { 526 Exitf("cannot implicitly include runtime/cgo in a shared library") 527 } 528 objfile(Ctxt.Library[i]) 529 } 530 } 531 } 532 533 if Linkmode == LinkInternal { 534 // Drop all the cgo_import_static declarations. 535 // Turns out we won't be needing them. 536 for s := Ctxt.Allsym; s != nil; s = s.Allsym { 537 if s.Type == obj.SHOSTOBJ { 538 // If a symbol was marked both 539 // cgo_import_static and cgo_import_dynamic, 540 // then we want to make it cgo_import_dynamic 541 // now. 542 if s.Extname != "" && s.Dynimplib != "" && s.Cgoexport == 0 { 543 s.Type = obj.SDYNIMPORT 544 } else { 545 s.Type = 0 546 } 547 } 548 } 549 } 550 551 tlsg := Linklookup(Ctxt, "runtime.tlsg", 0) 552 553 // For most ports, runtime.tlsg is a placeholder symbol for TLS 554 // relocation. However, the Android and Darwin arm ports need it 555 // to be a real variable. 556 // 557 // TODO(crawshaw): android should require leaving the tlsg->type 558 // alone (as the runtime-provided SNOPTRBSS) just like darwin/arm. 559 // But some other part of the linker is expecting STLSBSS. 560 if tlsg.Type != obj.SDYNIMPORT && (goos != "darwin" || Thearch.Thechar != '5') { 561 tlsg.Type = obj.STLSBSS 562 } 563 tlsg.Size = int64(Thearch.Ptrsize) 564 tlsg.Reachable = true 565 Ctxt.Tlsg = tlsg 566 567 moduledata := Linklookup(Ctxt, "runtime.firstmoduledata", 0) 568 if moduledata.Type == 0 || moduledata.Type == obj.SDYNIMPORT { 569 // If the module we are linking does not define the 570 // runtime.firstmoduledata symbol, create a local symbol for 571 // the moduledata. 572 moduledata = Linklookup(Ctxt, "local.moduledata", 0) 573 moduledata.Local = true 574 } else { 575 // If OTOH the module does define the symbol, we truncate the 576 // symbol back to 0 bytes so we can define its entire 577 // contents. 578 moduledata.Size = 0 579 } 580 // Either way we mark it as noptrdata to hide it from the GC. 581 moduledata.Type = obj.SNOPTRDATA 582 moduledata.Reachable = true 583 Ctxt.Moduledata = moduledata 584 585 // Now that we know the link mode, trim the dynexp list. 586 x := CgoExportDynamic 587 588 if Linkmode == LinkExternal { 589 x = CgoExportStatic 590 } 591 w := 0 592 for i := 0; i < len(dynexp); i++ { 593 if int(dynexp[i].Cgoexport)&x != 0 { 594 dynexp[w] = dynexp[i] 595 w++ 596 } 597 } 598 dynexp = dynexp[:w] 599 600 // In internal link mode, read the host object files. 601 if Linkmode == LinkInternal { 602 hostobjs() 603 } else { 604 hostlinksetup() 605 } 606 607 // We've loaded all the code now. 608 // If there are no dynamic libraries needed, gcc disables dynamic linking. 609 // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13) 610 // assumes that a dynamic binary always refers to at least one dynamic library. 611 // Rather than be a source of test cases for glibc, disable dynamic linking 612 // the same way that gcc would. 613 // 614 // Exception: on OS X, programs such as Shark only work with dynamic 615 // binaries, so leave it enabled on OS X (Mach-O) binaries. 616 // Also leave it enabled on Solaris which doesn't support 617 // statically linked binaries. 618 if Buildmode == BuildmodeExe && havedynamic == 0 && HEADTYPE != obj.Hdarwin && HEADTYPE != obj.Hsolaris { 619 Debug['d'] = 1 620 } 621 622 importcycles() 623 } 624 625 /* 626 * look for the next file in an archive. 627 * adapted from libmach. 628 */ 629 func nextar(bp *obj.Biobuf, off int64, a *ArHdr) int64 { 630 if off&1 != 0 { 631 off++ 632 } 633 obj.Bseek(bp, off, 0) 634 buf := make([]byte, SAR_HDR) 635 if n := obj.Bread(bp, buf); n < len(buf) { 636 if n >= 0 { 637 return 0 638 } 639 return -1 640 } 641 642 a.name = artrim(buf[0:16]) 643 a.date = artrim(buf[16:28]) 644 a.uid = artrim(buf[28:34]) 645 a.gid = artrim(buf[34:40]) 646 a.mode = artrim(buf[40:48]) 647 a.size = artrim(buf[48:58]) 648 a.fmag = artrim(buf[58:60]) 649 650 arsize := atolwhex(a.size) 651 if arsize&1 != 0 { 652 arsize++ 653 } 654 return int64(arsize) + SAR_HDR 655 } 656 657 func objfile(lib *Library) { 658 pkg := pathtoprefix(lib.Pkg) 659 660 if Debug['v'] > 1 { 661 fmt.Fprintf(&Bso, "%5.2f ldobj: %s (%s)\n", obj.Cputime(), lib.File, pkg) 662 } 663 Bso.Flush() 664 var err error 665 var f *obj.Biobuf 666 f, err = obj.Bopenr(lib.File) 667 if err != nil { 668 Exitf("cannot open file %s: %v", lib.File, err) 669 } 670 671 magbuf := make([]byte, len(ARMAG)) 672 if obj.Bread(f, magbuf) != len(magbuf) || !strings.HasPrefix(string(magbuf), ARMAG) { 673 /* load it as a regular file */ 674 l := obj.Bseek(f, 0, 2) 675 676 obj.Bseek(f, 0, 0) 677 ldobj(f, pkg, l, lib.File, lib.File, FileObj) 678 obj.Bterm(f) 679 680 return 681 } 682 683 /* skip over optional __.GOSYMDEF and process __.PKGDEF */ 684 off := obj.Boffset(f) 685 686 var arhdr ArHdr 687 l := nextar(f, off, &arhdr) 688 var pname string 689 if l <= 0 { 690 Diag("%s: short read on archive file symbol header", lib.File) 691 goto out 692 } 693 694 if strings.HasPrefix(arhdr.name, symname) { 695 off += l 696 l = nextar(f, off, &arhdr) 697 if l <= 0 { 698 Diag("%s: short read on archive file symbol header", lib.File) 699 goto out 700 } 701 } 702 703 if !strings.HasPrefix(arhdr.name, pkgname) { 704 Diag("%s: cannot find package header", lib.File) 705 goto out 706 } 707 708 if Buildmode == BuildmodeShared { 709 before := obj.Boffset(f) 710 pkgdefBytes := make([]byte, atolwhex(arhdr.size)) 711 obj.Bread(f, pkgdefBytes) 712 hash := sha1.Sum(pkgdefBytes) 713 lib.hash = hash[:] 714 obj.Bseek(f, before, 0) 715 } 716 717 off += l 718 719 if Debug['u'] != 0 { 720 ldpkg(f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef) 721 } 722 723 /* 724 * load all the object files from the archive now. 725 * this gives us sequential file access and keeps us 726 * from needing to come back later to pick up more 727 * objects. it breaks the usual C archive model, but 728 * this is Go, not C. the common case in Go is that 729 * we need to load all the objects, and then we throw away 730 * the individual symbols that are unused. 731 * 732 * loading every object will also make it possible to 733 * load foreign objects not referenced by __.GOSYMDEF. 734 */ 735 for { 736 l = nextar(f, off, &arhdr) 737 if l == 0 { 738 break 739 } 740 if l < 0 { 741 Exitf("%s: malformed archive", lib.File) 742 } 743 744 off += l 745 746 pname = fmt.Sprintf("%s(%s)", lib.File, arhdr.name) 747 l = atolwhex(arhdr.size) 748 ldobj(f, pkg, l, pname, lib.File, ArchiveObj) 749 } 750 751 out: 752 obj.Bterm(f) 753 } 754 755 type Hostobj struct { 756 ld func(*obj.Biobuf, string, int64, string) 757 pkg string 758 pn string 759 file string 760 off int64 761 length int64 762 } 763 764 var hostobj []Hostobj 765 766 // These packages can use internal linking mode. 767 // Others trigger external mode. 768 var internalpkg = []string{ 769 "crypto/x509", 770 "net", 771 "os/user", 772 "runtime/cgo", 773 "runtime/race", 774 } 775 776 func ldhostobj(ld func(*obj.Biobuf, string, int64, string), f *obj.Biobuf, pkg string, length int64, pn string, file string) { 777 isinternal := false 778 for i := 0; i < len(internalpkg); i++ { 779 if pkg == internalpkg[i] { 780 isinternal = true 781 break 782 } 783 } 784 785 // DragonFly declares errno with __thread, which results in a symbol 786 // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not 787 // currently know how to handle TLS relocations, hence we have to 788 // force external linking for any libraries that link in code that 789 // uses errno. This can be removed if the Go linker ever supports 790 // these relocation types. 791 if HEADTYPE == obj.Hdragonfly { 792 if pkg == "net" || pkg == "os/user" { 793 isinternal = false 794 } 795 } 796 797 if !isinternal { 798 externalobj = true 799 } 800 801 hostobj = append(hostobj, Hostobj{}) 802 h := &hostobj[len(hostobj)-1] 803 h.ld = ld 804 h.pkg = pkg 805 h.pn = pn 806 h.file = file 807 h.off = obj.Boffset(f) 808 h.length = length 809 } 810 811 func hostobjs() { 812 var f *obj.Biobuf 813 var h *Hostobj 814 815 for i := 0; i < len(hostobj); i++ { 816 h = &hostobj[i] 817 var err error 818 f, err = obj.Bopenr(h.file) 819 if f == nil { 820 Exitf("cannot reopen %s: %v", h.pn, err) 821 } 822 823 obj.Bseek(f, h.off, 0) 824 h.ld(f, h.pkg, h.length, h.pn) 825 obj.Bterm(f) 826 } 827 } 828 829 // provided by lib9 830 831 func rmtemp() { 832 os.RemoveAll(tmpdir) 833 } 834 835 func hostlinksetup() { 836 if Linkmode != LinkExternal { 837 return 838 } 839 840 // For external link, record that we need to tell the external linker -s, 841 // and turn off -s internally: the external linker needs the symbol 842 // information for its final link. 843 debug_s = Debug['s'] 844 Debug['s'] = 0 845 846 // create temporary directory and arrange cleanup 847 if tmpdir == "" { 848 dir, err := ioutil.TempDir("", "go-link-") 849 if err != nil { 850 log.Fatal(err) 851 } 852 tmpdir = dir 853 AtExit(rmtemp) 854 } 855 856 // change our output to temporary object file 857 coutbuf.f.Close() 858 mayberemoveoutfile() 859 860 p := fmt.Sprintf("%s/go.o", tmpdir) 861 var err error 862 f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775) 863 if err != nil { 864 Exitf("cannot create %s: %v", p, err) 865 } 866 867 coutbuf.Writer = bufio.NewWriter(f) 868 coutbuf.f = f 869 } 870 871 // hostobjCopy creates a copy of the object files in hostobj in a 872 // temporary directory. 873 func hostobjCopy() (paths []string) { 874 for i, h := range hostobj { 875 f, err := os.Open(h.file) 876 if err != nil { 877 Exitf("cannot reopen %s: %v", h.pn, err) 878 } 879 if _, err := f.Seek(h.off, 0); err != nil { 880 Exitf("cannot seek %s: %v", h.pn, err) 881 } 882 883 p := fmt.Sprintf("%s/%06d.o", tmpdir, i) 884 paths = append(paths, p) 885 w, err := os.Create(p) 886 if err != nil { 887 Exitf("cannot create %s: %v", p, err) 888 } 889 if _, err := io.CopyN(w, f, h.length); err != nil { 890 Exitf("cannot write %s: %v", p, err) 891 } 892 if err := w.Close(); err != nil { 893 Exitf("cannot close %s: %v", p, err) 894 } 895 } 896 return paths 897 } 898 899 // archive builds a .a archive from the hostobj object files. 900 func archive() { 901 if Buildmode != BuildmodeCArchive { 902 return 903 } 904 905 mayberemoveoutfile() 906 argv := []string{"ar", "-q", "-c", "-s", outfile} 907 argv = append(argv, hostobjCopy()...) 908 argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir)) 909 910 if Debug['v'] != 0 { 911 fmt.Fprintf(&Bso, "archive: %s\n", strings.Join(argv, " ")) 912 Bso.Flush() 913 } 914 915 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 916 Exitf("running %s failed: %v\n%s", argv[0], err, out) 917 } 918 } 919 920 func hostlink() { 921 if Linkmode != LinkExternal || nerrors > 0 { 922 return 923 } 924 if Buildmode == BuildmodeCArchive { 925 return 926 } 927 928 if extld == "" { 929 extld = "gcc" 930 } 931 932 var argv []string 933 argv = append(argv, extld) 934 switch Thearch.Thechar { 935 case '8': 936 argv = append(argv, "-m32") 937 938 case '6', '9': 939 argv = append(argv, "-m64") 940 941 case '5': 942 argv = append(argv, "-marm") 943 944 case '7': 945 // nothing needed 946 } 947 948 if Debug['s'] == 0 && debug_s == 0 { 949 argv = append(argv, "-gdwarf-2") 950 } else { 951 argv = append(argv, "-s") 952 } 953 954 if HEADTYPE == obj.Hdarwin { 955 argv = append(argv, "-Wl,-no_pie,-headerpad,1144") 956 } 957 if HEADTYPE == obj.Hopenbsd { 958 argv = append(argv, "-Wl,-nopie") 959 } 960 if HEADTYPE == obj.Hwindows { 961 if headstring == "windowsgui" { 962 argv = append(argv, "-mwindows") 963 } else { 964 argv = append(argv, "-mconsole") 965 } 966 } 967 968 if Iself && AssumeGoldLinker != 0 /*TypeKind(100016)*/ { 969 argv = append(argv, "-Wl,--rosegment") 970 } 971 972 switch Buildmode { 973 case BuildmodeExe: 974 if HEADTYPE == obj.Hdarwin { 975 argv = append(argv, "-Wl,-pagezero_size,4000000") 976 } 977 case BuildmodeCShared: 978 if HEADTYPE == obj.Hdarwin { 979 argv = append(argv, "-dynamiclib") 980 } else { 981 argv = append(argv, "-Wl,-Bsymbolic") 982 argv = append(argv, "-shared") 983 } 984 case BuildmodeShared: 985 // TODO(mwhudson): unless you do this, dynamic relocations fill 986 // out the findfunctab table and for some reason shared libraries 987 // and the executable both define a main function and putting the 988 // address of executable's main into the shared libraries 989 // findfunctab violates the assumptions of the runtime. TBH, I 990 // think we may well end up wanting to use -Bsymbolic here 991 // anyway. 992 argv = append(argv, "-Wl,-Bsymbolic-functions") 993 argv = append(argv, "-shared") 994 } 995 996 if Linkshared && Iself { 997 // We force all symbol resolution to be done at program startup 998 // because lazy PLT resolution can use large amounts of stack at 999 // times we cannot allow it to do so. 1000 argv = append(argv, "-Wl,-znow") 1001 } 1002 1003 if Iself && len(buildinfo) > 0 { 1004 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo)) 1005 } 1006 1007 // On Windows, given -o foo, GCC will append ".exe" to produce 1008 // "foo.exe". We have decided that we want to honor the -o 1009 // option. To make this work, we append a '.' so that GCC 1010 // will decide that the file already has an extension. We 1011 // only want to do this when producing a Windows output file 1012 // on a Windows host. 1013 outopt := outfile 1014 if goos == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" { 1015 outopt += "." 1016 } 1017 argv = append(argv, "-o") 1018 argv = append(argv, outopt) 1019 1020 if rpath.val != "" { 1021 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val)) 1022 } 1023 1024 // Force global symbols to be exported for dlopen, etc. 1025 if Iself { 1026 argv = append(argv, "-rdynamic") 1027 } 1028 1029 if strings.Contains(argv[0], "clang") { 1030 argv = append(argv, "-Qunused-arguments") 1031 } 1032 1033 argv = append(argv, hostobjCopy()...) 1034 argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir)) 1035 1036 if Linkshared { 1037 seenDirs := make(map[string]bool) 1038 seenLibs := make(map[string]bool) 1039 addshlib := func(path string) { 1040 dir, base := filepath.Split(path) 1041 if !seenDirs[dir] { 1042 argv = append(argv, "-L"+dir) 1043 if !rpath.set { 1044 argv = append(argv, "-Wl,-rpath="+dir) 1045 } 1046 seenDirs[dir] = true 1047 } 1048 base = strings.TrimSuffix(base, ".so") 1049 base = strings.TrimPrefix(base, "lib") 1050 if !seenLibs[base] { 1051 argv = append(argv, "-l"+base) 1052 seenLibs[base] = true 1053 } 1054 } 1055 for _, shlib := range Ctxt.Shlibs { 1056 addshlib(shlib.Path) 1057 for _, dep := range shlib.Deps { 1058 if dep == "" { 1059 continue 1060 } 1061 libpath := findshlib(dep) 1062 if libpath != "" { 1063 addshlib(libpath) 1064 } 1065 } 1066 } 1067 } 1068 1069 argv = append(argv, ldflag...) 1070 1071 for _, p := range strings.Fields(extldflags) { 1072 argv = append(argv, p) 1073 1074 // clang, unlike GCC, passes -rdynamic to the linker 1075 // even when linking with -static, causing a linker 1076 // error when using GNU ld. So take out -rdynamic if 1077 // we added it. We do it in this order, rather than 1078 // only adding -rdynamic later, so that -extldflags 1079 // can override -rdynamic without using -static. 1080 if Iself && p == "-static" { 1081 for i := range argv { 1082 if argv[i] == "-rdynamic" { 1083 argv[i] = "-static" 1084 } 1085 } 1086 } 1087 } 1088 if HEADTYPE == obj.Hwindows { 1089 argv = append(argv, peimporteddlls()...) 1090 } 1091 1092 if Debug['v'] != 0 { 1093 fmt.Fprintf(&Bso, "host link:") 1094 for _, v := range argv { 1095 fmt.Fprintf(&Bso, " %q", v) 1096 } 1097 fmt.Fprintf(&Bso, "\n") 1098 Bso.Flush() 1099 } 1100 1101 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1102 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1103 } else if Debug['v'] != 0 && len(out) > 0 { 1104 fmt.Fprintf(&Bso, "%s", out) 1105 Bso.Flush() 1106 } 1107 1108 if Debug['s'] == 0 && debug_s == 0 && HEADTYPE == obj.Hdarwin { 1109 // Skip combining dwarf on arm. 1110 if Thearch.Thechar != '5' && Thearch.Thechar != '7' { 1111 dsym := fmt.Sprintf("%s/go.dwarf", tmpdir) 1112 if out, err := exec.Command("dsymutil", "-f", outfile, "-o", dsym).CombinedOutput(); err != nil { 1113 Ctxt.Cursym = nil 1114 Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out) 1115 } 1116 // For os.Rename to work reliably, must be in same directory as outfile. 1117 combinedOutput := outfile + "~" 1118 if err := machoCombineDwarf(outfile, dsym, combinedOutput); err != nil { 1119 Ctxt.Cursym = nil 1120 Exitf("%s: combining dwarf failed: %v", os.Args[0], err) 1121 } 1122 os.Remove(outfile) 1123 if err := os.Rename(combinedOutput, outfile); err != nil { 1124 Ctxt.Cursym = nil 1125 Exitf("%s: %v", os.Args[0], err) 1126 } 1127 } 1128 } 1129 } 1130 1131 func ldobj(f *obj.Biobuf, pkg string, length int64, pn string, file string, whence int) { 1132 eof := obj.Boffset(f) + length 1133 1134 start := obj.Boffset(f) 1135 c1 := obj.Bgetc(f) 1136 c2 := obj.Bgetc(f) 1137 c3 := obj.Bgetc(f) 1138 c4 := obj.Bgetc(f) 1139 obj.Bseek(f, start, 0) 1140 1141 magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) 1142 if magic == 0x7f454c46 { // \x7F E L F 1143 ldhostobj(ldelf, f, pkg, length, pn, file) 1144 return 1145 } 1146 1147 if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe { 1148 ldhostobj(ldmacho, f, pkg, length, pn, file) 1149 return 1150 } 1151 1152 if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 { 1153 ldhostobj(ldpe, f, pkg, length, pn, file) 1154 return 1155 } 1156 1157 /* check the header */ 1158 line := obj.Brdline(f, '\n') 1159 if line == "" { 1160 if obj.Blinelen(f) > 0 { 1161 Diag("%s: not an object file", pn) 1162 return 1163 } 1164 Diag("truncated object file: %s", pn) 1165 return 1166 } 1167 1168 if !strings.HasPrefix(line, "go object ") { 1169 if strings.HasSuffix(pn, ".go") { 1170 Exitf("%cl: input %s is not .%c file (use %cg to compile .go files)", Thearch.Thechar, pn, Thearch.Thechar, Thearch.Thechar) 1171 } 1172 1173 if line == Thestring { 1174 // old header format: just $GOOS 1175 Diag("%s: stale object file", pn) 1176 return 1177 } 1178 1179 Diag("%s: not an object file", pn) 1180 return 1181 } 1182 1183 // First, check that the basic goos, goarch, and version match. 1184 t := fmt.Sprintf("%s %s %s ", goos, obj.Getgoarch(), obj.Getgoversion()) 1185 1186 line = strings.TrimRight(line, "\n") 1187 if !strings.HasPrefix(line[10:]+" ", t) && Debug['f'] == 0 { 1188 Diag("%s: object is [%s] expected [%s]", pn, line[10:], t) 1189 return 1190 } 1191 1192 // Second, check that longer lines match each other exactly, 1193 // so that the Go compiler and write additional information 1194 // that must be the same from run to run. 1195 if len(line) >= len(t)+10 { 1196 if theline == "" { 1197 theline = line[10:] 1198 } else if theline != line[10:] { 1199 Diag("%s: object is [%s] expected [%s]", pn, line[10:], theline) 1200 return 1201 } 1202 } 1203 1204 /* skip over exports and other info -- ends with \n!\n */ 1205 import0 := obj.Boffset(f) 1206 1207 c1 = '\n' // the last line ended in \n 1208 c2 = obj.Bgetc(f) 1209 c3 = obj.Bgetc(f) 1210 for c1 != '\n' || c2 != '!' || c3 != '\n' { 1211 c1 = c2 1212 c2 = c3 1213 c3 = obj.Bgetc(f) 1214 if c3 == obj.Beof { 1215 Diag("truncated object file: %s", pn) 1216 return 1217 } 1218 } 1219 1220 import1 := obj.Boffset(f) 1221 1222 obj.Bseek(f, import0, 0) 1223 ldpkg(f, pkg, import1-import0-2, pn, whence) // -2 for !\n 1224 obj.Bseek(f, import1, 0) 1225 1226 ldobjfile(Ctxt, f, pkg, eof-obj.Boffset(f), pn) 1227 } 1228 1229 func readelfsymboldata(f *elf.File, sym *elf.Symbol) []byte { 1230 data := make([]byte, sym.Size) 1231 sect := f.Sections[sym.Section] 1232 if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE { 1233 Diag("reading %s from non-data section", sym.Name) 1234 } 1235 n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr)) 1236 if uint64(n) != sym.Size { 1237 Diag("reading contents of %s: %v", sym.Name, err) 1238 } 1239 return data 1240 } 1241 1242 func readwithpad(r io.Reader, sz int32) ([]byte, error) { 1243 data := make([]byte, Rnd(int64(sz), 4)) 1244 _, err := io.ReadFull(r, data) 1245 if err != nil { 1246 return nil, err 1247 } 1248 data = data[:sz] 1249 return data, nil 1250 } 1251 1252 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 1253 for _, sect := range f.Sections { 1254 if sect.Type != elf.SHT_NOTE { 1255 continue 1256 } 1257 r := sect.Open() 1258 for { 1259 var namesize, descsize, noteType int32 1260 err := binary.Read(r, f.ByteOrder, &namesize) 1261 if err != nil { 1262 if err == io.EOF { 1263 break 1264 } 1265 return nil, fmt.Errorf("read namesize failed:", err) 1266 } 1267 err = binary.Read(r, f.ByteOrder, &descsize) 1268 if err != nil { 1269 return nil, fmt.Errorf("read descsize failed:", err) 1270 } 1271 err = binary.Read(r, f.ByteOrder, ¬eType) 1272 if err != nil { 1273 return nil, fmt.Errorf("read type failed:", err) 1274 } 1275 noteName, err := readwithpad(r, namesize) 1276 if err != nil { 1277 return nil, fmt.Errorf("read name failed:", err) 1278 } 1279 desc, err := readwithpad(r, descsize) 1280 if err != nil { 1281 return nil, fmt.Errorf("read desc failed:", err) 1282 } 1283 if string(name) == string(noteName) && typ == noteType { 1284 return desc, nil 1285 } 1286 } 1287 } 1288 return nil, nil 1289 } 1290 1291 func findshlib(shlib string) string { 1292 for _, libdir := range Ctxt.Libdir { 1293 libpath := filepath.Join(libdir, shlib) 1294 if _, err := os.Stat(libpath); err == nil { 1295 return libpath 1296 } 1297 } 1298 Diag("cannot find shared library: %s", shlib) 1299 return "" 1300 } 1301 1302 func ldshlibsyms(shlib string) { 1303 libpath := findshlib(shlib) 1304 if libpath == "" { 1305 return 1306 } 1307 for _, processedlib := range Ctxt.Shlibs { 1308 if processedlib.Path == libpath { 1309 return 1310 } 1311 } 1312 if Ctxt.Debugvlog > 1 && Ctxt.Bso != nil { 1313 fmt.Fprintf(Ctxt.Bso, "%5.2f ldshlibsyms: found library with name %s at %s\n", obj.Cputime(), shlib, libpath) 1314 Ctxt.Bso.Flush() 1315 } 1316 1317 f, err := elf.Open(libpath) 1318 if err != nil { 1319 Diag("cannot open shared library: %s", libpath) 1320 return 1321 } 1322 1323 hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG) 1324 if err != nil { 1325 Diag("cannot read ABI hash from shared library %s: %v", libpath, err) 1326 return 1327 } 1328 1329 depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG) 1330 if err != nil { 1331 Diag("cannot read dep list from shared library %s: %v", libpath, err) 1332 return 1333 } 1334 deps := strings.Split(string(depsbytes), "\n") 1335 1336 syms, err := f.DynamicSymbols() 1337 if err != nil { 1338 Diag("cannot read symbols from shared library: %s", libpath) 1339 return 1340 } 1341 for _, elfsym := range syms { 1342 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { 1343 continue 1344 } 1345 lsym := Linklookup(Ctxt, elfsym.Name, 0) 1346 if lsym.Type != 0 && lsym.Type != obj.SDYNIMPORT && lsym.Dupok == 0 { 1347 if (lsym.Type != obj.SBSS && lsym.Type != obj.SNOPTRBSS) || len(lsym.R) != 0 || len(lsym.P) != 0 || f.Sections[elfsym.Section].Type != elf.SHT_NOBITS { 1348 Diag("Found duplicate symbol %s reading from %s, first found in %s", elfsym.Name, shlib, lsym.File) 1349 } 1350 if lsym.Size > int64(elfsym.Size) { 1351 // If the existing symbol is a BSS value that is 1352 // larger than the one read from the shared library, 1353 // keep references to that. Conversely, if the 1354 // version from the shared libray is larger, we want 1355 // to make all references be to that. 1356 continue 1357 } 1358 } 1359 lsym.Type = obj.SDYNIMPORT 1360 lsym.ElfType = elf.ST_TYPE(elfsym.Info) 1361 lsym.Size = int64(elfsym.Size) 1362 if elfsym.Section != elf.SHN_UNDEF { 1363 // Set .File for the library that actually defines the symbol. 1364 lsym.File = libpath 1365 // The decodetype_* functions in decodetype.go need access to 1366 // the type data. 1367 if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") { 1368 lsym.P = readelfsymboldata(f, &elfsym) 1369 } 1370 } 1371 } 1372 1373 // We might have overwritten some functions above (this tends to happen for the 1374 // autogenerated type equality/hashing functions) and we don't want to generated 1375 // pcln table entries for these any more so unstitch them from the Textp linked 1376 // list. 1377 var last *LSym 1378 1379 for s := Ctxt.Textp; s != nil; s = s.Next { 1380 if s.Type == obj.SDYNIMPORT { 1381 continue 1382 } 1383 1384 if last == nil { 1385 Ctxt.Textp = s 1386 } else { 1387 last.Next = s 1388 } 1389 last = s 1390 } 1391 1392 if last == nil { 1393 Ctxt.Textp = nil 1394 Ctxt.Etextp = nil 1395 } else { 1396 last.Next = nil 1397 Ctxt.Etextp = last 1398 } 1399 1400 Ctxt.Shlibs = append(Ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f}) 1401 } 1402 1403 func mywhatsys() { 1404 goroot = obj.Getgoroot() 1405 goos = obj.Getgoos() 1406 goarch = obj.Getgoarch() 1407 1408 if !strings.HasPrefix(goarch, Thestring) { 1409 log.Fatalf("cannot use %cc with GOARCH=%s", Thearch.Thechar, goarch) 1410 } 1411 } 1412 1413 // Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync. 1414 /* 1415 * Convert raw string to the prefix that will be used in the symbol table. 1416 * Invalid bytes turn into %xx. Right now the only bytes that need 1417 * escaping are %, ., and ", but we escape all control characters too. 1418 * 1419 * If you edit this, edit ../gc/subr.c:/^pathtoprefix too. 1420 * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. 1421 */ 1422 func pathtoprefix(s string) string { 1423 slash := strings.LastIndex(s, "/") 1424 for i := 0; i < len(s); i++ { 1425 c := s[i] 1426 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 1427 var buf bytes.Buffer 1428 for i := 0; i < len(s); i++ { 1429 c := s[i] 1430 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 1431 fmt.Fprintf(&buf, "%%%02x", c) 1432 continue 1433 } 1434 buf.WriteByte(c) 1435 } 1436 return buf.String() 1437 } 1438 } 1439 return s 1440 } 1441 1442 func addsection(seg *Segment, name string, rwx int) *Section { 1443 var l **Section 1444 1445 for l = &seg.Sect; *l != nil; l = &(*l).Next { 1446 } 1447 sect := new(Section) 1448 sect.Rwx = uint8(rwx) 1449 sect.Name = name 1450 sect.Seg = seg 1451 sect.Align = int32(Thearch.Ptrsize) // everything is at least pointer-aligned 1452 *l = sect 1453 return sect 1454 } 1455 1456 func Le16(b []byte) uint16 { 1457 return uint16(b[0]) | uint16(b[1])<<8 1458 } 1459 1460 func Le32(b []byte) uint32 { 1461 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 1462 } 1463 1464 func Le64(b []byte) uint64 { 1465 return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32 1466 } 1467 1468 func Be16(b []byte) uint16 { 1469 return uint16(b[0])<<8 | uint16(b[1]) 1470 } 1471 1472 func Be32(b []byte) uint32 { 1473 return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]) 1474 } 1475 1476 func Be64(b []byte) uint64 { 1477 return uint64(Be32(b))<<32 | uint64(Be32(b[4:])) 1478 } 1479 1480 type Chain struct { 1481 sym *LSym 1482 up *Chain 1483 limit int // limit on entry to sym 1484 } 1485 1486 var morestack *LSym 1487 1488 // TODO: Record enough information in new object files to 1489 // allow stack checks here. 1490 1491 func haslinkregister() bool { 1492 return Thearch.Thechar == '5' || Thearch.Thechar == '9' || Thearch.Thechar == '7' 1493 } 1494 1495 func callsize() int { 1496 if haslinkregister() { 1497 return 0 1498 } 1499 return Thearch.Regsize 1500 } 1501 1502 func dostkcheck() { 1503 var ch Chain 1504 1505 morestack = Linklookup(Ctxt, "runtime.morestack", 0) 1506 1507 // Every splitting function ensures that there are at least StackLimit 1508 // bytes available below SP when the splitting prologue finishes. 1509 // If the splitting function calls F, then F begins execution with 1510 // at least StackLimit - callsize() bytes available. 1511 // Check that every function behaves correctly with this amount 1512 // of stack, following direct calls in order to piece together chains 1513 // of non-splitting functions. 1514 ch.up = nil 1515 1516 ch.limit = obj.StackLimit - callsize() 1517 1518 // Check every function, but do the nosplit functions in a first pass, 1519 // to make the printed failure chains as short as possible. 1520 for s := Ctxt.Textp; s != nil; s = s.Next { 1521 // runtime.racesymbolizethunk is called from gcc-compiled C 1522 // code running on the operating system thread stack. 1523 // It uses more than the usual amount of stack but that's okay. 1524 if s.Name == "runtime.racesymbolizethunk" { 1525 continue 1526 } 1527 1528 if s.Nosplit != 0 { 1529 Ctxt.Cursym = s 1530 ch.sym = s 1531 stkcheck(&ch, 0) 1532 } 1533 } 1534 1535 for s := Ctxt.Textp; s != nil; s = s.Next { 1536 if s.Nosplit == 0 { 1537 Ctxt.Cursym = s 1538 ch.sym = s 1539 stkcheck(&ch, 0) 1540 } 1541 } 1542 } 1543 1544 func stkcheck(up *Chain, depth int) int { 1545 limit := up.limit 1546 s := up.sym 1547 1548 // Don't duplicate work: only need to consider each 1549 // function at top of safe zone once. 1550 top := limit == obj.StackLimit-callsize() 1551 if top { 1552 if s.Stkcheck != 0 { 1553 return 0 1554 } 1555 s.Stkcheck = 1 1556 } 1557 1558 if depth > 100 { 1559 Diag("nosplit stack check too deep") 1560 stkbroke(up, 0) 1561 return -1 1562 } 1563 1564 if s.External != 0 || s.Pcln == nil { 1565 // external function. 1566 // should never be called directly. 1567 // only diagnose the direct caller. 1568 // TODO(mwhudson): actually think about this. 1569 if depth == 1 && s.Type != obj.SXREF && !DynlinkingGo() { 1570 Diag("call to external function %s", s.Name) 1571 } 1572 return -1 1573 } 1574 1575 if limit < 0 { 1576 stkbroke(up, limit) 1577 return -1 1578 } 1579 1580 // morestack looks like it calls functions, 1581 // but it switches the stack pointer first. 1582 if s == morestack { 1583 return 0 1584 } 1585 1586 var ch Chain 1587 ch.up = up 1588 1589 if s.Nosplit == 0 { 1590 // Ensure we have enough stack to call morestack. 1591 ch.limit = limit - callsize() 1592 ch.sym = morestack 1593 if stkcheck(&ch, depth+1) < 0 { 1594 return -1 1595 } 1596 if !top { 1597 return 0 1598 } 1599 // Raise limit to allow frame. 1600 limit = int(obj.StackLimit + s.Locals) 1601 if haslinkregister() { 1602 limit += Thearch.Regsize 1603 } 1604 } 1605 1606 // Walk through sp adjustments in function, consuming relocs. 1607 ri := 0 1608 1609 endr := len(s.R) 1610 var ch1 Chain 1611 var pcsp Pciter 1612 var r *Reloc 1613 for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1614 // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). 1615 1616 // Check stack size in effect for this span. 1617 if int32(limit)-pcsp.value < 0 { 1618 stkbroke(up, int(int32(limit)-pcsp.value)) 1619 return -1 1620 } 1621 1622 // Process calls in this span. 1623 for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ { 1624 r = &s.R[ri] 1625 switch r.Type { 1626 // Direct call. 1627 case obj.R_CALL, obj.R_CALLARM, obj.R_CALLARM64, obj.R_CALLPOWER: 1628 ch.limit = int(int32(limit) - pcsp.value - int32(callsize())) 1629 ch.sym = r.Sym 1630 if stkcheck(&ch, depth+1) < 0 { 1631 return -1 1632 } 1633 1634 // Indirect call. Assume it is a call to a splitting function, 1635 // so we have to make sure it can call morestack. 1636 // Arrange the data structures to report both calls, so that 1637 // if there is an error, stkprint shows all the steps involved. 1638 case obj.R_CALLIND: 1639 ch.limit = int(int32(limit) - pcsp.value - int32(callsize())) 1640 1641 ch.sym = nil 1642 ch1.limit = ch.limit - callsize() // for morestack in called prologue 1643 ch1.up = &ch 1644 ch1.sym = morestack 1645 if stkcheck(&ch1, depth+2) < 0 { 1646 return -1 1647 } 1648 } 1649 } 1650 } 1651 1652 return 0 1653 } 1654 1655 func stkbroke(ch *Chain, limit int) { 1656 Diag("nosplit stack overflow") 1657 stkprint(ch, limit) 1658 } 1659 1660 func stkprint(ch *Chain, limit int) { 1661 var name string 1662 1663 if ch.sym != nil { 1664 name = ch.sym.Name 1665 if ch.sym.Nosplit != 0 { 1666 name += " (nosplit)" 1667 } 1668 } else { 1669 name = "function pointer" 1670 } 1671 1672 if ch.up == nil { 1673 // top of chain. ch->sym != nil. 1674 if ch.sym.Nosplit != 0 { 1675 fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name) 1676 } else { 1677 fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name) 1678 } 1679 } else { 1680 stkprint(ch.up, ch.limit+callsize()) 1681 if !haslinkregister() { 1682 fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name) 1683 } 1684 } 1685 1686 if ch.limit != limit { 1687 fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit) 1688 } 1689 } 1690 1691 func Yconv(s *LSym) string { 1692 var fp string 1693 1694 if s == nil { 1695 fp += fmt.Sprintf("<nil>") 1696 } else { 1697 fmt_ := "" 1698 fmt_ += fmt.Sprintf("%s @0x%08x [%d]", s.Name, int64(s.Value), int64(s.Size)) 1699 for i := 0; int64(i) < s.Size; i++ { 1700 if i%8 == 0 { 1701 fmt_ += fmt.Sprintf("\n\t0x%04x ", i) 1702 } 1703 fmt_ += fmt.Sprintf("%02x ", s.P[i]) 1704 } 1705 1706 fmt_ += fmt.Sprintf("\n") 1707 for i := 0; i < len(s.R); i++ { 1708 fmt_ += fmt.Sprintf("\t0x%04x[%x] %d %s[%x]\n", s.R[i].Off, s.R[i].Siz, s.R[i].Type, s.R[i].Sym.Name, int64(s.R[i].Add)) 1709 } 1710 1711 str := fmt_ 1712 fp += str 1713 } 1714 1715 return fp 1716 } 1717 1718 func Cflush() { 1719 if err := coutbuf.Writer.Flush(); err != nil { 1720 Exitf("flushing %s: %v", coutbuf.f.Name(), err) 1721 } 1722 } 1723 1724 func Cpos() int64 { 1725 off, err := coutbuf.f.Seek(0, 1) 1726 if err != nil { 1727 Exitf("seeking in output [0, 1]: %v", err) 1728 } 1729 return off + int64(coutbuf.Buffered()) 1730 } 1731 1732 func Cseek(p int64) { 1733 Cflush() 1734 if _, err := coutbuf.f.Seek(p, 0); err != nil { 1735 Exitf("seeking in output [0, 1]: %v", err) 1736 } 1737 } 1738 1739 func Cwrite(p []byte) { 1740 coutbuf.Write(p) 1741 } 1742 1743 func Cput(c uint8) { 1744 coutbuf.WriteByte(c) 1745 } 1746 1747 func usage() { 1748 fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n") 1749 obj.Flagprint(2) 1750 Exit(2) 1751 } 1752 1753 func setheadtype(s string) { 1754 h := headtype(s) 1755 if h < 0 { 1756 Exitf("unknown header type -H %s", s) 1757 } 1758 1759 headstring = s 1760 HEADTYPE = int32(headtype(s)) 1761 } 1762 1763 func setinterp(s string) { 1764 Debug['I'] = 1 // denote cmdline interpreter override 1765 interpreter = s 1766 } 1767 1768 func doversion() { 1769 Exitf("version %s", obj.Getgoversion()) 1770 } 1771 1772 func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) { 1773 // These symbols won't show up in the first loop below because we 1774 // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. 1775 s := Linklookup(Ctxt, "runtime.text", 0) 1776 1777 if s.Type == obj.STEXT { 1778 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil) 1779 } 1780 s = Linklookup(Ctxt, "runtime.etext", 0) 1781 if s.Type == obj.STEXT { 1782 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil) 1783 } 1784 1785 for s := Ctxt.Allsym; s != nil; s = s.Allsym { 1786 if s.Hide != 0 || (s.Name[0] == '.' && s.Version == 0 && s.Name != ".rathole") { 1787 continue 1788 } 1789 switch s.Type & obj.SMASK { 1790 case obj.SCONST, 1791 obj.SRODATA, 1792 obj.SSYMTAB, 1793 obj.SPCLNTAB, 1794 obj.SINITARR, 1795 obj.SDATA, 1796 obj.SNOPTRDATA, 1797 obj.SELFROSECT, 1798 obj.SMACHOGOT, 1799 obj.STYPE, 1800 obj.SSTRING, 1801 obj.SGOSTRING, 1802 obj.SGOFUNC, 1803 obj.SGCBITS, 1804 obj.SWINDOWS: 1805 if !s.Reachable { 1806 continue 1807 } 1808 put(s, s.Name, 'D', Symaddr(s), s.Size, int(s.Version), s.Gotype) 1809 1810 case obj.SBSS, obj.SNOPTRBSS: 1811 if !s.Reachable { 1812 continue 1813 } 1814 if len(s.P) > 0 { 1815 Diag("%s should not be bss (size=%d type=%d special=%d)", s.Name, int(len(s.P)), s.Type, s.Special) 1816 } 1817 put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype) 1818 1819 case obj.SFILE: 1820 put(nil, s.Name, 'f', s.Value, 0, int(s.Version), nil) 1821 1822 case obj.SHOSTOBJ: 1823 if HEADTYPE == obj.Hwindows || Iself { 1824 put(s, s.Name, 'U', s.Value, 0, int(s.Version), nil) 1825 } 1826 1827 case obj.SDYNIMPORT: 1828 if !s.Reachable { 1829 continue 1830 } 1831 put(s, s.Extname, 'U', 0, 0, int(s.Version), nil) 1832 1833 case obj.STLSBSS: 1834 if Linkmode == LinkExternal && HEADTYPE != obj.Hopenbsd { 1835 var type_ int 1836 if goos == "android" { 1837 type_ = 'B' 1838 } else { 1839 type_ = 't' 1840 } 1841 put(s, s.Name, type_, Symaddr(s), s.Size, int(s.Version), s.Gotype) 1842 } 1843 } 1844 } 1845 1846 var a *Auto 1847 var off int32 1848 for s := Ctxt.Textp; s != nil; s = s.Next { 1849 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype) 1850 1851 // NOTE(ality): acid can't produce a stack trace without .frame symbols 1852 put(nil, ".frame", 'm', int64(s.Locals)+int64(Thearch.Ptrsize), 0, 0, nil) 1853 1854 for a = s.Autom; a != nil; a = a.Link { 1855 // Emit a or p according to actual offset, even if label is wrong. 1856 // This avoids negative offsets, which cannot be encoded. 1857 if a.Name != obj.A_AUTO && a.Name != obj.A_PARAM { 1858 continue 1859 } 1860 1861 // compute offset relative to FP 1862 if a.Name == obj.A_PARAM { 1863 off = a.Aoffset 1864 } else { 1865 off = a.Aoffset - int32(Thearch.Ptrsize) 1866 } 1867 1868 // FP 1869 if off >= 0 { 1870 put(nil, a.Asym.Name, 'p', int64(off), 0, 0, a.Gotype) 1871 continue 1872 } 1873 1874 // SP 1875 if off <= int32(-Thearch.Ptrsize) { 1876 put(nil, a.Asym.Name, 'a', -(int64(off) + int64(Thearch.Ptrsize)), 0, 0, a.Gotype) 1877 continue 1878 } 1879 } 1880 } 1881 1882 // Otherwise, off is addressing the saved program counter. 1883 // Something underhanded is going on. Say nothing. 1884 if Debug['v'] != 0 || Debug['n'] != 0 { 1885 fmt.Fprintf(&Bso, "%5.2f symsize = %d\n", obj.Cputime(), uint32(Symsize)) 1886 } 1887 Bso.Flush() 1888 } 1889 1890 func Symaddr(s *LSym) int64 { 1891 if !s.Reachable { 1892 Diag("unreachable symbol in symaddr - %s", s.Name) 1893 } 1894 return s.Value 1895 } 1896 1897 func xdefine(p string, t int, v int64) { 1898 s := Linklookup(Ctxt, p, 0) 1899 s.Type = int16(t) 1900 s.Value = v 1901 s.Reachable = true 1902 s.Special = 1 1903 s.Local = true 1904 } 1905 1906 func datoff(addr int64) int64 { 1907 if uint64(addr) >= Segdata.Vaddr { 1908 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) 1909 } 1910 if uint64(addr) >= Segtext.Vaddr { 1911 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) 1912 } 1913 Diag("datoff %#x", addr) 1914 return 0 1915 } 1916 1917 func Entryvalue() int64 { 1918 a := INITENTRY 1919 if a[0] >= '0' && a[0] <= '9' { 1920 return atolwhex(a) 1921 } 1922 s := Linklookup(Ctxt, a, 0) 1923 if s.Type == 0 { 1924 return INITTEXT 1925 } 1926 if s.Type != obj.STEXT { 1927 Diag("entry not text: %s", s.Name) 1928 } 1929 return s.Value 1930 } 1931 1932 func undefsym(s *LSym) { 1933 var r *Reloc 1934 1935 Ctxt.Cursym = s 1936 for i := 0; i < len(s.R); i++ { 1937 r = &s.R[i] 1938 if r.Sym == nil { // happens for some external ARM relocs 1939 continue 1940 } 1941 if r.Sym.Type == obj.Sxxx || r.Sym.Type == obj.SXREF { 1942 Diag("undefined: %s", r.Sym.Name) 1943 } 1944 if !r.Sym.Reachable { 1945 Diag("use of unreachable symbol: %s", r.Sym.Name) 1946 } 1947 } 1948 } 1949 1950 func undef() { 1951 for s := Ctxt.Textp; s != nil; s = s.Next { 1952 undefsym(s) 1953 } 1954 for s := datap; s != nil; s = s.Next { 1955 undefsym(s) 1956 } 1957 if nerrors > 0 { 1958 errorexit() 1959 } 1960 } 1961 1962 func callgraph() { 1963 if Debug['c'] == 0 { 1964 return 1965 } 1966 1967 var i int 1968 var r *Reloc 1969 for s := Ctxt.Textp; s != nil; s = s.Next { 1970 for i = 0; i < len(s.R); i++ { 1971 r = &s.R[i] 1972 if r.Sym == nil { 1973 continue 1974 } 1975 if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM || r.Type == obj.R_CALLPOWER) && r.Sym.Type == obj.STEXT { 1976 fmt.Fprintf(&Bso, "%s calls %s\n", s.Name, r.Sym.Name) 1977 } 1978 } 1979 } 1980 } 1981 1982 func Diag(format string, args ...interface{}) { 1983 tn := "" 1984 sep := "" 1985 if Ctxt.Cursym != nil { 1986 tn = Ctxt.Cursym.Name 1987 sep = ": " 1988 } 1989 fmt.Printf("%s%s%s\n", tn, sep, fmt.Sprintf(format, args...)) 1990 nerrors++ 1991 if Debug['h'] != 0 { 1992 panic("error") 1993 } 1994 if nerrors > 20 { 1995 Exitf("too many errors") 1996 } 1997 } 1998 1999 func checkgo() { 2000 if Debug['C'] == 0 { 2001 return 2002 } 2003 2004 // TODO(rsc,khr): Eventually we want to get to no Go-called C functions at all, 2005 // which would simplify this logic quite a bit. 2006 2007 // Mark every Go-called C function with cfunc=2, recursively. 2008 var changed int 2009 var i int 2010 var r *Reloc 2011 var s *LSym 2012 for { 2013 changed = 0 2014 for s = Ctxt.Textp; s != nil; s = s.Next { 2015 if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) { 2016 for i = 0; i < len(s.R); i++ { 2017 r = &s.R[i] 2018 if r.Sym == nil { 2019 continue 2020 } 2021 if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM) && r.Sym.Type == obj.STEXT { 2022 if r.Sym.Cfunc == 1 { 2023 changed = 1 2024 r.Sym.Cfunc = 2 2025 } 2026 } 2027 } 2028 } 2029 } 2030 if changed == 0 { 2031 break 2032 } 2033 } 2034 2035 // Complain about Go-called C functions that can split the stack 2036 // (that can be preempted for garbage collection or trigger a stack copy). 2037 for s := Ctxt.Textp; s != nil; s = s.Next { 2038 if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) { 2039 for i = 0; i < len(s.R); i++ { 2040 r = &s.R[i] 2041 if r.Sym == nil { 2042 continue 2043 } 2044 if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM) && r.Sym.Type == obj.STEXT { 2045 if s.Cfunc == 0 && r.Sym.Cfunc == 2 && r.Sym.Nosplit == 0 { 2046 fmt.Printf("Go %s calls C %s\n", s.Name, r.Sym.Name) 2047 } else if s.Cfunc == 2 && s.Nosplit != 0 && r.Sym.Nosplit == 0 { 2048 fmt.Printf("Go calls C %s calls %s\n", s.Name, r.Sym.Name) 2049 } 2050 } 2051 } 2052 } 2053 } 2054 } 2055 2056 func Rnd(v int64, r int64) int64 { 2057 if r <= 0 { 2058 return v 2059 } 2060 v += r - 1 2061 c := v % r 2062 if c < 0 { 2063 c += r 2064 } 2065 v -= c 2066 return v 2067 }