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  }