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 (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 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 (a] 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 (a] 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 // Now that we know the link mode, trim the dynexp list. 568 x := CgoExportDynamic 569 570 if Linkmode == LinkExternal { 571 x = CgoExportStatic 572 } 573 w := 0 574 for i := 0; i < len(dynexp); i++ { 575 if int(dynexp[i].Cgoexport)&x != 0 { 576 dynexp[w] = dynexp[i] 577 w++ 578 } 579 } 580 dynexp = dynexp[:w] 581 582 // In internal link mode, read the host object files. 583 if Linkmode == LinkInternal { 584 hostobjs() 585 } else { 586 hostlinksetup() 587 } 588 589 // We've loaded all the code now. 590 // If there are no dynamic libraries needed, gcc disables dynamic linking. 591 // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13) 592 // assumes that a dynamic binary always refers to at least one dynamic library. 593 // Rather than be a source of test cases for glibc, disable dynamic linking 594 // the same way that gcc would. 595 // 596 // Exception: on OS X, programs such as Shark only work with dynamic 597 // binaries, so leave it enabled on OS X (Mach-O) binaries. 598 // Also leave it enabled on Solaris which doesn't support 599 // statically linked binaries. 600 if Buildmode == BuildmodeExe && havedynamic == 0 && HEADTYPE != obj.Hdarwin && HEADTYPE != obj.Hsolaris { 601 Debug['d'] = 1 602 } 603 604 importcycles() 605 } 606 607 /* 608 * look for the next file in an archive. 609 * adapted from libmach. 610 */ 611 func nextar(bp *obj.Biobuf, off int64, a *ArHdr) int64 { 612 if off&1 != 0 { 613 off++ 614 } 615 obj.Bseek(bp, off, 0) 616 buf := make([]byte, SAR_HDR) 617 if n := obj.Bread(bp, buf); n < len(buf) { 618 if n >= 0 { 619 return 0 620 } 621 return -1 622 } 623 624 a.name = artrim(buf[0:16]) 625 a.date = artrim(buf[16:28]) 626 a.uid = artrim(buf[28:34]) 627 a.gid = artrim(buf[34:40]) 628 a.mode = artrim(buf[40:48]) 629 a.size = artrim(buf[48:58]) 630 a.fmag = artrim(buf[58:60]) 631 632 arsize := atolwhex(a.size) 633 if arsize&1 != 0 { 634 arsize++ 635 } 636 return int64(arsize) + SAR_HDR 637 } 638 639 func objfile(lib *Library) { 640 pkg := pathtoprefix(lib.Pkg) 641 642 if Debug['v'] > 1 { 643 fmt.Fprintf(&Bso, "%5.2f ldobj: %s (%s)\n", obj.Cputime(), lib.File, pkg) 644 } 645 Bso.Flush() 646 var err error 647 var f *obj.Biobuf 648 f, err = obj.Bopenr(lib.File) 649 if err != nil { 650 Exitf("cannot open file %s: %v", lib.File, err) 651 } 652 653 magbuf := make([]byte, len(ARMAG)) 654 if obj.Bread(f, magbuf) != len(magbuf) || !strings.HasPrefix(string(magbuf), ARMAG) { 655 /* load it as a regular file */ 656 l := obj.Bseek(f, 0, 2) 657 658 obj.Bseek(f, 0, 0) 659 ldobj(f, pkg, l, lib.File, lib.File, FileObj) 660 obj.Bterm(f) 661 662 return 663 } 664 665 /* skip over optional __.GOSYMDEF and process __.PKGDEF */ 666 off := obj.Boffset(f) 667 668 var arhdr ArHdr 669 l := nextar(f, off, &arhdr) 670 var pname string 671 if l <= 0 { 672 Diag("%s: short read on archive file symbol header", lib.File) 673 goto out 674 } 675 676 if strings.HasPrefix(arhdr.name, symname) { 677 off += l 678 l = nextar(f, off, &arhdr) 679 if l <= 0 { 680 Diag("%s: short read on archive file symbol header", lib.File) 681 goto out 682 } 683 } 684 685 if !strings.HasPrefix(arhdr.name, pkgname) { 686 Diag("%s: cannot find package header", lib.File) 687 goto out 688 } 689 690 if Buildmode == BuildmodeShared { 691 before := obj.Boffset(f) 692 pkgdefBytes := make([]byte, atolwhex(arhdr.size)) 693 obj.Bread(f, pkgdefBytes) 694 hash := sha1.Sum(pkgdefBytes) 695 lib.hash = hash[:] 696 obj.Bseek(f, before, 0) 697 } 698 699 off += l 700 701 if Debug['u'] != 0 { 702 ldpkg(f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef) 703 } 704 705 /* 706 * load all the object files from the archive now. 707 * this gives us sequential file access and keeps us 708 * from needing to come back later to pick up more 709 * objects. it breaks the usual C archive model, but 710 * this is Go, not C. the common case in Go is that 711 * we need to load all the objects, and then we throw away 712 * the individual symbols that are unused. 713 * 714 * loading every object will also make it possible to 715 * load foreign objects not referenced by __.GOSYMDEF. 716 */ 717 for { 718 l = nextar(f, off, &arhdr) 719 if l == 0 { 720 break 721 } 722 if l < 0 { 723 Exitf("%s: malformed archive", lib.File) 724 } 725 726 off += l 727 728 pname = fmt.Sprintf("%s(%s)", lib.File, arhdr.name) 729 l = atolwhex(arhdr.size) 730 ldobj(f, pkg, l, pname, lib.File, ArchiveObj) 731 } 732 733 out: 734 obj.Bterm(f) 735 } 736 737 type Hostobj struct { 738 ld func(*obj.Biobuf, string, int64, string) 739 pkg string 740 pn string 741 file string 742 off int64 743 length int64 744 } 745 746 var hostobj []Hostobj 747 748 // These packages can use internal linking mode. 749 // Others trigger external mode. 750 var internalpkg = []string{ 751 "crypto/x509", 752 "net", 753 "os/user", 754 "runtime/cgo", 755 "runtime/race", 756 } 757 758 func ldhostobj(ld func(*obj.Biobuf, string, int64, string), f *obj.Biobuf, pkg string, length int64, pn string, file string) { 759 isinternal := false 760 for i := 0; i < len(internalpkg); i++ { 761 if pkg == internalpkg[i] { 762 isinternal = true 763 break 764 } 765 } 766 767 // DragonFly declares errno with __thread, which results in a symbol 768 // type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not 769 // currently know how to handle TLS relocations, hence we have to 770 // force external linking for any libraries that link in code that 771 // uses errno. This can be removed if the Go linker ever supports 772 // these relocation types. 773 if HEADTYPE == obj.Hdragonfly { 774 if pkg == "net" || pkg == "os/user" { 775 isinternal = false 776 } 777 } 778 779 if !isinternal { 780 externalobj = true 781 } 782 783 hostobj = append(hostobj, Hostobj{}) 784 h := &hostobj[len(hostobj)-1] 785 h.ld = ld 786 h.pkg = pkg 787 h.pn = pn 788 h.file = file 789 h.off = obj.Boffset(f) 790 h.length = length 791 } 792 793 func hostobjs() { 794 var f *obj.Biobuf 795 var h *Hostobj 796 797 for i := 0; i < len(hostobj); i++ { 798 h = &hostobj[i] 799 var err error 800 f, err = obj.Bopenr(h.file) 801 if f == nil { 802 Exitf("cannot reopen %s: %v", h.pn, err) 803 } 804 805 obj.Bseek(f, h.off, 0) 806 h.ld(f, h.pkg, h.length, h.pn) 807 obj.Bterm(f) 808 } 809 } 810 811 // provided by lib9 812 813 func rmtemp() { 814 os.RemoveAll(tmpdir) 815 } 816 817 func hostlinksetup() { 818 if Linkmode != LinkExternal { 819 return 820 } 821 822 // For external link, record that we need to tell the external linker -s, 823 // and turn off -s internally: the external linker needs the symbol 824 // information for its final link. 825 debug_s = Debug['s'] 826 Debug['s'] = 0 827 828 // create temporary directory and arrange cleanup 829 if tmpdir == "" { 830 dir, err := ioutil.TempDir("", "go-link-") 831 if err != nil { 832 log.Fatal(err) 833 } 834 tmpdir = dir 835 AtExit(rmtemp) 836 } 837 838 // change our output to temporary object file 839 coutbuf.f.Close() 840 mayberemoveoutfile() 841 842 p := fmt.Sprintf("%s/go.o", tmpdir) 843 var err error 844 f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775) 845 if err != nil { 846 Exitf("cannot create %s: %v", p, err) 847 } 848 849 coutbuf.Writer = bufio.NewWriter(f) 850 coutbuf.f = f 851 } 852 853 // hostobjCopy creates a copy of the object files in hostobj in a 854 // temporary directory. 855 func hostobjCopy() (paths []string) { 856 for i, h := range hostobj { 857 f, err := os.Open(h.file) 858 if err != nil { 859 Exitf("cannot reopen %s: %v", h.pn, err) 860 } 861 if _, err := f.Seek(h.off, 0); err != nil { 862 Exitf("cannot seek %s: %v", h.pn, err) 863 } 864 865 p := fmt.Sprintf("%s/%06d.o", tmpdir, i) 866 paths = append(paths, p) 867 w, err := os.Create(p) 868 if err != nil { 869 Exitf("cannot create %s: %v", p, err) 870 } 871 if _, err := io.CopyN(w, f, h.length); err != nil { 872 Exitf("cannot write %s: %v", p, err) 873 } 874 if err := w.Close(); err != nil { 875 Exitf("cannot close %s: %v", p, err) 876 } 877 } 878 return paths 879 } 880 881 // archive builds a .a archive from the hostobj object files. 882 func archive() { 883 if Buildmode != BuildmodeCArchive { 884 return 885 } 886 887 mayberemoveoutfile() 888 argv := []string{"ar", "-q", "-c", "-s", outfile} 889 argv = append(argv, hostobjCopy()...) 890 argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir)) 891 892 if Debug['v'] != 0 { 893 fmt.Fprintf(&Bso, "archive: %s\n", strings.Join(argv, " ")) 894 Bso.Flush() 895 } 896 897 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 898 Exitf("running %s failed: %v\n%s", argv[0], err, out) 899 } 900 } 901 902 func hostlink() { 903 if Linkmode != LinkExternal || nerrors > 0 { 904 return 905 } 906 if Buildmode == BuildmodeCArchive { 907 return 908 } 909 910 if extld == "" { 911 extld = "gcc" 912 } 913 914 var argv []string 915 argv = append(argv, extld) 916 switch Thearch.Thechar { 917 case '8': 918 argv = append(argv, "-m32") 919 920 case '6', '9': 921 argv = append(argv, "-m64") 922 923 case '5': 924 argv = append(argv, "-marm") 925 926 case '7': 927 // nothing needed 928 } 929 930 if Debug['s'] == 0 && debug_s == 0 { 931 argv = append(argv, "-gdwarf-2") 932 } else { 933 argv = append(argv, "-s") 934 } 935 936 if HEADTYPE == obj.Hdarwin { 937 argv = append(argv, "-Wl,-no_pie,-headerpad,1144") 938 } 939 if HEADTYPE == obj.Hopenbsd { 940 argv = append(argv, "-Wl,-nopie") 941 } 942 if HEADTYPE == obj.Hwindows { 943 if headstring == "windowsgui" { 944 argv = append(argv, "-mwindows") 945 } else { 946 argv = append(argv, "-mconsole") 947 } 948 } 949 950 if Iself && AssumeGoldLinker != 0 /*TypeKind(100016)*/ { 951 argv = append(argv, "-Wl,--rosegment") 952 } 953 954 switch Buildmode { 955 case BuildmodeExe: 956 if HEADTYPE == obj.Hdarwin { 957 argv = append(argv, "-Wl,-pagezero_size,4000000") 958 } 959 case BuildmodeCShared: 960 if HEADTYPE == obj.Hdarwin { 961 argv = append(argv, "-dynamiclib") 962 } else { 963 argv = append(argv, "-Wl,-Bsymbolic") 964 argv = append(argv, "-shared") 965 } 966 case BuildmodeShared: 967 // TODO(mwhudson): unless you do this, dynamic relocations fill 968 // out the findfunctab table and for some reason shared libraries 969 // and the executable both define a main function and putting the 970 // address of executable's main into the shared libraries 971 // findfunctab violates the assumptions of the runtime. TBH, I 972 // think we may well end up wanting to use -Bsymbolic here 973 // anyway. 974 argv = append(argv, "-Wl,-Bsymbolic-functions") 975 argv = append(argv, "-shared") 976 } 977 978 if Linkshared && Iself { 979 // We force all symbol resolution to be done at program startup 980 // because lazy PLT resolution can use large amounts of stack at 981 // times we cannot allow it to do so. 982 argv = append(argv, "-Wl,-znow") 983 } 984 985 if Iself && len(buildinfo) > 0 { 986 argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo)) 987 } 988 989 // On Windows, given -o foo, GCC will append ".exe" to produce 990 // "foo.exe". We have decided that we want to honor the -o 991 // option. To make this work, we append a '.' so that GCC 992 // will decide that the file already has an extension. We 993 // only want to do this when producing a Windows output file 994 // on a Windows host. 995 outopt := outfile 996 if goos == "windows" && runtime.GOOS == "windows" && filepath.Ext(outopt) == "" { 997 outopt += "." 998 } 999 argv = append(argv, "-o") 1000 argv = append(argv, outopt) 1001 1002 if rpath.val != "" { 1003 argv = append(argv, fmt.Sprintf("-Wl,-rpath,%s", rpath.val)) 1004 } 1005 1006 // Force global symbols to be exported for dlopen, etc. 1007 if Iself { 1008 argv = append(argv, "-rdynamic") 1009 } 1010 1011 if strings.Contains(argv[0], "clang") { 1012 argv = append(argv, "-Qunused-arguments") 1013 } 1014 1015 argv = append(argv, hostobjCopy()...) 1016 argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir)) 1017 1018 if Linkshared { 1019 seenDirs := make(map[string]bool) 1020 seenLibs := make(map[string]bool) 1021 addshlib := func(path string) { 1022 dir, base := filepath.Split(path) 1023 if !seenDirs[dir] { 1024 argv = append(argv, "-L"+dir) 1025 if !rpath.set { 1026 argv = append(argv, "-Wl,-rpath="+dir) 1027 } 1028 seenDirs[dir] = true 1029 } 1030 base = strings.TrimSuffix(base, ".so") 1031 base = strings.TrimPrefix(base, "lib") 1032 if !seenLibs[base] { 1033 argv = append(argv, "-l"+base) 1034 seenLibs[base] = true 1035 } 1036 } 1037 for _, shlib := range Ctxt.Shlibs { 1038 addshlib(shlib.Path) 1039 for _, dep := range shlib.Deps { 1040 if dep == "" { 1041 continue 1042 } 1043 libpath := findshlib(dep) 1044 if libpath != "" { 1045 addshlib(libpath) 1046 } 1047 } 1048 } 1049 } 1050 1051 argv = append(argv, ldflag...) 1052 1053 for _, p := range strings.Fields(extldflags) { 1054 argv = append(argv, p) 1055 1056 // clang, unlike GCC, passes -rdynamic to the linker 1057 // even when linking with -static, causing a linker 1058 // error when using GNU ld. So take out -rdynamic if 1059 // we added it. We do it in this order, rather than 1060 // only adding -rdynamic later, so that -extldflags 1061 // can override -rdynamic without using -static. 1062 if Iself && p == "-static" { 1063 for i := range argv { 1064 if argv[i] == "-rdynamic" { 1065 argv[i] = "-static" 1066 } 1067 } 1068 } 1069 } 1070 if HEADTYPE == obj.Hwindows { 1071 argv = append(argv, peimporteddlls()...) 1072 } 1073 1074 if Debug['v'] != 0 { 1075 fmt.Fprintf(&Bso, "host link:") 1076 for _, v := range argv { 1077 fmt.Fprintf(&Bso, " %q", v) 1078 } 1079 fmt.Fprintf(&Bso, "\n") 1080 Bso.Flush() 1081 } 1082 1083 if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { 1084 Exitf("running %s failed: %v\n%s", argv[0], err, out) 1085 } else if Debug['v'] != 0 && len(out) > 0 { 1086 fmt.Fprintf(&Bso, "%s", out) 1087 Bso.Flush() 1088 } 1089 1090 if Debug['s'] == 0 && debug_s == 0 && HEADTYPE == obj.Hdarwin { 1091 // Skip combining dwarf on arm. 1092 if Thearch.Thechar != '5' && Thearch.Thechar != '7' { 1093 dsym := fmt.Sprintf("%s/go.dwarf", tmpdir) 1094 if out, err := exec.Command("dsymutil", "-f", outfile, "-o", dsym).CombinedOutput(); err != nil { 1095 Ctxt.Cursym = nil 1096 Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out) 1097 } 1098 // For os.Rename to work reliably, must be in same directory as outfile. 1099 combinedOutput := outfile + "~" 1100 if err := machoCombineDwarf(outfile, dsym, combinedOutput); err != nil { 1101 Ctxt.Cursym = nil 1102 Exitf("%s: combining dwarf failed: %v", os.Args[0], err) 1103 } 1104 os.Remove(outfile) 1105 if err := os.Rename(combinedOutput, outfile); err != nil { 1106 Ctxt.Cursym = nil 1107 Exitf("%s: %v", os.Args[0], err) 1108 } 1109 } 1110 } 1111 } 1112 1113 func ldobj(f *obj.Biobuf, pkg string, length int64, pn string, file string, whence int) { 1114 eof := obj.Boffset(f) + length 1115 1116 start := obj.Boffset(f) 1117 c1 := obj.Bgetc(f) 1118 c2 := obj.Bgetc(f) 1119 c3 := obj.Bgetc(f) 1120 c4 := obj.Bgetc(f) 1121 obj.Bseek(f, start, 0) 1122 1123 magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) 1124 if magic == 0x7f454c46 { // \x7F E L F 1125 ldhostobj(ldelf, f, pkg, length, pn, file) 1126 return 1127 } 1128 1129 if magic&^1 == 0xfeedface || magic&^0x01000000 == 0xcefaedfe { 1130 ldhostobj(ldmacho, f, pkg, length, pn, file) 1131 return 1132 } 1133 1134 if c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86 { 1135 ldhostobj(ldpe, f, pkg, length, pn, file) 1136 return 1137 } 1138 1139 /* check the header */ 1140 line := obj.Brdline(f, '\n') 1141 if line == "" { 1142 if obj.Blinelen(f) > 0 { 1143 Diag("%s: not an object file", pn) 1144 return 1145 } 1146 Diag("truncated object file: %s", pn) 1147 return 1148 } 1149 1150 if !strings.HasPrefix(line, "go object ") { 1151 if strings.HasSuffix(pn, ".go") { 1152 Exitf("%cl: input %s is not .%c file (use %cg to compile .go files)", Thearch.Thechar, pn, Thearch.Thechar, Thearch.Thechar) 1153 } 1154 1155 if line == Thestring { 1156 // old header format: just $GOOS 1157 Diag("%s: stale object file", pn) 1158 return 1159 } 1160 1161 Diag("%s: not an object file", pn) 1162 return 1163 } 1164 1165 // First, check that the basic goos, goarch, and version match. 1166 t := fmt.Sprintf("%s %s %s ", goos, obj.Getgoarch(), obj.Getgoversion()) 1167 1168 line = strings.TrimRight(line, "\n") 1169 if !strings.HasPrefix(line[10:]+" ", t) && Debug['f'] == 0 { 1170 Diag("%s: object is [%s] expected [%s]", pn, line[10:], t) 1171 return 1172 } 1173 1174 // Second, check that longer lines match each other exactly, 1175 // so that the Go compiler and write additional information 1176 // that must be the same from run to run. 1177 if len(line) >= len(t)+10 { 1178 if theline == "" { 1179 theline = line[10:] 1180 } else if theline != line[10:] { 1181 Diag("%s: object is [%s] expected [%s]", pn, line[10:], theline) 1182 return 1183 } 1184 } 1185 1186 /* skip over exports and other info -- ends with \n!\n */ 1187 import0 := obj.Boffset(f) 1188 1189 c1 = '\n' // the last line ended in \n 1190 c2 = obj.Bgetc(f) 1191 c3 = obj.Bgetc(f) 1192 for c1 != '\n' || c2 != '!' || c3 != '\n' { 1193 c1 = c2 1194 c2 = c3 1195 c3 = obj.Bgetc(f) 1196 if c3 == obj.Beof { 1197 Diag("truncated object file: %s", pn) 1198 return 1199 } 1200 } 1201 1202 import1 := obj.Boffset(f) 1203 1204 obj.Bseek(f, import0, 0) 1205 ldpkg(f, pkg, import1-import0-2, pn, whence) // -2 for !\n 1206 obj.Bseek(f, import1, 0) 1207 1208 ldobjfile(Ctxt, f, pkg, eof-obj.Boffset(f), pn) 1209 } 1210 1211 func readelfsymboldata(f *elf.File, sym *elf.Symbol) []byte { 1212 data := make([]byte, sym.Size) 1213 sect := f.Sections[sym.Section] 1214 if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE { 1215 Diag("reading %s from non-data section", sym.Name) 1216 } 1217 n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr)) 1218 if uint64(n) != sym.Size { 1219 Diag("reading contents of %s: %v", sym.Name, err) 1220 } 1221 return data 1222 } 1223 1224 func readwithpad(r io.Reader, sz int32) ([]byte, error) { 1225 data := make([]byte, Rnd(int64(sz), 4)) 1226 _, err := io.ReadFull(r, data) 1227 if err != nil { 1228 return nil, err 1229 } 1230 data = data[:sz] 1231 return data, nil 1232 } 1233 1234 func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 1235 for _, sect := range f.Sections { 1236 if sect.Type != elf.SHT_NOTE { 1237 continue 1238 } 1239 r := sect.Open() 1240 for { 1241 var namesize, descsize, noteType int32 1242 err := binary.Read(r, f.ByteOrder, &namesize) 1243 if err != nil { 1244 if err == io.EOF { 1245 break 1246 } 1247 return nil, fmt.Errorf("read namesize failed:", err) 1248 } 1249 err = binary.Read(r, f.ByteOrder, &descsize) 1250 if err != nil { 1251 return nil, fmt.Errorf("read descsize failed:", err) 1252 } 1253 err = binary.Read(r, f.ByteOrder, ¬eType) 1254 if err != nil { 1255 return nil, fmt.Errorf("read type failed:", err) 1256 } 1257 noteName, err := readwithpad(r, namesize) 1258 if err != nil { 1259 return nil, fmt.Errorf("read name failed:", err) 1260 } 1261 desc, err := readwithpad(r, descsize) 1262 if err != nil { 1263 return nil, fmt.Errorf("read desc failed:", err) 1264 } 1265 if string(name) == string(noteName) && typ == noteType { 1266 return desc, nil 1267 } 1268 } 1269 } 1270 return nil, nil 1271 } 1272 1273 func findshlib(shlib string) string { 1274 for _, libdir := range Ctxt.Libdir { 1275 libpath := filepath.Join(libdir, shlib) 1276 if _, err := os.Stat(libpath); err == nil { 1277 return libpath 1278 } 1279 } 1280 Diag("cannot find shared library: %s", shlib) 1281 return "" 1282 } 1283 1284 func ldshlibsyms(shlib string) { 1285 libpath := findshlib(shlib) 1286 if libpath == "" { 1287 return 1288 } 1289 for _, processedlib := range Ctxt.Shlibs { 1290 if processedlib.Path == libpath { 1291 return 1292 } 1293 } 1294 if Ctxt.Debugvlog > 1 && Ctxt.Bso != nil { 1295 fmt.Fprintf(Ctxt.Bso, "%5.2f ldshlibsyms: found library with name %s at %s\n", obj.Cputime(), shlib, libpath) 1296 Ctxt.Bso.Flush() 1297 } 1298 1299 f, err := elf.Open(libpath) 1300 if err != nil { 1301 Diag("cannot open shared library: %s", libpath) 1302 return 1303 } 1304 1305 hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG) 1306 if err != nil { 1307 Diag("cannot read ABI hash from shared library %s: %v", libpath, err) 1308 return 1309 } 1310 1311 depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG) 1312 if err != nil { 1313 Diag("cannot read dep list from shared library %s: %v", libpath, err) 1314 return 1315 } 1316 deps := strings.Split(string(depsbytes), "\n") 1317 1318 syms, err := f.DynamicSymbols() 1319 if err != nil { 1320 Diag("cannot read symbols from shared library: %s", libpath) 1321 return 1322 } 1323 for _, elfsym := range syms { 1324 if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION { 1325 continue 1326 } 1327 lsym := Linklookup(Ctxt, elfsym.Name, 0) 1328 if lsym.Type != 0 && lsym.Type != obj.SDYNIMPORT && lsym.Dupok == 0 { 1329 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 { 1330 Diag("Found duplicate symbol %s reading from %s, first found in %s", elfsym.Name, shlib, lsym.File) 1331 } 1332 if lsym.Size > int64(elfsym.Size) { 1333 // If the existing symbol is a BSS value that is 1334 // larger than the one read from the shared library, 1335 // keep references to that. Conversely, if the 1336 // version from the shared libray is larger, we want 1337 // to make all references be to that. 1338 continue 1339 } 1340 } 1341 lsym.Type = obj.SDYNIMPORT 1342 lsym.ElfType = elf.ST_TYPE(elfsym.Info) 1343 lsym.Size = int64(elfsym.Size) 1344 if elfsym.Section != elf.SHN_UNDEF { 1345 // Set .File for the library that actually defines the symbol. 1346 lsym.File = libpath 1347 // The decodetype_* functions in decodetype.go need access to 1348 // the type data. 1349 if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") { 1350 lsym.P = readelfsymboldata(f, &elfsym) 1351 } 1352 } 1353 } 1354 1355 // We might have overwritten some functions above (this tends to happen for the 1356 // autogenerated type equality/hashing functions) and we don't want to generated 1357 // pcln table entries for these any more so unstitch them from the Textp linked 1358 // list. 1359 var last *LSym 1360 1361 for s := Ctxt.Textp; s != nil; s = s.Next { 1362 if s.Type == obj.SDYNIMPORT { 1363 continue 1364 } 1365 1366 if last == nil { 1367 Ctxt.Textp = s 1368 } else { 1369 last.Next = s 1370 } 1371 last = s 1372 } 1373 1374 if last == nil { 1375 Ctxt.Textp = nil 1376 Ctxt.Etextp = nil 1377 } else { 1378 last.Next = nil 1379 Ctxt.Etextp = last 1380 } 1381 1382 Ctxt.Shlibs = append(Ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f}) 1383 } 1384 1385 func mywhatsys() { 1386 goroot = obj.Getgoroot() 1387 goos = obj.Getgoos() 1388 goarch = obj.Getgoarch() 1389 1390 if !strings.HasPrefix(goarch, Thestring) { 1391 log.Fatalf("cannot use %cc with GOARCH=%s", Thearch.Thechar, goarch) 1392 } 1393 } 1394 1395 // Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync. 1396 /* 1397 * Convert raw string to the prefix that will be used in the symbol table. 1398 * Invalid bytes turn into %xx. Right now the only bytes that need 1399 * escaping are %, ., and ", but we escape all control characters too. 1400 * 1401 * If you edit this, edit ../gc/subr.c:/^pathtoprefix too. 1402 * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. 1403 */ 1404 func pathtoprefix(s string) string { 1405 slash := strings.LastIndex(s, "/") 1406 for i := 0; i < len(s); i++ { 1407 c := s[i] 1408 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 1409 var buf bytes.Buffer 1410 for i := 0; i < len(s); i++ { 1411 c := s[i] 1412 if c <= ' ' || i >= slash && c == '.' || c == '%' || c == '"' || c >= 0x7F { 1413 fmt.Fprintf(&buf, "%%%02x", c) 1414 continue 1415 } 1416 buf.WriteByte(c) 1417 } 1418 return buf.String() 1419 } 1420 } 1421 return s 1422 } 1423 1424 func addsection(seg *Segment, name string, rwx int) *Section { 1425 var l **Section 1426 1427 for l = &seg.Sect; *l != nil; l = &(*l).Next { 1428 } 1429 sect := new(Section) 1430 sect.Rwx = uint8(rwx) 1431 sect.Name = name 1432 sect.Seg = seg 1433 sect.Align = int32(Thearch.Ptrsize) // everything is at least pointer-aligned 1434 *l = sect 1435 return sect 1436 } 1437 1438 func Le16(b []byte) uint16 { 1439 return uint16(b[0]) | uint16(b[1])<<8 1440 } 1441 1442 func Le32(b []byte) uint32 { 1443 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 1444 } 1445 1446 func Le64(b []byte) uint64 { 1447 return uint64(Le32(b)) | uint64(Le32(b[4:]))<<32 1448 } 1449 1450 func Be16(b []byte) uint16 { 1451 return uint16(b[0])<<8 | uint16(b[1]) 1452 } 1453 1454 func Be32(b []byte) uint32 { 1455 return uint32(b[0])<<24 | uint32(b[1])<<16 | uint32(b[2])<<8 | uint32(b[3]) 1456 } 1457 1458 func Be64(b []byte) uint64 { 1459 return uint64(Be32(b))<<32 | uint64(Be32(b[4:])) 1460 } 1461 1462 type Chain struct { 1463 sym *LSym 1464 up *Chain 1465 limit int // limit on entry to sym 1466 } 1467 1468 var morestack *LSym 1469 1470 // TODO: Record enough information in new object files to 1471 // allow stack checks here. 1472 1473 func haslinkregister() bool { 1474 return Thearch.Thechar == '5' || Thearch.Thechar == '9' || Thearch.Thechar == '7' 1475 } 1476 1477 func callsize() int { 1478 if haslinkregister() { 1479 return 0 1480 } 1481 return Thearch.Regsize 1482 } 1483 1484 func dostkcheck() { 1485 var ch Chain 1486 1487 morestack = Linklookup(Ctxt, "runtime.morestack", 0) 1488 1489 // Every splitting function ensures that there are at least StackLimit 1490 // bytes available below SP when the splitting prologue finishes. 1491 // If the splitting function calls F, then F begins execution with 1492 // at least StackLimit - callsize() bytes available. 1493 // Check that every function behaves correctly with this amount 1494 // of stack, following direct calls in order to piece together chains 1495 // of non-splitting functions. 1496 ch.up = nil 1497 1498 ch.limit = obj.StackLimit - callsize() 1499 1500 // Check every function, but do the nosplit functions in a first pass, 1501 // to make the printed failure chains as short as possible. 1502 for s := Ctxt.Textp; s != nil; s = s.Next { 1503 // runtime.racesymbolizethunk is called from gcc-compiled C 1504 // code running on the operating system thread stack. 1505 // It uses more than the usual amount of stack but that's okay. 1506 if s.Name == "runtime.racesymbolizethunk" { 1507 continue 1508 } 1509 1510 if s.Nosplit != 0 { 1511 Ctxt.Cursym = s 1512 ch.sym = s 1513 stkcheck(&ch, 0) 1514 } 1515 } 1516 1517 for s := Ctxt.Textp; s != nil; s = s.Next { 1518 if s.Nosplit == 0 { 1519 Ctxt.Cursym = s 1520 ch.sym = s 1521 stkcheck(&ch, 0) 1522 } 1523 } 1524 } 1525 1526 func stkcheck(up *Chain, depth int) int { 1527 limit := up.limit 1528 s := up.sym 1529 1530 // Don't duplicate work: only need to consider each 1531 // function at top of safe zone once. 1532 top := limit == obj.StackLimit-callsize() 1533 if top { 1534 if s.Stkcheck != 0 { 1535 return 0 1536 } 1537 s.Stkcheck = 1 1538 } 1539 1540 if depth > 100 { 1541 Diag("nosplit stack check too deep") 1542 stkbroke(up, 0) 1543 return -1 1544 } 1545 1546 if s.External != 0 || s.Pcln == nil { 1547 // external function. 1548 // should never be called directly. 1549 // only diagnose the direct caller. 1550 // TODO(mwhudson): actually think about this. 1551 if depth == 1 && s.Type != obj.SXREF && !DynlinkingGo() { 1552 Diag("call to external function %s", s.Name) 1553 } 1554 return -1 1555 } 1556 1557 if limit < 0 { 1558 stkbroke(up, limit) 1559 return -1 1560 } 1561 1562 // morestack looks like it calls functions, 1563 // but it switches the stack pointer first. 1564 if s == morestack { 1565 return 0 1566 } 1567 1568 var ch Chain 1569 ch.up = up 1570 1571 if s.Nosplit == 0 { 1572 // Ensure we have enough stack to call morestack. 1573 ch.limit = limit - callsize() 1574 ch.sym = morestack 1575 if stkcheck(&ch, depth+1) < 0 { 1576 return -1 1577 } 1578 if !top { 1579 return 0 1580 } 1581 // Raise limit to allow frame. 1582 limit = int(obj.StackLimit + s.Locals) 1583 if haslinkregister() { 1584 limit += Thearch.Regsize 1585 } 1586 } 1587 1588 // Walk through sp adjustments in function, consuming relocs. 1589 ri := 0 1590 1591 endr := len(s.R) 1592 var ch1 Chain 1593 var pcsp Pciter 1594 var r *Reloc 1595 for pciterinit(Ctxt, &pcsp, &s.Pcln.Pcsp); pcsp.done == 0; pciternext(&pcsp) { 1596 // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). 1597 1598 // Check stack size in effect for this span. 1599 if int32(limit)-pcsp.value < 0 { 1600 stkbroke(up, int(int32(limit)-pcsp.value)) 1601 return -1 1602 } 1603 1604 // Process calls in this span. 1605 for ; ri < endr && uint32(s.R[ri].Off) < pcsp.nextpc; ri++ { 1606 r = &s.R[ri] 1607 switch r.Type { 1608 // Direct call. 1609 case obj.R_CALL, obj.R_CALLARM, obj.R_CALLARM64, obj.R_CALLPOWER: 1610 ch.limit = int(int32(limit) - pcsp.value - int32(callsize())) 1611 ch.sym = r.Sym 1612 if stkcheck(&ch, depth+1) < 0 { 1613 return -1 1614 } 1615 1616 // Indirect call. Assume it is a call to a splitting function, 1617 // so we have to make sure it can call morestack. 1618 // Arrange the data structures to report both calls, so that 1619 // if there is an error, stkprint shows all the steps involved. 1620 case obj.R_CALLIND: 1621 ch.limit = int(int32(limit) - pcsp.value - int32(callsize())) 1622 1623 ch.sym = nil 1624 ch1.limit = ch.limit - callsize() // for morestack in called prologue 1625 ch1.up = &ch 1626 ch1.sym = morestack 1627 if stkcheck(&ch1, depth+2) < 0 { 1628 return -1 1629 } 1630 } 1631 } 1632 } 1633 1634 return 0 1635 } 1636 1637 func stkbroke(ch *Chain, limit int) { 1638 Diag("nosplit stack overflow") 1639 stkprint(ch, limit) 1640 } 1641 1642 func stkprint(ch *Chain, limit int) { 1643 var name string 1644 1645 if ch.sym != nil { 1646 name = ch.sym.Name 1647 if ch.sym.Nosplit != 0 { 1648 name += " (nosplit)" 1649 } 1650 } else { 1651 name = "function pointer" 1652 } 1653 1654 if ch.up == nil { 1655 // top of chain. ch->sym != nil. 1656 if ch.sym.Nosplit != 0 { 1657 fmt.Printf("\t%d\tassumed on entry to %s\n", ch.limit, name) 1658 } else { 1659 fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name) 1660 } 1661 } else { 1662 stkprint(ch.up, ch.limit+callsize()) 1663 if !haslinkregister() { 1664 fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name) 1665 } 1666 } 1667 1668 if ch.limit != limit { 1669 fmt.Printf("\t%d\tafter %s uses %d\n", limit, name, ch.limit-limit) 1670 } 1671 } 1672 1673 func Yconv(s *LSym) string { 1674 var fp string 1675 1676 if s == nil { 1677 fp += fmt.Sprintf("<nil>") 1678 } else { 1679 fmt_ := "" 1680 fmt_ += fmt.Sprintf("%s @0x%08x [%d]", s.Name, int64(s.Value), int64(s.Size)) 1681 for i := 0; int64(i) < s.Size; i++ { 1682 if i%8 == 0 { 1683 fmt_ += fmt.Sprintf("\n\t0x%04x ", i) 1684 } 1685 fmt_ += fmt.Sprintf("%02x ", s.P[i]) 1686 } 1687 1688 fmt_ += fmt.Sprintf("\n") 1689 for i := 0; i < len(s.R); i++ { 1690 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)) 1691 } 1692 1693 str := fmt_ 1694 fp += str 1695 } 1696 1697 return fp 1698 } 1699 1700 func Cflush() { 1701 if err := coutbuf.Writer.Flush(); err != nil { 1702 Exitf("flushing %s: %v", coutbuf.f.Name(), err) 1703 } 1704 } 1705 1706 func Cpos() int64 { 1707 off, err := coutbuf.f.Seek(0, 1) 1708 if err != nil { 1709 Exitf("seeking in output [0, 1]: %v", err) 1710 } 1711 return off + int64(coutbuf.Buffered()) 1712 } 1713 1714 func Cseek(p int64) { 1715 Cflush() 1716 if _, err := coutbuf.f.Seek(p, 0); err != nil { 1717 Exitf("seeking in output [0, 1]: %v", err) 1718 } 1719 } 1720 1721 func Cwrite(p []byte) { 1722 coutbuf.Write(p) 1723 } 1724 1725 func Cput(c uint8) { 1726 coutbuf.WriteByte(c) 1727 } 1728 1729 func usage() { 1730 fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n") 1731 obj.Flagprint(2) 1732 Exit(2) 1733 } 1734 1735 func setheadtype(s string) { 1736 h := headtype(s) 1737 if h < 0 { 1738 Exitf("unknown header type -H %s", s) 1739 } 1740 1741 headstring = s 1742 HEADTYPE = int32(headtype(s)) 1743 } 1744 1745 func setinterp(s string) { 1746 Debug['I'] = 1 // denote cmdline interpreter override 1747 interpreter = s 1748 } 1749 1750 func doversion() { 1751 Exitf("version %s", obj.Getgoversion()) 1752 } 1753 1754 func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) { 1755 // These symbols won't show up in the first loop below because we 1756 // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. 1757 s := Linklookup(Ctxt, "runtime.text", 0) 1758 1759 if s.Type == obj.STEXT { 1760 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil) 1761 } 1762 s = Linklookup(Ctxt, "runtime.etext", 0) 1763 if s.Type == obj.STEXT { 1764 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil) 1765 } 1766 1767 for s := Ctxt.Allsym; s != nil; s = s.Allsym { 1768 if s.Hide != 0 || (s.Name[0] == '.' && s.Version == 0 && s.Name != ".rathole") { 1769 continue 1770 } 1771 switch s.Type & obj.SMASK { 1772 case obj.SCONST, 1773 obj.SRODATA, 1774 obj.SSYMTAB, 1775 obj.SPCLNTAB, 1776 obj.SINITARR, 1777 obj.SDATA, 1778 obj.SNOPTRDATA, 1779 obj.SELFROSECT, 1780 obj.SMACHOGOT, 1781 obj.STYPE, 1782 obj.SSTRING, 1783 obj.SGOSTRING, 1784 obj.SGOFUNC, 1785 obj.SGCBITS, 1786 obj.SWINDOWS: 1787 if !s.Reachable { 1788 continue 1789 } 1790 put(s, s.Name, 'D', Symaddr(s), s.Size, int(s.Version), s.Gotype) 1791 1792 case obj.SBSS, obj.SNOPTRBSS: 1793 if !s.Reachable { 1794 continue 1795 } 1796 if len(s.P) > 0 { 1797 Diag("%s should not be bss (size=%d type=%d special=%d)", s.Name, int(len(s.P)), s.Type, s.Special) 1798 } 1799 put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype) 1800 1801 case obj.SFILE: 1802 put(nil, s.Name, 'f', s.Value, 0, int(s.Version), nil) 1803 1804 case obj.SHOSTOBJ: 1805 if HEADTYPE == obj.Hwindows || Iself { 1806 put(s, s.Name, 'U', s.Value, 0, int(s.Version), nil) 1807 } 1808 1809 case obj.SDYNIMPORT: 1810 if !s.Reachable { 1811 continue 1812 } 1813 put(s, s.Extname, 'U', 0, 0, int(s.Version), nil) 1814 1815 case obj.STLSBSS: 1816 if Linkmode == LinkExternal && HEADTYPE != obj.Hopenbsd { 1817 var type_ int 1818 if goos == "android" { 1819 type_ = 'B' 1820 } else { 1821 type_ = 't' 1822 } 1823 put(s, s.Name, type_, Symaddr(s), s.Size, int(s.Version), s.Gotype) 1824 } 1825 } 1826 } 1827 1828 var a *Auto 1829 var off int32 1830 for s := Ctxt.Textp; s != nil; s = s.Next { 1831 put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype) 1832 1833 // NOTE(ality): acid can't produce a stack trace without .frame symbols 1834 put(nil, ".frame", 'm', int64(s.Locals)+int64(Thearch.Ptrsize), 0, 0, nil) 1835 1836 for a = s.Autom; a != nil; a = a.Link { 1837 // Emit a or p according to actual offset, even if label is wrong. 1838 // This avoids negative offsets, which cannot be encoded. 1839 if a.Name != obj.A_AUTO && a.Name != obj.A_PARAM { 1840 continue 1841 } 1842 1843 // compute offset relative to FP 1844 if a.Name == obj.A_PARAM { 1845 off = a.Aoffset 1846 } else { 1847 off = a.Aoffset - int32(Thearch.Ptrsize) 1848 } 1849 1850 // FP 1851 if off >= 0 { 1852 put(nil, a.Asym.Name, 'p', int64(off), 0, 0, a.Gotype) 1853 continue 1854 } 1855 1856 // SP 1857 if off <= int32(-Thearch.Ptrsize) { 1858 put(nil, a.Asym.Name, 'a', -(int64(off) + int64(Thearch.Ptrsize)), 0, 0, a.Gotype) 1859 continue 1860 } 1861 } 1862 } 1863 1864 // Otherwise, off is addressing the saved program counter. 1865 // Something underhanded is going on. Say nothing. 1866 if Debug['v'] != 0 || Debug['n'] != 0 { 1867 fmt.Fprintf(&Bso, "%5.2f symsize = %d\n", obj.Cputime(), uint32(Symsize)) 1868 } 1869 Bso.Flush() 1870 } 1871 1872 func Symaddr(s *LSym) int64 { 1873 if !s.Reachable { 1874 Diag("unreachable symbol in symaddr - %s", s.Name) 1875 } 1876 return s.Value 1877 } 1878 1879 func xdefine(p string, t int, v int64) { 1880 s := Linklookup(Ctxt, p, 0) 1881 s.Type = int16(t) 1882 s.Value = v 1883 s.Reachable = true 1884 s.Special = 1 1885 s.Local = true 1886 } 1887 1888 func datoff(addr int64) int64 { 1889 if uint64(addr) >= Segdata.Vaddr { 1890 return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff) 1891 } 1892 if uint64(addr) >= Segtext.Vaddr { 1893 return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff) 1894 } 1895 Diag("datoff %#x", addr) 1896 return 0 1897 } 1898 1899 func Entryvalue() int64 { 1900 a := INITENTRY 1901 if a[0] >= '0' && a[0] <= '9' { 1902 return atolwhex(a) 1903 } 1904 s := Linklookup(Ctxt, a, 0) 1905 if s.Type == 0 { 1906 return INITTEXT 1907 } 1908 if s.Type != obj.STEXT { 1909 Diag("entry not text: %s", s.Name) 1910 } 1911 return s.Value 1912 } 1913 1914 func undefsym(s *LSym) { 1915 var r *Reloc 1916 1917 Ctxt.Cursym = s 1918 for i := 0; i < len(s.R); i++ { 1919 r = &s.R[i] 1920 if r.Sym == nil { // happens for some external ARM relocs 1921 continue 1922 } 1923 if r.Sym.Type == obj.Sxxx || r.Sym.Type == obj.SXREF { 1924 Diag("undefined: %s", r.Sym.Name) 1925 } 1926 if !r.Sym.Reachable { 1927 Diag("use of unreachable symbol: %s", r.Sym.Name) 1928 } 1929 } 1930 } 1931 1932 func undef() { 1933 for s := Ctxt.Textp; s != nil; s = s.Next { 1934 undefsym(s) 1935 } 1936 for s := datap; s != nil; s = s.Next { 1937 undefsym(s) 1938 } 1939 if nerrors > 0 { 1940 errorexit() 1941 } 1942 } 1943 1944 func callgraph() { 1945 if Debug['c'] == 0 { 1946 return 1947 } 1948 1949 var i int 1950 var r *Reloc 1951 for s := Ctxt.Textp; s != nil; s = s.Next { 1952 for i = 0; i < len(s.R); i++ { 1953 r = &s.R[i] 1954 if r.Sym == nil { 1955 continue 1956 } 1957 if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM || r.Type == obj.R_CALLPOWER) && r.Sym.Type == obj.STEXT { 1958 fmt.Fprintf(&Bso, "%s calls %s\n", s.Name, r.Sym.Name) 1959 } 1960 } 1961 } 1962 } 1963 1964 func Diag(format string, args ...interface{}) { 1965 tn := "" 1966 sep := "" 1967 if Ctxt.Cursym != nil { 1968 tn = Ctxt.Cursym.Name 1969 sep = ": " 1970 } 1971 fmt.Printf("%s%s%s\n", tn, sep, fmt.Sprintf(format, args...)) 1972 nerrors++ 1973 if Debug['h'] != 0 { 1974 panic("error") 1975 } 1976 if nerrors > 20 { 1977 Exitf("too many errors") 1978 } 1979 } 1980 1981 func checkgo() { 1982 if Debug['C'] == 0 { 1983 return 1984 } 1985 1986 // TODO(rsc,khr): Eventually we want to get to no Go-called C functions at all, 1987 // which would simplify this logic quite a bit. 1988 1989 // Mark every Go-called C function with cfunc=2, recursively. 1990 var changed int 1991 var i int 1992 var r *Reloc 1993 var s *LSym 1994 for { 1995 changed = 0 1996 for s = Ctxt.Textp; s != nil; s = s.Next { 1997 if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) { 1998 for i = 0; i < len(s.R); i++ { 1999 r = &s.R[i] 2000 if r.Sym == nil { 2001 continue 2002 } 2003 if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM) && r.Sym.Type == obj.STEXT { 2004 if r.Sym.Cfunc == 1 { 2005 changed = 1 2006 r.Sym.Cfunc = 2 2007 } 2008 } 2009 } 2010 } 2011 } 2012 if changed == 0 { 2013 break 2014 } 2015 } 2016 2017 // Complain about Go-called C functions that can split the stack 2018 // (that can be preempted for garbage collection or trigger a stack copy). 2019 for s := Ctxt.Textp; s != nil; s = s.Next { 2020 if s.Cfunc == 0 || (s.Cfunc == 2 && s.Nosplit != 0) { 2021 for i = 0; i < len(s.R); i++ { 2022 r = &s.R[i] 2023 if r.Sym == nil { 2024 continue 2025 } 2026 if (r.Type == obj.R_CALL || r.Type == obj.R_CALLARM) && r.Sym.Type == obj.STEXT { 2027 if s.Cfunc == 0 && r.Sym.Cfunc == 2 && r.Sym.Nosplit == 0 { 2028 fmt.Printf("Go %s calls C %s\n", s.Name, r.Sym.Name) 2029 } else if s.Cfunc == 2 && s.Nosplit != 0 && r.Sym.Nosplit == 0 { 2030 fmt.Printf("Go calls C %s calls %s\n", s.Name, r.Sym.Name) 2031 } 2032 } 2033 } 2034 } 2035 } 2036 } 2037 2038 func Rnd(v int64, r int64) int64 { 2039 if r <= 0 { 2040 return v 2041 } 2042 v += r - 1 2043 c := v % r 2044 if c < 0 { 2045 c += r 2046 } 2047 v -= c 2048 return v 2049 } 2050