void main(int argc, char *argv[]) { int c; Binit(&bso, 1, OWRITE); cout = -1; listinit(); memset(debug, 0, sizeof(debug)); nerrors = 0; outfile = nil; HEADTYPE = -1; INITTEXT = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; ARGBEGIN { default: c = ARGC(); if(c == 'l') usage(); if(c >= 0 && c < sizeof(debug)) debug[c]++; break; case 'o': /* output to (next arg) */ outfile = EARGF(usage()); break; case 'E': INITENTRY = EARGF(usage()); break; case 'H': HEADTYPE = headtype(EARGF(usage())); break; case 'I': interpreter = EARGF(usage()); break; case 'L': Lflag(EARGF(usage())); break; case 'T': INITTEXT = atolwhex(EARGF(usage())); break; case 'D': INITDAT = atolwhex(EARGF(usage())); break; case 'R': INITRND = atolwhex(EARGF(usage())); break; case 'r': rpath = EARGF(usage()); break; case 'V': print("%cl version %s\n", thechar, getgoversion()); errorexit(); } ARGEND if(argc != 1) usage(); mywhatsys(); // get goos if(HEADTYPE == -1) HEADTYPE = headtype(goos); if(outfile == nil) { if(HEADTYPE == Hwindows) outfile = "8.out.exe"; else outfile = "8.out"; } libinit(); switch(HEADTYPE) { default: diag("unknown -H option"); errorexit(); case Hgarbunix: /* this is garbage */ HEADR = 20L+56L; if(INITTEXT == -1) INITTEXT = 0x40004CL; if(INITDAT == -1) INITDAT = 0x10000000L; if(INITRND == -1) INITRND = 0; break; case Hunixcoff: /* is unix coff */ HEADR = 0xd0L; if(INITTEXT == -1) INITTEXT = 0xd0; if(INITDAT == -1) INITDAT = 0x400000; if(INITRND == -1) INITRND = 0; break; case Hplan9x32: /* plan 9 */ tlsoffset = -8; HEADR = 32L; if(INITTEXT == -1) INITTEXT = 4096+32; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hmsdoscom: /* MS-DOS .COM */ HEADR = 0; if(INITTEXT == -1) INITTEXT = 0x0100; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4; break; case Hmsdosexe: /* fake MS-DOS .EXE */ HEADR = 0x200; if(INITTEXT == -1) INITTEXT = 0x0100; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4; HEADR += (INITTEXT & 0xFFFF); if(debug['v']) Bprint(&bso, "HEADR = 0x%d\n", HEADR); break; case Hdarwin: /* apple MACH */ /* * OS X system constant - offset from %gs to our TLS. * Explained in ../../libcgo/darwin_386.c. */ tlsoffset = 0x468; machoinit(); HEADR = INITIAL_MACHO_HEADR; if(INITTEXT == -1) INITTEXT = 4096+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hlinux: /* elf32 executable */ case Hfreebsd: /* * ELF uses TLS offsets negative from %gs. * Translate 0(GS) and 4(GS) into -8(GS) and -4(GS). * Also known to ../../pkg/runtime/linux/386/sys.s * and ../../libcgo/linux_386.c. */ tlsoffset = -8; elfinit(); HEADR = ELFRESERVE; if(INITTEXT == -1) INITTEXT = 0x08048000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hwindows: /* PE executable */ peinit(); HEADR = PEFILEHEADR; if(INITTEXT == -1) INITTEXT = PEBASE+PESECTHEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = PESECTALIGN; break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%ux is ignored because of -R0x%ux\n", INITDAT, INITRND); if(debug['v']) Bprint(&bso, "HEADER = -H0x%d -T0x%ux -D0x%ux -R0x%ux\n", HEADTYPE, INITTEXT, INITDAT, INITRND); Bflush(&bso); instinit(); zprg.link = P; zprg.pcond = P; zprg.back = 2; zprg.as = AGOK; zprg.from.type = D_NONE; zprg.from.index = D_NONE; zprg.from.scale = 1; zprg.to = zprg.from; pcstr = "%.6ux "; nuxiinit(); histgen = 0; pc = 0; dtype = 4; version = 0; cbp = buf.cbuf; cbc = sizeof(buf.cbuf); addlibpath("command line", "command line", argv[0], "main"); loadlib(); deadcode(); patch(); follow(); doelf(); if(HEADTYPE == Hdarwin) domacho(); if(HEADTYPE == Hwindows) dope(); dostkoff(); if(debug['p']) if(debug['1']) doprof1(); else doprof2(); span(); addexport(); textaddress(); pclntab(); symtab(); dodata(); address(); doweak(); reloc(); asmb(); undef(); if(debug['v']) { Bprint(&bso, "%5.2f cpu time\n", cputime()); Bprint(&bso, "%d symbols\n", nsymbol); Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); } Bflush(&bso); errorexit(); }
void archinit(void) { // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when // Go was built; see ../../make.bash. if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0) linkmode = LinkInternal; if(flag_shared) linkmode = LinkExternal; switch(HEADTYPE) { default: if(linkmode == LinkAuto) linkmode = LinkInternal; if(linkmode == LinkExternal && strcmp(getgoextlinkenabled(), "1") != 0) sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE)); break; case Hdarwin: case Hdragonfly: case Hfreebsd: case Hlinux: case Hnetbsd: case Hopenbsd: case Hsolaris: break; } ctxt->linkmode = linkmode; switch(HEADTYPE) { default: diag("unknown -H option"); errorexit(); case Hplan9: /* plan 9 */ HEADR = 32L + 8L; if(INITTEXT == -1) INITTEXT = 0x200000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 0x200000; break; case Helf: /* elf32 executable */ HEADR = rnd(52L+3*32L, 16); if(INITTEXT == -1) INITTEXT = 0x80110000L; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hdarwin: /* apple MACH */ machoinit(); HEADR = INITIAL_MACHO_HEADR; if(INITRND == -1) INITRND = 4096; if(INITTEXT == -1) INITTEXT = 4096+HEADR; if(INITDAT == -1) INITDAT = 0; break; case Hlinux: /* elf64 executable */ case Hfreebsd: /* freebsd */ case Hnetbsd: /* netbsd */ case Hopenbsd: /* openbsd */ case Hdragonfly: /* dragonfly */ case Hsolaris: /* solaris */ elfinit(); HEADR = ELFRESERVE; if(INITTEXT == -1) INITTEXT = (1<<22)+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hwindows: /* PE executable */ peinit(); HEADR = PEFILEHEADR; if(INITTEXT == -1) INITTEXT = PEBASE+PESECTHEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = PESECTALIGN; break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%llux is ignored because of -R0x%ux\n", INITDAT, INITRND); }
void main(int argc, char *argv[]) { Binit(&bso, 1, OWRITE); listinit(); memset(debug, 0, sizeof(debug)); nerrors = 0; outfile = nil; HEADTYPE = -1; INITTEXT = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; LIBINITENTRY = 0; linkmode = LinkInternal; // TODO: LinkAuto once everything works. nuxiinit(); flagcount("1", "use alternate profiling code", &debug['1']); flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo); flagstr("E", "sym: entry symbol", &INITENTRY); flagint32("D", "addr: data address", &INITDAT); flagfn1("I", "interp: set ELF interp", setinterp); flagfn1("L", "dir: add dir to library path", Lflag); flagfn1("H", "head: header type", setheadtype); flagcount("K", "add stack underflow checks", &debug['K']); flagcount("O", "print pc-line tables", &debug['O']); flagcount("Q", "debug byte-register code gen", &debug['Q']); flagint32("R", "rnd: address rounding", &INITRND); flagcount("S", "check type signatures", &debug['S']); flagint32("T", "addr: text address", &INITTEXT); flagfn0("V", "print version and exit", doversion); flagcount("W", "disassemble input", &debug['W']); flagfn2("X", "name value: define string data", addstrdata); flagcount("Z", "clear stack frame on entry", &debug['Z']); flagcount("a", "disassemble output", &debug['a']); flagcount("c", "dump call graph", &debug['c']); flagcount("d", "disable dynamic executable", &debug['d']); flagcount("f", "ignore version mismatch", &debug['f']); flagcount("g", "disable go package data checks", &debug['g']); flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode); flagstr("k", "sym: set field tracking symbol", &tracksym); flagstr("o", "outfile: set output file", &outfile); flagcount("p", "insert profiling code", &debug['p']); flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath); flagcount("race", "enable race detector", &flag_race); flagcount("s", "disable symbol table", &debug['s']); flagcount("n", "dump symbol table", &debug['n']); flagstr("tmpdir", "leave temporary files in this directory", &tmpdir); flagcount("u", "reject unsafe packages", &debug['u']); flagcount("v", "print link trace", &debug['v']); flagcount("w", "disable DWARF generation", &debug['w']); // TODO: link mode flag flagparse(&argc, &argv, usage); if(argc != 1) usage(); mywhatsys(); // get goos if(HEADTYPE == -1) HEADTYPE = headtype(goos); switch(HEADTYPE) { default: if(linkmode == LinkAuto) linkmode = LinkInternal; if(linkmode == LinkExternal) sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE)); break; case Hdarwin: case Hfreebsd: case Hlinux: case Hnetbsd: case Hopenbsd: break; } if(outfile == nil) { if(HEADTYPE == Hwindows) outfile = "8.out.exe"; else outfile = "8.out"; } libinit(); switch(HEADTYPE) { default: diag("unknown -H option"); errorexit(); case Hgarbunix: /* this is garbage */ HEADR = 20L+56L; if(INITTEXT == -1) INITTEXT = 0x40004CL; if(INITDAT == -1) INITDAT = 0x10000000L; if(INITRND == -1) INITRND = 0; break; case Hunixcoff: /* is unix coff */ HEADR = 0xd0L; if(INITTEXT == -1) INITTEXT = 0xd0; if(INITDAT == -1) INITDAT = 0x400000; if(INITRND == -1) INITRND = 0; break; case Hplan9x32: /* plan 9 */ tlsoffset = -8; HEADR = 32L; if(INITTEXT == -1) INITTEXT = 4096+32; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hmsdoscom: /* MS-DOS .COM */ HEADR = 0; if(INITTEXT == -1) INITTEXT = 0x0100; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4; break; case Hmsdosexe: /* fake MS-DOS .EXE */ HEADR = 0x200; if(INITTEXT == -1) INITTEXT = 0x0100; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4; HEADR += (INITTEXT & 0xFFFF); if(debug['v']) Bprint(&bso, "HEADR = 0x%d\n", HEADR); break; case Hdarwin: /* apple MACH */ /* * OS X system constant - offset from %gs to our TLS. * Explained in ../../pkg/runtime/cgo/gcc_darwin_386.c. */ tlsoffset = 0x468; machoinit(); HEADR = INITIAL_MACHO_HEADR; if(INITTEXT == -1) INITTEXT = 4096+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hlinux: /* elf32 executable */ case Hfreebsd: case Hnetbsd: case Hopenbsd: /* * ELF uses TLS offsets negative from %gs. * Translate 0(GS) and 4(GS) into -8(GS) and -4(GS). * Also known to ../../pkg/runtime/sys_linux_386.s * and ../../pkg/runtime/cgo/gcc_linux_386.c. */ tlsoffset = -8; elfinit(); HEADR = ELFRESERVE; if(INITTEXT == -1) INITTEXT = 0x08048000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hwindows: /* PE executable */ peinit(); HEADR = PEFILEHEADR; if(INITTEXT == -1) INITTEXT = PEBASE+PESECTHEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = PESECTALIGN; break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%ux is ignored because of -R0x%ux\n", INITDAT, INITRND); if(debug['v']) Bprint(&bso, "HEADER = -H0x%d -T0x%ux -D0x%ux -R0x%ux\n", HEADTYPE, INITTEXT, INITDAT, INITRND); Bflush(&bso); instinit(); zprg.link = P; zprg.pcond = P; zprg.back = 2; zprg.as = AGOK; zprg.from.type = D_NONE; zprg.from.index = D_NONE; zprg.from.scale = 1; zprg.to = zprg.from; pcstr = "%.6ux "; histgen = 0; pc = 0; dtype = 4; version = 0; cbp = buf.cbuf; cbc = sizeof(buf.cbuf); addlibpath("command line", "command line", argv[0], "main"); loadlib(); deadcode(); patch(); follow(); doelf(); if(HEADTYPE == Hdarwin) domacho(); if(HEADTYPE == Hwindows) dope(); dostkoff(); dostkcheck(); if(debug['p']) if(debug['1']) doprof1(); else doprof2(); span(); addexport(); textaddress(); pclntab(); symtab(); dodata(); address(); doweak(); reloc(); asmb(); undef(); hostlink(); if(debug['v']) { Bprint(&bso, "%5.2f cpu time\n", cputime()); Bprint(&bso, "%d symbols\n", nsymbol); Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); } Bflush(&bso); errorexit(); }
void main(int argc, char *argv[]) { int i, c; Binit(&bso, 1, OWRITE); cout = -1; listinit(); memset(debug, 0, sizeof(debug)); nerrors = 0; outfile = nil; HEADTYPE = -1; INITTEXT = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; ARGBEGIN { default: c = ARGC(); if(c == 'l') usage(); if(c >= 0 && c < sizeof(debug)) debug[c]++; break; case 'o': /* output to (next arg) */ outfile = EARGF(usage()); break; case 'E': INITENTRY = EARGF(usage()); break; case 'H': HEADTYPE = atolwhex(EARGF(usage())); break; case 'L': Lflag(EARGF(usage())); break; case 'T': INITTEXT = atolwhex(EARGF(usage())); break; case 'D': INITDAT = atolwhex(EARGF(usage())); break; case 'R': INITRND = atolwhex(EARGF(usage())); break; case 'r': rpath = EARGF(usage()); break; case 'x': /* produce export table */ doexp = 1; if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) readundefs(ARGF(), SEXPORT); break; case 'u': /* produce dynamically loadable module */ dlm = 1; if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) readundefs(ARGF(), SIMPORT); break; case 'V': print("%cl version %s\n", thechar, getgoversion()); errorexit(); } ARGEND if(argc != 1) usage(); mywhatsys(); // get goos if(HEADTYPE == -1) { HEADTYPE = 2; if(strcmp(goos, "linux") == 0) HEADTYPE = 7; else if(strcmp(goos, "darwin") == 0) HEADTYPE = 6; else if(strcmp(goos, "nacl") == 0) HEADTYPE = 8; else if(strcmp(goos, "freebsd") == 0) HEADTYPE = 9; else if(strcmp(goos, "mingw") == 0) HEADTYPE = 10; else if(strcmp(goos, "pchw") == 0) HEADTYPE = 11; else print("goos is not known: %s\n", goos); } if(outfile == nil) { if(HEADTYPE == 10) outfile = "8.out.exe"; else outfile = "8.out"; } libinit(); switch(HEADTYPE) { default: diag("unknown -H option"); errorexit(); case 0: /* this is garbage */ HEADR = 20L+56L; if(INITTEXT == -1) INITTEXT = 0x40004CL; if(INITDAT == -1) INITDAT = 0x10000000L; if(INITRND == -1) INITRND = 0; break; case 1: /* is unix coff */ HEADR = 0xd0L; if(INITTEXT == -1) INITTEXT = 0xd0; if(INITDAT == -1) INITDAT = 0x400000; if(INITRND == -1) INITRND = 0; break; case 2: /* plan 9 */ HEADR = 32L; if(INITTEXT == -1) INITTEXT = 4096+32; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case 3: /* MS-DOS .COM */ HEADR = 0; if(INITTEXT == -1) INITTEXT = 0x0100; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4; break; case 4: /* fake MS-DOS .EXE */ HEADR = 0x200; if(INITTEXT == -1) INITTEXT = 0x0100; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4; HEADR += (INITTEXT & 0xFFFF); if(debug['v']) Bprint(&bso, "HEADR = 0x%ld\n", HEADR); break; case 6: /* apple MACH */ /* * OS X system constant - offset from %gs to our TLS. * Explained in ../../libcgo/darwin_386.c. */ tlsoffset = 0x468; machoinit(); HEADR = MACHORESERVE; if(INITTEXT == -1) INITTEXT = 4096+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case 7: /* elf32 executable */ case 9: /* * Linux ELF uses TLS offsets negative from %gs. * Translate 0(GS) and 4(GS) into -8(GS) and -4(GS). * Also known to ../../pkg/runtime/linux/386/sys.s * and ../../libcgo/linux_386.c. */ tlsoffset = -8; elfinit(); HEADR = ELFRESERVE; if(INITTEXT == -1) INITTEXT = 0x08048000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case 8: /* native client elf32 executable */ elfinit(); HEADR = 4096; if(INITTEXT == -1) INITTEXT = 0x20000; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case 10: /* PE executable */ peinit(); HEADR = PERESERVE; if(INITTEXT == -1) INITTEXT = PEBASE+0x1000; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = PEALIGN; break; case 11: tlsoffset = 0; elfinit(); HEADR = ELFRESERVE; if(INITTEXT == -1) INITTEXT = 0x100000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", INITDAT, INITRND); if(debug['v']) Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n", HEADTYPE, INITTEXT, INITDAT, INITRND); Bflush(&bso); for(i=1; optab[i].as; i++) if(i != optab[i].as) { diag("phase error in optab: %d", i); errorexit(); } maxop = i; for(i=0; i<Ymax; i++) ycover[i*Ymax + i] = 1; ycover[Yi0*Ymax + Yi8] = 1; ycover[Yi1*Ymax + Yi8] = 1; ycover[Yi0*Ymax + Yi32] = 1; ycover[Yi1*Ymax + Yi32] = 1; ycover[Yi8*Ymax + Yi32] = 1; ycover[Yal*Ymax + Yrb] = 1; ycover[Ycl*Ymax + Yrb] = 1; ycover[Yax*Ymax + Yrb] = 1; ycover[Ycx*Ymax + Yrb] = 1; ycover[Yrx*Ymax + Yrb] = 1; ycover[Yax*Ymax + Yrx] = 1; ycover[Ycx*Ymax + Yrx] = 1; ycover[Yax*Ymax + Yrl] = 1; ycover[Ycx*Ymax + Yrl] = 1; ycover[Yrx*Ymax + Yrl] = 1; ycover[Yf0*Ymax + Yrf] = 1; ycover[Yal*Ymax + Ymb] = 1; ycover[Ycl*Ymax + Ymb] = 1; ycover[Yax*Ymax + Ymb] = 1; ycover[Ycx*Ymax + Ymb] = 1; ycover[Yrx*Ymax + Ymb] = 1; ycover[Yrb*Ymax + Ymb] = 1; ycover[Ym*Ymax + Ymb] = 1; ycover[Yax*Ymax + Yml] = 1; ycover[Ycx*Ymax + Yml] = 1; ycover[Yrx*Ymax + Yml] = 1; ycover[Yrl*Ymax + Yml] = 1; ycover[Ym*Ymax + Yml] = 1; for(i=0; i<D_NONE; i++) { reg[i] = -1; if(i >= D_AL && i <= D_BH) reg[i] = (i-D_AL) & 7; if(i >= D_AX && i <= D_DI) reg[i] = (i-D_AX) & 7; if(i >= D_F0 && i <= D_F0+7) reg[i] = (i-D_F0) & 7; } zprg.link = P; zprg.pcond = P; zprg.back = 2; zprg.as = AGOK; zprg.from.type = D_NONE; zprg.from.index = D_NONE; zprg.from.scale = 1; zprg.to = zprg.from; pcstr = "%.6lux "; nuxiinit(); histgen = 0; textp = P; datap = P; edatap = P; pc = 0; dtype = 4; version = 0; cbp = buf.cbuf; cbc = sizeof(buf.cbuf); firstp = prg(); lastp = firstp; addlibpath("command line", "command line", argv[0], "main"); loadlib(); deadcode(); firstp = firstp->link; if(firstp == P) errorexit(); if(doexp || dlm){ EXPTAB = "_exporttab"; zerosig(EXPTAB); zerosig("etext"); zerosig("edata"); zerosig("end"); if(dlm){ import(); HEADTYPE = 2; INITTEXT = INITDAT = 0; INITRND = 8; INITENTRY = EXPTAB; } export();
void main(int argc, char *argv[]) { int c; char *name, *val; Binit(&bso, 1, OWRITE); listinit(); memset(debug, 0, sizeof(debug)); nerrors = 0; outfile = nil; HEADTYPE = -1; INITTEXT = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; nuxiinit(); ARGBEGIN { default: c = ARGC(); if(c == 'l') usage(); if(c >= 0 && c < sizeof(debug)) debug[c]++; break; case 'o': /* output to (next arg) */ outfile = EARGF(usage()); break; case 'E': INITENTRY = EARGF(usage()); break; case 'H': HEADTYPE = headtype(EARGF(usage())); break; case 'I': debug['I'] = 1; // denote cmdline interpreter override interpreter = EARGF(usage()); break; case 'L': Lflag(EARGF(usage())); break; case 'T': INITTEXT = atolwhex(EARGF(usage())); break; case 'D': INITDAT = atolwhex(EARGF(usage())); break; case 'R': INITRND = atolwhex(EARGF(usage())); break; case 'r': rpath = EARGF(usage()); break; case 'V': print("%cl version %s\n", thechar, getgoversion()); errorexit(); case 'X': name = EARGF(usage()); val = EARGF(usage()); addstrdata(name, val); break; case 'B': val = EARGF(usage()); addbuildinfo(val); break; } ARGEND if(argc != 1) usage(); mywhatsys(); // get goos if(HEADTYPE == -1) HEADTYPE = headtype(goos); if(outfile == nil) { if(HEADTYPE == Hwindows) outfile = "6.out.exe"; else outfile = "6.out"; } libinit(); switch(HEADTYPE) { default: diag("unknown -H option"); errorexit(); case Hplan9x32: /* plan 9 */ HEADR = 32L; if(INITTEXT == -1) INITTEXT = 4096+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hplan9x64: /* plan 9 */ HEADR = 32L + 8L; if(INITTEXT == -1) INITTEXT = 0x200000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 0x200000; break; case Helf: /* elf32 executable */ HEADR = rnd(52L+3*32L, 16); if(INITTEXT == -1) INITTEXT = 0x80110000L; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hdarwin: /* apple MACH */ /* * OS X system constant - offset from 0(GS) to our TLS. * Explained in ../../pkg/runtime/cgo/gcc_darwin_amd64.c. */ tlsoffset = 0x8a0; machoinit(); HEADR = INITIAL_MACHO_HEADR; if(INITRND == -1) INITRND = 4096; if(INITTEXT == -1) INITTEXT = 4096+HEADR; if(INITDAT == -1) INITDAT = 0; break; case Hlinux: /* elf64 executable */ case Hfreebsd: /* freebsd */ case Hnetbsd: /* netbsd */ case Hopenbsd: /* openbsd */ /* * ELF uses TLS offset negative from FS. * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS). * Also known to ../../pkg/runtime/sys_linux_amd64.s * and ../../pkg/runtime/cgo/gcc_linux_amd64.c. */ tlsoffset = -16; elfinit(); HEADR = ELFRESERVE; if(INITTEXT == -1) INITTEXT = (1<<22)+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case Hwindows: /* PE executable */ peinit(); HEADR = PEFILEHEADR; if(INITTEXT == -1) INITTEXT = PEBASE+PESECTHEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = PESECTALIGN; break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%llux is ignored because of -R0x%ux\n", INITDAT, INITRND); if(debug['v']) Bprint(&bso, "HEADER = -H%d -T0x%llux -D0x%llux -R0x%ux\n", HEADTYPE, INITTEXT, INITDAT, INITRND); Bflush(&bso); instinit(); zprg.link = P; zprg.pcond = P; zprg.back = 2; zprg.as = AGOK; zprg.from.type = D_NONE; zprg.from.index = D_NONE; zprg.from.scale = 1; zprg.to = zprg.from; zprg.mode = 64; pcstr = "%.6llux "; histgen = 0; pc = 0; dtype = 4; version = 0; cbp = buf.cbuf; cbc = sizeof(buf.cbuf); addlibpath("command line", "command line", argv[0], "main"); loadlib(); deadcode(); patch(); follow(); doelf(); if(HEADTYPE == Hdarwin) domacho(); dostkoff(); dostkcheck(); paramspace = "SP"; /* (FP) now (SP) on output */ if(debug['p']) if(debug['1']) doprof1(); else doprof2(); span(); if(HEADTYPE == Hwindows) dope(); addexport(); textaddress(); pclntab(); symtab(); dodata(); address(); doweak(); reloc(); asmb(); undef(); if(debug['v']) { Bprint(&bso, "%5.2f cpu time\n", cputime()); Bprint(&bso, "%d symbols\n", nsymbol); Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); } Bflush(&bso); errorexit(); }
int crackmacho(int fd, Fhdr *fp) { int i; Macho *m; if((m = machoinit(fd)) == nil) return -1; fp->fd = fd; fp->macho = m; for(i=0; i<nelem(mtab); i++){ if(m->cputype != mtab[i].etype) continue; fp->mach = mtab[i].mach; fp->mtype = mtab[i].mtype; fp->mname = mtab[i].name; m->coreregs = mtab[i].coreregs; break; } if(i == nelem(mtab)){ werrstr("unsupported cpu type %ud", m->cputype); goto err; } fp->atype = AMACH; fp->aname = "mach"; if(mach == nil) mach = fp->mach; switch(m->filetype){ default: werrstr("unsupported macho file type %lud", m->filetype); goto err; case MachoFileObject: fp->ftype = FOBJ; fp->fname = "object"; break; case MachoFileExecutable: fp->ftype = FEXEC; fp->fname = "executable"; break; case MachoFileFvmlib: fp->ftype = FSHLIB; fp->fname = "shared library"; break; case MachoFileCore: fp->ftype = FCORE; fp->fname = "core"; break; case MachoFilePreload: fp->ftype = FBOOT; fp->fname = "preloaded executable"; break; } fp->txtaddr = fp->dataddr = 0; fp->txtsz = fp->datsz = 0; for(i=0; i<m->ncmd; i++){ if(m->cmd[i].type != MachoCmdSegment) continue; if(strcmp(m->cmd[i].seg.name, "__TEXT") == 0){ fp->txtaddr = m->cmd[i].seg.vmaddr; fp->txtsz = m->cmd[i].seg.vmsize; fp->txtoff = m->cmd[i].seg.fileoff; } if(strcmp(m->cmd[i].seg.name, "__DATA") == 0){ fp->dataddr = m->cmd[i].seg.vmaddr; fp->datsz = m->cmd[i].seg.filesz; fp->datoff = m->cmd[i].seg.fileoff; fp->bsssz = m->cmd[i].seg.vmsize - fp->datsz; } } fp->map = mapmacho; fp->syminit = symmacho; for(i=0; i<m->ncmd; i++) if(m->cmd[i].type == MachoCmdSymtab) break; if(i < m->ncmd){ fp->stabs.stabbase = load(fp->fd, m->cmd[i].sym.symoff, m->cmd[i].sym.nsym*16); fp->stabs.stabsize = m->cmd[i].sym.nsym*16; fp->stabs.strbase = (char*)load(fp->fd, m->cmd[i].sym.stroff, m->cmd[i].sym.strsize); if(fp->stabs.stabbase == nil || fp->stabs.strbase == nil){ fp->stabs.stabbase = nil; fp->stabs.strbase = nil; }else{ fp->stabs.strsize = m->cmd[i].sym.strsize; fp->stabs.e2 = (m->e4==beload4 ? beload2 : leload2); fp->stabs.e4 = m->e4; } } return 0; err: machoclose(m); return -1; }