diff options
author | Hector Chu <hectorchu@gmail.com> | 2009-12-13 12:39:20 -0800 |
---|---|---|
committer | Hector Chu <hectorchu@gmail.com> | 2009-12-13 12:39:20 -0800 |
commit | 41571e5c6b33f5a48ad748ddcbe0b65b93bccd10 (patch) | |
tree | cda9259e623b814b5a7abe41839cea648a6763aa /src/cmd/8l | |
parent | 4a1dc14dabaee0d29e13736cf255dfb5a1736f80 (diff) | |
download | golang-41571e5c6b33f5a48ad748ddcbe0b65b93bccd10.tar.gz |
8l: add support for PE output.
R=rsc
http://codereview.appspot.com/166080
Committer: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/cmd/8l')
-rw-r--r-- | src/cmd/8l/Makefile | 2 | ||||
-rw-r--r-- | src/cmd/8l/asm.c | 9 | ||||
-rw-r--r-- | src/cmd/8l/obj.c | 31 | ||||
-rw-r--r-- | src/cmd/8l/pass.c | 42 |
4 files changed, 77 insertions, 7 deletions
diff --git a/src/cmd/8l/Makefile b/src/cmd/8l/Makefile index 52bd021c3..88c7c512b 100644 --- a/src/cmd/8l/Makefile +++ b/src/cmd/8l/Makefile @@ -17,6 +17,7 @@ OFILES=\ obj.$O\ optab.$O\ pass.$O\ + pe.$O\ span.$O\ go.$O\ @@ -25,6 +26,7 @@ HFILES=\ ../8l/8.out.h\ ../ld/elf.h\ ../ld/macho.h\ + ../ld/pe.h\ $(TARG): $(OFILES) diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c index 00e9e6925..73ceeba6e 100644 --- a/src/cmd/8l/asm.c +++ b/src/cmd/8l/asm.c @@ -32,6 +32,7 @@ #include "../ld/lib.h" #include "../ld/elf.h" #include "../ld/macho.h" +#include "../ld/pe.h" #define Dbufslop 100 @@ -531,6 +532,7 @@ asmb(void) case 7: case 8: case 9: + case 10: v = rnd(HEADR+textsize, INITRND); seek(cout, v, 0); break; @@ -588,6 +590,7 @@ asmb(void) case 7: case 8: case 9: + case 10: symo = rnd(HEADR+textsize, INITRND)+datsize; symo = rnd(symo, INITRND); break; @@ -605,6 +608,8 @@ asmb(void) asmlc(); if(dlm) asmdyn(); + if(HEADTYPE == 10) + strnput("", INITRND-(8+symsize+lcsize)%INITRND); cflush(); seek(cout, symo, 0); lputl(symsize); @@ -1018,6 +1023,10 @@ asmb(void) if(a+elfwriteinterp() > ELFRESERVE) diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); break; + + case 10: + asmbpe(); + break; } cflush(); } diff --git a/src/cmd/8l/obj.c b/src/cmd/8l/obj.c index dc66e6ee3..89ddf0313 100644 --- a/src/cmd/8l/obj.c +++ b/src/cmd/8l/obj.c @@ -33,6 +33,7 @@ #include "../ld/lib.h" #include "../ld/elf.h" #include "../ld/macho.h" +#include "../ld/pe.h" #include <ar.h> #ifndef DEFAULT @@ -94,7 +95,7 @@ main(int argc, char *argv[]) listinit(); memset(debug, 0, sizeof(debug)); nerrors = 0; - outfile = "8.out"; + outfile = nil; HEADTYPE = -1; INITTEXT = -1; INITDAT = -1; @@ -145,7 +146,7 @@ main(int argc, char *argv[]) if(*argv == 0) usage(); - libinit(); + mywhatsys(); // get goos if(HEADTYPE == -1) { HEADTYPE = 2; @@ -161,9 +162,21 @@ main(int argc, char *argv[]) if(strcmp(goos, "freebsd") == 0) HEADTYPE = 9; else - print("goos is not known: %sn", goos); + if(strcmp(goos, "mingw") == 0) + HEADTYPE = 10; + 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"); @@ -260,6 +273,16 @@ main(int argc, char *argv[]) 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; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", @@ -387,6 +410,8 @@ main(int argc, char *argv[]) doprof2(); span(); doinit(); + if(HEADTYPE == 10) + dope(); asmb(); undef(); if(debug['v']) { diff --git a/src/cmd/8l/pass.c b/src/cmd/8l/pass.c index 16f5a1b5e..6cf2f5d9a 100644 --- a/src/cmd/8l/pass.c +++ b/src/cmd/8l/pass.c @@ -358,6 +358,27 @@ patch(void) s = lookup("exit", 0); vexit = s->value; for(p = firstp; p != P; p = p->link) { + if(HEADTYPE == 10) { + // Convert + // op n(GS), reg + // to + // MOVL 0x2C(FS), reg + // op n(reg), reg + // The purpose of this patch is to fix some accesses + // to extern register variables (TLS) on Windows, as + // a different method is used to access them. + if(p->from.type == D_INDIR+D_GS + && p->to.type >= D_AX && p->to.type <= D_DI) { + q = appendp(p); + q->from = p->from; + q->from.type += p->to.type-D_GS; + q->to = p->to; + q->as = p->as; + p->as = AMOVL; + p->from.type = D_INDIR+D_FS; + p->from.offset = 0x2C; + } + } if(p->as == ATEXT) curtext = p; if(p->as == ACALL || (p->as == AJMP && p->to.type != D_BRANCH)) { @@ -575,10 +596,23 @@ dostkoff(void) if(pmorestack != P) if(!(p->from.scale & NOSPLIT)) { p = appendp(p); // load g into CX - p->as = AMOVL; - p->from.type = D_INDIR+D_GS; - p->from.offset = tlsoffset + 0; - p->to.type = D_CX; + if(HEADTYPE == 10) { + p->as = AMOVL; + p->from.type = D_INDIR+D_FS; + p->from.offset = 0x2c; + p->to.type = D_CX; + + p = appendp(p); + p->as = AMOVL; + p->from.type = D_INDIR+D_CX; + p->from.offset = 0; + p->to.type = D_CX; + } else { + p->as = AMOVL; + p->from.type = D_INDIR+D_GS; + p->from.offset = tlsoffset + 0; + p->to.type = D_CX; + } if(debug['K']) { // 8l -K means check not only for stack |