summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-05-23 09:45:29 +0200
committerOndřej Surý <ondrej@sury.org>2011-05-23 09:45:29 +0200
commit63d29fefab5290dc96e0a03ff70603aefa995887 (patch)
tree95da0105686f9aba568a72e7a8ebd580a4fda20e /src/cmd
parentad811fbb8897a9a3063274e927133915941f1dca (diff)
downloadgolang-63d29fefab5290dc96e0a03ff70603aefa995887.tar.gz
Imported Upstream version 2011.05.22upstream-weekly/2011.05.22
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/5a/lex.c53
-rw-r--r--src/cmd/5c/gc.h4
-rw-r--r--src/cmd/5g/gg.h4
-rw-r--r--src/cmd/5l/asm.c216
-rw-r--r--src/cmd/5l/obj.c5
-rw-r--r--src/cmd/5l/optab.c35
-rw-r--r--src/cmd/5l/span.c4
-rw-r--r--src/cmd/6a/lex.c53
-rw-r--r--src/cmd/6g/cgen.c38
-rw-r--r--src/cmd/6g/ggen.c34
-rw-r--r--src/cmd/6g/gsubr.c41
-rw-r--r--src/cmd/6g/reg.c5
-rw-r--r--src/cmd/6l/asm.c74
-rw-r--r--src/cmd/6l/l.h3
-rw-r--r--src/cmd/8a/lex.c53
-rw-r--r--src/cmd/8g/cgen.c40
-rw-r--r--src/cmd/8g/ggen.c29
-rw-r--r--src/cmd/8g/gsubr.c68
-rw-r--r--src/cmd/8l/asm.c75
-rw-r--r--src/cmd/8l/obj.c2
-rw-r--r--src/cmd/8l/pass.c15
-rw-r--r--src/cmd/cc/lex.c58
-rw-r--r--src/cmd/cgo/gcc.go14
-rw-r--r--src/cmd/cgo/out.go12
-rw-r--r--src/cmd/gc/builtin.c.boot4
-rw-r--r--src/cmd/gc/go.h1
-rw-r--r--src/cmd/gc/runtime.go1
-rw-r--r--src/cmd/gc/subr.c14
-rw-r--r--src/cmd/gc/swt.c5
-rw-r--r--src/cmd/gc/typecheck.c21
-rw-r--r--src/cmd/gc/unsafe.c1
-rw-r--r--src/cmd/gc/walk.c146
-rw-r--r--src/cmd/godoc/doc.go3
-rw-r--r--src/cmd/godoc/godoc.go35
-rw-r--r--src/cmd/godoc/main.go15
-rw-r--r--src/cmd/gofix/Makefile1
-rw-r--r--src/cmd/gofix/httpfinalurl.go56
-rw-r--r--src/cmd/gofix/httpfinalurl_test.go37
-rwxr-xr-xsrc/cmd/gofmt/test.sh3
-rw-r--r--src/cmd/gotest/gotest.go5
-rw-r--r--src/cmd/gotype/gotype.go6
-rw-r--r--src/cmd/ld/data.c12
-rw-r--r--src/cmd/ld/dwarf.c1
-rw-r--r--src/cmd/ld/elf.h4
-rw-r--r--src/cmd/ld/go.c2
-rw-r--r--src/cmd/ld/lib.c12
-rw-r--r--src/cmd/ld/lib.h2
-rw-r--r--src/cmd/ld/pe.c6
-rwxr-xr-xsrc/cmd/prof/gopprof9
49 files changed, 731 insertions, 606 deletions
diff --git a/src/cmd/5a/lex.c b/src/cmd/5a/lex.c
index dbee3657f..a04cda220 100644
--- a/src/cmd/5a/lex.c
+++ b/src/cmd/5a/lex.c
@@ -50,7 +50,7 @@ void
main(int argc, char *argv[])
{
char *p;
- int nout, nproc, i, c;
+ int c;
thechar = '5';
thestring = "arm";
@@ -94,46 +94,10 @@ main(int argc, char *argv[])
print("usage: %ca [-options] file.s\n", thechar);
errorexit();
}
- if(argc > 1 && systemtype(Windows)){
- print("can't assemble multiple files on windows\n");
+ if(argc > 1){
+ print("can't assemble multiple files\n");
errorexit();
}
- if(argc > 1 && !systemtype(Windows)) {
- nproc = 1;
- if(p = getenv("NPROC"))
- nproc = atol(p); /* */
- c = 0;
- nout = 0;
- for(;;) {
- Waitmsg *w;
-
- while(nout < nproc && argc > 0) {
- i = fork();
- if(i < 0) {
- fprint(2, "fork: %r\n");
- errorexit();
- }
- if(i == 0) {
- print("%s:\n", *argv);
- if(assemble(*argv))
- errorexit();
- exits(0);
- }
- nout++;
- argc--;
- argv++;
- }
- w = wait();
- if(w == nil) {
- if(c)
- errorexit();
- exits(0);
- }
- if(w->msg[0])
- c++;
- nout--;
- }
- }
if(assemble(argv[0]))
errorexit();
exits(0);
@@ -142,7 +106,7 @@ main(int argc, char *argv[])
int
assemble(char *file)
{
- char *ofile, incfile[20], *p;
+ char *ofile, *p;
int i, of;
ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
@@ -167,15 +131,6 @@ assemble(char *file)
} else
outfile = "/dev/null";
}
- p = getenv("INCLUDE");
- if(p) {
- setinclude(p);
- } else {
- if(systemtype(Plan9)) {
- sprint(incfile,"/%s/include", thestring);
- setinclude(strdup(incfile));
- }
- }
of = create(outfile, OWRITE, 0664);
if(of < 0) {
diff --git a/src/cmd/5c/gc.h b/src/cmd/5c/gc.h
index 9e9d1bd7d..549e0c88a 100644
--- a/src/cmd/5c/gc.h
+++ b/src/cmd/5c/gc.h
@@ -69,7 +69,7 @@ struct Adr
Sym* sym;
char type;
- char reg;
+ uchar reg;
char name;
char etype;
};
@@ -83,7 +83,7 @@ struct Prog
Prog* link;
int32 lineno;
char as;
- char reg;
+ uchar reg;
uchar scond;
};
#define P ((Prog*)0)
diff --git a/src/cmd/5g/gg.h b/src/cmd/5g/gg.h
index 78e6833b2..fe404ed79 100644
--- a/src/cmd/5g/gg.h
+++ b/src/cmd/5g/gg.h
@@ -26,7 +26,7 @@ struct Addr
int width;
uchar type;
char name;
- char reg;
+ uchar reg;
char pun;
uchar etype;
};
@@ -41,7 +41,7 @@ struct Prog
Addr to; // dst address
Prog* link; // next instruction in this func
void* regp; // points to enclosing Reg struct
- char reg; // doubles as width in DATA op
+ uchar reg; // doubles as width in DATA op
uchar scond;
};
diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c
index e2583e7c3..9e9c2c1eb 100644
--- a/src/cmd/5l/asm.c
+++ b/src/cmd/5l/asm.c
@@ -73,6 +73,8 @@ enum {
ElfStrGosymcounts,
ElfStrGosymtab,
ElfStrGopclntab,
+ ElfStrSymtab,
+ ElfStrStrtab,
ElfStrShstrtab,
ElfStrRelPlt,
ElfStrPlt,
@@ -87,6 +89,9 @@ needlib(char *name)
char *p;
Sym *s;
+ if(*name == '\0')
+ return 0;
+
/* reuse hash code in symbol table */
p = smprint(".dynlib.%s", name);
s = lookup(p, 0);
@@ -163,6 +168,8 @@ doelf(void)
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
+ elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
+ elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
}
elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab");
@@ -288,19 +295,20 @@ asmb(void)
{
int32 t;
int a, dynsym;
- uint32 va, fo, w, startva;
- int strtabsize;
+ uint32 fo, symo, startva, elfsymo, elfstro, elfsymsize;
ElfEhdr *eh;
ElfPhdr *ph, *pph;
ElfShdr *sh;
Section *sect;
- strtabsize = 0;
-
if(debug['v'])
Bprint(&bso, "%5.2f asmb\n", cputime());
Bflush(&bso);
+ elfsymsize = 0;
+ elfstro = 0;
+ elfsymo = 0;
+
sect = segtext.sect;
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
codeblk(sect->vaddr, sect->len);
@@ -322,15 +330,30 @@ asmb(void)
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
datblk(sect->vaddr, sect->len);
+ if(iself) {
+ /* index of elf text section; needed by asmelfsym, double-checked below */
+ /* !debug['d'] causes extra sections before the .text section */
+ elftextsh = 1;
+ if(!debug['d']) {
+ elftextsh += 10;
+ if(elfverneed)
+ elftextsh += 2;
+ }
+ }
+
/* output symbol table */
symsize = 0;
lcsize = 0;
+ symo = 0;
if(!debug['s']) {
// TODO: rationalize
if(debug['v'])
Bprint(&bso, "%5.2f sym\n", cputime());
Bflush(&bso);
switch(HEADTYPE) {
+ default:
+ if(iself)
+ goto ElfSym;
case Hnoheader:
case Hrisc:
case Hixp1200:
@@ -345,14 +368,29 @@ asmb(void)
OFFSET += rnd(segdata.filelen, 4096);
seek(cout, OFFSET, 0);
break;
- case Hlinux:
- OFFSET += segdata.filelen;
- seek(cout, rnd(OFFSET, INITRND), 0);
+ ElfSym:
+ symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
+ symo = rnd(symo, INITRND);
break;
}
- if(!debug['s'])
- asmthumbmap();
+ if(iself) {
+ if(debug['v'])
+ Bprint(&bso, "%5.2f elfsym\n", cputime());
+ elfsymo = symo+8+symsize+lcsize;
+ seek(cout, elfsymo, 0);
+ asmelfsym32();
+ cflush();
+ elfstro = seek(cout, 0, 1);
+ elfsymsize = elfstro - elfsymo;
+ ewrite(cout, elfstrdat, elfstrsize);
+
+ // if(debug['v'])
+ // Bprint(&bso, "%5.2f dwarf\n", cputime());
+ // dwarfemitdebugsections();
+ }
+ asmthumbmap();
cflush();
+
}
cursym = nil;
@@ -426,9 +464,7 @@ asmb(void)
/* elf arm */
eh = getElfEhdr();
fo = HEADR;
- va = INITTEXT;
startva = INITTEXT - fo; /* va of byte 0 of file */
- w = textsize;
/* This null SHdr must appear before all others */
sh = newElfShdr(elfstr[ElfStrEmpty]);
@@ -541,6 +577,8 @@ asmb(void)
ph->flags = PF_W+PF_R;
ph->align = 4;
+ if(elftextsh != eh->shnum)
+ diag("elftextsh = %d, want %d", elftextsh, eh->shnum);
for(sect=segtext.sect; sect!=nil; sect=sect->next)
elfshbits(sect);
for(sect=segdata.sect; sect!=nil; sect=sect->next)
@@ -558,6 +596,22 @@ asmb(void)
sh->flags = SHF_ALLOC;
sh->addralign = 1;
shsym(sh, lookup("pclntab", 0));
+
+ sh = newElfShdr(elfstr[ElfStrSymtab]);
+ sh->type = SHT_SYMTAB;
+ sh->off = elfsymo;
+ sh->size = elfsymsize;
+ sh->addralign = 4;
+ sh->entsize = 16;
+ sh->link = eh->shnum; // link to strtab
+
+ sh = newElfShdr(elfstr[ElfStrStrtab]);
+ sh->type = SHT_STRTAB;
+ sh->off = elfstro;
+ sh->size = elfstrsize;
+ sh->addralign = 1;
+
+ // dwarfaddelfheaders();
}
sh = newElfShstrtab(elfstr[ElfStrShstrtab]);
@@ -990,40 +1044,6 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= 1<<22;
break;
- case 22: /* movb/movh/movhu O(R),R -> lr,shl,shr */
- aclass(&p->from);
- r = p->from.reg;
- if(r == NREG)
- r = o->param;
- o1 = olr(instoffset, r, p->to.reg, p->scond);
-
- o2 = oprrr(ASLL, p->scond);
- o3 = oprrr(ASRA, p->scond);
- r = p->to.reg;
- if(p->as == AMOVB) {
- o2 |= (24<<7)|(r)|(r<<12);
- o3 |= (24<<7)|(r)|(r<<12);
- } else {
- o2 |= (16<<7)|(r)|(r<<12);
- if(p->as == AMOVHU)
- o3 = oprrr(ASRL, p->scond);
- o3 |= (16<<7)|(r)|(r<<12);
- }
- break;
-
- case 23: /* movh/movhu R,O(R) -> sb,sb */
- aclass(&p->to);
- r = p->to.reg;
- if(r == NREG)
- r = o->param;
- o1 = osr(AMOVH, p->from.reg, instoffset, r, p->scond);
-
- o2 = oprrr(ASRL, p->scond);
- o2 |= (8<<7)|(p->from.reg)|(REGTMP<<12);
-
- o3 = osr(AMOVH, REGTMP, instoffset+1, r, p->scond);
- break;
-
case 30: /* mov/movb/movbu R,L(R) */
o1 = omvl(p, &p->to, REGTMP);
if(!o1)
@@ -1037,7 +1057,6 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
break;
case 31: /* mov/movbu L(R),R -> lr[b] */
- case 32: /* movh/movb L(R),R -> lr[b] */
o1 = omvl(p, &p->from, REGTMP);
if(!o1)
break;
@@ -1047,53 +1066,6 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
o2 = olrr(REGTMP,r, p->to.reg, p->scond);
if(p->as == AMOVBU || p->as == AMOVB)
o2 |= 1<<22;
- if(o->type == 31)
- break;
-
- o3 = oprrr(ASLL, p->scond);
-
- if(p->as == AMOVBU || p->as == AMOVHU)
- o4 = oprrr(ASRL, p->scond);
- else
- o4 = oprrr(ASRA, p->scond);
-
- r = p->to.reg;
- o3 |= (r)|(r<<12);
- o4 |= (r)|(r<<12);
- if(p->as == AMOVB || p->as == AMOVBU) {
- o3 |= (24<<7);
- o4 |= (24<<7);
- } else {
- o3 |= (16<<7);
- o4 |= (16<<7);
- }
- break;
-
- case 33: /* movh/movhu R,L(R) -> sb, sb */
- o1 = omvl(p, &p->to, REGTMP);
- if(!o1)
- break;
- r = p->to.reg;
- if(r == NREG)
- r = o->param;
- o2 = osrr(p->from.reg, REGTMP, r, p->scond);
- o2 |= (1<<22) ;
-
- o3 = oprrr(ASRL, p->scond);
- o3 |= (8<<7)|(p->from.reg)|(p->from.reg<<12);
- o3 |= (1<<6); /* ROR 8 */
-
- o4 = oprrr(AADD, p->scond);
- o4 |= (REGTMP << 12) | (REGTMP << 16);
- o4 |= immrot(1);
-
- o5 = osrr(p->from.reg, REGTMP,r,p->scond);
- o5 |= (1<<22);
-
- o6 = oprrr(ASRL, p->scond);
- o6 |= (24<<7)|(p->from.reg)|(p->from.reg<<12);
- o6 |= (1<<6); /* ROL 8 */
-
break;
case 34: /* mov $lacon,R */
@@ -1304,54 +1276,12 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
break;
case 65: /* mov/movbu addr,R */
- case 66: /* movh/movhu/movb addr,R */
o1 = omvl(p, &p->from, REGTMP);
if(!o1)
break;
o2 = olr(0, REGTMP, p->to.reg, p->scond);
if(p->as == AMOVBU || p->as == AMOVB)
o2 |= 1<<22;
- if(o->type == 65)
- break;
-
- o3 = oprrr(ASLL, p->scond);
-
- if(p->as == AMOVBU || p->as == AMOVHU)
- o4 = oprrr(ASRL, p->scond);
- else
- o4 = oprrr(ASRA, p->scond);
-
- r = p->to.reg;
- o3 |= (r)|(r<<12);
- o4 |= (r)|(r<<12);
- if(p->as == AMOVB || p->as == AMOVBU) {
- o3 |= (24<<7);
- o4 |= (24<<7);
- } else {
- o3 |= (16<<7);
- o4 |= (16<<7);
- }
- break;
-
- case 67: /* movh/movhu R,addr -> sb, sb */
- o1 = omvl(p, &p->to, REGTMP);
- if(!o1)
- break;
- o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);
-
- o3 = oprrr(ASRL, p->scond);
- o3 |= (8<<7)|(p->from.reg)|(p->from.reg<<12);
- o3 |= (1<<6); /* ROR 8 */
-
- o4 = oprrr(AADD, p->scond);
- o4 |= (REGTMP << 12) | (REGTMP << 16);
- o4 |= immrot(1);
-
- o5 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);
-
- o6 = oprrr(ASRL, p->scond);
- o6 |= (24<<7)|(p->from.reg)|(p->from.reg<<12);
- o6 |= (1<<6); /* ROL 8 */
break;
case 68: /* floating point store -> ADDR */
@@ -1572,6 +1502,22 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= p->to.reg << 12;
o1 |= (p->scond & C_SCOND) << 28;
break;
+ case 93: /* movb/movh/movhu addr,R -> ldrsb/ldrsh/ldrh */
+ o1 = omvl(p, &p->from, REGTMP);
+ if(!o1)
+ break;
+ o2 = olhr(0, REGTMP, p->to.reg, p->scond);
+ if(p->as == AMOVB)
+ o2 ^= (1<<5)|(1<<6);
+ else if(p->as == AMOVH)
+ o2 ^= (1<<6);
+ break;
+ case 94: /* movh/movhu R,addr -> strh */
+ o1 = omvl(p, &p->to, REGTMP);
+ if(!o1)
+ break;
+ o2 = oshr(p->from.reg, 0, REGTMP, p->scond);
+ break;
}
out[0] = o1;
diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c
index c4a2bfc3f..96ba0010f 100644
--- a/src/cmd/5l/obj.c
+++ b/src/cmd/5l/obj.c
@@ -219,7 +219,7 @@ main(int argc, char *argv[])
elfinit();
HEADR = ELFRESERVE;
if(INITTEXT == -1)
- INITTEXT = 0x8000 + HEADR;
+ INITTEXT = 0x10000 + HEADR;
if(INITDAT == -1)
INITDAT = 0;
if(INITRND == -1)
@@ -412,7 +412,7 @@ ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
{
int32 ipc;
Prog *p;
- Sym *h[NSYM], *s, *di;
+ Sym *h[NSYM], *s;
int v, o, r, skip;
uint32 sig;
char *name;
@@ -424,7 +424,6 @@ ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
lastp = nil;
ntext = 0;
eof = Boffset(f) + len;
- di = S;
src[0] = 0;
newloop:
diff --git a/src/cmd/5l/optab.c b/src/cmd/5l/optab.c
index 625b66812..4816aa40f 100644
--- a/src/cmd/5l/optab.c
+++ b/src/cmd/5l/optab.c
@@ -117,18 +117,6 @@ Optab optab[] =
{ AMOVBU, C_SAUTO,C_NONE, C_REG, 21, 4, REGSP },
{ AMOVBU, C_SOREG,C_NONE, C_REG, 21, 4, 0 },
- { AMOVB, C_SAUTO,C_NONE, C_REG, 22, 12, REGSP },
- { AMOVB, C_SOREG,C_NONE, C_REG, 22, 12, 0 },
- { AMOVH, C_SAUTO,C_NONE, C_REG, 22, 12, REGSP },
- { AMOVH, C_SOREG,C_NONE, C_REG, 22, 12, 0 },
- { AMOVHU, C_SAUTO,C_NONE, C_REG, 22, 12, REGSP },
- { AMOVHU, C_SOREG,C_NONE, C_REG, 22, 12, 0 },
-
- { AMOVH, C_REG, C_NONE, C_SAUTO, 23, 12, REGSP },
- { AMOVH, C_REG, C_NONE, C_SOREG, 23, 12, 0 },
- { AMOVHU, C_REG, C_NONE, C_SAUTO, 23, 12, REGSP },
- { AMOVHU, C_REG, C_NONE, C_SOREG, 23, 12, 0 },
-
{ AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO },
{ AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO },
{ AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO },
@@ -146,23 +134,6 @@ Optab optab[] =
{ AMOVBU, C_LOREG,C_NONE, C_REG, 31, 8, 0, LFROM },
{ AMOVBU, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM },
- { AMOVB, C_LAUTO,C_NONE, C_REG, 32, 16, REGSP, LFROM },
- { AMOVB, C_LOREG,C_NONE, C_REG, 32, 16, 0, LFROM },
- { AMOVB, C_ADDR, C_NONE, C_REG, 66, 16, 0, LFROM },
- { AMOVH, C_LAUTO,C_NONE, C_REG, 32, 16, REGSP, LFROM },
- { AMOVH, C_LOREG,C_NONE, C_REG, 32, 16, 0, LFROM },
- { AMOVH, C_ADDR, C_NONE, C_REG, 66, 16, 0, LFROM },
- { AMOVHU, C_LAUTO,C_NONE, C_REG, 32, 16, REGSP, LFROM },
- { AMOVHU, C_LOREG,C_NONE, C_REG, 32, 16, 0, LFROM },
- { AMOVHU, C_ADDR, C_NONE, C_REG, 66, 16, 0, LFROM },
-
- { AMOVH, C_REG, C_NONE, C_LAUTO, 33, 24, REGSP, LTO },
- { AMOVH, C_REG, C_NONE, C_LOREG, 33, 24, 0, LTO },
- { AMOVH, C_REG, C_NONE, C_ADDR, 67, 24, 0, LTO },
- { AMOVHU, C_REG, C_NONE, C_LAUTO, 33, 24, REGSP, LTO },
- { AMOVHU, C_REG, C_NONE, C_LOREG, 33, 24, 0, LTO },
- { AMOVHU, C_REG, C_NONE, C_ADDR, 67, 24, 0, LTO },
-
{ AMOVW, C_LACON,C_NONE, C_REG, 34, 8, REGSP, LFROM },
{ AMOVW, C_PSR, C_NONE, C_REG, 35, 4, 0 },
@@ -224,15 +195,21 @@ Optab optab[] =
{ AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO|V4 },
{ AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO|V4 },
+ { AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO|V4 },
{ AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO|V4 },
{ AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO|V4 },
+ { AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO|V4 },
{ AMOVB, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM|V4 },
{ AMOVB, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM|V4 },
+ { AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM|V4 },
{ AMOVH, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM|V4 },
{ AMOVH, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM|V4 },
+ { AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM|V4 },
{ AMOVHU, C_LAUTO,C_NONE, C_REG, 73, 8, REGSP, LFROM|V4 },
{ AMOVHU, C_LOREG,C_NONE, C_REG, 73, 8, 0, LFROM|V4 },
+ { AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM|V4 },
+
{ ALDREX, C_SOREG,C_NONE, C_REG, 77, 4, 0 },
{ ASTREX, C_SOREG,C_REG, C_REG, 78, 4, 0 },
diff --git a/src/cmd/5l/span.c b/src/cmd/5l/span.c
index 482d3e90a..4067f1a32 100644
--- a/src/cmd/5l/span.c
+++ b/src/cmd/5l/span.c
@@ -168,7 +168,6 @@ span(void)
Optab *o;
int m, bflag, i, v;
int32 c, otxt, out[6];
- int lastthumb = -1;
Section *sect;
uchar *bp;
@@ -187,7 +186,6 @@ span(void)
p->pc = c;
cursym->value = c;
- lastthumb = thumb;
autosize = p->to.offset + 4;
if(p->from.sym != S)
p->from.sym->value = c;
@@ -927,7 +925,7 @@ buildop(void)
{
int i, n, r;
- armv4 = !debug['h'];
+ armv4 = 1;
for(i=0; i<C_GOK; i++)
for(n=0; n<C_GOK; n++)
xcmp[i][n] = cmp(n, i);
diff --git a/src/cmd/6a/lex.c b/src/cmd/6a/lex.c
index 37144c888..b4c7d0c2c 100644
--- a/src/cmd/6a/lex.c
+++ b/src/cmd/6a/lex.c
@@ -56,7 +56,7 @@ void
main(int argc, char *argv[])
{
char *p;
- int nout, nproc, i, c;
+ int c;
thechar = '6';
thestring = "amd64";
@@ -96,46 +96,10 @@ main(int argc, char *argv[])
print("usage: %ca [-options] file.s\n", thechar);
errorexit();
}
- if(argc > 1 && systemtype(Windows)){
- print("can't assemble multiple files on windows\n");
+ if(argc > 1){
+ print("can't assemble multiple files\n");
errorexit();
}
- if(argc > 1 && !systemtype(Windows)) {
- nproc = 1;
- if(p = getenv("NPROC"))
- nproc = atol(p); /* */
- c = 0;
- nout = 0;
- for(;;) {
- Waitmsg *w;
-
- while(nout < nproc && argc > 0) {
- i = fork();
- if(i < 0) {
- fprint(2, "fork: %r\n");
- errorexit();
- }
- if(i == 0) {
- print("%s:\n", *argv);
- if(assemble(*argv))
- errorexit();
- exits(0);
- }
- nout++;
- argc--;
- argv++;
- }
- w = wait();
- if(w == nil) {
- if(c)
- errorexit();
- exits(0);
- }
- if(w->msg[0])
- c++;
- nout--;
- }
- }
if(assemble(argv[0]))
errorexit();
exits(0);
@@ -144,7 +108,7 @@ main(int argc, char *argv[])
int
assemble(char *file)
{
- char *ofile, incfile[20], *p;
+ char *ofile, *p;
int i, of;
ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
@@ -169,15 +133,6 @@ assemble(char *file)
} else
outfile = "/dev/null";
}
- p = getenv("INCLUDE");
- if(p) {
- setinclude(p);
- } else {
- if(systemtype(Plan9)) {
- sprint(incfile,"/%s/include", thestring);
- setinclude(strdup(incfile));
- }
- }
of = create(outfile, OWRITE, 0664);
if(of < 0) {
diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c
index 75dc4fe13..fca4b64dd 100644
--- a/src/cmd/6g/cgen.c
+++ b/src/cmd/6g/cgen.c
@@ -283,11 +283,9 @@ cgen(Node *n, Node *res)
if(istype(nl->type, TSTRING) || isslice(nl->type)) {
// both slice and string have len one pointer into the struct.
// a zero pointer means zero length
- regalloc(&n1, types[tptr], res);
- agen(nl, &n1);
- n1.op = OINDREG;
+ igen(nl, &n1, res);
n1.type = types[TUINT32];
- n1.xoffset = Array_nel;
+ n1.xoffset += Array_nel;
gmove(&n1, res);
regfree(&n1);
break;
@@ -319,11 +317,9 @@ cgen(Node *n, Node *res)
break;
}
if(isslice(nl->type)) {
- regalloc(&n1, types[tptr], res);
- agen(nl, &n1);
- n1.op = OINDREG;
+ igen(nl, &n1, res);
n1.type = types[TUINT32];
- n1.xoffset = Array_cap;
+ n1.xoffset += Array_cap;
gmove(&n1, res);
regfree(&n1);
break;
@@ -542,7 +538,8 @@ agen(Node *n, Node *res)
gmove(&n1, &n3);
}
- ginscon(optoas(OADD, types[tptr]), v*w, &n3);
+ if (v*w != 0)
+ ginscon(optoas(OADD, types[tptr]), v*w, &n3);
gmove(&n3, res);
regfree(&n3);
break;
@@ -682,6 +679,28 @@ ret:
void
igen(Node *n, Node *a, Node *res)
{
+ Type *fp;
+ Iter flist;
+
+ switch(n->op) {
+ case ONAME:
+ if((n->class&PHEAP) || n->class == PPARAMREF)
+ break;
+ *a = *n;
+ return;
+
+ case OCALLFUNC:
+ fp = structfirst(&flist, getoutarg(n->left->type));
+ cgen_call(n, 0);
+ memset(a, 0, sizeof *a);
+ a->op = OINDREG;
+ a->val.u.reg = D_SP;
+ a->addable = 1;
+ a->xoffset = fp->width;
+ a->type = n->type;
+ return;
+ }
+
regalloc(a, types[tptr], res);
agen(n, a);
a->op = OINDREG;
@@ -848,6 +867,7 @@ bgen(Node *n, int true, Prog *to)
n2 = n1;
n2.op = OINDREG;
n2.xoffset = Array_array;
+ n2.type = types[tptr];
nodconst(&tmp, types[tptr], 0);
gins(optoas(OCMP, types[tptr]), &n2, &tmp);
patch(gbranch(a, types[tptr]), to);
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
index 8d89fb164..ce66b43f0 100644
--- a/src/cmd/6g/ggen.c
+++ b/src/cmd/6g/ggen.c
@@ -201,7 +201,7 @@ cgen_callinter(Node *n, Node *res, int proc)
regalloc(&nodo, types[tptr], &nodr);
nodo.op = OINDREG;
- agen(i, &nodr); // REG = &inter
+ agen(i, &nodr); // REG = &inter
nodindreg(&nodsp, types[tptr], D_SP);
nodo.xoffset += widthptr;
@@ -1206,7 +1206,7 @@ cgen_inline(Node *n, Node *res)
Node nodes[5];
Node n1, n2, nres, ntemp;
vlong v;
- int i, narg;
+ int i, narg, nochk;
if(n->op != OCALLFUNC)
goto no;
@@ -1242,6 +1242,7 @@ slicearray:
// len = hb[3] - lb[2] (destroys hb)
n2 = *res;
n2.xoffset += Array_nel;
+ n2.type = types[TUINT32];
if(smallintconst(&nodes[3]) && smallintconst(&nodes[2])) {
v = mpgetfix(nodes[3].val.u.xval) -
@@ -1260,6 +1261,7 @@ slicearray:
// cap = nel[1] - lb[2] (destroys nel)
n2 = *res;
n2.xoffset += Array_cap;
+ n2.type = types[TUINT32];
if(smallintconst(&nodes[1]) && smallintconst(&nodes[2])) {
v = mpgetfix(nodes[1].val.u.xval) -
@@ -1288,6 +1290,7 @@ slicearray:
// ary = old[0] + (lb[2] * width[4]) (destroys old)
n2 = *res;
n2.xoffset += Array_array;
+ n2.type = types[tptr];
if(smallintconst(&nodes[2]) && smallintconst(&nodes[4])) {
v = mpgetfix(nodes[2].val.u.xval) *
@@ -1311,6 +1314,7 @@ slicearray:
return 1;
sliceslice:
+ nochk = n->etype; // skip bounds checking
ntemp.op = OXXX;
if(!sleasy(n->list->n->right)) {
Node *n0;
@@ -1340,11 +1344,13 @@ sliceslice:
n2 = nodes[0];
n2.xoffset += Array_nel;
n2.type = types[TUINT32];
- cmpandthrow(&nodes[1], &n2);
+ if(!nochk)
+ cmpandthrow(&nodes[1], &n2);
// ret.nel = old.nel[0]-lb[1];
n2 = nodes[0];
n2.xoffset += Array_nel;
+ n2.type = types[TUINT32];
regalloc(&n1, types[TUINT32], N);
gins(optoas(OAS, types[TUINT32]), &n2, &n1);
@@ -1353,22 +1359,24 @@ sliceslice:
n2 = nres;
n2.xoffset += Array_nel;
+ n2.type = types[TUINT32];
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1);
} else { // old[lb:hb]
- // if(hb[2] > old.cap[0]) goto throw;
n2 = nodes[0];
n2.xoffset += Array_cap;
n2.type = types[TUINT32];
- cmpandthrow(&nodes[2], &n2);
-
- // if(lb[1] > hb[2]) goto throw;
- cmpandthrow(&nodes[1], &nodes[2]);
-
+ if(!nochk) {
+ // if(hb[2] > old.cap[0]) goto throw;
+ cmpandthrow(&nodes[2], &n2);
+ // if(lb[1] > hb[2]) goto throw;
+ cmpandthrow(&nodes[1], &nodes[2]);
+ }
// ret.len = hb[2]-lb[1]; (destroys hb[2])
n2 = nres;
n2.xoffset += Array_nel;
-
+ n2.type = types[TUINT32];
+
if(smallintconst(&nodes[2]) && smallintconst(&nodes[1])) {
v = mpgetfix(nodes[2].val.u.xval) -
mpgetfix(nodes[1].val.u.xval);
@@ -1387,6 +1395,7 @@ sliceslice:
// ret.cap = old.cap[0]-lb[1]; (uses hb[2])
n2 = nodes[0];
n2.xoffset += Array_cap;
+ n2.type = types[TUINT32];
regalloc(&n1, types[TUINT32], &nodes[2]);
gins(optoas(OAS, types[TUINT32]), &n2, &n1);
@@ -1395,13 +1404,15 @@ sliceslice:
n2 = nres;
n2.xoffset += Array_cap;
+ n2.type = types[TUINT32];
+
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1);
// ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
n2 = nodes[0];
n2.xoffset += Array_array;
-
+ n2.type = types[tptr];
regalloc(&n1, types[tptr], &nodes[1]);
if(smallintconst(&nodes[1]) && smallintconst(&nodes[3])) {
gins(optoas(OAS, types[tptr]), &n2, &n1);
@@ -1418,6 +1429,7 @@ sliceslice:
n2 = nres;
n2.xoffset += Array_array;
+ n2.type = types[tptr];
gins(optoas(OAS, types[tptr]), &n1, &n2);
regfree(&n1);
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c
index c3dac1fdc..ed98d1bc9 100644
--- a/src/cmd/6g/gsubr.c
+++ b/src/cmd/6g/gsubr.c
@@ -48,7 +48,7 @@ clearp(Prog *p)
/*
* generate and return proc with p->as = as,
- * linked into program. pc is next instruction.
+ * linked into program. pc is next instruction.
*/
Prog*
prog(int as)
@@ -330,11 +330,13 @@ regfree(Node *n)
{
int i;
- if(n->op == ONAME && iscomplex[n->type->etype])
+ if(n->op == ONAME)
return;
if(n->op != OREGISTER && n->op != OINDREG)
fatal("regfree: not a register");
i = n->val.u.reg;
+ if(i == D_SP)
+ return;
if(i < 0 || i >= sizeof(reg))
fatal("regfree: reg out of range");
if(reg[i] <= 0)
@@ -888,7 +890,7 @@ Prog*
gins(int as, Node *f, Node *t)
{
// Node nod;
-// int32 v;
+ int32 w;
Prog *p;
Addr af, at;
@@ -933,6 +935,27 @@ gins(int as, Node *f, Node *t)
p->to = at;
if(debug['g'])
print("%P\n", p);
+
+
+ w = 0;
+ switch(as) {
+ case AMOVB:
+ w = 1;
+ break;
+ case AMOVW:
+ w = 2;
+ break;
+ case AMOVL:
+ w = 4;
+ break;
+ case AMOVQ:
+ w = 8;
+ break;
+ }
+ if(w != 0 && f != N && (af.width > w || at.width > w)) {
+ fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
+ }
+
return p;
}
@@ -947,7 +970,7 @@ checkoffset(Addr *a, int canemitcode)
fatal("checkoffset %#llx, cannot emit code", a->offset);
// cannot rely on unmapped nil page at 0 to catch
- // reference with large offset. instead, emit explicit
+ // reference with large offset. instead, emit explicit
// test of 0(reg).
p = gins(ATESTB, nodintconst(0), N);
p->to = *a;
@@ -1106,8 +1129,9 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
break; // len(nil)
- a->etype = TUINT;
+ a->etype = TUINT32;
a->offset += Array_nel;
+ a->width = 4;
if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
checkoffset(a, canemitcode);
break;
@@ -1117,8 +1141,9 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
break; // cap(nil)
- a->etype = TUINT;
+ a->etype = TUINT32;
a->offset += Array_cap;
+ a->width = 4;
if(a->offset >= unmappedzero && a->offset-Array_cap < unmappedzero)
checkoffset(a, canemitcode);
break;
@@ -1962,12 +1987,12 @@ oindex:
if(o & OAddable) {
n2 = *l;
n2.xoffset += Array_array;
- n2.type = types[TUINT64];
+ n2.type = types[tptr];
gmove(&n2, reg);
} else {
n2 = *reg;
- n2.xoffset = Array_array;
n2.op = OINDREG;
+ n2.xoffset = Array_array;
n2.type = types[tptr];
gmove(&n2, reg);
}
diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c
index ed8bac3f0..b4b5b7d6b 100644
--- a/src/cmd/6g/reg.c
+++ b/src/cmd/6g/reg.c
@@ -873,14 +873,17 @@ mkvar(Reg *r, Adr *a)
// if they overlaps, disable both
if(overlap(v->offset, v->width, o, w)) {
+// print("disable overlap %s %d %d %d %d, %E != %E\n", s->name, v->offset, v->width, o, w, v->etype, et);
v->addr = 1;
flag = 1;
}
}
}
- if(a->pun)
+ if(a->pun) {
+// print("disable pun %s\n", s->name);
flag = 1;
+ }
switch(et) {
case 0:
case TFUNC:
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index dda19e48d..6dffa20f2 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -108,6 +108,9 @@ needlib(char *name)
char *p;
Sym *s;
+ if(*name == '\0')
+ return 0;
+
/* reuse hash code in symbol table */
p = smprint(".elfload.%s", name);
s = lookup(p, 0);
@@ -787,40 +790,51 @@ asmb(void)
symo = rnd(symo, PEFILEALIGN);
break;
}
- /*
- * the symbol information is stored as
- * 32-bit symbol table size
- * 32-bit line number table size
- * symbol table
- * line number table
- */
- seek(cout, symo+8, 0);
- if(debug['v'])
- Bprint(&bso, "%5.2f sp\n", cputime());
- Bflush(&bso);
- if(debug['v'])
- Bprint(&bso, "%5.2f pc\n", cputime());
- Bflush(&bso);
- if(!debug['s'])
- strnput("", INITRND-(8+symsize+lcsize)%INITRND);
- cflush();
- seek(cout, symo, 0);
- lputl(symsize);
- lputl(lcsize);
- cflush();
- if(HEADTYPE != Hwindows && !debug['s']) {
- elfsymo = symo+8+symsize+lcsize;
- seek(cout, elfsymo, 0);
- asmelfsym64();
- cflush();
- elfstro = seek(cout, 0, 1);
- elfsymsize = elfstro - elfsymo;
- ewrite(cout, elfstrdat, elfstrsize);
-
+ switch(HEADTYPE) {
+ default:
+ if(iself) {
+ /*
+ * the symbol information is stored as
+ * 32-bit symbol table size
+ * 32-bit line number table size
+ * symbol table
+ * line number table
+ */
+ seek(cout, symo+8, 0);
+ if(debug['v'])
+ Bprint(&bso, "%5.2f sp\n", cputime());
+ Bflush(&bso);
+ if(debug['v'])
+ Bprint(&bso, "%5.2f pc\n", cputime());
+ Bflush(&bso);
+ if(!debug['s'])
+ strnput("", INITRND-(8+symsize+lcsize)%INITRND);
+ cflush();
+ seek(cout, symo, 0);
+ lputl(symsize);
+ lputl(lcsize);
+ cflush();
+ elfsymo = symo+8+symsize+lcsize;
+ seek(cout, elfsymo, 0);
+ asmelfsym64();
+ cflush();
+ elfstro = seek(cout, 0, 1);
+ elfsymsize = elfstro - elfsymo;
+ ewrite(cout, elfstrdat, elfstrsize);
+
+ if(debug['v'])
+ Bprint(&bso, "%5.2f dwarf\n", cputime());
+
+ dwarfemitdebugsections();
+ }
+ break;
+ case Hwindows:
+ seek(cout, symo, 0);
if(debug['v'])
Bprint(&bso, "%5.2f dwarf\n", cputime());
dwarfemitdebugsections();
+ break;
}
}
diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h
index 33ca51b2c..f4ee6aa92 100644
--- a/src/cmd/6l/l.h
+++ b/src/cmd/6l/l.h
@@ -350,9 +350,6 @@ EXTERN Sym* fromgotype; // type symbol on last p->from read
EXTERN vlong textstksiz;
EXTERN vlong textarg;
-EXTERN int elfstrsize;
-EXTERN char* elfstrdat;
-EXTERN int elftextsh;
extern Optab optab[];
extern Optab* opindex[];
diff --git a/src/cmd/8a/lex.c b/src/cmd/8a/lex.c
index ca18b69ce..078861877 100644
--- a/src/cmd/8a/lex.c
+++ b/src/cmd/8a/lex.c
@@ -56,7 +56,7 @@ void
main(int argc, char *argv[])
{
char *p;
- int nout, nproc, i, c;
+ int c;
thechar = '8';
thestring = "386";
@@ -96,46 +96,10 @@ main(int argc, char *argv[])
print("usage: %ca [-options] file.s\n", thechar);
errorexit();
}
- if(argc > 1 && systemtype(Windows)){
- print("can't assemble multiple files on windows\n");
+ if(argc > 1){
+ print("can't assemble multiple files\n");
errorexit();
}
- if(argc > 1 && !systemtype(Windows)) {
- nproc = 1;
- if(p = getenv("NPROC"))
- nproc = atol(p); /* */
- c = 0;
- nout = 0;
- for(;;) {
- Waitmsg *w;
-
- while(nout < nproc && argc > 0) {
- i = fork();
- if(i < 0) {
- fprint(2, "fork: %r\n");
- errorexit();
- }
- if(i == 0) {
- print("%s:\n", *argv);
- if(assemble(*argv))
- errorexit();
- exits(0);
- }
- nout++;
- argc--;
- argv++;
- }
- w = wait();
- if(w == nil) {
- if(c)
- errorexit();
- exits(0);
- }
- if(w->msg[0])
- c++;
- nout--;
- }
- }
if(assemble(argv[0]))
errorexit();
exits(0);
@@ -144,7 +108,7 @@ main(int argc, char *argv[])
int
assemble(char *file)
{
- char *ofile, incfile[20], *p;
+ char *ofile, *p;
int i, of;
ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
@@ -169,15 +133,6 @@ assemble(char *file)
} else
outfile = "/dev/null";
}
- p = getenv("INCLUDE");
- if(p) {
- setinclude(p);
- } else {
- if(systemtype(Plan9)) {
- sprint(incfile,"/%s/include", thestring);
- setinclude(strdup(incfile));
- }
- }
of = create(outfile, OWRITE, 0664);
if(of < 0) {
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c
index 596824a6c..1614a2d77 100644
--- a/src/cmd/8g/cgen.c
+++ b/src/cmd/8g/cgen.c
@@ -232,6 +232,7 @@ cgen(Node *n, Node *res)
cgen(nl, res);
break;
}
+
tempname(&n2, n->type);
mgen(nl, &n1, res);
gmove(&n1, &n2);
@@ -277,15 +278,10 @@ cgen(Node *n, Node *res)
if(istype(nl->type, TSTRING) || isslice(nl->type)) {
// both slice and string have len one pointer into the struct.
igen(nl, &n1, res);
- n1.op = OREGISTER; // was OINDREG
- regalloc(&n2, types[TUINT32], &n1);
- n1.op = OINDREG;
n1.type = types[TUINT32];
- n1.xoffset = Array_nel;
- gmove(&n1, &n2);
- gmove(&n2, res);
+ n1.xoffset += Array_nel;
+ gmove(&n1, res);
regfree(&n1);
- regfree(&n2);
break;
}
fatal("cgen: OLEN: unknown type %lT", nl->type);
@@ -594,9 +590,10 @@ agen(Node *n, Node *res)
gmove(&n1, &n3);
}
- nodconst(&n2, types[tptr], v*w);
- gins(optoas(OADD, types[tptr]), &n2, &n3);
-
+ if (v*w != 0) {
+ nodconst(&n2, types[tptr], v*w);
+ gins(optoas(OADD, types[tptr]), &n2, &n3);
+ }
gmove(&n3, res);
regfree(&n3);
break;
@@ -729,7 +726,27 @@ void
igen(Node *n, Node *a, Node *res)
{
Node n1;
-
+ Type *fp;
+ Iter flist;
+
+ switch(n->op) {
+ case ONAME:
+ if((n->class&PHEAP) || n->class == PPARAMREF)
+ break;
+ *a = *n;
+ return;
+
+ case OCALLFUNC:
+ fp = structfirst(&flist, getoutarg(n->left->type));
+ cgen_call(n, 0);
+ memset(a, 0, sizeof *a);
+ a->op = OINDREG;
+ a->val.u.reg = D_SP;
+ a->addable = 1;
+ a->xoffset = fp->width;
+ a->type = n->type;
+ return;
+ }
// release register for now, to avoid
// confusing tempname.
if(res != N && res->op == OREGISTER)
@@ -919,6 +936,7 @@ bgen(Node *n, int true, Prog *to)
n2 = n1;
n2.op = OINDREG;
n2.xoffset = Array_array;
+ n2.type = types[tptr];
nodconst(&tmp, types[tptr], 0);
gins(optoas(OCMP, types[tptr]), &n2, &tmp);
patch(gbranch(a, types[tptr]), to);
diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c
index 920725c3e..223152536 100644
--- a/src/cmd/8g/ggen.c
+++ b/src/cmd/8g/ggen.c
@@ -915,7 +915,7 @@ cgen_inline(Node *n, Node *res)
Node nodes[5];
Node n1, n2, nres, ntemp;
vlong v;
- int i, narg;
+ int i, narg, nochk;
if(n->op != OCALLFUNC)
goto no;
@@ -953,6 +953,7 @@ slicearray:
// len = hb[3] - lb[2] (destroys hb)
n2 = *res;
n2.xoffset += Array_nel;
+ n2.type = types[TUINT32];
if(smallintconst(&nodes[3]) && smallintconst(&nodes[2])) {
v = mpgetfix(nodes[3].val.u.xval) -
@@ -971,6 +972,7 @@ slicearray:
// cap = nel[1] - lb[2] (destroys nel)
n2 = *res;
n2.xoffset += Array_cap;
+ n2.type = types[TUINT32];
if(smallintconst(&nodes[1]) && smallintconst(&nodes[2])) {
v = mpgetfix(nodes[1].val.u.xval) -
@@ -999,6 +1001,7 @@ slicearray:
// ary = old[0] + (lb[2] * width[4]) (destroys old)
n2 = *res;
n2.xoffset += Array_array;
+ n2.type = types[tptr];
if(smallintconst(&nodes[2]) && smallintconst(&nodes[4])) {
v = mpgetfix(nodes[2].val.u.xval) *
@@ -1026,6 +1029,7 @@ slicearray:
sliceslice:
if(!fix64(n->list, narg))
goto no;
+ nochk = n->etype; // skip bounds checking
ntemp.op = OXXX;
if(!sleasy(n->list->n->right)) {
Node *n0;
@@ -1055,11 +1059,13 @@ sliceslice:
n2 = nodes[0];
n2.xoffset += Array_nel;
n2.type = types[TUINT32];
- cmpandthrow(&nodes[1], &n2);
+ if(!nochk)
+ cmpandthrow(&nodes[1], &n2);
// ret.nel = old.nel[0]-lb[1];
n2 = nodes[0];
n2.xoffset += Array_nel;
+ n2.type = types[TUINT32];
regalloc(&n1, types[TUINT32], N);
gins(optoas(OAS, types[TUINT32]), &n2, &n1);
@@ -1068,22 +1074,25 @@ sliceslice:
n2 = nres;
n2.xoffset += Array_nel;
+ n2.type = types[TUINT32];
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1);
} else { // old[lb:hb]
- // if(hb[2] > old.cap[0]) goto throw;
n2 = nodes[0];
n2.xoffset += Array_cap;
n2.type = types[TUINT32];
- cmpandthrow(&nodes[2], &n2);
-
- // if(lb[1] > hb[2]) goto throw;
- cmpandthrow(&nodes[1], &nodes[2]);
+ if (!nochk) {
+ // if(hb[2] > old.cap[0]) goto throw;
+ cmpandthrow(&nodes[2], &n2);
+ // if(lb[1] > hb[2]) goto throw;
+ cmpandthrow(&nodes[1], &nodes[2]);
+ }
// ret.len = hb[2]-lb[1]; (destroys hb[2])
n2 = nres;
n2.xoffset += Array_nel;
-
+ n2.type = types[TUINT32];
+
if(smallintconst(&nodes[2]) && smallintconst(&nodes[1])) {
v = mpgetfix(nodes[2].val.u.xval) -
mpgetfix(nodes[1].val.u.xval);
@@ -1102,6 +1111,7 @@ sliceslice:
// ret.cap = old.cap[0]-lb[1]; (uses hb[2])
n2 = nodes[0];
n2.xoffset += Array_cap;
+ n2.type = types[TUINT32];
regalloc(&n1, types[TUINT32], &nodes[2]);
gins(optoas(OAS, types[TUINT32]), &n2, &n1);
@@ -1110,12 +1120,14 @@ sliceslice:
n2 = nres;
n2.xoffset += Array_cap;
+ n2.type = types[TUINT32];
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1);
// ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
n2 = nodes[0];
n2.xoffset += Array_array;
+ n2.type = types[tptr];
regalloc(&n1, types[tptr], &nodes[1]);
if(smallintconst(&nodes[1]) && smallintconst(&nodes[3])) {
@@ -1135,6 +1147,7 @@ sliceslice:
n2 = nres;
n2.xoffset += Array_array;
+ n2.type = types[tptr];
gins(optoas(OAS, types[tptr]), &n1, &n2);
regfree(&n1);
diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c
index 8ed7e5564..5ad35fdce 100644
--- a/src/cmd/8g/gsubr.c
+++ b/src/cmd/8g/gsubr.c
@@ -698,7 +698,6 @@ ginit(void)
reg[i] = 1;
for(i=D_AL; i<=D_DI; i++)
reg[i] = 0;
-
for(i=0; i<nelem(resvd); i++)
reg[resvd[i]]++;
}
@@ -789,6 +788,8 @@ err:
return;
out:
+ if (i == D_SP)
+ print("alloc SP\n");
if(reg[i] == 0) {
regpc[i] = (ulong)__builtin_return_address(0);
if(i == D_AX || i == D_CX || i == D_DX || i == D_SP) {
@@ -804,10 +805,14 @@ void
regfree(Node *n)
{
int i;
-
+
+ if(n->op == ONAME)
+ return;
if(n->op != OREGISTER && n->op != OINDREG)
fatal("regfree: not a register");
i = n->val.u.reg;
+ if(i == D_SP)
+ return;
if(i < 0 || i >= sizeof(reg))
fatal("regfree: reg out of range");
if(reg[i] <= 0)
@@ -1129,6 +1134,9 @@ gmove(Node *f, Node *t)
case CASE(TINT8, TUINT8):
case CASE(TUINT8, TINT8):
case CASE(TUINT8, TUINT8):
+ a = AMOVB;
+ break;
+
case CASE(TINT16, TINT8): // truncate
case CASE(TUINT16, TINT8):
case CASE(TINT32, TINT8):
@@ -1138,7 +1146,7 @@ gmove(Node *f, Node *t)
case CASE(TINT32, TUINT8):
case CASE(TUINT32, TUINT8):
a = AMOVB;
- break;
+ goto rsrc;
case CASE(TINT64, TINT8): // truncate low word
case CASE(TUINT64, TINT8):
@@ -1146,7 +1154,7 @@ gmove(Node *f, Node *t)
case CASE(TUINT64, TUINT8):
split64(f, &flo, &fhi);
nodreg(&r1, t->type, D_AX);
- gins(AMOVB, &flo, &r1);
+ gmove(&flo, &r1);
gins(AMOVB, &r1, t);
splitclean();
return;
@@ -1155,12 +1163,15 @@ gmove(Node *f, Node *t)
case CASE(TINT16, TUINT16):
case CASE(TUINT16, TINT16):
case CASE(TUINT16, TUINT16):
+ a = AMOVW;
+ break;
+
case CASE(TINT32, TINT16): // truncate
case CASE(TUINT32, TINT16):
case CASE(TINT32, TUINT16):
case CASE(TUINT32, TUINT16):
a = AMOVW;
- break;
+ goto rsrc;
case CASE(TINT64, TINT16): // truncate low word
case CASE(TUINT64, TINT16):
@@ -1168,7 +1179,7 @@ gmove(Node *f, Node *t)
case CASE(TUINT64, TUINT16):
split64(f, &flo, &fhi);
nodreg(&r1, t->type, D_AX);
- gins(AMOVW, &flo, &r1);
+ gmove(&flo, &r1);
gins(AMOVW, &r1, t);
splitclean();
return;
@@ -1186,7 +1197,7 @@ gmove(Node *f, Node *t)
case CASE(TUINT64, TUINT32):
split64(f, &flo, &fhi);
nodreg(&r1, t->type, D_AX);
- gins(AMOVL, &flo, &r1);
+ gmove(&flo, &r1);
gins(AMOVL, &r1, t);
splitclean();
return;
@@ -1340,14 +1351,14 @@ gmove(Node *f, Node *t)
case TUINT8:
gins(ATESTL, ncon(0xffffff00), &t1);
p1 = gbranch(AJEQ, T);
- gins(AMOVB, ncon(0), &t1);
+ gins(AMOVL, ncon(0), &t1);
patch(p1, pc);
gmove(&t1, t);
break;
case TUINT16:
gins(ATESTL, ncon(0xffff0000), &t1);
p1 = gbranch(AJEQ, T);
- gins(AMOVW, ncon(0), &t1);
+ gins(AMOVL, ncon(0), &t1);
patch(p1, pc);
gmove(&t1, t);
break;
@@ -1418,11 +1429,11 @@ gmove(Node *f, Node *t)
split64(t, &tlo, &thi);
gins(AXORL, ncon(0x80000000), &thi); // + 2^63
patch(p3, pc);
- patch(p1, pc);
splitclean();
-
// restore rounding mode
gins(AFLDCW, &t1, N);
+
+ patch(p1, pc);
return;
/*
@@ -1571,6 +1582,14 @@ gmove(Node *f, Node *t)
gins(a, f, t);
return;
+rsrc:
+ // requires register source
+ regalloc(&r1, f->type, t);
+ gmove(f, &r1);
+ gins(a, &r1, t);
+ regfree(&r1);
+ return;
+
rdst:
// requires register destination
regalloc(&r1, t->type, t);
@@ -1623,6 +1642,7 @@ gins(int as, Node *f, Node *t)
{
Prog *p;
Addr af, at;
+ int w;
if(as == AFMOVF && f && f->op == OREGISTER && t && t->op == OREGISTER)
fatal("gins MOVF reg, reg");
@@ -1648,6 +1668,26 @@ gins(int as, Node *f, Node *t)
p->to = at;
if(debug['g'])
print("%P\n", p);
+
+ w = 0;
+ switch(as) {
+ case AMOVB:
+ w = 1;
+ break;
+ case AMOVW:
+ w = 2;
+ break;
+ case AMOVL:
+ w = 4;
+ break;
+ }
+
+ if(1 && w != 0 && f != N && (af.width > w || at.width > w)) {
+ dump("bad width from:", f);
+ dump("bad width to:", t);
+ fatal("bad width: %P (%d, %d)\n", p, af.width, at.width);
+ }
+
return p;
}
@@ -1799,8 +1839,9 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
break; // len(nil)
- a->etype = TUINT;
+ a->etype = TUINT32;
a->offset += Array_nel;
+ a->width = 4;
if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
checkoffset(a, canemitcode);
break;
@@ -1810,8 +1851,9 @@ naddr(Node *n, Addr *a, int canemitcode)
naddr(n->left, a, canemitcode);
if(a->type == D_CONST && a->offset == 0)
break; // cap(nil)
- a->etype = TUINT;
+ a->etype = TUINT32;
a->offset += Array_cap;
+ a->width = 4;
if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero)
checkoffset(a, canemitcode);
break;
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c
index f28b8d904..7de7753a2 100644
--- a/src/cmd/8l/asm.c
+++ b/src/cmd/8l/asm.c
@@ -104,6 +104,9 @@ needlib(char *name)
char *p;
Sym *s;
+ if(*name == '\0')
+ return 0;
+
/* reuse hash code in symbol table */
p = smprint(".dynlib.%s", name);
s = lookup(p, 0);
@@ -532,6 +535,8 @@ doelf(void)
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
+ elfstr[ElfStrSymtab] = addstring(shstrtab, ".symtab");
+ elfstr[ElfStrStrtab] = addstring(shstrtab, ".strtab");
dwarfaddshstrings(shstrtab);
}
elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab");
@@ -658,7 +663,7 @@ asmb(void)
{
int32 v, magic;
int a, dynsym;
- uint32 symo, startva, machlink;
+ uint32 symo, startva, machlink, elfsymo, elfstro, elfsymsize;
ElfEhdr *eh;
ElfPhdr *ph, *pph;
ElfShdr *sh;
@@ -670,6 +675,10 @@ asmb(void)
Bprint(&bso, "%5.2f asmb\n", cputime());
Bflush(&bso);
+ elfsymsize = 0;
+ elfstro = 0;
+ elfsymo = 0;
+
sect = segtext.sect;
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0);
codeblk(sect->vaddr, sect->len);
@@ -736,32 +745,48 @@ asmb(void)
symo = rnd(symo, INITRND);
break;
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);
break;
}
- if(!debug['s']) {
- seek(cout, symo, 0);
-
- if(HEADTYPE == Hplan9x32) {
- asmplan9sym();
+ switch(HEADTYPE) {
+ default:
+ if(iself) {
+ if(debug['v'])
+ Bprint(&bso, "%5.2f elfsym\n", cputime());
+ elfsymo = symo+8+symsize+lcsize;
+ seek(cout, elfsymo, 0);
+ asmelfsym32();
cflush();
-
- sym = lookup("pclntab", 0);
- if(sym != nil) {
- lcsize = sym->np;
- for(i=0; i < lcsize; i++)
- cput(sym->p[i]);
-
- cflush();
- }
-
- } else if(HEADTYPE != Hwindows) {
+ elfstro = seek(cout, 0, 1);
+ elfsymsize = elfstro - elfsymo;
+ ewrite(cout, elfstrdat, elfstrsize);
+
if(debug['v'])
Bprint(&bso, "%5.2f dwarf\n", cputime());
dwarfemitdebugsections();
}
+ break;
+ case Hplan9x32:
+ seek(cout, symo, 0);
+ asmplan9sym();
+ cflush();
+
+ sym = lookup("pclntab", 0);
+ if(sym != nil) {
+ lcsize = sym->np;
+ for(i=0; i < lcsize; i++)
+ cput(sym->p[i]);
+
+ cflush();
+ }
+ break;
+ case Hwindows:
+ seek(cout, symo, 0);
+ if(debug['v'])
+ Bprint(&bso, "%5.2f dwarf\n", cputime());
+ dwarfemitdebugsections();
+ break;
}
}
if(debug['v'])
@@ -1082,6 +1107,20 @@ asmb(void)
sh->addralign = 1;
shsym(sh, lookup("pclntab", 0));
+ sh = newElfShdr(elfstr[ElfStrSymtab]);
+ sh->type = SHT_SYMTAB;
+ sh->off = elfsymo;
+ sh->size = elfsymsize;
+ sh->addralign = 4;
+ sh->entsize = 16;
+ sh->link = eh->shnum; // link to strtab
+
+ sh = newElfShdr(elfstr[ElfStrStrtab]);
+ sh->type = SHT_STRTAB;
+ sh->off = elfstro;
+ sh->size = elfstrsize;
+ sh->addralign = 1;
+
dwarfaddelfheaders();
}
diff --git a/src/cmd/8l/obj.c b/src/cmd/8l/obj.c
index 2a38f7ef0..f84a30f39 100644
--- a/src/cmd/8l/obj.c
+++ b/src/cmd/8l/obj.c
@@ -188,7 +188,7 @@ main(int argc, char *argv[])
if(INITDAT == -1)
INITDAT = 0;
if(INITRND == -1)
- INITRND = 1;
+ INITRND = 4096;
break;
case Hmsdoscom: /* MS-DOS .COM */
HEADR = 0;
diff --git a/src/cmd/8l/pass.c b/src/cmd/8l/pass.c
index 28589b66a..72ae043d6 100644
--- a/src/cmd/8l/pass.c
+++ b/src/cmd/8l/pass.c
@@ -32,23 +32,10 @@
#include "l.h"
#include "../ld/lib.h"
+#include "../../pkg/runtime/stack.h"
static void xfol(Prog*, Prog**);
-// see ../../pkg/runtime/proc.c:/StackGuard
-enum
-{
-#ifdef __WINDOWS__
- // use larger stacks to compensate for larger stack guard,
- // needed for exception handling.
- StackSmall = 256,
- StackBig = 8192,
-#else
- StackSmall = 128,
- StackBig = 4096,
-#endif
-};
-
Prog*
brchain(Prog *p)
{
diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c
index dba8ff634..71cc89bf0 100644
--- a/src/cmd/cc/lex.c
+++ b/src/cmd/cc/lex.c
@@ -88,7 +88,7 @@ void
main(int argc, char *argv[])
{
char **defs, *p;
- int nproc, nout, i, c, ndef;
+ int c, ndef;
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
@@ -142,51 +142,10 @@ main(int argc, char *argv[])
print("usage: %cc [-options] files\n", thechar);
errorexit();
}
- if(argc > 1 && systemtype(Windows)){
- print("can't compile multiple files on windows\n");
+ if(argc > 1){
+ print("can't compile multiple files\n");
errorexit();
}
- if(argc > 1 && !systemtype(Windows)) {
- nproc = 1;
- /*
- * if we're writing acid to standard output, don't compile
- * concurrently, to avoid interleaving output.
- */
- if(((!debug['a'] && !debug['q'] && !debug['Q']) || debug['n']) &&
- (p = getenv("NPROC")) != nil)
- nproc = atol(p); /* */
- c = 0;
- nout = 0;
- for(;;) {
- Waitmsg *w;
-
- while(nout < nproc && argc > 0) {
- i = fork();
- if(i < 0) {
- print("cannot create a process\n");
- errorexit();
- }
- if(i == 0) {
- fprint(2, "%s:\n", *argv);
- if (compile(*argv, defs, ndef))
- errorexit();
- exits(0);
- }
- nout++;
- argc--;
- argv++;
- }
- w = wait();
- if(w == nil) {
- if(c)
- errorexit();
- exits(0);
- }
- if(w->msg[0])
- c++;
- nout--;
- }
- }
if(argc == 0)
c = compile("stdin", defs, ndef);
@@ -201,7 +160,7 @@ main(int argc, char *argv[])
int
compile(char *file, char **defs, int ndef)
{
- char *ofile, incfile[20];
+ char *ofile;
char *p, **av, opt[256];
int i, c, fd[2];
static int first = 1;
@@ -236,15 +195,6 @@ compile(char *file, char **defs, int ndef)
outfile = "/dev/null";
}
- if(p = getenv("INCLUDE")) {
- setinclude(p);
- } else {
- if(systemtype(Plan9)) {
- sprint(incfile, "/%s/include", thestring);
- setinclude(strdup(incfile));
- setinclude("/sys/include");
- }
- }
if (first)
Binit(&diagbuf, 1, OWRITE);
/*
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index ae5ca2c7d..ac6561345 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -604,7 +604,7 @@ const gccTmp = "_obj/_cgo_.o"
// gccCmd returns the gcc command line to use for compiling
// the input.
func (p *Package) gccCmd() []string {
- return []string{
+ c := []string{
p.gccName(),
p.gccMachine(),
"-Wall", // many warnings
@@ -614,15 +614,17 @@ func (p *Package) gccCmd() []string {
"-fno-eliminate-unused-debug-types", // gets rid of e.g. untyped enum otherwise
"-c", // do not link
"-xc", // input language is C
- "-", // read input from standard input
}
+ c = append(c, p.GccOptions...)
+ c = append(c, "-") //read input from standard input
+ return c
}
// gccDebug runs gcc -gdwarf-2 over the C program stdin and
// returns the corresponding DWARF data and any messages
// printed to standard error.
func (p *Package) gccDebug(stdin []byte) *dwarf.Data {
- runGcc(stdin, append(p.gccCmd(), p.GccOptions...))
+ runGcc(stdin, p.gccCmd())
// Try to parse f as ELF and Mach-O and hope one works.
var f interface {
@@ -649,8 +651,8 @@ func (p *Package) gccDebug(stdin []byte) *dwarf.Data {
// #defines that gcc encountered while processing the input
// and its included files.
func (p *Package) gccDefines(stdin []byte) string {
- base := []string{p.gccName(), p.gccMachine(), "-E", "-dM", "-xc", "-"}
- stdout, _ := runGcc(stdin, append(base, p.GccOptions...))
+ base := []string{p.gccName(), p.gccMachine(), "-E", "-dM", "-xc"}
+ stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
return stdout
}
@@ -659,7 +661,7 @@ func (p *Package) gccDefines(stdin []byte) string {
// gcc to fail.
func (p *Package) gccErrors(stdin []byte) string {
// TODO(rsc): require failure
- args := append(p.gccCmd(), p.GccOptions...)
+ args := p.gccCmd()
if *debugGcc {
fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
os.Stderr.Write(stdin)
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index bc031cc58..2ce4e9752 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -331,7 +331,11 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
fmt.Fprintf(fgcc, "\tint e;\n") // assuming 32 bit (see comment above structType)
fmt.Fprintf(fgcc, "\terrno = 0;\n")
}
- fmt.Fprintf(fgcc, "\t%s *a = v;\n", ctype)
+ // We're trying to write a gcc struct that matches 6c/8c/5c's layout.
+ // Use packed attribute to force no padding in this struct in case
+ // gcc has different packing requirements. For example,
+ // on 386 Windows, gcc wants to 8-align int64s, but 8c does not.
+ fmt.Fprintf(fgcc, "\t%s __attribute__((__packed__)) *a = v;\n", ctype)
fmt.Fprintf(fgcc, "\t")
if t := n.FuncType.Result; t != nil {
fmt.Fprintf(fgcc, "a->r = ")
@@ -370,7 +374,9 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
fn := exp.Func
// Construct a gcc struct matching the 6c argument and
- // result frame.
+ // result frame. The gcc struct will be compiled with
+ // __attribute__((packed)) so all padding must be accounted
+ // for explicitly.
ctype := "struct {\n"
off := int64(0)
npad := 0
@@ -458,7 +464,7 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
fmt.Fprintf(fgcc, "extern _cgoexp%s_%s(void *, int);\n", cPrefix, exp.ExpName)
fmt.Fprintf(fgcc, "\n%s\n", s)
fmt.Fprintf(fgcc, "{\n")
- fmt.Fprintf(fgcc, "\t%s a;\n", ctype)
+ fmt.Fprintf(fgcc, "\t%s __attribute__((packed)) a;\n", ctype)
if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) {
fmt.Fprintf(fgcc, "\t%s r;\n", gccResult)
}
diff --git a/src/cmd/gc/builtin.c.boot b/src/cmd/gc/builtin.c.boot
index bdbca7f78..c9bf501d1 100644
--- a/src/cmd/gc/builtin.c.boot
+++ b/src/cmd/gc/builtin.c.boot
@@ -1,5 +1,6 @@
char *runtimeimport =
"package runtime\n"
+ "import runtime \"runtime\"\n"
"func \"\".new (? int32) *any\n"
"func \"\".panicindex ()\n"
"func \"\".panicslice ()\n"
@@ -21,7 +22,6 @@ char *runtimeimport =
"func \"\".printsp ()\n"
"func \"\".goprintf ()\n"
"func \"\".concatstring ()\n"
- "func \"\".append ()\n"
"func \"\".appendslice (typ *uint8, x any, y []any) any\n"
"func \"\".cmpstring (? string, ? string) int\n"
"func \"\".slicestring (? string, ? int, ? int) string\n"
@@ -81,6 +81,7 @@ char *runtimeimport =
"func \"\".selectgo (sel *uint8)\n"
"func \"\".block ()\n"
"func \"\".makeslice (typ *uint8, nel int64, cap int64) []any\n"
+ "func \"\".growslice (typ *uint8, old []any, cap int64) []any\n"
"func \"\".sliceslice1 (old []any, lb uint64, width uint64) []any\n"
"func \"\".sliceslice (old []any, lb uint64, hb uint64, width uint64) []any\n"
"func \"\".slicearray (old *any, nel uint64, lb uint64, hb uint64, width uint64) []any\n"
@@ -98,6 +99,7 @@ char *runtimeimport =
"$$\n";
char *unsafeimport =
"package unsafe\n"
+ "import runtime \"runtime\"\n"
"type \"\".Pointer uintptr\n"
"func \"\".Offsetof (? any) int\n"
"func \"\".Sizeof (? any) int\n"
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index f58b76789..359881e11 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -225,6 +225,7 @@ struct Node
Type* realtype; // as determined by typecheck
NodeList* list;
NodeList* rlist;
+ Node* orig; // original form, for printing
// for-body
NodeList* ninit;
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
index 35d11eca9..00fc720b8 100644
--- a/src/cmd/gc/runtime.go
+++ b/src/cmd/gc/runtime.go
@@ -110,6 +110,7 @@ func selectgo(sel *byte)
func block()
func makeslice(typ *byte, nel int64, cap int64) (ary []any)
+func growslice(typ *byte, old []any, n int64) (ary []any)
func sliceslice1(old []any, lb uint64, width uint64) (ary []any)
func sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any)
func slicearray(old *any, nel uint64, lb uint64, hb uint64, width uint64) (ary []any)
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index bb2505694..326a5ba74 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -1073,6 +1073,9 @@ Jconv(Fmt *fp)
if(n->implicit != 0)
fmtprint(fp, " implicit(%d)", n->implicit);
+ if(n->pun != 0)
+ fmtprint(fp, " pun(%d)", n->pun);
+
return 0;
}
@@ -1141,7 +1144,7 @@ Tpretty(Fmt *fp, Type *t)
Type *t1;
Sym *s;
- if(debug['r']) {
+ if(0 && debug['r']) {
debug['r'] = 0;
fmtprint(fp, "%T (orig=%T)", t, t->orig);
debug['r'] = 1;
@@ -1454,6 +1457,8 @@ Nconv(Fmt *fp)
}
if(fp->flags & FmtSharp) {
+ if(n->orig != N)
+ n = n->orig;
exprfmt(fp, n, 0);
goto out;
}
@@ -3107,7 +3112,7 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
Type *tpad;
int isddd;
- if(debug['r'])
+ if(0 && debug['r'])
print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
rcvr, method, newnam);
@@ -3161,7 +3166,7 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
fn->nbody = list1(n);
}
- if(debug['r'])
+ if(0 && debug['r'])
dumplist("genwrapper body", fn->nbody);
funcbody(fn);
@@ -3256,8 +3261,9 @@ implements(Type *t, Type *iface, Type **m, Type **samename, int *ptr)
// the method does not exist for value types.
rcvr = getthisx(tm->type)->type->type;
if(isptr[rcvr->etype] && !isptr[t0->etype] && !followptr && !isifacemethod(tm->type)) {
- if(debug['r'])
+ if(0 && debug['r'])
yyerror("interface pointer mismatch");
+
*m = im;
*samename = nil;
*ptr = 1;
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
index 6e8436c3c..c2968c44b 100644
--- a/src/cmd/gc/swt.c
+++ b/src/cmd/gc/swt.c
@@ -867,8 +867,11 @@ typecheckswitch(Node *n)
case Etype: // type switch
if(ll->n->op == OLITERAL && istype(ll->n->type, TNIL))
;
- else if(ll->n->op != OTYPE && ll->n->type != T)
+ else if(ll->n->op != OTYPE && ll->n->type != T) {
yyerror("%#N is not a type", ll->n);
+ // reset to original type
+ ll->n = n->ntest->right;
+ }
break;
}
}
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index c48bf7a29..9aaf3e6ef 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -894,12 +894,20 @@ reswitch:
// might be constant
switch(t->etype) {
case TSTRING:
- if(isconst(l, CTSTR))
- nodconst(n, types[TINT], l->val.u.sval->len);
+ if(isconst(l, CTSTR)) {
+ r = nod(OXXX, N, N);
+ nodconst(r, types[TINT], l->val.u.sval->len);
+ r->orig = n;
+ n = r;
+ }
break;
case TARRAY:
- if(t->bound >= 0 && l->op == ONAME)
- nodconst(n, types[TINT], t->bound);
+ if(t->bound >= 0 && l->op == ONAME) {
+ r = nod(OXXX, N, N);
+ nodconst(r, types[TINT], t->bound);
+ r->orig = n;
+ n = r;
+ }
break;
}
n->type = types[TINT];
@@ -1357,7 +1365,10 @@ ret:
goto error;
}
if((top & Etop) && !(top & (Ecall|Erv|Etype)) && !(ok & Etop)) {
- yyerror("%#N not used", n);
+ if(n->diag == 0) {
+ yyerror("%#N not used", n);
+ n->diag = 1;
+ }
goto error;
}
diff --git a/src/cmd/gc/unsafe.c b/src/cmd/gc/unsafe.c
index 33f375631..540994ddd 100644
--- a/src/cmd/gc/unsafe.c
+++ b/src/cmd/gc/unsafe.c
@@ -41,6 +41,7 @@ unsafenmagic(Node *nn)
tr = r->type;
if(tr == T)
goto bad;
+ dowidth(tr);
v = tr->width;
goto yes;
}
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 278eef414..b3b400556 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -18,12 +18,13 @@ static NodeList* paramstoheap(Type **argin, int out);
static NodeList* reorder1(NodeList*);
static NodeList* reorder3(NodeList*);
static Node* addstr(Node*, NodeList**);
+static Node* appendslice(Node*, NodeList**);
static Node* append(Node*, NodeList**);
static NodeList* walkdefstack;
// can this code branch reach the end
-// without an undcontitional RETURN
+// without an unconditional RETURN
// this is hard, so it is conservative
static int
walkret(NodeList *l)
@@ -805,18 +806,17 @@ walkexpr(Node **np, NodeList **init)
n->ninit = nil;
walkexpr(&n->left, init);
n->left = safeexpr(n->left, init);
+
if(oaslit(n, init))
goto ret;
+
walkexpr(&n->right, init);
- l = n->left;
- r = n->right;
- if(l == N || r == N)
- goto ret;
- r = ascompatee1(n->op, l, r, init);
- if(r != N) {
+ if(n->left != N && n->right != N) {
+ r = convas(nod(OAS, n->left, n->right), init);
r->dodata = n->dodata;
n = r;
}
+
goto ret;
case OAS2:
@@ -1134,6 +1134,7 @@ walkexpr(Node **np, NodeList **init)
case OINDEXMAP:
if(n->etype == 1)
goto ret;
+
t = n->left->type;
n = mkcall1(mapfn("mapaccess1", t), t->type, init, n->left, n->right);
goto ret;
@@ -1188,6 +1189,7 @@ walkexpr(Node **np, NodeList **init)
// sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any)
// sliceslice1(old []any, lb uint64, width uint64) (ary []any)
t = n->type;
+ et = n->etype;
if(n->right->left == N)
l = nodintconst(0);
else
@@ -1210,6 +1212,7 @@ walkexpr(Node **np, NodeList **init)
l,
nodintconst(t->type->width));
}
+ n->etype = et; // preserve no-typecheck flag from OSLICE to the slice* call.
goto ret;
slicearray:
@@ -1332,7 +1335,10 @@ walkexpr(Node **np, NodeList **init)
goto ret;
case OAPPEND:
- n = append(n, init);
+ if(n->isddd)
+ n = appendslice(n, init);
+ else
+ n = append(n, init);
goto ret;
case OCOPY:
@@ -1953,23 +1959,18 @@ callnew(Type *t)
static Node*
convas(Node *n, NodeList **init)
{
- Node *l, *r;
Type *lt, *rt;
if(n->op != OAS)
fatal("convas: not OAS %O", n->op);
- n->typecheck = 1;
- lt = T;
- rt = T;
+ n->typecheck = 1;
- l = n->left;
- r = n->right;
- if(l == N || r == N)
+ if(n->left == N || n->right == N)
goto out;
- lt = l->type;
- rt = r->type;
+ lt = n->left->type;
+ rt = n->right->type;
if(lt == T || rt == T)
goto out;
@@ -1987,7 +1988,7 @@ convas(Node *n, NodeList **init)
if(eqtype(lt, rt))
goto out;
- n->right = assignconv(r, lt, "assignment");
+ n->right = assignconv(n->right, lt, "assignment");
walkexpr(&n->right, init);
out:
@@ -2365,42 +2366,85 @@ addstr(Node *n, NodeList **init)
}
static Node*
-append(Node *n, NodeList **init)
+appendslice(Node *n, NodeList **init)
{
- int i, j;
- Node *f, *r;
- NodeList *in, *args;
+ Node *f;
- if(n->isddd) {
- f = syslook("appendslice", 1);
- argtype(f, n->type);
- argtype(f, n->type->type);
- argtype(f, n->type);
- r = mkcall1(f, n->type, init, typename(n->type), n->list->n, n->list->next->n);
- return r;
+ f = syslook("appendslice", 1);
+ argtype(f, n->type);
+ argtype(f, n->type->type);
+ argtype(f, n->type);
+ return mkcall1(f, n->type, init, typename(n->type), n->list->n, n->list->next->n);
+}
+
+// expand append(src, a [, b]* ) to
+//
+// init {
+// s := src
+// const argc = len(args) - 1
+// if cap(s) - len(s) < argc {
+// s = growslice(s, argc)
+// }
+// n := len(s)
+// s = s[:n+argc]
+// s[n] = a
+// s[n+1] = b
+// ...
+// }
+// s
+static Node*
+append(Node *n, NodeList **init)
+{
+ NodeList *l, *a;
+ Node *nsrc, *ns, *nn, *na, *nx, *fn;
+ int argc;
+
+ walkexprlistsafe(n->list, init);
+
+ nsrc = n->list->n;
+ argc = count(n->list) - 1;
+ if (argc < 1) {
+ return nsrc;
}
- j = count(n->list) - 1;
- f = syslook("append", 1);
- f->type = T;
- f->ntype = nod(OTFUNC, N, N);
- in = list1(nod(ODCLFIELD, N, typenod(ptrto(types[TUINT8])))); // type
- in = list(in, nod(ODCLFIELD, N, typenod(types[TINT]))); // count
- in = list(in, nod(ODCLFIELD, N, typenod(n->type))); // slice
- for(i=0; i<j; i++)
- in = list(in, nod(ODCLFIELD, N, typenod(n->type->type)));
- f->ntype->list = in;
- f->ntype->rlist = list1(nod(ODCLFIELD, N, typenod(n->type)));
-
- args = list1(typename(n->type));
- args = list(args, nodintconst(j));
- args = concat(args, n->list);
-
- r = nod(OCALL, f, N);
- r->list = args;
- typecheck(&r, Erv);
- walkexpr(&r, init);
- r->type = n->type;
+ l = nil;
- return r;
+ ns = nod(OXXX, N, N); // var s
+ tempname(ns, nsrc->type);
+ l = list(l, nod(OAS, ns, nsrc)); // s = src
+
+ na = nodintconst(argc); // const argc
+ nx = nod(OIF, N, N); // if cap(s) - len(s) < argc
+ nx->ntest = nod(OLT, nod(OSUB, nod(OCAP, ns, N), nod(OLEN, ns, N)), na);
+
+ fn = syslook("growslice", 1); // growslice(<type>, old []T, n int64) (ret []T)
+ argtype(fn, ns->type->type); // 1 old []any
+ argtype(fn, ns->type->type); // 2 ret []any
+
+ nx->nbody = list1(nod(OAS, ns, mkcall1(fn, ns->type, &nx->ninit,
+ typename(ns->type),
+ ns,
+ conv(na, types[TINT64]))));
+ l = list(l, nx);
+
+ nn = nod(OXXX, N, N); // var n
+ tempname(nn, types[TINT]);
+ l = list(l, nod(OAS, nn, nod(OLEN, ns, N))); // n = len(s)
+
+ nx = nod(OSLICE, ns, nod(OKEY, N, nod(OADD, nn, na))); // ...s[:n+argc]
+ nx->etype = 1; // disable bounds check
+ l = list(l, nod(OAS, ns, nx)); // s = s[:n+argc]
+
+ for (a = n->list->next; a != nil; a = a->next) {
+ nx = nod(OINDEX, ns, nn); // s[n] ...
+ nx->etype = 1; // disable bounds check
+ l = list(l, nod(OAS, nx, a->n)); // s[n] = arg
+ if (a->next != nil)
+ l = list(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))); // n = n + 1
+ }
+
+ typechecklist(l, Etop);
+ walkstmtlist(l);
+ *init = concat(*init, l);
+ return ns;
}
diff --git a/src/cmd/godoc/doc.go b/src/cmd/godoc/doc.go
index f0006e750..26d436d72 100644
--- a/src/cmd/godoc/doc.go
+++ b/src/cmd/godoc/doc.go
@@ -47,6 +47,9 @@ The flags are:
width of tabs in units of spaces
-timestamps=true
show timestamps with directory listings
+ -index
+ enable identifier and full text search index
+ (no search box is shown if -index is not set)
-maxresults=10000
maximum number of full text search results shown
(no full text index is built if maxresults <= 0)
diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go
index b8e9dbc92..f97c764f9 100644
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -64,9 +64,12 @@ var (
// layout control
tabwidth = flag.Int("tabwidth", 4, "tab width")
showTimestamps = flag.Bool("timestamps", true, "show timestamps with directory listings")
- maxResults = flag.Int("maxresults", 10000, "maximum number of full text search results shown")
templateDir = flag.String("templates", "", "directory containing alternate template files")
+ // search index
+ indexEnabled = flag.Bool("index", false, "enable search index")
+ maxResults = flag.Int("maxresults", 10000, "maximum number of full text search results shown")
+
// file system mapping
fsMap Mapping // user-defined mapping
fsTree RWValue // *Directory tree of packages, updated with each sync
@@ -687,17 +690,19 @@ func readTemplates() {
func servePage(w http.ResponseWriter, title, subtitle, query string, content []byte) {
d := struct {
- Title string
- Subtitle string
- PkgRoots []string
- Query string
- Version string
- Menu []byte
- Content []byte
+ Title string
+ Subtitle string
+ PkgRoots []string
+ SearchBox bool
+ Query string
+ Version string
+ Menu []byte
+ Content []byte
}{
title,
subtitle,
fsMap.PrefixList(),
+ *indexEnabled,
query,
runtime.Version(),
nil,
@@ -1174,11 +1179,15 @@ func lookup(query string) (result SearchResult) {
}
// is the result accurate?
- if _, ts := fsModified.get(); timestamp < ts {
- // The index is older than the latest file system change
- // under godoc's observation. Indexing may be in progress
- // or start shortly (see indexer()).
- result.Alert = "Indexing in progress: result may be inaccurate"
+ if *indexEnabled {
+ if _, ts := fsModified.get(); timestamp < ts {
+ // The index is older than the latest file system change
+ // under godoc's observation. Indexing may be in progress
+ // or start shortly (see indexer()).
+ result.Alert = "Indexing in progress: result may be inaccurate"
+ }
+ } else {
+ result.Alert = "Search index disabled: no results available"
}
return
diff --git a/src/cmd/godoc/main.go b/src/cmd/godoc/main.go
index e426626b3..967ea8727 100644
--- a/src/cmd/godoc/main.go
+++ b/src/cmd/godoc/main.go
@@ -176,7 +176,7 @@ func remoteSearch(query string) (res *http.Response, err os.Error) {
// remote search
for _, addr := range addrs {
url := "http://" + addr + search
- res, _, err = http.Get(url)
+ res, err = http.Get(url)
if err == nil && res.StatusCode == http.StatusOK {
break
}
@@ -246,8 +246,13 @@ func main() {
log.Printf("address = %s", *httpAddr)
log.Printf("goroot = %s", *goroot)
log.Printf("tabwidth = %d", *tabwidth)
- if *maxResults > 0 {
- log.Printf("maxresults = %d (full text index enabled)", *maxResults)
+ switch {
+ case !*indexEnabled:
+ log.Print("search index disabled")
+ case *maxResults > 0:
+ log.Printf("full text index enabled (maxresults = %d)", *maxResults)
+ default:
+ log.Print("identifier search index enabled")
}
if !fsMap.IsEmpty() {
log.Print("user-defined mapping:")
@@ -284,7 +289,9 @@ func main() {
}
// Start indexing goroutine.
- go indexer()
+ if *indexEnabled {
+ go indexer()
+ }
// Start http server.
if err := http.ListenAndServe(*httpAddr, handler); err != nil {
diff --git a/src/cmd/gofix/Makefile b/src/cmd/gofix/Makefile
index 12f09b4e4..d19de5c4f 100644
--- a/src/cmd/gofix/Makefile
+++ b/src/cmd/gofix/Makefile
@@ -10,6 +10,7 @@ GOFILES=\
netdial.go\
main.go\
osopen.go\
+ httpfinalurl.go\
httpserver.go\
procattr.go\
reflect.go\
diff --git a/src/cmd/gofix/httpfinalurl.go b/src/cmd/gofix/httpfinalurl.go
new file mode 100644
index 000000000..53642b22f
--- /dev/null
+++ b/src/cmd/gofix/httpfinalurl.go
@@ -0,0 +1,56 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "go/ast"
+)
+
+var httpFinalURLFix = fix{
+ "httpfinalurl",
+ httpfinalurl,
+ `Adapt http Get calls to not have a finalURL result parameter.
+
+ http://codereview.appspot.com/4535056/
+`,
+}
+
+func init() {
+ register(httpFinalURLFix)
+}
+
+func httpfinalurl(f *ast.File) bool {
+ if !imports(f, "http") {
+ return false
+ }
+
+ fixed := false
+ walk(f, func(n interface{}) {
+ // Fix up calls to http.Get.
+ //
+ // If they have blank identifiers, remove them:
+ // resp, _, err := http.Get(url)
+ // -> resp, err := http.Get(url)
+ //
+ // But if they're using the finalURL parameter, warn:
+ // resp, finalURL, err := http.Get(url)
+ as, ok := n.(*ast.AssignStmt)
+ if !ok || len(as.Lhs) != 3 || len(as.Rhs) != 1 {
+ return
+ }
+
+ if !isCall(as.Rhs[0], "http", "Get") {
+ return
+ }
+
+ if isBlank(as.Lhs[1]) {
+ as.Lhs = []ast.Expr{as.Lhs[0], as.Lhs[2]}
+ fixed = true
+ } else {
+ warn(as.Pos(), "call to http.Get records final URL")
+ }
+ })
+ return fixed
+}
diff --git a/src/cmd/gofix/httpfinalurl_test.go b/src/cmd/gofix/httpfinalurl_test.go
new file mode 100644
index 000000000..9e7d6242d
--- /dev/null
+++ b/src/cmd/gofix/httpfinalurl_test.go
@@ -0,0 +1,37 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func init() {
+ addTestCases(httpfinalurlTests)
+}
+
+var httpfinalurlTests = []testCase{
+ {
+ Name: "finalurl.0",
+ In: `package main
+
+import (
+ "http"
+)
+
+func f() {
+ resp, _, err := http.Get("http://www.google.com/")
+ _, _ = resp, err
+}
+`,
+ Out: `package main
+
+import (
+ "http"
+)
+
+func f() {
+ resp, err := http.Get("http://www.google.com/")
+ _, _ = resp, err
+}
+`,
+ },
+}
diff --git a/src/cmd/gofmt/test.sh b/src/cmd/gofmt/test.sh
index 99ec76932..f60ff9b32 100755
--- a/src/cmd/gofmt/test.sh
+++ b/src/cmd/gofmt/test.sh
@@ -42,7 +42,8 @@ apply1() {
bug163.go | bug166.go | bug169.go | bug217.go | bug222.go | \
bug226.go | bug228.go | bug248.go | bug274.go | bug280.go | \
bug282.go | bug287.go | bug298.go | bug299.go | bug300.go | \
- bug302.go | bug306.go | bug322.go | bug324.go ) return ;;
+ bug302.go | bug306.go | bug322.go | bug324.go | bug335.go | \
+ bug340.go ) return ;;
esac
# the following directories are skipped because they contain test
# cases for syntax errors and thus won't parse in the first place:
diff --git a/src/cmd/gotest/gotest.go b/src/cmd/gotest/gotest.go
index a7ba8dd11..8c81baf97 100644
--- a/src/cmd/gotest/gotest.go
+++ b/src/cmd/gotest/gotest.go
@@ -52,7 +52,7 @@ var (
xFlag bool
)
-// elapsed returns time elapsed since gotest started.
+// elapsed returns the number of seconds since gotest started.
func elapsed() float64 {
return float64(time.Nanoseconds()-start) / 1e9
}
@@ -182,7 +182,7 @@ func getTestFileNames() {
}
}
-// parseFiles parses the files and remembers the packages we find.
+// parseFiles parses the files and remembers the packages we find.
func parseFiles() {
fileSet := token.NewFileSet()
for _, f := range files {
@@ -285,6 +285,7 @@ func doRun(argv []string, returnStdout bool) string {
}
cmd += `"` + v + `"`
}
+ command = "sh"
argv = []string{"sh", "-c", cmd}
}
var err os.Error
diff --git a/src/cmd/gotype/gotype.go b/src/cmd/gotype/gotype.go
index 568467322..b6a23ae5f 100644
--- a/src/cmd/gotype/gotype.go
+++ b/src/cmd/gotype/gotype.go
@@ -178,8 +178,10 @@ func processPackage(fset *token.FileSet, files map[string]*ast.File) {
report(err)
return
}
- // TODO(gri): typecheck package
- _ = pkg
+ _, err = types.Check(fset, pkg)
+ if err != nil {
+ report(err)
+ }
}
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 0cb2b2138..3f3faade0 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -804,6 +804,10 @@ dodata(void)
diag("%s: no size", s->name);
t = 1;
}
+ if(t >= PtrSize)
+ t = rnd(t, PtrSize);
+ else if(t > 2)
+ t = rnd(t, 4);
if(t & 1)
;
else if(t & 2)
@@ -826,6 +830,10 @@ dodata(void)
diag("unexpected symbol type %d", s->type);
}
t = s->size;
+ if(t >= PtrSize)
+ t = rnd(t, PtrSize);
+ else if(t > 2)
+ t = rnd(t, 4);
if(t & 1)
;
else if(t & 2)
@@ -899,10 +907,8 @@ address(void)
segdata.fileoff = va - segtext.vaddr + segtext.fileoff;
if(HEADTYPE == Hwindows)
segdata.fileoff = segtext.fileoff + rnd(segtext.len, PEFILEALIGN);
- if(HEADTYPE == Hplan9x32) {
- segdata.vaddr = va = rnd(va, 4096);
+ if(HEADTYPE == Hplan9x32)
segdata.fileoff = segtext.fileoff + segtext.filelen;
- }
for(s=segdata.sect; s != nil; s=s->next) {
s->vaddr = va;
va += s->len;
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index 98b068008..ed11f5e5a 100644
--- a/src/cmd/ld/dwarf.c
+++ b/src/cmd/ld/dwarf.c
@@ -2562,7 +2562,6 @@ dwarfaddmachoheaders(void)
void
dwarfaddpeheaders(void)
{
- dwarfemitdebugsections();
newPEDWARFSection(".debug_abbrev", abbrevsize);
newPEDWARFSection(".debug_line", linesize);
newPEDWARFSection(".debug_frame", framesize);
diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h
index 08583cc8f..d1370d28b 100644
--- a/src/cmd/ld/elf.h
+++ b/src/cmd/ld/elf.h
@@ -978,6 +978,10 @@ ElfShdr* elfshbits(Section*);
void elfsetstring(char*, int);
void elfaddverneed(Sym*);
+EXTERN int elfstrsize;
+EXTERN char* elfstrdat;
+EXTERN int elftextsh;
+
/*
* Total amount of space to reserve at the start of the file
* for Header, PHeaders, SHeaders, and interp.
diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c
index e52c5cb34..a19fe460d 100644
--- a/src/cmd/ld/go.c
+++ b/src/cmd/ld/go.c
@@ -454,6 +454,7 @@ loaddynimport(char *file, char *pkg, char *p, int n)
if(strcmp(name, "_") == 0 && strcmp(def, "_") == 0) {
// allow #pragma dynimport _ _ "foo.so"
// to force a link of foo.so.
+ havedynamic = 1;
adddynlib(lib);
continue;
}
@@ -468,6 +469,7 @@ loaddynimport(char *file, char *pkg, char *p, int n)
s->dynimpname = def;
s->dynimpvers = q;
s->type = SDYNIMPORT;
+ havedynamic = 1;
}
}
return;
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c
index 15219ba11..105d982e4 100644
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -259,6 +259,18 @@ loadlib(void)
Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i].file, library[i].objref);
objfile(library[i].file, library[i].pkg);
}
+
+ // We've loaded all the code now.
+ // If there are no dynamic libraries needed, gcc disables dynamic linking.
+ // Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
+ // assumes that a dynamic binary always refers to at least one dynamic library.
+ // Rather than be a source of test cases for glibc, disable dynamic linking
+ // the same way that gcc would.
+ //
+ // Exception: on OS X, programs such as Shark only work with dynamic
+ // binaries, so leave it enabled on OS X (Mach-O) binaries.
+ if(!havedynamic && HEADTYPE != Hdarwin)
+ debug['d'] = 1;
}
/*
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index 8b603a04a..cd4608085 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -122,6 +122,7 @@ EXTERN char* outfile;
EXTERN int32 nsymbol;
EXTERN char* thestring;
EXTERN int ndynexp;
+EXTERN int havedynamic;
EXTERN Segment segtext;
EXTERN Segment segdata;
@@ -185,6 +186,7 @@ vlong addsize(Sym*, Sym*);
vlong adduint8(Sym*, uint8);
vlong adduint16(Sym*, uint16);
void asmsym(void);
+void asmelfsym32(void);
void asmelfsym64(void);
void asmplan9sym(void);
void strnput(char*, int);
diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c
index d523ca9c5..1c0c66538 100644
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -484,13 +484,13 @@ asmbpe(void)
d->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
+ if(!debug['s'])
+ dwarfaddpeheaders();
+
addimports(nextfileoff, d);
addexports(nextfileoff);
- if(!debug['s'])
- dwarfaddpeheaders();
-
addsymtable();
fh.NumberOfSections = nsect;
diff --git a/src/cmd/prof/gopprof b/src/cmd/prof/gopprof
index 8fa00cbe8..8863fc623 100755
--- a/src/cmd/prof/gopprof
+++ b/src/cmd/prof/gopprof
@@ -2880,17 +2880,18 @@ sub FetchSymbols {
my @toask = @pcs;
while (@toask > 0) {
my $n = @toask;
- if ($n > 49) { $n = 49; }
+ # NOTE(rsc): Limiting the number of PCs requested per round
+ # used to be necessary, but I think it was a bug in
+ # debug/pprof/symbol's implementation. Leaving here
+ # in case I am wrong.
+ # if ($n > 49) { $n = 49; }
my @thisround = @toask[0..$n];
-my $t = @toask;
-print STDERR "$n $t\n";
@toask = @toask[($n+1)..(@toask-1)];
my $post_data = join("+", sort((map {"0x" . "$_"} @thisround)));
open(POSTFILE, ">$main::tmpfile_sym");
print POSTFILE $post_data;
close(POSTFILE);
-print STDERR "SYMBL!\n";
my $url = SymbolPageURL();
$url = ResolveRedirectionForCurl($url);
my $command_line = "$CURL -sd '\@$main::tmpfile_sym' '$url'";