summaryrefslogtreecommitdiff
path: root/src/cmd/6l
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6l')
-rw-r--r--src/cmd/6l/asm.c58
-rw-r--r--src/cmd/6l/doc.go8
-rw-r--r--src/cmd/6l/l.h4
-rw-r--r--src/cmd/6l/obj.c68
-rw-r--r--src/cmd/6l/pass.c30
5 files changed, 77 insertions, 91 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index d179e77b1..fb041d83a 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -262,7 +262,7 @@ adddynrel(Sym *s, Reloc *r)
r->type = 256; // ignore during relocsym
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.
@@ -365,7 +365,7 @@ addpltsym(Sym *s)
adduint64(rela, 0);
s->plt = plt->size - 16;
- } else if(HEADTYPE == 6) { // Mach-O
+ } else if(HEADTYPE == Hdarwin) {
// To do lazy symbol lookup right, we're supposed
// to tell the dynamic loader which library each
// symbol comes from and format the link info
@@ -412,7 +412,7 @@ addgotsym(Sym *s)
addaddrplus(rela, got, s->got);
adduint64(rela, ELF64_R_INFO(s->dynid, R_X86_64_GLOB_DAT));
adduint64(rela, 0);
- } else if(HEADTYPE == 6) { // Mach-O
+ } else if(HEADTYPE == Hdarwin) {
adduint32(lookup(".linkedit.got", 0), s->dynid);
} else {
diag("addgotsym: unsupported binary format");
@@ -486,7 +486,7 @@ adddynsym(Sym *s)
elfwritedynent(lookup(".dynamic", 0), DT_NEEDED,
addstring(lookup(".dynstr", 0), s->dynimplib));
}
- } else if(HEADTYPE == 6) {
+ } else if(HEADTYPE == Hdarwin) {
// Mach-o symbol nlist64
d = lookup(".dynsym", 0);
name = s->dynimpname;
@@ -539,7 +539,7 @@ 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 {
diag("adddynlib: unsupported binary format");
@@ -551,7 +551,7 @@ doelf(void)
{
Sym *s, *shstrtab, *dynstr;
- if(HEADTYPE != 7 && HEADTYPE != 9)
+ if(HEADTYPE != Hlinux && HEADTYPE != Hfreebsd)
return;
/* predefine strings we need for section headers */
@@ -717,20 +717,20 @@ asmb(void)
datblk(segdata.vaddr, segdata.filelen);
machlink = 0;
- if(HEADTYPE == 6)
+ if(HEADTYPE == Hdarwin)
machlink = domacholink();
switch(HEADTYPE) {
default:
diag("unknown header type %d", HEADTYPE);
- case 2:
- case 5:
+ case Hplan9x32:
+ case Helf:
break;
- case 6:
+ case Hdarwin:
debug['8'] = 1; /* 64-bit addresses */
break;
- case 7:
- case 9:
+ case Hlinux:
+ case Hfreebsd:
debug['8'] = 1; /* 64-bit addresses */
/* index of elf text section; needed by asmelfsym, double-checked below */
/* !debug['d'] causes extra sections before the .text section */
@@ -738,7 +738,7 @@ asmb(void)
if(!debug['d'])
elftextsh += 10;
break;
- case 10:
+ case Hwindows:
break;
}
@@ -752,20 +752,20 @@ asmb(void)
Bflush(&bso);
switch(HEADTYPE) {
default:
- case 2:
- case 5:
+ case Hplan9x32:
+ case Helf:
debug['s'] = 1;
symo = HEADR+segtext.len+segdata.filelen;
break;
- case 6:
+ case Hdarwin:
symo = rnd(HEADR+segtext.len, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
break;
- case 7:
- case 9:
+ case Hlinux:
+ case Hfreebsd:
symo = rnd(HEADR+segtext.len, INITRND)+segdata.filelen;
symo = rnd(symo, INITRND);
break;
- case 10:
+ case Hwindows:
symo = rnd(HEADR+segtext.filelen, PEFILEALIGN)+segdata.filelen;
symo = rnd(symo, PEFILEALIGN);
break;
@@ -791,7 +791,7 @@ asmb(void)
lputl(symsize);
lputl(lcsize);
cflush();
- if(HEADTYPE != 10 && !debug['s']) {
+ if(HEADTYPE != Hwindows && !debug['s']) {
elfsymo = symo+8+symsize+lcsize;
seek(cout, elfsymo, 0);
asmelfsym64();
@@ -813,7 +813,7 @@ asmb(void)
seek(cout, 0L, 0);
switch(HEADTYPE) {
default:
- case 2: /* plan9 */
+ case Hplan9x32: /* plan9 */
magic = 4*26*26+7;
magic |= 0x00008000; /* fat header */
lputb(magic); /* magic */
@@ -827,7 +827,7 @@ asmb(void)
lputb(lcsize); /* line offsets */
vputb(vl); /* va of entry */
break;
- case 3: /* plan9 */
+ case Hplan9x64: /* plan9 */
magic = 4*26*26+7;
lputb(magic); /* magic */
lputb(segtext.filelen); /* sizes */
@@ -838,11 +838,11 @@ asmb(void)
lputb(spsize); /* sp offsets */
lputb(lcsize); /* line offsets */
break;
- case 6:
+ case Hdarwin:
asmbmacho();
break;
- case 7:
- case 9:
+ case Hlinux:
+ case Hfreebsd:
/* elf amd-64 */
eh = getElfEhdr();
@@ -871,10 +871,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;
}
@@ -1032,7 +1032,7 @@ asmb(void)
eh->ident[EI_MAG1] = 'E';
eh->ident[EI_MAG2] = 'L';
eh->ident[EI_MAG3] = 'F';
- if(HEADTYPE == 9)
+ if(HEADTYPE == Hfreebsd)
eh->ident[EI_OSABI] = 9;
eh->ident[EI_CLASS] = ELFCLASS64;
eh->ident[EI_DATA] = ELFDATA2LSB;
@@ -1055,7 +1055,7 @@ asmb(void)
if(a+elfwriteinterp() > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
- case 10:
+ case Hwindows:
asmbpe();
break;
}
diff --git a/src/cmd/6l/doc.go b/src/cmd/6l/doc.go
index 97fa2cc5a..cc7782cfe 100644
--- a/src/cmd/6l/doc.go
+++ b/src/cmd/6l/doc.go
@@ -28,10 +28,14 @@ Options new in this version:
-e
Emit an extra ELF-compatible symbol table useful with tools such as
nm, gdb, and oprofile. This option makes the binary file considerably larger.
--H6
+-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/6l/l.h b/src/cmd/6l/l.h
index 70473ecd2..6933d8eb1 100644
--- a/src/cmd/6l/l.h
+++ b/src/cmd/6l/l.h
@@ -39,6 +39,7 @@
enum
{
+ thechar = '6',
PtrSize = 8
};
@@ -111,6 +112,7 @@ struct Prog
};
#define datasize from.scale
#define textflag from.scale
+#define iscall(p) ((p)->as == ACALL)
struct Auto
{
@@ -129,6 +131,7 @@ struct Sym
uchar reachable;
uchar dynexport;
uchar special;
+ uchar stkcheck;
int32 dynid;
int32 sig;
int32 plt;
@@ -367,7 +370,6 @@ EXTERN Sym* fromgotype; // type symbol on last p->from read
EXTERN vlong textstksiz;
EXTERN vlong textarg;
-extern char thechar;
EXTERN int elfstrsize;
EXTERN char* elfstrdat;
EXTERN int elftextsh;
diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c
index f9e257842..f113e3ec1 100644
--- a/src/cmd/6l/obj.c
+++ b/src/cmd/6l/obj.c
@@ -40,17 +40,29 @@
#include <ar.h>
char *noname = "<none>";
-char thechar = '6';
char* thestring = "amd64";
char* paramspace = "FP";
+Header headers[] = {
+ "plan9x32", Hplan9x32,
+ "plan9", Hplan9x64,
+ "elf", Helf,
+ "darwin", Hdarwin,
+ "linux", Hlinux,
+ "freebsd", Hfreebsd,
+ "windows", Hwindows,
+ "windowsgui", Hwindows,
+ 0, 0
+};
+
/*
- * -H2 -T4136 -R4096 is plan9 64-bit format
- * -H3 -T4128 -R4096 is plan9 32-bit format
- * -H5 -T0x80110000 -R4096 is ELF32
- * -H6 -Tx -Rx is apple MH-exec
- * -H7 -Tx -Rx is linux elf-exec
- * -H9 -Tx -Rx is FreeBSD elf-exec
+ * -Hplan9x32 -T4136 -R4096 is plan9 64-bit format
+ * -Hplan9 -T4128 -R4096 is plan9 32-bit format
+ * -Helf -T0x80110000 -R4096 is ELF32
+ * -Hdarwin -Tx -Rx is apple MH-exec
+ * -Hlinux -Tx -Rx is linux elf-exec
+ * -Hfreebsd -Tx -Rx is FreeBSD elf-exec
+ * -Hwindows -Tx -Rx is MS Windows PE32+
*
* options used: 189BLQSWabcjlnpsvz
*/
@@ -94,7 +106,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());
@@ -123,31 +135,15 @@ main(int argc, char *argv[])
usage();
libinit();
- if(rpath == nil)
- rpath = smprint("%s/pkg/%s_%s", goroot, goos, goarch);
- 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
- print("goos is not known: %s\n", goos);
- }
+ if(HEADTYPE == -1)
+ HEADTYPE = headtype(goos);
switch(HEADTYPE) {
default:
diag("unknown -H option");
errorexit();
- case 2: /* plan 9 */
+ case Hplan9x32: /* plan 9 */
HEADR = 32L+8L;
if(INITTEXT == -1)
INITTEXT = 4096+HEADR;
@@ -156,7 +152,7 @@ main(int argc, char *argv[])
if(INITRND == -1)
INITRND = 4096;
break;
- case 3: /* plan 9 */
+ case Hplan9x64: /* plan 9 */
HEADR = 32L;
if(INITTEXT == -1)
INITTEXT = 4096+32;
@@ -165,7 +161,7 @@ main(int argc, char *argv[])
if(INITRND == -1)
INITRND = 4096;
break;
- case 5: /* elf32 executable */
+ case Helf: /* elf32 executable */
HEADR = rnd(52L+3*32L, 16);
if(INITTEXT == -1)
INITTEXT = 0x80110000L;
@@ -174,7 +170,7 @@ main(int argc, char *argv[])
if(INITRND == -1)
INITRND = 4096;
break;
- case 6: /* apple MACH */
+ case Hdarwin: /* apple MACH */
/*
* OS X system constant - offset from 0(GS) to our TLS.
* Explained in ../../libcgo/darwin_amd64.c.
@@ -189,8 +185,8 @@ main(int argc, char *argv[])
if(INITDAT == -1)
INITDAT = 0;
break;
- case 7: /* elf64 executable */
- case 9: /* freebsd */
+ case Hlinux: /* elf64 executable */
+ case Hfreebsd: /* freebsd */
/*
* ELF uses TLS offset negative from FS.
* Translate 0(FS) and 8(FS) into -16(FS) and -8(FS).
@@ -207,7 +203,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)
@@ -252,9 +248,10 @@ main(int argc, char *argv[])
patch();
follow();
doelf();
- if(HEADTYPE == 6)
+ if(HEADTYPE == Hdarwin)
domacho();
dostkoff();
+ dostkcheck();
paramspace = "SP"; /* (FP) now (SP) on output */
if(debug['p'])
if(debug['1'])
@@ -262,7 +259,7 @@ main(int argc, char *argv[])
else
doprof2();
span();
- if(HEADTYPE == 10)
+ if(HEADTYPE == Hwindows)
dope();
addexport();
textaddress();
@@ -270,6 +267,7 @@ main(int argc, char *argv[])
symtab();
dodata();
address();
+ doweak();
reloc();
asmb();
undef();
diff --git a/src/cmd/6l/pass.c b/src/cmd/6l/pass.c
index 5eb221a35..8fda94392 100644
--- a/src/cmd/6l/pass.c
+++ b/src/cmd/6l/pass.c
@@ -32,16 +32,10 @@
#include "l.h"
#include "../ld/lib.h"
+#include "../../pkg/runtime/stack.h"
static void xfol(Prog*, Prog**);
-// see ../../runtime/proc.c:/StackGuard
-enum
-{
- StackSmall = 128,
- StackBig = 4096,
-};
-
Prog*
brchain(Prog *p)
{
@@ -277,7 +271,7 @@ patch(void)
vexit = s->value;
for(cursym = textp; cursym != nil; cursym = cursym->next)
for(p = cursym->text; p != P; p = p->link) {
- if(HEADTYPE == 10) {
+ if(HEADTYPE == Hwindows) {
// Windows
// Convert
// op n(GS), reg
@@ -289,7 +283,7 @@ patch(void)
// 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
- && p->from.offset != 0x58) {
+ && p->from.offset <= 8) {
q = appendp(p);
q->from = p->from;
q->from.type = D_INDIR + p->to.type;
@@ -300,7 +294,7 @@ patch(void)
p->from.offset = 0x58;
}
}
- if(HEADTYPE == 7 || HEADTYPE == 9) {
+ if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd) {
// ELF uses FS instead of GS.
if(p->from.type == D_INDIR+D_GS)
p->from.type = D_INDIR+D_FS;
@@ -428,13 +422,13 @@ dostkoff(void)
if(!(p->from.scale & NOSPLIT)) {
p = appendp(p); // load g into CX
p->as = AMOVQ;
- if(HEADTYPE == 7 || HEADTYPE == 9) // ELF uses FS
+ if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd) // ELF uses FS
p->from.type = D_INDIR+D_FS;
else
p->from.type = D_INDIR+D_GS;
p->from.offset = tlsoffset+0;
p->to.type = D_CX;
- if(HEADTYPE == 10) { // Windows
+ if(HEADTYPE == Hwindows) {
// movq %gs:0x58, %rcx
// movq (%rcx), %rcx
p->as = AMOVQ;
@@ -724,15 +718,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: not defined", s->name);
-}