github.com/rsc/tmp@v0.0.0-20240517235954-6deaab19748b/bootstrap/internal/ld/pobj.go (about) 1 // Do not edit. Bootstrap copy of /Users/rsc/g/go/src/cmd/internal/ld/pobj.go 2 3 // Inferno utils/6l/obj.c 4 // http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c 5 // 6 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 7 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 8 // Portions Copyright © 1997-1999 Vita Nuova Limited 9 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 10 // Portions Copyright © 2004,2006 Bruce Ellis 11 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 12 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 13 // Portions Copyright © 2009 The Go Authors. All rights reserved. 14 // 15 // Permission is hereby granted, free of charge, to any person obtaining a copy 16 // of this software and associated documentation files (the "Software"), to deal 17 // in the Software without restriction, including without limitation the rights 18 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 // copies of the Software, and to permit persons to whom the Software is 20 // furnished to do so, subject to the following conditions: 21 // 22 // The above copyright notice and this permission notice shall be included in 23 // all copies or substantial portions of the Software. 24 // 25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 // THE SOFTWARE. 32 33 package ld 34 35 import ( 36 "rsc.io/tmp/bootstrap/internal/obj" 37 "flag" 38 "fmt" 39 "os" 40 "strings" 41 ) 42 43 // Reading object files. 44 45 func Ldmain() { 46 Ctxt = linknew(Thelinkarch) 47 Ctxt.Thechar = int32(Thearch.Thechar) 48 Ctxt.Thestring = Thestring 49 Ctxt.Diag = Diag 50 Ctxt.Bso = &Bso 51 52 Bso = *Binitw(os.Stdout) 53 Debug = [128]int{} 54 nerrors = 0 55 outfile = "" 56 HEADTYPE = -1 57 INITTEXT = -1 58 INITDAT = -1 59 INITRND = -1 60 INITENTRY = "" 61 Linkmode = LinkAuto 62 63 // For testing behavior of go command when tools crash. 64 // Undocumented, not in standard flag parser to avoid 65 // exposing in usage message. 66 for _, arg := range os.Args { 67 if arg == "-crash_for_testing" { 68 *(*int)(nil) = 0 69 } 70 } 71 72 if Thearch.Thechar == '5' && Ctxt.Goarm == 5 { 73 Debug['F'] = 1 74 } 75 76 obj.Flagcount("1", "use alternate profiling code", &Debug['1']) 77 if Thearch.Thechar == '6' { 78 obj.Flagcount("8", "assume 64-bit addresses", &Debug['8']) 79 } 80 obj.Flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo) 81 obj.Flagcount("C", "check Go calls to C code", &Debug['C']) 82 obj.Flagint64("D", "addr: data address", &INITDAT) 83 obj.Flagstr("E", "sym: entry symbol", &INITENTRY) 84 if Thearch.Thechar == '5' { 85 obj.Flagcount("G", "debug pseudo-ops", &Debug['G']) 86 } 87 obj.Flagfn1("I", "interp: set ELF interp", setinterp) 88 obj.Flagfn1("L", "dir: add dir to library path", Lflag) 89 obj.Flagfn1("H", "head: header type", setheadtype) 90 obj.Flagcount("K", "add stack underflow checks", &Debug['K']) 91 if Thearch.Thechar == '5' { 92 obj.Flagcount("M", "disable software div/mod", &Debug['M']) 93 } 94 obj.Flagcount("O", "print pc-line tables", &Debug['O']) 95 obj.Flagcount("Q", "debug byte-register code gen", &Debug['Q']) 96 if Thearch.Thechar == '5' { 97 obj.Flagcount("P", "debug code generation", &Debug['P']) 98 } 99 obj.Flagint32("R", "rnd: address rounding", &INITRND) 100 obj.Flagcount("nil", "check type signatures", &Debug['S']) 101 obj.Flagint64("T", "addr: text address", &INITTEXT) 102 obj.Flagfn0("V", "print version and exit", doversion) 103 obj.Flagcount("W", "disassemble input", &Debug['W']) 104 obj.Flagfn1("X", "name value: define string data", addstrdata1) 105 obj.Flagcount("Z", "clear stack frame on entry", &Debug['Z']) 106 obj.Flagcount("a", "disassemble output", &Debug['a']) 107 flag.Var(&Buildmode, "buildmode", "build mode to use") 108 obj.Flagcount("c", "dump call graph", &Debug['c']) 109 obj.Flagcount("d", "disable dynamic executable", &Debug['d']) 110 obj.Flagstr("extld", "ld: linker to run in external mode", &extld) 111 obj.Flagstr("extldflags", "ldflags: flags for external linker", &extldflags) 112 obj.Flagcount("f", "ignore version mismatch", &Debug['f']) 113 obj.Flagcount("g", "disable go package data checks", &Debug['g']) 114 obj.Flagstr("installsuffix", "suffix: pkg directory suffix", &flag_installsuffix) 115 obj.Flagstr("k", "sym: set field tracking symbol", &tracksym) 116 obj.Flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode) 117 flag.BoolVar(&Linkshared, "linkshared", false, "link against installed Go shared libraries") 118 obj.Flagcount("n", "dump symbol table", &Debug['n']) 119 obj.Flagstr("o", "outfile: set output file", &outfile) 120 flag.Var(&rpath, "r", "dir1:dir2:...: set ELF dynamic linker search path") 121 obj.Flagcount("race", "enable race detector", &flag_race) 122 obj.Flagcount("s", "disable symbol table", &Debug['s']) 123 var flagShared int 124 if Thearch.Thechar == '5' || Thearch.Thechar == '6' { 125 obj.Flagcount("shared", "generate shared object (implies -linkmode external)", &flagShared) 126 } 127 obj.Flagstr("tmpdir", "dir: leave temporary files in this directory", &tmpdir) 128 obj.Flagcount("u", "reject unsafe packages", &Debug['u']) 129 obj.Flagcount("v", "print link trace", &Debug['v']) 130 obj.Flagcount("w", "disable DWARF generation", &Debug['w']) 131 132 // Clumsy hack to preserve old behavior of -X taking two arguments. 133 for i := 0; i < len(os.Args); i++ { 134 arg := os.Args[i] 135 if (arg == "--X" || arg == "-X") && i+2 < len(os.Args) { 136 os.Args[i+2] = "-X=VALUE:" + os.Args[i+2] 137 i += 2 138 } else if (strings.HasPrefix(arg, "--X=") || strings.HasPrefix(arg, "-X=")) && i+1 < len(os.Args) { 139 os.Args[i+1] = "-X=VALUE:" + os.Args[i+1] 140 i++ 141 } 142 } 143 obj.Flagstr("cpuprofile", "file: write cpu profile to file", &cpuprofile) 144 obj.Flagstr("memprofile", "file: write memory profile to file", &memprofile) 145 obj.Flagint64("memprofilerate", "set runtime.MemProfileRate", &memprofilerate) 146 obj.Flagparse(usage) 147 startProfile() 148 Ctxt.Bso = &Bso 149 Ctxt.Debugvlog = int32(Debug['v']) 150 if flagShared != 0 { 151 if Buildmode == BuildmodeExe { 152 Buildmode = BuildmodeCShared 153 } else if Buildmode != BuildmodeCShared { 154 Exitf("-shared and -buildmode=%s are incompatible", Buildmode.String()) 155 } 156 } 157 158 if Buildmode != BuildmodeShared && flag.NArg() != 1 { 159 usage() 160 } 161 162 if outfile == "" { 163 if HEADTYPE == obj.Hwindows { 164 outfile = fmt.Sprintf("%c.out.exe", Thearch.Thechar) 165 } else { 166 outfile = fmt.Sprintf("%c.out", Thearch.Thechar) 167 } 168 } 169 170 libinit() // creates outfile 171 172 if HEADTYPE == -1 { 173 HEADTYPE = int32(headtype(goos)) 174 } 175 Ctxt.Headtype = int(HEADTYPE) 176 if headstring == "" { 177 headstring = Headstr(int(HEADTYPE)) 178 } 179 180 Thearch.Archinit() 181 182 if Linkshared && !Iself { 183 Exitf("-linkshared can only be used on elf systems") 184 } 185 186 if Debug['v'] != 0 { 187 fmt.Fprintf(&Bso, "HEADER = -H%d -T0x%x -D0x%x -R0x%x\n", HEADTYPE, uint64(INITTEXT), uint64(INITDAT), uint32(INITRND)) 188 } 189 Bflush(&Bso) 190 191 if Buildmode == BuildmodeShared { 192 for i := 0; i < flag.NArg(); i++ { 193 arg := flag.Arg(i) 194 parts := strings.SplitN(arg, "=", 2) 195 var pkgpath, file string 196 if len(parts) == 1 { 197 pkgpath, file = "main", arg 198 } else { 199 pkgpath, file = parts[0], parts[1] 200 } 201 addlibpath(Ctxt, "command line", "command line", file, pkgpath, "") 202 } 203 } else { 204 addlibpath(Ctxt, "command line", "command line", flag.Arg(0), "main", "") 205 } 206 loadlib() 207 208 if Thearch.Thechar == '5' { 209 // mark some functions that are only referenced after linker code editing 210 if Debug['F'] != 0 { 211 mark(Linkrlookup(Ctxt, "_sfloat", 0)) 212 } 213 mark(Linklookup(Ctxt, "runtime.read_tls_fallback", 0)) 214 } 215 216 checkgo() 217 deadcode() 218 callgraph() 219 220 doelf() 221 if HEADTYPE == obj.Hdarwin { 222 domacho() 223 } 224 dostkcheck() 225 if HEADTYPE == obj.Hwindows { 226 dope() 227 } 228 addexport() 229 Thearch.Gentext() // trampolines, call stubs, etc. 230 textaddress() 231 pclntab() 232 findfunctab() 233 symtab() 234 dodata() 235 address() 236 doweak() 237 reloc() 238 Thearch.Asmb() 239 undef() 240 hostlink() 241 archive() 242 if Debug['v'] != 0 { 243 fmt.Fprintf(&Bso, "%5.2f cpu time\n", obj.Cputime()) 244 fmt.Fprintf(&Bso, "%d symbols\n", Ctxt.Nsymbol) 245 fmt.Fprintf(&Bso, "%d liveness data\n", liveness) 246 } 247 248 Bflush(&Bso) 249 250 errorexit() 251 }