diff options
Diffstat (limited to 'src/cmd/6l')
-rw-r--r-- | src/cmd/6l/asm.c | 58 | ||||
-rw-r--r-- | src/cmd/6l/doc.go | 8 | ||||
-rw-r--r-- | src/cmd/6l/l.h | 4 | ||||
-rw-r--r-- | src/cmd/6l/obj.c | 68 | ||||
-rw-r--r-- | src/cmd/6l/pass.c | 30 |
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); -} |