github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/cmd/ld/pobj.c (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 // Reading object files. 32 33 #define EXTERN 34 #include "l.h" 35 #include "../ld/lib.h" 36 #include "../ld/elf.h" 37 #include "../ld/macho.h" 38 #include "../ld/dwarf.h" 39 #include "../ld/pe.h" 40 #include <ar.h> 41 42 char *noname = "<none>"; 43 char* paramspace = "FP"; 44 45 void 46 main(int argc, char *argv[]) 47 { 48 int i; 49 50 linkarchinit(); 51 ctxt = linknew(thelinkarch); 52 ctxt->thechar = thechar; 53 ctxt->thestring = thestring; 54 ctxt->diag = diag; 55 ctxt->bso = &bso; 56 57 Binit(&bso, 1, OWRITE); 58 listinit(); 59 memset(debug, 0, sizeof(debug)); 60 nerrors = 0; 61 outfile = nil; 62 HEADTYPE = -1; 63 INITTEXT = -1; 64 INITDAT = -1; 65 INITRND = -1; 66 INITENTRY = 0; 67 linkmode = LinkAuto; 68 69 // For testing behavior of go command when tools crash. 70 // Undocumented, not in standard flag parser to avoid 71 // exposing in usage message. 72 for(i=1; i<argc; i++) 73 if(strcmp(argv[i], "-crash_for_testing") == 0) 74 *(volatile int*)0 = 0; 75 76 if(thechar == '5' && ctxt->goarm == 5) 77 debug['F'] = 1; 78 79 flagcount("1", "use alternate profiling code", &debug['1']); 80 if(thechar == '6') 81 flagcount("8", "assume 64-bit addresses", &debug['8']); 82 flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo); 83 flagcount("C", "check Go calls to C code", &debug['C']); 84 flagint64("D", "addr: data address", &INITDAT); 85 flagstr("E", "sym: entry symbol", &INITENTRY); 86 if(thechar == '5') 87 flagcount("G", "debug pseudo-ops", &debug['G']); 88 flagfn1("I", "interp: set ELF interp", setinterp); 89 flagfn1("L", "dir: add dir to library path", Lflag); 90 flagfn1("H", "head: header type", setheadtype); 91 flagcount("K", "add stack underflow checks", &debug['K']); 92 if(thechar == '5') 93 flagcount("M", "disable software div/mod", &debug['M']); 94 flagcount("O", "print pc-line tables", &debug['O']); 95 flagcount("Q", "debug byte-register code gen", &debug['Q']); 96 if(thechar == '5') 97 flagcount("P", "debug code generation", &debug['P']); 98 flagint32("R", "rnd: address rounding", &INITRND); 99 flagcount("S", "check type signatures", &debug['S']); 100 flagint64("T", "addr: text address", &INITTEXT); 101 flagfn0("V", "print version and exit", doversion); 102 flagcount("W", "disassemble input", &debug['W']); 103 flagfn2("X", "name value: define string data", addstrdata); 104 flagcount("Z", "clear stack frame on entry", &debug['Z']); 105 flagcount("a", "disassemble output", &debug['a']); 106 flagcount("c", "dump call graph", &debug['c']); 107 flagcount("d", "disable dynamic executable", &debug['d']); 108 flagstr("extld", "ld: linker to run in external mode", &extld); 109 flagstr("extldflags", "ldflags: flags for external linker", &extldflags); 110 flagcount("f", "ignore version mismatch", &debug['f']); 111 flagcount("g", "disable go package data checks", &debug['g']); 112 flagstr("installsuffix", "suffix: pkg directory suffix", &flag_installsuffix); 113 flagstr("k", "sym: set field tracking symbol", &tracksym); 114 flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode); 115 flagcount("n", "dump symbol table", &debug['n']); 116 flagstr("o", "outfile: set output file", &outfile); 117 flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath); 118 flagcount("race", "enable race detector", &flag_race); 119 flagcount("s", "disable symbol table", &debug['s']); 120 if(thechar == '5' || thechar == '6') 121 flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared); 122 flagstr("tmpdir", "dir: leave temporary files in this directory", &tmpdir); 123 flagcount("u", "reject unsafe packages", &debug['u']); 124 flagcount("v", "print link trace", &debug['v']); 125 flagcount("w", "disable DWARF generation", &debug['w']); 126 127 flagparse(&argc, &argv, usage); 128 ctxt->bso = &bso; 129 ctxt->debugdivmod = debug['M']; 130 ctxt->debugfloat = debug['F']; 131 ctxt->debughist = debug['O']; 132 ctxt->debugpcln = debug['O']; 133 ctxt->debugread = debug['W']; 134 ctxt->debugstack = debug['K']; 135 ctxt->debugvlog = debug['v']; 136 137 if(argc != 1) 138 usage(); 139 140 if(outfile == nil) { 141 if(HEADTYPE == Hwindows) 142 outfile = smprint("%c.out.exe", thechar); 143 else 144 outfile = smprint("%c.out", thechar); 145 } 146 libinit(); // creates outfile 147 148 if(HEADTYPE == -1) 149 HEADTYPE = headtype(goos); 150 ctxt->headtype = HEADTYPE; 151 if(headstring == nil) 152 headstring = headstr(HEADTYPE); 153 154 archinit(); 155 ctxt->debugfloat = debug['F']; 156 157 if(debug['v']) 158 Bprint(&bso, "HEADER = -H%d -T0x%llux -D0x%llux -R0x%ux\n", 159 HEADTYPE, INITTEXT, INITDAT, INITRND); 160 Bflush(&bso); 161 162 cbp = buf.cbuf; 163 cbc = sizeof(buf.cbuf); 164 165 addlibpath(ctxt, "command line", "command line", argv[0], "main"); 166 loadlib(); 167 168 if(thechar == '5') { 169 // mark some functions that are only referenced after linker code editing 170 if(debug['F']) 171 mark(linkrlookup(ctxt, "_sfloat", 0)); 172 mark(linklookup(ctxt, "runtime.read_tls_fallback", 0)); 173 } 174 175 checkgo(); 176 deadcode(); 177 callgraph(); 178 paramspace = "SP"; /* (FP) now (SP) on output */ 179 180 doelf(); 181 if(HEADTYPE == Hdarwin) 182 domacho(); 183 dostkcheck(); 184 if(HEADTYPE == Hwindows) 185 dope(); 186 addexport(); 187 textaddress(); 188 pclntab(); 189 symtab(); 190 dodata(); 191 address(); 192 doweak(); 193 reloc(); 194 asmb(); 195 undef(); 196 hostlink(); 197 if(debug['v']) { 198 Bprint(&bso, "%5.2f cpu time\n", cputime()); 199 Bprint(&bso, "%d symbols\n", ctxt->nsymbol); 200 Bprint(&bso, "%d sizeof adr\n", sizeof(Addr)); 201 Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); 202 Bprint(&bso, "%lld liveness data\n", liveness); 203 } 204 Bflush(&bso); 205 206 errorexit(); 207 }