]> Cypherpunks repositories - gostls13.git/commitdiff
update 8a, 8c, 8l to use new object format.
authorRuss Cox <rsc@golang.org>
Fri, 20 Mar 2009 23:40:00 +0000 (16:40 -0700)
committerRuss Cox <rsc@golang.org>
Fri, 20 Mar 2009 23:40:00 +0000 (16:40 -0700)
add "extern register" support to 8c.
extern register means allocate in the FS-relative segment.

make 8l generate segmented stack checks.

R=ken
OCL=26600
CL=26606

18 files changed:
src/cmd/8a/a.h
src/cmd/8a/a.y
src/cmd/8a/lex.c
src/cmd/8c/gc.h
src/cmd/8c/list.c
src/cmd/8c/sgen.c
src/cmd/8c/swt.c
src/cmd/8c/txt.c
src/cmd/8l/8.out.h
src/cmd/8l/l.h
src/cmd/8l/list.c
src/cmd/8l/obj.c
src/cmd/8l/optab.c
src/cmd/8l/pass.c
src/cmd/8l/span.c
src/cmd/cc/cc.h
src/cmd/cc/com.c
src/cmd/cc/sub.c

index 8b5f7d9efa9eff24b7d275dd5502bc218b53a7f8..dbe43992953c24874df66130f050a274613769d5 100644 (file)
@@ -32,7 +32,6 @@
 #include <libc.h>
 #include <bio.h>
 #include "../8l/8.out.h"
-#include "compat.h"
 
 
 #ifndef        EXTERN
@@ -104,6 +103,7 @@ struct      Gen
        double  dval;
        char    sval[8];
        int32   offset;
+       int32   offset2;
        Sym*    sym;
        short   type;
        short   index;
index 505defd2878a7d2873feb0b8755f7b7d189cb337..fced3efa47bf285a36b1d5eebb38adb4a3b4ddb1 100644 (file)
 %union {
        Sym     *sym;
        int32   lval;
+       struct {
+               int32 v1;
+               int32 v2;
+       } con2;
        double  dval;
        char    sval[8];
        Gen     gen;
 %left  '+' '-'
 %left  '*' '/' '%'
 %token <lval>  LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
-%token <lval>  LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI
+%token <lval>  LTYPEC LTYPED LTYPEN LTYPER LTYPET LTYPES LTYPEM LTYPEI LTYPEG
 %token <lval>  LCONST LFP LPC LSB
 %token <lval>  LBREG LLREG LSREG LFREG
 %token <dval>  LFCONST
 %token <sval>  LSCONST LSP
 %token <sym>   LNAME LLAB LVAR
 %type  <lval>  con expr pointer offset
-%type  <gen>   mem imm reg nam rel rem rim rom omem nmem
+%type  <con2>  con2
+%type  <gen>   mem imm imm2 reg nam rel rem rim rom omem nmem
 %type  <gen2>  nonnon nonrel nonrem rimnon rimrem remrim
-%type  <gen2>  spec1 spec2 spec3 spec4 spec5 spec6 spec7
+%type  <gen2>  spec1 spec2 spec3 spec4 spec5 spec6 spec7 spec8
 %%
 prog:
 |      prog line
@@ -103,6 +108,7 @@ inst:
 |      LTYPES spec5    { outcode($1, &$2); }
 |      LTYPEM spec6    { outcode($1, &$2); }
 |      LTYPEI spec7    { outcode($1, &$2); }
+|      LTYPEG spec8    { outcode($1, &$2); }
 
 nonnon:
        {
@@ -174,12 +180,12 @@ spec1:    /* DATA */
        }
 
 spec2: /* TEXT */
-       mem ',' imm
+       mem ',' imm2
        {
                $$.from = $1;
                $$.to = $3;
        }
-|      mem ',' con ',' imm
+|      mem ',' con ',' imm2
        {
                $$.from = $1;
                $$.from.scale = $3;
@@ -249,6 +255,19 @@ spec7:
                $$.to = $3;
        }
 
+spec8: /* GLOBL */
+       mem ',' imm
+       {
+               $$.from = $1;
+               $$.to = $3;
+       }
+|      mem ',' con ',' imm
+       {
+               $$.from = $1;
+               $$.from.scale = $3;
+               $$.to = $5;
+       }
+
 rem:
        reg
 |      mem
@@ -365,6 +384,37 @@ imm:
                $$.dval = -$3;
        }
 
+imm2:
+       '$' con2
+       {
+               $$ = nullgen;
+               $$.type = D_CONST2;
+               $$.offset = $2.v1;
+               $$.offset2 = $2.v2;
+       }
+
+con2:
+       LCONST
+       {
+               $$.v1 = $1;
+               $$.v2 = 0;
+       }
+|      '-' LCONST
+       {
+               $$.v1 = -$2;
+               $$.v2 = 0;
+       }
+|      LCONST '-' LCONST
+       {
+               $$.v1 = $1;
+               $$.v2 = $3;
+       }
+|      '-' LCONST '-' LCONST
+       {
+               $$.v1 = -$2;
+               $$.v2 = $4;
+       }
+
 mem:
        omem
 |      nmem
@@ -416,6 +466,12 @@ omem:
                $$ = nullgen;
                $$.type = D_INDIR+D_SP;
        }
+|      con '(' LSREG ')'
+       {
+               $$ = nullgen;
+               $$.type = D_INDIR+$3;
+               $$.offset = $1;
+       }
 |      '(' LLREG '*' con ')'
        {
                $$ = nullgen;
index 8576f01b7309a8701f15f215513f4ea78446922c..fcc4cf964a8f3d814fdc8c46054443320eb07550 100644 (file)
@@ -165,6 +165,9 @@ assemble(char *file)
 
        pass = 1;
        pinit(file);
+       
+       Bprint(&obuf, "%s\n", thestring);
+
        for(i=0; i<nDlist; i++)
                dodefine(Dlist[i]);
        yyparse();
@@ -172,6 +175,8 @@ assemble(char *file)
                cclean();
                return nerrors;
        }
+       
+       Bprint(&obuf, "\n!\n");
 
        pass = 2;
        outhist();
@@ -304,6 +309,9 @@ struct
        "CMPSB",        LTYPE0, ACMPSB,
        "CMPSL",        LTYPE0, ACMPSL,
        "CMPSW",        LTYPE0, ACMPSW,
+       "CMPXCHGB",     LTYPE3, ACMPXCHGB,
+       "CMPXCHGL",     LTYPE3, ACMPXCHGL,
+       "CMPXCHGW",     LTYPE3, ACMPXCHGW,      
        "DAA",          LTYPE0, ADAA,
        "DAS",          LTYPE0, ADAS,
        "DATA",         LTYPED, ADATA,
@@ -315,7 +323,7 @@ struct
        "DIVW",         LTYPE2, ADIVW,
        "END",          LTYPE0, AEND,
        "ENTER",        LTYPE2, AENTER,
-       "GLOBL",        LTYPET, AGLOBL,
+       "GLOBL",        LTYPEG, AGLOBL,
        "HLT",          LTYPE0, AHLT,
        "IDIVB",        LTYPE2, AIDIVB,
        "IDIVL",        LTYPE2, AIDIVL,
@@ -714,7 +722,7 @@ zname(char *n, int t, int s)
 void
 zaddr(Gen *a, int s)
 {
-       long l;
+       int32 l;
        int i, t;
        char *n;
        Ieee e;
@@ -734,6 +742,9 @@ zaddr(Gen *a, int s)
        case D_FCONST:
                t |= T_FCONST;
                break;
+       case D_CONST2:
+               t |= T_OFFSET|T_OFFSET2;
+               break;
        case D_SCONST:
                t |= T_SCONST;
                break;
@@ -753,6 +764,13 @@ zaddr(Gen *a, int s)
                Bputc(&obuf, l>>16);
                Bputc(&obuf, l>>24);
        }
+       if(t & T_OFFSET2) {
+               l = a->offset2;
+               Bputc(&obuf, l);
+               Bputc(&obuf, l>>8);
+               Bputc(&obuf, l>>16);
+               Bputc(&obuf, l>>24);
+       }
        if(t & T_SYM)           /* implies sym */
                Bputc(&obuf, s);
        if(t & T_FCONST) {
index c30eb55bc169a499f133a16cb02787bf60064fbb..55a37c42cdfe72a6cb2879cc5a569e77158e20b6 100644 (file)
@@ -66,6 +66,7 @@ EXTERN        struct
 struct Adr
 {
        int32   offset;
+       int32   offset2;
        double  dval;
        char    sval[NSNAME];
 
index d700b63af526985b92da16b9641c3507e61b4365..ec5ac9d60f87857d83e7ecdf178fcfbe4dfaa3d1 100644 (file)
@@ -154,6 +154,10 @@ Dconv(Fmt *fp)
                sprint(str, "$%ld", a->offset);
                break;
 
+       case D_CONST2:
+               sprint(str, "$%ld-%ld", a->offset, a->offset2);
+               break;
+
        case D_FCONST:
                sprint(str, "$(%.17e)", a->dval);
                break;
index 14bd32adb32429ffeaadf995f841c64937e1837c..c4d5665d8358be8d12cfa07985d07ef1498e45ff 100644 (file)
 
 #include "gc.h"
 
+int32
+argsize(void)
+{
+       Type *t;
+       int32 s;
+
+//print("t=%T\n", thisfn);
+       s = 0;
+       for(t=thisfn->down; t!=T; t=t->down) {
+               switch(t->etype) {
+               case TVOID:
+                       break;
+               case TDOT:
+                       s += 64;
+                       break;
+               default:
+                       s = align(s, t, Aarg1);
+                       s = align(s, t, Aarg2);
+                       break;
+               }
+//print("      %d %T\n", s, t);
+       }
+       return (s+7) & ~7;
+}
+
 void
 codgen(Node *n, Node *nn)
 {
@@ -52,7 +77,10 @@ codgen(Node *n, Node *nn)
                        break;
        }
        nearln = nn->lineno;
+
        gpseudo(ATEXT, n1->sym, nodconst(stkoff));
+       p->to.type = D_CONST2;
+       p->to.offset2 = argsize();
 
        /*
         * isolate first argument
@@ -494,6 +522,10 @@ xcom(Node *n)
                        n->addable = 11;
                break;
 
+       case OEXREG:
+               n->addable = 10;
+               break;
+
        case OREGISTER:
                n->addable = 12;
                break;
index 13e9a51e31692c37cce2760e8c613dc411cfdb69..6d693337ae8a5618e48f998ec12beb7880f935df 100644 (file)
@@ -328,7 +328,10 @@ outcode(void)
                return;
        }
        Binit(&b, f, OWRITE);
-       Bseek(&b, 0L, 2);
+
+       Bprint(&b, "%s\n", thestring);
+       Bprint(&b, "!\n");
+
        outhist(&b);
        for(sym=0; sym<NSYM; sym++) {
                h[sym].sym = S;
@@ -530,6 +533,9 @@ zaddr(Biobuf *b, Adr *a, int s)
        case D_SCONST:
                t |= T_SCONST;
                break;
+       case D_CONST2:
+               t |= T_OFFSET|T_OFFSET2;
+               break;
        }
        Bputc(b, t);
 
@@ -544,6 +550,13 @@ zaddr(Biobuf *b, Adr *a, int s)
                Bputc(b, l>>16);
                Bputc(b, l>>24);
        }
+       if(t & T_OFFSET2) {     /* implies offset2 */
+               l = a->offset2;
+               Bputc(b, l);
+               Bputc(b, l>>8);
+               Bputc(b, l>>16);
+               Bputc(b, l>>24);
+       }
        if(t & T_SYM)           /* implies sym */
                Bputc(b, s);
        if(t & T_FCONST) {
index 4e95f3c7a87957b0ef2bbaa2287537980105eb7e..5cc43e0e94cccd7f02715fe4c322c59c0887a441 100644 (file)
@@ -449,6 +449,10 @@ naddr(Node *n, Adr *a)
                a->sym = S;
                break;
 
+       case OEXREG:
+               a->type = D_INDIR + D_FS;
+               a->offset = n->reg - 1;
+               break;
 
        case OIND:
                naddr(n->left, a);
@@ -1389,6 +1393,15 @@ sconst(Node *n)
 int32
 exreg(Type *t)
 {
+       int32 o;
+
+       if(typechlp[t->etype]){
+               if(exregoffset >= 32)
+                       return 0;
+               o = exregoffset;
+               exregoffset += 4;
+               return o+1;     // +1 to avoid 0 == failure; naddr case OEXREG will -1.
+       }
 
        USED(t);
        return 0;
index 647c1dd59655e91f9c2a55c48b62e6daa41cd18a..f7750129d8e6617eb333569ea76481d705f28591 100644 (file)
@@ -32,6 +32,7 @@
 #define        NSNAME  8
 #define NOPROF (1<<0)
 #define DUPOK  (1<<1)
+#define NOSPLIT        (1<<2)
 
 enum   as
 {
@@ -78,6 +79,9 @@ enum  as
        ACMPSB,
        ACMPSL,
        ACMPSW,
+       ACMPXCHGB,
+       ACMPXCHGL,
+       ACMPXCHGW,
        ADAA,
        ADAS,
        ADATA,
@@ -437,6 +441,7 @@ enum
        D_FCONST        = 66,
        D_SCONST        = 67,
        D_ADDR          = 68,
+       D_CONST2        = 69,
 
        D_FILE,
        D_FILE1,
@@ -449,6 +454,7 @@ enum
        T_FCONST        = 1<<3,
        T_SYM           = 1<<4,
        T_SCONST        = 1<<5,
+       T_OFFSET2       = 1<<6,
 
        REGARG          = 0,
        REGRET          = D_AX,
index fabf8903417580bbcc351de7000b265e8c164dde..114c66369042beeb3bfa56348061909d931376d2 100644 (file)
@@ -67,6 +67,7 @@ struct        Adr
        short   type;
        uchar   index;
        char    scale;
+       int32   offset2;
 };
 
 #define        offset  u0.u0offset
@@ -342,7 +343,7 @@ void        histtoauto(void);
 double ieeedtod(Ieee*);
 int32  ieeedtof(Ieee*);
 void   import(void);
-void   ldobj(int, int32, char*);
+void   ldobj(Biobuf*, int32, char*);
 void   loadlib(void);
 void   listinit(void);
 Sym*   lookup(char*, int);
@@ -368,7 +369,7 @@ int32       vaddr(Adr*);
 void   wput(ushort);
 void   xdefine(char*, int, int32);
 void   xfol(Prog*);
-int    zaddr(uchar*, Adr*, Sym*[]);
+void   zaddr(Biobuf*, Adr*, Sym*[]);
 void   zerosig(char*);
 uint32 machheadr(void);
 uint32 elfheadr(void);
index ebd8b864b90eb50fd2dc86fcfcf5a651d2eae9f5..873f7c1f857b16544f5ea6fade37c7a48f3579db 100644 (file)
@@ -82,6 +82,14 @@ Aconv(Fmt *fp)
        return fmtstrcpy(fp, anames[i]);
 }
 
+char*
+xsymname(Sym *s)
+{
+       if(s == nil)
+               return "!!noname!!";
+       return s->name;
+}
+
 int
 Dconv(Fmt *fp)
 {
@@ -120,16 +128,16 @@ Dconv(Fmt *fp)
                break;
 
        case D_EXTERN:
-               sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
+               sprint(str, "%s+%ld(SB)", xsymname(a->sym), a->offset);
                break;
 
        case D_STATIC:
-               sprint(str, "%s<%d>+%ld(SB)", a->sym->name,
+               sprint(str, "%s<%d>+%ld(SB)", xsymname(a->sym),
                        a->sym->version, a->offset);
                break;
 
        case D_AUTO:
-               sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
+               sprint(str, "%s+%ld(SP)", xsymname(a->sym), a->offset);
                break;
 
        case D_PARAM:
@@ -143,6 +151,10 @@ Dconv(Fmt *fp)
                sprint(str, "$%ld", a->offset);
                break;
 
+       case D_CONST2:
+               sprint(str, "$%ld-%ld", a->offset, a->offset2);
+               break;
+
        case D_FCONST:
                sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
                break;
index a1d14318dda4f0c7b1183cce6b97b92b9d2f9f63..022f315d297a40b65eee71df75592305b60828d4 100644 (file)
@@ -419,14 +419,15 @@ void
 objfile(char *file)
 {
        int32 off, esym, cnt, l;
-       int f, work;
+       int work;
+       Biobuf *f;
        Sym *s;
        char magbuf[SARMAG];
        char name[100], pname[150];
        struct ar_hdr arhdr;
        char *e, *start, *stop;
 
-       if(file[0] == '-' && file[1] == 'l') {
+       if(file[0] == '-' && file[1] == 'l') {  // TODO: fix this
                if(debug['9'])
                        sprint(name, "/%s/lib/lib", thestring);
                else
@@ -438,22 +439,22 @@ objfile(char *file)
        if(debug['v'])
                Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
        Bflush(&bso);
-       f = open(file, 0);
-       if(f < 0) {
+       f = Bopen(file, 0);
+       if(f == nil) {
                diag("cannot open file: %s", file);
                errorexit();
        }
-       l = read(f, magbuf, SARMAG);
+       l = Bread(f, magbuf, SARMAG);
        if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
                /* load it as a regular file */
-               l = seek(f, 0L, 2);
-               seek(f, 0L, 0);
+               l = Bseek(f, 0L, 2);
+               Bseek(f, 0L, 0);
                ldobj(f, l, file);
-               close(f);
+               Bterm(f);
                return;
        }
 
-       l = read(f, &arhdr, SAR_HDR);
+       l = Bread(f, &arhdr, SAR_HDR);
        if(l != SAR_HDR) {
                diag("%s: short read on archive file symbol header", file);
                goto out;
@@ -469,12 +470,12 @@ objfile(char *file)
        /*
         * just bang the whole symbol file into memory
         */
-       seek(f, off, 0);
+       Bseek(f, off, 0);
        cnt = esym - off;
        start = malloc(cnt + 10);
-       cnt = read(f, start, cnt);
+       cnt = Bread(f, start, cnt);
        if(cnt <= 0){
-               close(f);
+               Bterm(f);
                return;
        }
        stop = &start[cnt];
@@ -498,12 +499,16 @@ objfile(char *file)
                        l |= (e[2] & 0xff) << 8;
                        l |= (e[3] & 0xff) << 16;
                        l |= (e[4] & 0xff) << 24;
-                       seek(f, l, 0);
-                       l = read(f, &arhdr, SAR_HDR);
+                       Bseek(f, l, 0);
+                       l = Bread(f, &arhdr, SAR_HDR);
                        if(l != SAR_HDR)
                                goto bad;
                        if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))
                                goto bad;
+                       l = SARNAME;
+                       while(l > 0 && arhdr.name[l-1] == ' ')
+                               l--;
+                       sprint(pname, "%s(%.*s)", file, l, arhdr.name);
                        l = atolwhex(arhdr.size);
                        ldobj(f, l, pname);
                        if(s->type == SXREF) {
@@ -519,85 +524,87 @@ objfile(char *file)
 bad:
        diag("%s: bad or out of date archive", file);
 out:
-       close(f);
+       Bterm(f);
 }
 
-int
-zaddr(uchar *p, Adr *a, Sym *h[])
+int32
+Bget4(Biobuf *f)
+{
+       uchar p[4];
+
+       if(Bread(f, p, 4) != 4)
+               return 0;
+       return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+void
+zaddr(Biobuf *f, Adr *a, Sym *h[])
 {
-       int c, t, i;
+       int t;
        int32 l;
        Sym *s;
        Auto *u;
 
-       t = p[0];
-
-       c = 1;
+       t = Bgetc(f);
        if(t & T_INDEX) {
-               a->index = p[c];
-               a->scale = p[c+1];
-               c += 2;
+               a->index = Bgetc(f);
+               a->scale = Bgetc(f);
        } else {
                a->index = D_NONE;
                a->scale = 0;
        }
+       a->type = D_NONE;
        a->offset = 0;
-       if(t & T_OFFSET) {
-               a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);
-               c += 4;
+       if(t & T_OFFSET)
+               a->offset = Bget4(f);
+       a->offset2 = 0;
+       if(t & T_OFFSET2) {
+               a->offset2 = Bget4(f);
+               a->type = D_CONST2;
        }
        a->sym = S;
-       if(t & T_SYM) {
-               a->sym = h[p[c]];
-               c++;
-       }
-       a->type = D_NONE;
+       if(t & T_SYM)
+               a->sym = h[Bgetc(f)];
        if(t & T_FCONST) {
-               a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);
-               a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24);
-               c += 8;
+               a->ieee.l = Bget4(f);
+               a->ieee.h = Bget4(f);
                a->type = D_FCONST;
        } else
        if(t & T_SCONST) {
-               for(i=0; i<NSNAME; i++)
-                       a->scon[i] = p[c+i];
-               c += NSNAME;
+               Bread(f, a->scon, NSNAME);
                a->type = D_SCONST;
        }
-       if(t & T_TYPE) {
-               a->type = p[c];
-               c++;
-       }
+       if(t & T_TYPE)
+               a->type = Bgetc(f);
        s = a->sym;
        if(s == S)
-               return c;
+               return;
 
        t = a->type;
        if(t != D_AUTO && t != D_PARAM)
-               return c;
+               return;
        l = a->offset;
        for(u=curauto; u; u=u->link) {
                if(u->asym == s)
                if(u->type == t) {
                        if(u->aoffset > l)
                                u->aoffset = l;
-                       return c;
+                       return;
                }
        }
 
-       u = mal(sizeof(Auto));
+       u = mal(sizeof(*u));
        u->link = curauto;
        curauto = u;
        u->asym = s;
        u->aoffset = l;
        u->type = t;
-       return c;
 }
 
 void
-addlib(char *obj)
+addlib(char *src, char *obj)
 {
-       char name[1024], comp[256], *p;
+       char name[1024], comp[256], *p, *q;
        int i;
 
        if(histfrogp <= 0)
@@ -645,6 +652,23 @@ addlib(char *obj)
                strcat(name, "/");
                strcat(name, comp);
        }
+       if(debug['v'])
+               Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, name);
+
+       p = strrchr(src, '/');
+       q = strrchr(name, '/');
+       if(p != nil && q != nil && p - src == q - name && memcmp(src, name, p - src) == 0) {
+               // leading paths are the same.
+               // if the source file refers to an object in its own directory
+               // and we are inside an archive, ignore the reference, in the hope
+               // that the archive contains that object too.
+               if(strchr(obj, '(')) {
+                       if(debug['v'])
+                               Bprint(&bso, "%5.2f ignored srcdir object %s\n", cputime(), name);
+                       return;
+               }
+       }
+
        for(i=0; i<libraryp; i++)
                if(strcmp(name, library[i]) == 0)
                        return;
@@ -662,6 +686,22 @@ addlib(char *obj)
        libraryp++;
 }
 
+void
+copyhistfrog(char *buf, int nbuf)
+{
+       char *p, *ep;
+       int i;
+
+       p = buf;
+       ep = buf + nbuf;
+       i = 0;
+       for(i=0; i<histfrogp; i++) {
+               p = seprint(p, ep, "%s", histfrog[i]->name+1);
+               if(i+1<histfrogp && (p == buf || p[-1] != '/'))
+                       p = seprint(p, ep, "/");
+       }
+}
+
 void
 addhist(int32 line, int type)
 {
@@ -679,6 +719,7 @@ addhist(int32 line, int type)
        u->link = curhist;
        curhist = u;
 
+       s->name[0] = 0;
        j = 1;
        for(i=0; i<histfrogp; i++) {
                k = histfrog[i]->value;
@@ -686,6 +727,8 @@ addhist(int32 line, int type)
                s->name[j+1] = k;
                j += 2;
        }
+       s->name[j] = 0;
+       s->name[j+1] = 0;
 }
 
 void
@@ -746,35 +789,27 @@ nopout(Prog *p)
        p->to.type = D_NONE;
 }
 
-uchar*
-readsome(int f, uchar *buf, uchar *good, uchar *stop, int max)
-{
-       int n;
-
-       n = stop - good;
-       memmove(buf, good, stop - good);
-       stop = buf + n;
-       n = MAXIO - n;
-       if(n > max)
-               n = max;
-       n = read(f, stop, n);
-       if(n <= 0)
-               return 0;
-       return stop + n;
-}
-
 void
-ldobj(int f, int32 c, char *pn)
+ldobj(Biobuf *f, int32 len, char *pn)
 {
        int32 ipc;
        Prog *p, *t;
-       uchar *bloc, *bsize, *stop;
        int v, o, r, skip;
        Sym *h[NSYM], *s, *di;
        uint32 sig;
        static int files;
        static char **filen;
        char **nfilen;
+       int ntext, n, c1, c2, c3;
+       int32 eof;
+       int32 import0, import1;
+       char *line, *name;
+       char src[1024];
+
+       src[0] = '\0';
+       eof = Boffset(f) + len;
+
+       ntext = 0;
 
        if((files&15) == 0){
                nfilen = malloc((files+16)*sizeof(char*));
@@ -782,12 +817,48 @@ ldobj(int f, int32 c, char *pn)
                free(filen);
                filen = nfilen;
        }
-       filen[files++] = strdup(pn);
+       pn = strdup(pn);
+       filen[files++] = pn;
 
-       bsize = buf.xbuf;
-       bloc = buf.xbuf;
        di = S;
 
+       /* check the header */
+       line = Brdline(f, '\n');
+       if(line == nil) {
+               if(Blinelen(f) > 0) {
+                       diag("%s: malformed object file", pn);
+                       return;
+               }
+               goto eof;
+       }
+       n = Blinelen(f) - 1;
+       if(n != strlen(thestring) || strncmp(line, thestring, n) != 0) {
+               if(line)
+                       line[n] = '\0';
+               diag("file not %s [%s]\n", thestring, line);
+               return;
+       }
+
+       /* skip over exports and other info -- ends with \n!\n */
+       import0 = Boffset(f);
+       c1 = '\n';      // the last line ended in \n
+       c2 = Bgetc(f);
+       c3 = Bgetc(f);
+       while(c1 != '\n' || c2 != '!' || c3 != '\n') {
+               c1 = c2;
+               c2 = c3;
+               c3 = Bgetc(f);
+               if(c3 == Beof)
+                       goto eof;
+       }
+       import1 = Boffset(f);
+
+       Bseek(f, import0, 0);
+//     ldpkg(f, import1 - import0 - 2, pn);    // -2 for !\n
+       Bseek(f, import1, 0);
+
+print("import %ld-%ld\n", import0, import1);
+
 newloop:
        memset(h, 0, sizeof(h));
        version++;
@@ -796,61 +867,46 @@ newloop:
        skip = 0;
 
 loop:
-       if(c <= 0)
+       if(f->state == Bracteof || Boffset(f) >= eof)
                goto eof;
-       r = bsize - bloc;
-       if(r < 100 && r < c) {          /* enough for largest prog */
-               bsize = readsome(f, buf.xbuf, bloc, bsize, c);
-               if(bsize == 0)
-                       goto eof;
-               bloc = buf.xbuf;
-               goto loop;
-       }
-       o = bloc[0] | (bloc[1] << 8);
+       o = Bgetc(f);
+       if(o == Beof)
+               goto eof;
+       o |= Bgetc(f) << 8;
        if(o <= AXXX || o >= ALAST) {
                if(o < 0)
                        goto eof;
-               diag("%s: opcode out of range %d", pn, o);
-               print(" probably not a .8 file\n");
+               diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
+               print(" probably not a .%c file\n", thechar);
                errorexit();
        }
 
        if(o == ANAME || o == ASIGNAME) {
                sig = 0;
-               if(o == ASIGNAME) {
-                       sig = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24);
-                       bloc += 4;
-                       c -= 4;
-               }
-               stop = memchr(&bloc[4], 0, bsize-&bloc[4]);
-               if(stop == 0){
-                       bsize = readsome(f, buf.xbuf, bloc, bsize, c);
-                       if(bsize == 0)
-                               goto eof;
-                       bloc = buf.xbuf;
-                       stop = memchr(&bloc[4], 0, bsize-&bloc[4]);
-                       if(stop == 0){
+               if(o == ASIGNAME)
+                       sig = Bget4(f);
+               v = Bgetc(f);   /* type */
+               o = Bgetc(f);   /* sym */
+               r = 0;
+               if(v == D_STATIC)
+                       r = version;
+               name = Brdline(f, '\0');
+               if(name == nil) {
+                       if(Blinelen(f) > 0) {
                                fprint(2, "%s: name too long\n", pn);
                                errorexit();
                        }
+                       goto eof;
                }
-               v = bloc[2];    /* type */
-               o = bloc[3];    /* sym */
-               bloc += 4;
-               c -= 4;
-
-               r = 0;
-               if(v == D_STATIC)
-                       r = version;
-               s = lookup((char*)bloc, r);
-               c -= &stop[1] - bloc;
-               bloc = stop + 1;
+               s = lookup(name, r);
 
                if(debug['S'] && r == 0)
                        sig = 1729;
                if(sig != 0){
                        if(s->sig != 0 && s->sig != sig)
-                               diag("incompatible type signatures %lux(%s) and %lux(%s) for %s", s->sig, filen[s->file], sig, pn, s->name);
+                               diag("incompatible type signatures"
+                                       "%lux(%s) and %lux(%s) for %s",
+                                       s->sig, filen[s->file], sig, pn, s->name);
                        s->sig = sig;
                        s->file = files-1;
                }
@@ -877,12 +933,10 @@ loop:
 
        p = mal(sizeof(*p));
        p->as = o;
-       p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24);
+       p->line = Bget4(f);
        p->back = 2;
-       r = zaddr(bloc+6, &p->from, h) + 6;
-       r += zaddr(bloc+r, &p->to, h);
-       bloc += r;
-       c -= r;
+       zaddr(f, &p->from, h);
+       zaddr(f, &p->to, h);
 
        if(debug['W'])
                print("%P\n", p);
@@ -890,10 +944,12 @@ loop:
        switch(p->as) {
        case AHISTORY:
                if(p->to.offset == -1) {
-                       addlib(pn);
+                       addlib(src, pn);
                        histfrogp = 0;
                        goto loop;
                }
+               if(src[0] == '\0')
+                       copyhistfrog(src, sizeof src);
                addhist(p->line, D_FILE);               /* 'z' */
                if(p->to.offset)
                        addhist(p->to.offset, D_FILE1); /* 'Z' */
@@ -906,9 +962,9 @@ loop:
                        curtext->to.autom = curauto;
                curauto = 0;
                curtext = P;
-               if(c)
-                       goto newloop;
-               return;
+               if(Boffset(f) == eof)
+                       return;
+               goto newloop;
 
        case AGLOBL:
                s = p->from.sym;
@@ -983,6 +1039,17 @@ loop:
                goto loop;
 
        case ATEXT:
+               s = p->from.sym;
+               if(s == S) {
+                       diag("%s: no TEXT symbol: %P", pn, p);
+                       errorexit();
+               }
+               if(ntext++ == 0 && s->type != 0 && s->type != SXREF) {
+                       /* redefinition, so file has probably been seen before */
+                       if(debug['v'])
+                               diag("skipping: %s: redefinition: %s", pn, s->name);
+                       return;
+               }
                if(curtext != P) {
                        histtoauto();
                        curtext->to.autom = curauto;
@@ -990,11 +1057,6 @@ loop:
                }
                skip = 0;
                curtext = p;
-               s = p->from.sym;
-               if(s == S) {
-                       diag("%s: no TEXT symbol: %P", pn, p);
-                       errorexit();
-               }
                if(s->type != 0 && s->type != SXREF) {
                        if(p->from.scale & DUPOK) {
                                skip = 1;
index d88e861c569f3daa9b0f97361df45783d229887c..934f14e9bca8273a46a997f399443611b637e430 100644 (file)
@@ -173,6 +173,11 @@ uchar      yml_rl[] =
        Yml,    Yrl,    Zm_r,   1,
        0
 };
+uchar  yrb_mb[] =
+{
+       Yrb,    Ymb,    Zr_m,   1,
+       0
+};
 uchar  yrl_ml[] =
 {
        Yrl,    Yml,    Zr_m,   1,
@@ -383,6 +388,9 @@ Optab optab[] =
        { ACMPSB,       ynone,  Pb, 0xa6 },
        { ACMPSL,       ynone,  Px, 0xa7 },
        { ACMPSW,       ynone,  Pe, 0xa7 },
+       { ACMPXCHGB,    yrb_mb, Pm, 0xb0 },
+       { ACMPXCHGL,    yrl_ml, Pm, 0xb1 },
+       { ACMPXCHGW,    yrl_ml, Pm, 0xb1 },
        { ADAA,         ynone,  Px, 0x27 },
        { ADAS,         ynone,  Px, 0x2f },
        { ADATA },
index aa69c58498dcd2d2afce180265ae9896cea2e2e1..0726d1ea8fcee0a918314e0096122de48eaf11c2 100644 (file)
@@ -165,7 +165,7 @@ loop:
        if(p->as == ATEXT)
                curtext = p;
        if(p->as == AJMP)
-       if((q = p->pcond) != P) {
+       if((q = p->pcond) != P && q->as != ATEXT) {
                p->mark = 1;
                p = q;
                if(p->mark == 0)
@@ -331,14 +331,15 @@ patch(void)
        for(p = firstp; p != P; p = p->link) {
                if(p->as == ATEXT)
                        curtext = p;
-               if(p->as == ACALL || p->as == ARET) {
+               if(p->as == ACALL || (p->as == AJMP && p->to.type != D_BRANCH)) {
                        s = p->to.sym;
                        if(s) {
                                if(debug['c'])
                                        Bprint(&bso, "%s calls %s\n", TNAME, s->name);
                                switch(s->type) {
                                default:
-                                       diag("undefined: %s in %s", s->name, TNAME);
+                                       /* diag prints TNAME first */
+                                       diag("%s is undefined", s->name);
                                        s->type = STEXT;
                                        s->value = vexit;
                                        break;  /* or fall through to set offset? */
@@ -440,9 +441,27 @@ brloop(Prog *p)
 void
 dostkoff(void)
 {
-       Prog *p, *q;
+       Prog *p, *q, *q1;
        int32 autoffset, deltasp;
        int a, f, curframe, curbecome, maxbecome;
+       Prog *pmorestack;
+       Sym *symmorestack;
+
+       pmorestack = P;
+       symmorestack = lookup("sys·morestack", 0);
+
+       if(symmorestack->type == STEXT)
+       for(p = firstp; p != P; p = p->link) {
+               if(p->as == ATEXT) {
+                       if(p->from.sym == symmorestack) {
+                               pmorestack = p;
+                               p->from.scale |= NOSPLIT;
+                               break;
+                       }
+               }
+       }
+       if(pmorestack == P)
+               diag("sys·morestack not defined");
 
        curframe = 0;
        curbecome = 0;
@@ -521,11 +540,122 @@ dostkoff(void)
                        autoffset = p->to.offset;
                        if(autoffset < 0)
                                autoffset = 0;
+
+                       q = P;
+                       q1 = P;
+                       if(pmorestack != P)
+                       if(!(p->from.scale & NOSPLIT)) {
+                               p = appendp(p); // load g into CX
+                               p->as = AMOVL;
+                               p->from.type = D_INDIR+D_FS;
+                               p->from.offset = 0;
+                               p->to.type = D_CX;
+
+                               if(debug['K']) {
+                                       // 8l -K means check not only for stack
+                                       // overflow but stack underflow.
+                                       // On underflow, INT 3 (breakpoint).
+                                       // Underflow itself is rare but this also
+                                       // catches out-of-sync stack guard info.
+                                       p = appendp(p);
+                                       p->as = ACMPL;
+                                       p->from.type = D_INDIR+D_CX;
+                                       p->from.offset = 4;
+                                       p->to.type = D_SP;
+
+                                       p = appendp(p);
+                                       p->as = AJHI;
+                                       p->to.type = D_BRANCH;
+                                       p->to.offset = 4;
+                                       q1 = p;
+
+                                       p = appendp(p);
+                                       p->as = AINT;
+                                       p->from.type = D_CONST;
+                                       p->from.offset = 3;
+                               }
+
+                               if(autoffset < 4096) {  // do we need to call morestack
+                                       if(autoffset <= 75) {
+                                               // small stack
+                                               p = appendp(p);
+                                               p->as = ACMPL;
+                                               p->from.type = D_SP;
+                                               p->to.type = D_INDIR+D_CX;
+                                               if(q1) {
+                                                       q1->pcond = p;
+                                                       q1 = P;
+                                               }
+                                       } else {
+                                               // large stack
+                                               p = appendp(p);
+                                               p->as = ALEAL;
+                                               p->from.type = D_INDIR+D_SP;
+                                               p->from.offset = -(autoffset-75);
+                                               p->to.type = D_AX;
+                                               if(q1) {
+                                                       q1->pcond = p;
+                                                       q1 = P;
+                                               }
+
+                                               p = appendp(p);
+                                               p->as = ACMPL;
+                                               p->from.type = D_AX;
+                                               p->to.type = D_INDIR+D_CX;
+                                       }
+
+                                       // common
+                                       p = appendp(p);
+                                       p->as = AJHI;
+                                       p->to.type = D_BRANCH;
+                                       p->to.offset = 4;
+                                       q = p;
+                               }
+
+                               p = appendp(p); // load m into DX
+                               p->as = AMOVL;
+                               p->from.type = D_INDIR+D_FS;
+                               p->from.offset = 4;
+                               p->to.type = D_DX;
+                               if(q1) {
+                                       q1->pcond = p;
+                                       q1 = P;
+                               }
+
+                               p = appendp(p); // save autoffset in 4(DX)
+                               p->as = AMOVL;
+                               p->to.type = D_INDIR+D_DX;
+                               p->to.offset = 4;
+                               /* 160 comes from 3 calls (3*8) 4 safes (4*8) and 104 guard */
+                               p->from.type = D_CONST;
+                               if(autoffset+160 > 4096)
+                                       p->from.offset = (autoffset+160) & ~7LL;
+
+                               p = appendp(p); // save textarg in 8(DX)
+                               p->as = AMOVL;
+                               p->to.type = D_INDIR+D_DX;
+                               p->to.offset = 8;
+                               p->from.type = D_CONST;
+                               p->from.offset = curtext->to.offset2;
+
+                               p = appendp(p);
+                               p->as = ACALL;
+                               p->to.type = D_BRANCH;
+                               p->pcond = pmorestack;
+                               p->to.sym = symmorestack;
+
+                       }
+
+                       if(q != P)
+                               q->pcond = p->link;
+
                        if(autoffset) {
                                p = appendp(p);
                                p->as = AADJSP;
                                p->from.type = D_CONST;
                                p->from.offset = autoffset;
+                               if(q != P)
+                                       q->pcond = p;
                        }
                        deltasp = autoffset;
                }
index b524c735f7a8bd88dc688ab5a5d7b8f0a225bd44..81703d3046af9ad8f290b8cd475d00e73d0ac840 100644 (file)
@@ -148,7 +148,10 @@ xdefine(char *p, int t, int32 v)
 void
 putsymb(char *s, int t, int32 v, int ver)
 {
-       int i, f;
+       int i, j, f;
+       char *go; 
+       
+       go = nil;       // TODO
 
        if(t == 'f')
                s++;
@@ -172,7 +175,14 @@ putsymb(char *s, int t, int32 v, int ver)
                        cput(s[i]);
                cput(0);
        }
-       symsize += 4 + 1 + i + 1;
+       j = 0;
+       if(go) {
+               for(j=0; go[j]; j++)
+                       cput(go[j]);
+       }
+       cput(0);
+
+       symsize += 4 + 1 + i + 1 + j + 1;
 
        if(debug['n']) {
                if(t == 'z' || t == 'Z') {
@@ -333,6 +343,24 @@ asmlc(void)
        Bflush(&bso);
 }
 
+int
+prefixof(Adr *a)
+{
+       switch(a->type) {
+       case D_INDIR+D_CS:
+               return 0x2e;
+       case D_INDIR+D_DS:
+               return 0x3e;
+       case D_INDIR+D_ES:
+               return 0x26;
+       case D_INDIR+D_FS:
+               return 0x64;
+       case D_INDIR+D_GS:
+               return 0x65;
+       }
+       return 0;
+}
+
 int
 oclass(Adr *a)
 {
@@ -447,6 +475,7 @@ oclass(Adr *a)
                return Ym;
 
        case D_CONST:
+       case D_CONST2:
        case D_ADDR:
                if(a->sym == S) {
                        v = a->offset;
@@ -636,7 +665,7 @@ asmand(Adr *a, int r)
        }
        if(t >= D_INDIR) {
                t -= D_INDIR;
-               if(t == D_NONE) {
+               if(t == D_NONE || (D_CS <= t && t <= D_GS)) {
                        *andptr++ = (0 << 6) | (5 << 0) | (r << 3);
                        put4(v);
                        return;
@@ -851,7 +880,14 @@ doasm(Prog *p)
        Prog *q, pp;
        uchar *t;
        int z, op, ft, tt;
-       int32 v;
+       int32 v, pre;
+
+       pre = prefixof(&p->from);
+       if(pre)
+               *andptr++ = pre;
+       pre = prefixof(&p->to);
+       if(pre)
+               *andptr++ = pre;
 
        o = &optab[p->as];
        ft = oclass(&p->from) * Ymax;
index 3b13126df4f0933a82727f7d17c362901900fafc..42341a70c9cfc089e5e8f796888e140826a74601 100644 (file)
@@ -262,6 +262,7 @@ enum
        ODWHILE,
        OENUM,
        OEQ,
+       OEXREG,
        OFOR,
        OFUNC,
        OGE,
index 5ee38e88237b97a2aaf99e29359251ef479faa17..af2509c5fd014b858aac6e46c967001c36e5044a 100644 (file)
@@ -638,6 +638,11 @@ tcomo(Node *n, int f)
                n->addable = 1;
                if(n->class == CEXREG) {
                        n->op = OREGISTER;
+                       // on 386, "extern register" generates
+                       // memory references relative to the
+                       // fs segment.
+                       if(thechar == '8')      // [sic]
+                               n->op = OEXREG;
                        n->reg = n->sym->offset;
                        n->xoffset = 0;
                        break;
index cad5eda729f138563864a46b3ecb380ed094d07b..335d30bfb0b1a91b1435b0b2a1f9296faf45d723 100644 (file)
@@ -1460,6 +1460,7 @@ Init      onamesinit[] =
        ODWHILE,        0,      "DWHILE",
        OENUM,          0,      "ENUM",
        OEQ,            0,      "EQ",
+       OEXREG, 0,      "EXREG",
        OFOR,           0,      "FOR",
        OFUNC,          0,      "FUNC",
        OGE,            0,      "GE",