github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/internal/ld/pobj.go (about) 1 // Inferno utils/6l/obj.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.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 "cmd/internal/obj" 35 "flag" 36 "fmt" 37 "os" 38 "strings" 39 ) 40 41 // Reading object files. 42 43 func Ldmain() { 44 Ctxt = linknew(Thelinkarch) 45 Ctxt.Thechar = int32(Thearch.Thechar) 46 Ctxt.Thestring = Thestring 47 Ctxt.Diag = Diag 48 Ctxt.Bso = &Bso 49 50 Bso = *Binitw(os.Stdout) 51 Debug = [128]int{} 52 nerrors = 0 53 outfile = "" 54 HEADTYPE = -1 55 INITTEXT = -1 56 INITDAT = -1 57 INITRND = -1 58 INITENTRY = "" 59 Linkmode = LinkAuto 60 61 // For testing behavior of go command when tools crash. 62 // Undocumented, not in standard flag parser to avoid 63 // exposing in usage message. 64 for _, arg := range os.Args { 65 if arg == "-crash_for_testing" { 66 *(*int)(nil) = 0 67 } 68 } 69 70 if Thearch.Thechar == '5' && Ctxt.Goarm == 5 { 71 Debug['F'] = 1 72 } 73 74 obj.Flagcount("1", "use alternate profiling code", &Debug['1']) 75 if Thearch.Thechar == '6' { 76 obj.Flagcount("8", "assume 64-bit addresses", &Debug['8']) 77 } 78 obj.Flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo) 79 obj.Flagcount("C", "check Go calls to C code", &Debug['C']) 80 obj.Flagint64("D", "addr: data address", &INITDAT) 81 obj.Flagstr("E", "sym: entry symbol", &INITENTRY) 82 if Thearch.Thechar == '5' { 83 obj.Flagcount("G", "debug pseudo-ops", &Debug['G']) 84 } 85 obj.Flagfn1("I", "interp: set ELF interp", setinterp) 86 obj.Flagfn1("L", "dir: add dir to library path", Lflag) 87 obj.Flagfn1("H", "head: header type", setheadtype) 88 obj.Flagcount("K", "add stack underflow checks", &Debug['K']) 89 if Thearch.Thechar == '5' { 90 obj.Flagcount("M", "disable software div/mod", &Debug['M']) 91 } 92 obj.Flagcount("O", "print pc-line tables", &Debug['O']) 93 obj.Flagcount("Q", "debug byte-register code gen", &Debug['Q']) 94 if Thearch.Thechar == '5' { 95 obj.Flagcount("P", "debug code generation", &Debug['P']) 96 } 97 obj.Flagint32("R", "rnd: address rounding", &INITRND) 98 obj.Flagcount("nil", "check type signatures", &Debug['S']) 99 obj.Flagint64("T", "addr: text address", &INITTEXT) 100 obj.Flagfn0("V", "print version and exit", doversion) 101 obj.Flagcount("W", "disassemble input", &Debug['W']) 102 obj.Flagfn1("X", "name value: define string data", addstrdata1) 103 obj.Flagcount("Z", "clear stack frame on entry", &Debug['Z']) 104 obj.Flagcount("a", "disassemble output", &Debug['a']) 105 flag.Var(&Buildmode, "buildmode", "build mode to use") 106 obj.Flagcount("c", "dump call graph", &Debug['c']) 107 obj.Flagcount("d", "disable dynamic executable", &Debug['d']) 108 obj.Flagstr("extld", "ld: linker to run in external mode", &extld) 109 obj.Flagstr("extldflags", "ldflags: flags for external linker", &extldflags) 110 obj.Flagcount("f", "ignore version mismatch", &Debug['f']) 111 obj.Flagcount("g", "disable go package data checks", &Debug['g']) 112 obj.Flagstr("installsuffix", "suffix: pkg directory suffix", &flag_installsuffix) 113 obj.Flagstr("k", "sym: set field tracking symbol", &tracksym) 114 obj.Flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode) 115 flag.BoolVar(&Linkshared, "linkshared", false, "link against installed Go shared libraries") 116 obj.Flagcount("n", "dump symbol table", &Debug['n']) 117 obj.Flagstr("o", "outfile: set output file", &outfile) 118 flag.Var(&rpath, "r", "dir1:dir2:...: set ELF dynamic linker search path") 119 obj.Flagcount("race", "enable race detector", &flag_race) 120 obj.Flagcount("s", "disable symbol table", &Debug['s']) 121 var flagShared int 122 if Thearch.Thechar == '5' || Thearch.Thechar == '6' { 123 obj.Flagcount("shared", "generate shared object (implies -linkmode external)", &flagShared) 124 } 125 obj.Flagstr("tmpdir", "dir: leave temporary files in this directory", &tmpdir) 126 obj.Flagcount("u", "reject unsafe packages", &Debug['u']) 127 obj.Flagcount("v", "print link trace", &Debug['v']) 128 obj.Flagcount("w", "disable DWARF generation", &Debug['w']) 129 130 // Clumsy hack to preserve old behavior of -X taking two arguments. 131 for i := 0; i < len(os.Args); i++ { 132 arg := os.Args[i] 133 if (arg == "--X" || arg == "-X") && i+2 < len(os.Args) { 134 os.Args[i+2] = "-X=VALUE:" + os.Args[i+2] 135 i += 2 136 } else if (strings.HasPrefix(arg, "--X=") || strings.HasPrefix(arg, "-X=")) && i+1 < len(os.Args) { 137 os.Args[i+1] = "-X=VALUE:" + os.Args[i+1] 138 i++ 139 } 140 } 141 obj.Flagstr("cpuprofile", "file: write cpu profile to file", &cpuprofile) 142 obj.Flagstr("memprofile", "file: write memory profile to file", &memprofile) 143 obj.Flagparse(usage) 144 startProfile() 145 Ctxt.Bso = &Bso 146 Ctxt.Debugvlog = int32(Debug['v']) 147 if flagShared != 0 { 148 if Buildmode == BuildmodeExe { 149 Buildmode = BuildmodeCShared 150 } else if Buildmode != BuildmodeCShared { 151 Diag("-shared and -buildmode=%s are incompatible\n", Buildmode.String()) 152 Errorexit() 153 } 154 } 155 156 if Buildmode != BuildmodeShared && flag.NArg() != 1 { 157 usage() 158 } 159 160 if outfile == "" { 161 if HEADTYPE == Hwindows { 162 outfile = fmt.Sprintf("%c.out.exe", Thearch.Thechar) 163 } else { 164 outfile = fmt.Sprintf("%c.out", Thearch.Thechar) 165 } 166 } 167 168 libinit() // creates outfile 169 170 if HEADTYPE == -1 { 171 HEADTYPE = int32(headtype(goos)) 172 } 173 Ctxt.Headtype = int(HEADTYPE) 174 if headstring == "" { 175 headstring = Headstr(int(HEADTYPE)) 176 } 177 178 Thearch.Archinit() 179 180 if Linkshared && !Iself { 181 Diag("-linkshared can only be used on elf systems") 182 Errorexit() 183 } 184 185 if Debug['v'] != 0 { 186 fmt.Fprintf(&Bso, "HEADER = -H%d -T0x%x -D0x%x -R0x%x\n", HEADTYPE, uint64(INITTEXT), uint64(INITDAT), uint32(INITRND)) 187 } 188 Bflush(&Bso) 189 190 if Buildmode == BuildmodeShared { 191 for i := 0; i < flag.NArg(); i++ { 192 arg := flag.Arg(i) 193 parts := strings.SplitN(arg, "=", 2) 194 var pkgpath, file string 195 if len(parts) == 1 { 196 pkgpath, file = "main", arg 197 } else { 198 pkgpath, file = parts[0], parts[1] 199 } 200 addlibpath(Ctxt, "command line", "command line", file, pkgpath, "") 201 } 202 } else { 203 addlibpath(Ctxt, "command line", "command line", flag.Arg(0), "main", "") 204 } 205 loadlib() 206 207 if Thearch.Thechar == '5' { 208 // mark some functions that are only referenced after linker code editing 209 if Debug['F'] != 0 { 210 mark(Linkrlookup(Ctxt, "_sfloat", 0)) 211 } 212 mark(Linklookup(Ctxt, "runtime.read_tls_fallback", 0)) 213 } 214 215 checkgo() 216 deadcode() 217 callgraph() 218 219 doelf() 220 if HEADTYPE == Hdarwin { 221 domacho() 222 } 223 dostkcheck() 224 if HEADTYPE == Hwindows { 225 dope() 226 } 227 addexport() 228 Thearch.Gentext() // trampolines, call stubs, etc. 229 textaddress() 230 pclntab() 231 findfunctab() 232 symtab() 233 dodata() 234 address() 235 doweak() 236 reloc() 237 Thearch.Asmb() 238 undef() 239 hostlink() 240 archive() 241 if Debug['v'] != 0 { 242 fmt.Fprintf(&Bso, "%5.2f cpu time\n", obj.Cputime()) 243 fmt.Fprintf(&Bso, "%d symbols\n", Ctxt.Nsymbol) 244 fmt.Fprintf(&Bso, "%d liveness data\n", liveness) 245 } 246 247 Bflush(&Bso) 248 249 Errorexit() 250 }