diff options
Diffstat (limited to 'src/cmd/8l')
-rw-r--r-- | src/cmd/8l/8.out.h | 5 | ||||
-rw-r--r-- | src/cmd/8l/asm.c | 56 | ||||
-rw-r--r-- | src/cmd/8l/doc.go | 10 | ||||
-rw-r--r-- | src/cmd/8l/l.h | 3 | ||||
-rw-r--r-- | src/cmd/8l/obj.c | 94 | ||||
-rw-r--r-- | src/cmd/8l/optab.c | 5 | ||||
-rw-r--r-- | src/cmd/8l/pass.c | 30 |
7 files changed, 103 insertions, 100 deletions
diff --git a/src/cmd/8l/8.out.h b/src/cmd/8l/8.out.h index 0866f05f0..03db0016b 100644 --- a/src/cmd/8l/8.out.h +++ b/src/cmd/8l/8.out.h @@ -392,6 +392,11 @@ enum as ACMPXCHGB, ACMPXCHGL, ACMPXCHGW, + ACMPXCHG8B, + + AXADDB, + AXADDL, + AXADDW, /* conditional move */ ACMOVLCC, diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c index d90eab7e7..1e760d89e 100644 --- a/src/cmd/8l/asm.c +++ b/src/cmd/8l/asm.c @@ -246,7 +246,7 @@ adddynrel(Sym *s, Reloc *r) r->sym = S; return; } - if(HEADTYPE == 6 && s->size == PtrSize && r->off == 0) { + if(HEADTYPE == Hdarwin && s->size == PtrSize && r->off == 0) { // Mach-O relocations are a royal pain to lay out. // They use a compact stateful bytecode representation // that is too much bother to deal with. @@ -356,7 +356,7 @@ addpltsym(Sym *s) adduint32(rel, ELF32_R_INFO(s->dynid, R_386_JMP_SLOT)); s->plt = plt->size - 16; - } else if(HEADTYPE == 6) { // Mach-O + } else if(HEADTYPE == Hdarwin) { // Same laziness as in 6l. Sym *plt; @@ -395,7 +395,7 @@ addgotsym(Sym *s) rel = lookup(".rel", 0); addaddrplus(rel, got, s->got); adduint32(rel, ELF32_R_INFO(s->dynid, R_386_GLOB_DAT)); - } else if(HEADTYPE == 6) { // Mach-O + } else if(HEADTYPE == Hdarwin) { adduint32(lookup(".linkedit.got", 0), s->dynid); } else { diag("addgotsym: unsupported binary format"); @@ -465,7 +465,7 @@ adddynsym(Sym *s) } adduint16(d, t); } - } else if(HEADTYPE == 6) { + } else if(HEADTYPE == Hdarwin) { // Mach-O symbol nlist32 d = lookup(".dynsym", 0); name = s->dynimpname; @@ -481,7 +481,7 @@ adddynsym(Sym *s) adduint8(d, 0); // section adduint16(d, 0); // desc adduint32(d, 0); // value - } else if(HEADTYPE != 10) { + } else if(HEADTYPE != Hwindows) { diag("adddynsym: unsupported binary format"); } } @@ -499,9 +499,9 @@ adddynlib(char *lib) if(s->size == 0) addstring(s, ""); elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(s, lib)); - } else if(HEADTYPE == 6) { // Mach-O + } else if(HEADTYPE == Hdarwin) { machoadddynlib(lib); - } else if(HEADTYPE != 10) { + } else if(HEADTYPE != Hwindows) { diag("adddynlib: unsupported binary format"); } } @@ -673,7 +673,7 @@ asmb(void) datblk(segdata.vaddr, segdata.filelen); machlink = 0; - if(HEADTYPE == 6) + if(HEADTYPE == Hdarwin) machlink = domacholink(); if(iself) { @@ -697,28 +697,28 @@ asmb(void) default: if(iself) goto Elfsym; - case 0: + case Hgarbunix: seek(cout, rnd(HEADR+segtext.filelen, 8192)+segdata.filelen, 0); break; - case 1: + case Hunixcoff: seek(cout, rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen, 0); break; - case 2: + case Hplan9x32: symo = HEADR+segtext.filelen+segdata.filelen; break; - case 3: - case 4: + case Hmsdoscom: + case Hmsdosexe: debug['s'] = 1; symo = HEADR+segtext.filelen+segdata.filelen; break; - case 6: + case Hdarwin: symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(segdata.filelen, INITRND)+machlink; break; Elfsym: symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen; symo = rnd(symo, INITRND); break; - case 10: + case Hwindows: // TODO(brainman): not sure what symo meant to be, but it is not used for Windows PE for now anyway symo = rnd(HEADR+segtext.filelen, PEFILEALIGN)+segdata.filelen; symo = rnd(symo, PEFILEALIGN); @@ -727,7 +727,7 @@ asmb(void) if(!debug['s']) { seek(cout, symo, 0); - if(HEADTYPE == 2) { + if(HEADTYPE == Hplan9x32) { asmplan9sym(); cflush(); @@ -740,7 +740,7 @@ asmb(void) cflush(); } - } else if(HEADTYPE != 10) { + } else if(HEADTYPE != Hwindows) { if(debug['v']) Bprint(&bso, "%5.2f dwarf\n", cputime()); dwarfemitdebugsections(); @@ -755,7 +755,7 @@ asmb(void) default: if(iself) goto Elfput; - case 0: /* garbage */ + case Hgarbunix: /* garbage */ lputb(0x160L<<16); /* magic and sections */ lputb(0L); /* time and date */ lputb(rnd(HEADR+segtext.filelen, 4096)+segdata.filelen); @@ -777,7 +777,7 @@ asmb(void) lputb(~0L); /* gp value ?? */ break; lputl(0); /* x */ - case 1: /* unix coff */ + case Hunixcoff: /* unix coff */ /* * file header */ @@ -845,7 +845,7 @@ asmb(void) lputl(0); /* relocation, line numbers */ lputl(0x200); /* flags comment only */ break; - case 2: /* plan9 */ + case Hplan9x32: /* plan9 */ magic = 4*11*11+7; lputb(magic); /* magic */ lputb(segtext.filelen); /* sizes */ @@ -856,10 +856,10 @@ asmb(void) lputb(spsize); /* sp offsets */ lputb(lcsize); /* line offsets */ break; - case 3: + case Hmsdoscom: /* MS-DOS .COM */ break; - case 4: + case Hmsdosexe: /* fake MS-DOS .EXE */ v = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen; wputl(0x5A4D); /* 'MZ' */ @@ -882,13 +882,13 @@ asmb(void) wputl(0x0000); /* overlay number */ break; - case 6: + case Hdarwin: asmbmacho(); break; Elfput: /* elf 386 */ - if(HEADTYPE == 11) + if(HEADTYPE == Htiny) debug['d'] = 1; eh = getElfEhdr(); @@ -917,10 +917,10 @@ asmb(void) sh->addralign = 1; if(interpreter == nil) { switch(HEADTYPE) { - case 7: + case Hlinux: interpreter = linuxdynld; break; - case 9: + case Hfreebsd: interpreter = freebsddynld; break; } @@ -1068,7 +1068,7 @@ asmb(void) eh->ident[EI_DATA] = ELFDATA2LSB; eh->ident[EI_VERSION] = EV_CURRENT; switch(HEADTYPE) { - case 9: + case Hfreebsd: eh->ident[EI_OSABI] = 9; break; } @@ -1093,7 +1093,7 @@ asmb(void) diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); break; - case 10: + case Hwindows: asmbpe(); break; } diff --git a/src/cmd/8l/doc.go b/src/cmd/8l/doc.go index ef5ebc31d..b70888907 100644 --- a/src/cmd/8l/doc.go +++ b/src/cmd/8l/doc.go @@ -25,10 +25,16 @@ Options new in this version: Elide the dynamic linking header. With this option, the binary is statically linked and does not refer to dynld. Without this option (the default), the binary's contents are identical but it is loaded with dynld. --H6 +-Hplan9 + Write Plan 9 32-bit format binaries (default when $GOOS is plan9) +-Hdarwin Write Apple Mach-O binaries (default when $GOOS is darwin) --H7 +-Hlinux Write Linux ELF binaries (default when $GOOS is linux) +-Hfreebsd + Write FreeBSD ELF binaries (default when $GOOS is freebsd) +-Hwindows + Write Windows PE32 binaries (default when $GOOS is windows) -I interpreter Set the ELF dynamic linker to use. -L dir1 -L dir2 diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h index f2546cf20..e4650ee58 100644 --- a/src/cmd/8l/l.h +++ b/src/cmd/8l/l.h @@ -39,6 +39,7 @@ enum { + thechar = '8', PtrSize = 4 }; @@ -110,6 +111,7 @@ struct Prog }; #define datasize from.scale #define textflag from.scale +#define iscall(p) ((p)->as == ACALL) struct Auto { @@ -128,6 +130,7 @@ struct Sym uchar reachable; uchar dynexport; uchar special; + uchar stkcheck; int32 value; int32 size; int32 sig; diff --git a/src/cmd/8l/obj.c b/src/cmd/8l/obj.c index 9c687f2fc..d505dc10e 100644 --- a/src/cmd/8l/obj.c +++ b/src/cmd/8l/obj.c @@ -44,21 +44,36 @@ #endif char *noname = "<none>"; -char thechar = '8'; char *thestring = "386"; +Header headers[] = { + "garbunix", Hgarbunix, + "unixcoff", Hunixcoff, + "plan9", Hplan9x32, + "msdoscom", Hmsdoscom, + "msdosexe", Hmsdosexe, + "darwin", Hdarwin, + "linux", Hlinux, + "nacl", Hnacl, + "freebsd", Hfreebsd, + "windows", Hwindows, + "windowsgui", Hwindows, + "tiny", Htiny, + 0, 0 +}; + /* - * -H0 -T0x40004C -D0x10000000 is garbage unix - * -H1 -T0xd0 -R4 is unix coff - * -H2 -T4128 -R4096 is plan9 format - * -H3 -Tx -Rx is MS-DOS .COM - * -H4 -Tx -Rx is fake MS-DOS .EXE - * -H6 -Tx -Rx is Apple Mach-O - * -H7 -Tx -Rx is Linux ELF32 - * -H8 -Tx -Rx was Google Native Client - * -H9 -Tx -Rx is FreeBSD ELF32 - * -H10 -Tx -Rx is MS Windows PE - * -H11 -Tx -Rx is tiny (os image) + * -Hgarbunix -T0x40004C -D0x10000000 is garbage unix + * -Hunixcoff -T0xd0 -R4 is unix coff + * -Hplan9 -T4128 -R4096 is plan9 format + * -Hmsdoscom -Tx -Rx is MS-DOS .COM + * -Hmsdosexe -Tx -Rx is fake MS-DOS .EXE + * -Hdarwin -Tx -Rx is Apple Mach-O + * -Hlinux -Tx -Rx is Linux ELF32 + * -Hnacl -Tx -Rx was Google Native Client + * -Hfreebsd -Tx -Rx is FreeBSD ELF32 + * -Hwindows -Tx -Rx is MS Windows PE32 + * -Htiny -Tx -Rx is tiny (os image) */ void @@ -100,7 +115,7 @@ main(int argc, char *argv[]) INITENTRY = EARGF(usage()); break; case 'H': - HEADTYPE = atolwhex(EARGF(usage())); + HEADTYPE = headtype(EARGF(usage())); break; case 'I': interpreter = EARGF(usage()); @@ -130,46 +145,24 @@ main(int argc, char *argv[]) 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, "freebsd") == 0) - HEADTYPE = 9; - else - if(strcmp(goos, "windows") == 0) - HEADTYPE = 10; - else - if(strcmp(goos, "tiny") == 0) - HEADTYPE = 11; - else - if(strcmp(goos, "plan9") == 0) - HEADTYPE = 2; - else - print("goos is not known: %s\n", goos); - } + if(HEADTYPE == -1) + HEADTYPE = headtype(goos); if(outfile == nil) { - if(HEADTYPE == 10) + if(HEADTYPE == Hwindows) outfile = "8.out.exe"; else outfile = "8.out"; } libinit(); - if(rpath == nil) - rpath = smprint("%s/pkg/%s_%s", goroot, goos, goarch); switch(HEADTYPE) { default: diag("unknown -H option"); errorexit(); - case 0: /* this is garbage */ + case Hgarbunix: /* this is garbage */ HEADR = 20L+56L; if(INITTEXT == -1) INITTEXT = 0x40004CL; @@ -178,7 +171,7 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = 0; break; - case 1: /* is unix coff */ + case Hunixcoff: /* is unix coff */ HEADR = 0xd0L; if(INITTEXT == -1) INITTEXT = 0xd0; @@ -187,7 +180,7 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = 0; break; - case 2: /* plan 9 */ + case Hplan9x32: /* plan 9 */ tlsoffset = -8; HEADR = 32L; if(INITTEXT == -1) @@ -197,7 +190,7 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = 1; break; - case 3: /* MS-DOS .COM */ + case Hmsdoscom: /* MS-DOS .COM */ HEADR = 0; if(INITTEXT == -1) INITTEXT = 0x0100; @@ -206,7 +199,7 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = 4; break; - case 4: /* fake MS-DOS .EXE */ + case Hmsdosexe: /* fake MS-DOS .EXE */ HEADR = 0x200; if(INITTEXT == -1) INITTEXT = 0x0100; @@ -218,7 +211,7 @@ main(int argc, char *argv[]) if(debug['v']) Bprint(&bso, "HEADR = 0x%d\n", HEADR); break; - case 6: /* apple MACH */ + case Hdarwin: /* apple MACH */ /* * OS X system constant - offset from %gs to our TLS. * Explained in ../../libcgo/darwin_386.c. @@ -233,8 +226,8 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = 4096; break; - case 7: /* elf32 executable */ - case 9: + 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). @@ -251,7 +244,7 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = 4096; break; - case 10: /* PE executable */ + case Hwindows: /* PE executable */ peinit(); HEADR = PEFILEHEADR; if(INITTEXT == -1) @@ -261,7 +254,7 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = PESECTALIGN; break; - case 11: + case Htiny: tlsoffset = 0; elfinit(); HEADR = ELFRESERVE; @@ -306,9 +299,9 @@ main(int argc, char *argv[]) patch(); follow(); doelf(); - if(HEADTYPE == 6) + if(HEADTYPE == Hdarwin) domacho(); - if(HEADTYPE == 10) + if(HEADTYPE == Hwindows) dope(); dostkoff(); if(debug['p']) @@ -323,6 +316,7 @@ main(int argc, char *argv[]) symtab(); dodata(); address(); + doweak(); reloc(); asmb(); undef(); diff --git a/src/cmd/8l/optab.c b/src/cmd/8l/optab.c index fceab785d..1e89a2105 100644 --- a/src/cmd/8l/optab.c +++ b/src/cmd/8l/optab.c @@ -702,6 +702,11 @@ Optab optab[] = { ACMPXCHGB, yrb_mb, Pm, 0xb0 }, { ACMPXCHGL, yrl_ml, Pm, 0xb1 }, { ACMPXCHGW, yrl_ml, Pm, 0xb1 }, + { ACMPXCHG8B, yscond, Pm, 0xc7,(01) }, + + { AXADDB, yrb_mb, Pb, 0x0f,0xc0 }, + { AXADDL, yrl_ml, Pm, 0xc1 }, + { AXADDW, yrl_ml, Pe, 0x0f,0xc1 }, { ACMOVLCC, yml_rl, Pm, 0x43 }, { ACMOVLCS, yml_rl, Pm, 0x42 }, diff --git a/src/cmd/8l/pass.c b/src/cmd/8l/pass.c index 67acfa167..294926f29 100644 --- a/src/cmd/8l/pass.c +++ b/src/cmd/8l/pass.c @@ -262,12 +262,13 @@ patch(void) s = lookup("exit", 0); vexit = s->value; - if(HEADTYPE == 2) + plan9_tos = S; + if(HEADTYPE == Hplan9x32) plan9_tos = lookup("_tos", 0); for(cursym = textp; cursym != nil; cursym = cursym->next) { for(p = cursym->text; p != P; p = p->link) { - if(HEADTYPE == 10) { // Windows + if(HEADTYPE == Hwindows) { // Convert // op n(GS), reg // to @@ -288,7 +289,7 @@ patch(void) p->from.offset = 0x2C; } } - if(HEADTYPE == 7) { // Linux + if(HEADTYPE == Hlinux) { // Running binaries under Xen requires using // MOVL 0(GS), reg // and then off(reg) instead of saying off(GS) directly @@ -305,7 +306,7 @@ patch(void) p->from.offset = 0; } } - if(HEADTYPE == 2) { // Plan 9 + if(HEADTYPE == Hplan9x32) { if(p->from.type == D_INDIR+D_GS && p->to.type >= D_AX && p->to.type <= D_DI) { q = appendp(p); @@ -412,7 +413,8 @@ dostkoff(void) symmorestack->text->from.scale |= NOSPLIT; } - if(HEADTYPE == 2) + plan9_tos = S; + if(HEADTYPE == Hplan9x32) plan9_tos = lookup("_tos", 0); for(cursym = textp; cursym != nil; cursym = cursym->next) { @@ -430,7 +432,7 @@ dostkoff(void) if(!(p->from.scale & NOSPLIT)) { p = appendp(p); // load g into CX switch(HEADTYPE) { - case 10: // Windows + case Hwindows: p->as = AMOVL; p->from.type = D_INDIR+D_FS; p->from.offset = 0x2c; @@ -443,7 +445,7 @@ dostkoff(void) p->to.type = D_CX; break; - case 7: // Linux + case Hlinux: p->as = AMOVL; p->from.type = D_INDIR+D_GS; p->from.offset = 0; @@ -456,7 +458,7 @@ dostkoff(void) p->to.type = D_CX; break; - case 2: // Plan 9 + case Hplan9x32: p->as = AMOVL; p->from.type = D_EXTERN; p->from.sym = plan9_tos; @@ -664,15 +666,3 @@ atolwhex(char *s) n = -n; return n; } - -void -undef(void) -{ - int i; - Sym *s; - - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->hash) - if(s->type == SXREF) - diag("%s(%d): not defined", s->name, s->version); -} |