summaryrefslogtreecommitdiff
path: root/src/cmd/8l
diff options
context:
space:
mode:
authorHector Chu <hectorchu@gmail.com>2009-12-13 12:39:20 -0800
committerHector Chu <hectorchu@gmail.com>2009-12-13 12:39:20 -0800
commit41571e5c6b33f5a48ad748ddcbe0b65b93bccd10 (patch)
treecda9259e623b814b5a7abe41839cea648a6763aa /src/cmd/8l
parent4a1dc14dabaee0d29e13736cf255dfb5a1736f80 (diff)
downloadgolang-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/Makefile2
-rw-r--r--src/cmd/8l/asm.c9
-rw-r--r--src/cmd/8l/obj.c31
-rw-r--r--src/cmd/8l/pass.c42
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