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