mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
update 8a, 8c, 8l to use new object format.
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
This commit is contained in:
parent
c1e748bd2e
commit
2bd101c4b1
18 changed files with 544 additions and 145 deletions
|
|
@ -32,7 +32,6 @@
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <bio.h>
|
#include <bio.h>
|
||||||
#include "../8l/8.out.h"
|
#include "../8l/8.out.h"
|
||||||
#include "compat.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef EXTERN
|
#ifndef EXTERN
|
||||||
|
|
@ -104,6 +103,7 @@ struct Gen
|
||||||
double dval;
|
double dval;
|
||||||
char sval[8];
|
char sval[8];
|
||||||
int32 offset;
|
int32 offset;
|
||||||
|
int32 offset2;
|
||||||
Sym* sym;
|
Sym* sym;
|
||||||
short type;
|
short type;
|
||||||
short index;
|
short index;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,10 @@
|
||||||
%union {
|
%union {
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
int32 lval;
|
int32 lval;
|
||||||
|
struct {
|
||||||
|
int32 v1;
|
||||||
|
int32 v2;
|
||||||
|
} con2;
|
||||||
double dval;
|
double dval;
|
||||||
char sval[8];
|
char sval[8];
|
||||||
Gen gen;
|
Gen gen;
|
||||||
|
|
@ -46,16 +50,17 @@
|
||||||
%left '+' '-'
|
%left '+' '-'
|
||||||
%left '*' '/' '%'
|
%left '*' '/' '%'
|
||||||
%token <lval> LTYPE0 LTYPE1 LTYPE2 LTYPE3 LTYPE4
|
%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> LCONST LFP LPC LSB
|
||||||
%token <lval> LBREG LLREG LSREG LFREG
|
%token <lval> LBREG LLREG LSREG LFREG
|
||||||
%token <dval> LFCONST
|
%token <dval> LFCONST
|
||||||
%token <sval> LSCONST LSP
|
%token <sval> LSCONST LSP
|
||||||
%token <sym> LNAME LLAB LVAR
|
%token <sym> LNAME LLAB LVAR
|
||||||
%type <lval> con expr pointer offset
|
%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> 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:
|
||||||
| prog line
|
| prog line
|
||||||
|
|
@ -103,6 +108,7 @@ inst:
|
||||||
| LTYPES spec5 { outcode($1, &$2); }
|
| LTYPES spec5 { outcode($1, &$2); }
|
||||||
| LTYPEM spec6 { outcode($1, &$2); }
|
| LTYPEM spec6 { outcode($1, &$2); }
|
||||||
| LTYPEI spec7 { outcode($1, &$2); }
|
| LTYPEI spec7 { outcode($1, &$2); }
|
||||||
|
| LTYPEG spec8 { outcode($1, &$2); }
|
||||||
|
|
||||||
nonnon:
|
nonnon:
|
||||||
{
|
{
|
||||||
|
|
@ -174,12 +180,12 @@ spec1: /* DATA */
|
||||||
}
|
}
|
||||||
|
|
||||||
spec2: /* TEXT */
|
spec2: /* TEXT */
|
||||||
mem ',' imm
|
mem ',' imm2
|
||||||
{
|
{
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.to = $3;
|
$$.to = $3;
|
||||||
}
|
}
|
||||||
| mem ',' con ',' imm
|
| mem ',' con ',' imm2
|
||||||
{
|
{
|
||||||
$$.from = $1;
|
$$.from = $1;
|
||||||
$$.from.scale = $3;
|
$$.from.scale = $3;
|
||||||
|
|
@ -249,6 +255,19 @@ spec7:
|
||||||
$$.to = $3;
|
$$.to = $3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spec8: /* GLOBL */
|
||||||
|
mem ',' imm
|
||||||
|
{
|
||||||
|
$$.from = $1;
|
||||||
|
$$.to = $3;
|
||||||
|
}
|
||||||
|
| mem ',' con ',' imm
|
||||||
|
{
|
||||||
|
$$.from = $1;
|
||||||
|
$$.from.scale = $3;
|
||||||
|
$$.to = $5;
|
||||||
|
}
|
||||||
|
|
||||||
rem:
|
rem:
|
||||||
reg
|
reg
|
||||||
| mem
|
| mem
|
||||||
|
|
@ -365,6 +384,37 @@ imm:
|
||||||
$$.dval = -$3;
|
$$.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:
|
mem:
|
||||||
omem
|
omem
|
||||||
| nmem
|
| nmem
|
||||||
|
|
@ -416,6 +466,12 @@ omem:
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
$$.type = D_INDIR+D_SP;
|
$$.type = D_INDIR+D_SP;
|
||||||
}
|
}
|
||||||
|
| con '(' LSREG ')'
|
||||||
|
{
|
||||||
|
$$ = nullgen;
|
||||||
|
$$.type = D_INDIR+$3;
|
||||||
|
$$.offset = $1;
|
||||||
|
}
|
||||||
| '(' LLREG '*' con ')'
|
| '(' LLREG '*' con ')'
|
||||||
{
|
{
|
||||||
$$ = nullgen;
|
$$ = nullgen;
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,9 @@ assemble(char *file)
|
||||||
|
|
||||||
pass = 1;
|
pass = 1;
|
||||||
pinit(file);
|
pinit(file);
|
||||||
|
|
||||||
|
Bprint(&obuf, "%s\n", thestring);
|
||||||
|
|
||||||
for(i=0; i<nDlist; i++)
|
for(i=0; i<nDlist; i++)
|
||||||
dodefine(Dlist[i]);
|
dodefine(Dlist[i]);
|
||||||
yyparse();
|
yyparse();
|
||||||
|
|
@ -173,6 +176,8 @@ assemble(char *file)
|
||||||
return nerrors;
|
return nerrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bprint(&obuf, "\n!\n");
|
||||||
|
|
||||||
pass = 2;
|
pass = 2;
|
||||||
outhist();
|
outhist();
|
||||||
pinit(file);
|
pinit(file);
|
||||||
|
|
@ -304,6 +309,9 @@ struct
|
||||||
"CMPSB", LTYPE0, ACMPSB,
|
"CMPSB", LTYPE0, ACMPSB,
|
||||||
"CMPSL", LTYPE0, ACMPSL,
|
"CMPSL", LTYPE0, ACMPSL,
|
||||||
"CMPSW", LTYPE0, ACMPSW,
|
"CMPSW", LTYPE0, ACMPSW,
|
||||||
|
"CMPXCHGB", LTYPE3, ACMPXCHGB,
|
||||||
|
"CMPXCHGL", LTYPE3, ACMPXCHGL,
|
||||||
|
"CMPXCHGW", LTYPE3, ACMPXCHGW,
|
||||||
"DAA", LTYPE0, ADAA,
|
"DAA", LTYPE0, ADAA,
|
||||||
"DAS", LTYPE0, ADAS,
|
"DAS", LTYPE0, ADAS,
|
||||||
"DATA", LTYPED, ADATA,
|
"DATA", LTYPED, ADATA,
|
||||||
|
|
@ -315,7 +323,7 @@ struct
|
||||||
"DIVW", LTYPE2, ADIVW,
|
"DIVW", LTYPE2, ADIVW,
|
||||||
"END", LTYPE0, AEND,
|
"END", LTYPE0, AEND,
|
||||||
"ENTER", LTYPE2, AENTER,
|
"ENTER", LTYPE2, AENTER,
|
||||||
"GLOBL", LTYPET, AGLOBL,
|
"GLOBL", LTYPEG, AGLOBL,
|
||||||
"HLT", LTYPE0, AHLT,
|
"HLT", LTYPE0, AHLT,
|
||||||
"IDIVB", LTYPE2, AIDIVB,
|
"IDIVB", LTYPE2, AIDIVB,
|
||||||
"IDIVL", LTYPE2, AIDIVL,
|
"IDIVL", LTYPE2, AIDIVL,
|
||||||
|
|
@ -714,7 +722,7 @@ zname(char *n, int t, int s)
|
||||||
void
|
void
|
||||||
zaddr(Gen *a, int s)
|
zaddr(Gen *a, int s)
|
||||||
{
|
{
|
||||||
long l;
|
int32 l;
|
||||||
int i, t;
|
int i, t;
|
||||||
char *n;
|
char *n;
|
||||||
Ieee e;
|
Ieee e;
|
||||||
|
|
@ -734,6 +742,9 @@ zaddr(Gen *a, int s)
|
||||||
case D_FCONST:
|
case D_FCONST:
|
||||||
t |= T_FCONST;
|
t |= T_FCONST;
|
||||||
break;
|
break;
|
||||||
|
case D_CONST2:
|
||||||
|
t |= T_OFFSET|T_OFFSET2;
|
||||||
|
break;
|
||||||
case D_SCONST:
|
case D_SCONST:
|
||||||
t |= T_SCONST;
|
t |= T_SCONST;
|
||||||
break;
|
break;
|
||||||
|
|
@ -753,6 +764,13 @@ zaddr(Gen *a, int s)
|
||||||
Bputc(&obuf, l>>16);
|
Bputc(&obuf, l>>16);
|
||||||
Bputc(&obuf, l>>24);
|
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 */
|
if(t & T_SYM) /* implies sym */
|
||||||
Bputc(&obuf, s);
|
Bputc(&obuf, s);
|
||||||
if(t & T_FCONST) {
|
if(t & T_FCONST) {
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ EXTERN struct
|
||||||
struct Adr
|
struct Adr
|
||||||
{
|
{
|
||||||
int32 offset;
|
int32 offset;
|
||||||
|
int32 offset2;
|
||||||
double dval;
|
double dval;
|
||||||
char sval[NSNAME];
|
char sval[NSNAME];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,10 @@ Dconv(Fmt *fp)
|
||||||
sprint(str, "$%ld", a->offset);
|
sprint(str, "$%ld", a->offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case D_CONST2:
|
||||||
|
sprint(str, "$%ld-%ld", a->offset, a->offset2);
|
||||||
|
break;
|
||||||
|
|
||||||
case D_FCONST:
|
case D_FCONST:
|
||||||
sprint(str, "$(%.17e)", a->dval);
|
sprint(str, "$(%.17e)", a->dval);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,31 @@
|
||||||
|
|
||||||
#include "gc.h"
|
#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
|
void
|
||||||
codgen(Node *n, Node *nn)
|
codgen(Node *n, Node *nn)
|
||||||
{
|
{
|
||||||
|
|
@ -52,7 +77,10 @@ codgen(Node *n, Node *nn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nearln = nn->lineno;
|
nearln = nn->lineno;
|
||||||
|
|
||||||
gpseudo(ATEXT, n1->sym, nodconst(stkoff));
|
gpseudo(ATEXT, n1->sym, nodconst(stkoff));
|
||||||
|
p->to.type = D_CONST2;
|
||||||
|
p->to.offset2 = argsize();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* isolate first argument
|
* isolate first argument
|
||||||
|
|
@ -494,6 +522,10 @@ xcom(Node *n)
|
||||||
n->addable = 11;
|
n->addable = 11;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OEXREG:
|
||||||
|
n->addable = 10;
|
||||||
|
break;
|
||||||
|
|
||||||
case OREGISTER:
|
case OREGISTER:
|
||||||
n->addable = 12;
|
n->addable = 12;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -328,7 +328,10 @@ outcode(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Binit(&b, f, OWRITE);
|
Binit(&b, f, OWRITE);
|
||||||
Bseek(&b, 0L, 2);
|
|
||||||
|
Bprint(&b, "%s\n", thestring);
|
||||||
|
Bprint(&b, "!\n");
|
||||||
|
|
||||||
outhist(&b);
|
outhist(&b);
|
||||||
for(sym=0; sym<NSYM; sym++) {
|
for(sym=0; sym<NSYM; sym++) {
|
||||||
h[sym].sym = S;
|
h[sym].sym = S;
|
||||||
|
|
@ -530,6 +533,9 @@ zaddr(Biobuf *b, Adr *a, int s)
|
||||||
case D_SCONST:
|
case D_SCONST:
|
||||||
t |= T_SCONST;
|
t |= T_SCONST;
|
||||||
break;
|
break;
|
||||||
|
case D_CONST2:
|
||||||
|
t |= T_OFFSET|T_OFFSET2;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Bputc(b, t);
|
Bputc(b, t);
|
||||||
|
|
||||||
|
|
@ -544,6 +550,13 @@ zaddr(Biobuf *b, Adr *a, int s)
|
||||||
Bputc(b, l>>16);
|
Bputc(b, l>>16);
|
||||||
Bputc(b, l>>24);
|
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 */
|
if(t & T_SYM) /* implies sym */
|
||||||
Bputc(b, s);
|
Bputc(b, s);
|
||||||
if(t & T_FCONST) {
|
if(t & T_FCONST) {
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,10 @@ naddr(Node *n, Adr *a)
|
||||||
a->sym = S;
|
a->sym = S;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OEXREG:
|
||||||
|
a->type = D_INDIR + D_FS;
|
||||||
|
a->offset = n->reg - 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case OIND:
|
case OIND:
|
||||||
naddr(n->left, a);
|
naddr(n->left, a);
|
||||||
|
|
@ -1389,6 +1393,15 @@ sconst(Node *n)
|
||||||
int32
|
int32
|
||||||
exreg(Type *t)
|
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);
|
USED(t);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#define NSNAME 8
|
#define NSNAME 8
|
||||||
#define NOPROF (1<<0)
|
#define NOPROF (1<<0)
|
||||||
#define DUPOK (1<<1)
|
#define DUPOK (1<<1)
|
||||||
|
#define NOSPLIT (1<<2)
|
||||||
|
|
||||||
enum as
|
enum as
|
||||||
{
|
{
|
||||||
|
|
@ -78,6 +79,9 @@ enum as
|
||||||
ACMPSB,
|
ACMPSB,
|
||||||
ACMPSL,
|
ACMPSL,
|
||||||
ACMPSW,
|
ACMPSW,
|
||||||
|
ACMPXCHGB,
|
||||||
|
ACMPXCHGL,
|
||||||
|
ACMPXCHGW,
|
||||||
ADAA,
|
ADAA,
|
||||||
ADAS,
|
ADAS,
|
||||||
ADATA,
|
ADATA,
|
||||||
|
|
@ -437,6 +441,7 @@ enum
|
||||||
D_FCONST = 66,
|
D_FCONST = 66,
|
||||||
D_SCONST = 67,
|
D_SCONST = 67,
|
||||||
D_ADDR = 68,
|
D_ADDR = 68,
|
||||||
|
D_CONST2 = 69,
|
||||||
|
|
||||||
D_FILE,
|
D_FILE,
|
||||||
D_FILE1,
|
D_FILE1,
|
||||||
|
|
@ -449,6 +454,7 @@ enum
|
||||||
T_FCONST = 1<<3,
|
T_FCONST = 1<<3,
|
||||||
T_SYM = 1<<4,
|
T_SYM = 1<<4,
|
||||||
T_SCONST = 1<<5,
|
T_SCONST = 1<<5,
|
||||||
|
T_OFFSET2 = 1<<6,
|
||||||
|
|
||||||
REGARG = 0,
|
REGARG = 0,
|
||||||
REGRET = D_AX,
|
REGRET = D_AX,
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ struct Adr
|
||||||
short type;
|
short type;
|
||||||
uchar index;
|
uchar index;
|
||||||
char scale;
|
char scale;
|
||||||
|
int32 offset2;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define offset u0.u0offset
|
#define offset u0.u0offset
|
||||||
|
|
@ -342,7 +343,7 @@ void histtoauto(void);
|
||||||
double ieeedtod(Ieee*);
|
double ieeedtod(Ieee*);
|
||||||
int32 ieeedtof(Ieee*);
|
int32 ieeedtof(Ieee*);
|
||||||
void import(void);
|
void import(void);
|
||||||
void ldobj(int, int32, char*);
|
void ldobj(Biobuf*, int32, char*);
|
||||||
void loadlib(void);
|
void loadlib(void);
|
||||||
void listinit(void);
|
void listinit(void);
|
||||||
Sym* lookup(char*, int);
|
Sym* lookup(char*, int);
|
||||||
|
|
@ -368,7 +369,7 @@ int32 vaddr(Adr*);
|
||||||
void wput(ushort);
|
void wput(ushort);
|
||||||
void xdefine(char*, int, int32);
|
void xdefine(char*, int, int32);
|
||||||
void xfol(Prog*);
|
void xfol(Prog*);
|
||||||
int zaddr(uchar*, Adr*, Sym*[]);
|
void zaddr(Biobuf*, Adr*, Sym*[]);
|
||||||
void zerosig(char*);
|
void zerosig(char*);
|
||||||
uint32 machheadr(void);
|
uint32 machheadr(void);
|
||||||
uint32 elfheadr(void);
|
uint32 elfheadr(void);
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,14 @@ Aconv(Fmt *fp)
|
||||||
return fmtstrcpy(fp, anames[i]);
|
return fmtstrcpy(fp, anames[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
xsymname(Sym *s)
|
||||||
|
{
|
||||||
|
if(s == nil)
|
||||||
|
return "!!noname!!";
|
||||||
|
return s->name;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Dconv(Fmt *fp)
|
Dconv(Fmt *fp)
|
||||||
{
|
{
|
||||||
|
|
@ -120,16 +128,16 @@ Dconv(Fmt *fp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_EXTERN:
|
case D_EXTERN:
|
||||||
sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
|
sprint(str, "%s+%ld(SB)", xsymname(a->sym), a->offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_STATIC:
|
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);
|
a->sym->version, a->offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_AUTO:
|
case D_AUTO:
|
||||||
sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
|
sprint(str, "%s+%ld(SP)", xsymname(a->sym), a->offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case D_PARAM:
|
case D_PARAM:
|
||||||
|
|
@ -143,6 +151,10 @@ Dconv(Fmt *fp)
|
||||||
sprint(str, "$%ld", a->offset);
|
sprint(str, "$%ld", a->offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case D_CONST2:
|
||||||
|
sprint(str, "$%ld-%ld", a->offset, a->offset2);
|
||||||
|
break;
|
||||||
|
|
||||||
case D_FCONST:
|
case D_FCONST:
|
||||||
sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
|
sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
304
src/cmd/8l/obj.c
304
src/cmd/8l/obj.c
|
|
@ -419,14 +419,15 @@ void
|
||||||
objfile(char *file)
|
objfile(char *file)
|
||||||
{
|
{
|
||||||
int32 off, esym, cnt, l;
|
int32 off, esym, cnt, l;
|
||||||
int f, work;
|
int work;
|
||||||
|
Biobuf *f;
|
||||||
Sym *s;
|
Sym *s;
|
||||||
char magbuf[SARMAG];
|
char magbuf[SARMAG];
|
||||||
char name[100], pname[150];
|
char name[100], pname[150];
|
||||||
struct ar_hdr arhdr;
|
struct ar_hdr arhdr;
|
||||||
char *e, *start, *stop;
|
char *e, *start, *stop;
|
||||||
|
|
||||||
if(file[0] == '-' && file[1] == 'l') {
|
if(file[0] == '-' && file[1] == 'l') { // TODO: fix this
|
||||||
if(debug['9'])
|
if(debug['9'])
|
||||||
sprint(name, "/%s/lib/lib", thestring);
|
sprint(name, "/%s/lib/lib", thestring);
|
||||||
else
|
else
|
||||||
|
|
@ -438,22 +439,22 @@ objfile(char *file)
|
||||||
if(debug['v'])
|
if(debug['v'])
|
||||||
Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
|
Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
|
||||||
Bflush(&bso);
|
Bflush(&bso);
|
||||||
f = open(file, 0);
|
f = Bopen(file, 0);
|
||||||
if(f < 0) {
|
if(f == nil) {
|
||||||
diag("cannot open file: %s", file);
|
diag("cannot open file: %s", file);
|
||||||
errorexit();
|
errorexit();
|
||||||
}
|
}
|
||||||
l = read(f, magbuf, SARMAG);
|
l = Bread(f, magbuf, SARMAG);
|
||||||
if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
|
if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
|
||||||
/* load it as a regular file */
|
/* load it as a regular file */
|
||||||
l = seek(f, 0L, 2);
|
l = Bseek(f, 0L, 2);
|
||||||
seek(f, 0L, 0);
|
Bseek(f, 0L, 0);
|
||||||
ldobj(f, l, file);
|
ldobj(f, l, file);
|
||||||
close(f);
|
Bterm(f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
l = read(f, &arhdr, SAR_HDR);
|
l = Bread(f, &arhdr, SAR_HDR);
|
||||||
if(l != SAR_HDR) {
|
if(l != SAR_HDR) {
|
||||||
diag("%s: short read on archive file symbol header", file);
|
diag("%s: short read on archive file symbol header", file);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -469,12 +470,12 @@ objfile(char *file)
|
||||||
/*
|
/*
|
||||||
* just bang the whole symbol file into memory
|
* just bang the whole symbol file into memory
|
||||||
*/
|
*/
|
||||||
seek(f, off, 0);
|
Bseek(f, off, 0);
|
||||||
cnt = esym - off;
|
cnt = esym - off;
|
||||||
start = malloc(cnt + 10);
|
start = malloc(cnt + 10);
|
||||||
cnt = read(f, start, cnt);
|
cnt = Bread(f, start, cnt);
|
||||||
if(cnt <= 0){
|
if(cnt <= 0){
|
||||||
close(f);
|
Bterm(f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
stop = &start[cnt];
|
stop = &start[cnt];
|
||||||
|
|
@ -498,12 +499,16 @@ objfile(char *file)
|
||||||
l |= (e[2] & 0xff) << 8;
|
l |= (e[2] & 0xff) << 8;
|
||||||
l |= (e[3] & 0xff) << 16;
|
l |= (e[3] & 0xff) << 16;
|
||||||
l |= (e[4] & 0xff) << 24;
|
l |= (e[4] & 0xff) << 24;
|
||||||
seek(f, l, 0);
|
Bseek(f, l, 0);
|
||||||
l = read(f, &arhdr, SAR_HDR);
|
l = Bread(f, &arhdr, SAR_HDR);
|
||||||
if(l != SAR_HDR)
|
if(l != SAR_HDR)
|
||||||
goto bad;
|
goto bad;
|
||||||
if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))
|
if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
l = SARNAME;
|
||||||
|
while(l > 0 && arhdr.name[l-1] == ' ')
|
||||||
|
l--;
|
||||||
|
sprint(pname, "%s(%.*s)", file, l, arhdr.name);
|
||||||
l = atolwhex(arhdr.size);
|
l = atolwhex(arhdr.size);
|
||||||
ldobj(f, l, pname);
|
ldobj(f, l, pname);
|
||||||
if(s->type == SXREF) {
|
if(s->type == SXREF) {
|
||||||
|
|
@ -519,85 +524,87 @@ objfile(char *file)
|
||||||
bad:
|
bad:
|
||||||
diag("%s: bad or out of date archive", file);
|
diag("%s: bad or out of date archive", file);
|
||||||
out:
|
out:
|
||||||
close(f);
|
Bterm(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int32
|
||||||
zaddr(uchar *p, Adr *a, Sym *h[])
|
Bget4(Biobuf *f)
|
||||||
{
|
{
|
||||||
int c, t, i;
|
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 t;
|
||||||
int32 l;
|
int32 l;
|
||||||
Sym *s;
|
Sym *s;
|
||||||
Auto *u;
|
Auto *u;
|
||||||
|
|
||||||
t = p[0];
|
t = Bgetc(f);
|
||||||
|
|
||||||
c = 1;
|
|
||||||
if(t & T_INDEX) {
|
if(t & T_INDEX) {
|
||||||
a->index = p[c];
|
a->index = Bgetc(f);
|
||||||
a->scale = p[c+1];
|
a->scale = Bgetc(f);
|
||||||
c += 2;
|
|
||||||
} else {
|
} else {
|
||||||
a->index = D_NONE;
|
a->index = D_NONE;
|
||||||
a->scale = 0;
|
a->scale = 0;
|
||||||
}
|
}
|
||||||
|
a->type = D_NONE;
|
||||||
a->offset = 0;
|
a->offset = 0;
|
||||||
if(t & T_OFFSET) {
|
if(t & T_OFFSET)
|
||||||
a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);
|
a->offset = Bget4(f);
|
||||||
c += 4;
|
a->offset2 = 0;
|
||||||
|
if(t & T_OFFSET2) {
|
||||||
|
a->offset2 = Bget4(f);
|
||||||
|
a->type = D_CONST2;
|
||||||
}
|
}
|
||||||
a->sym = S;
|
a->sym = S;
|
||||||
if(t & T_SYM) {
|
if(t & T_SYM)
|
||||||
a->sym = h[p[c]];
|
a->sym = h[Bgetc(f)];
|
||||||
c++;
|
|
||||||
}
|
|
||||||
a->type = D_NONE;
|
|
||||||
if(t & T_FCONST) {
|
if(t & T_FCONST) {
|
||||||
a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);
|
a->ieee.l = Bget4(f);
|
||||||
a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24);
|
a->ieee.h = Bget4(f);
|
||||||
c += 8;
|
|
||||||
a->type = D_FCONST;
|
a->type = D_FCONST;
|
||||||
} else
|
} else
|
||||||
if(t & T_SCONST) {
|
if(t & T_SCONST) {
|
||||||
for(i=0; i<NSNAME; i++)
|
Bread(f, a->scon, NSNAME);
|
||||||
a->scon[i] = p[c+i];
|
|
||||||
c += NSNAME;
|
|
||||||
a->type = D_SCONST;
|
a->type = D_SCONST;
|
||||||
}
|
}
|
||||||
if(t & T_TYPE) {
|
if(t & T_TYPE)
|
||||||
a->type = p[c];
|
a->type = Bgetc(f);
|
||||||
c++;
|
|
||||||
}
|
|
||||||
s = a->sym;
|
s = a->sym;
|
||||||
if(s == S)
|
if(s == S)
|
||||||
return c;
|
return;
|
||||||
|
|
||||||
t = a->type;
|
t = a->type;
|
||||||
if(t != D_AUTO && t != D_PARAM)
|
if(t != D_AUTO && t != D_PARAM)
|
||||||
return c;
|
return;
|
||||||
l = a->offset;
|
l = a->offset;
|
||||||
for(u=curauto; u; u=u->link) {
|
for(u=curauto; u; u=u->link) {
|
||||||
if(u->asym == s)
|
if(u->asym == s)
|
||||||
if(u->type == t) {
|
if(u->type == t) {
|
||||||
if(u->aoffset > l)
|
if(u->aoffset > l)
|
||||||
u->aoffset = l;
|
u->aoffset = l;
|
||||||
return c;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u = mal(sizeof(Auto));
|
u = mal(sizeof(*u));
|
||||||
u->link = curauto;
|
u->link = curauto;
|
||||||
curauto = u;
|
curauto = u;
|
||||||
u->asym = s;
|
u->asym = s;
|
||||||
u->aoffset = l;
|
u->aoffset = l;
|
||||||
u->type = t;
|
u->type = t;
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
addlib(char *obj)
|
addlib(char *src, char *obj)
|
||||||
{
|
{
|
||||||
char name[1024], comp[256], *p;
|
char name[1024], comp[256], *p, *q;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(histfrogp <= 0)
|
if(histfrogp <= 0)
|
||||||
|
|
@ -645,6 +652,23 @@ addlib(char *obj)
|
||||||
strcat(name, "/");
|
strcat(name, "/");
|
||||||
strcat(name, comp);
|
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++)
|
for(i=0; i<libraryp; i++)
|
||||||
if(strcmp(name, library[i]) == 0)
|
if(strcmp(name, library[i]) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -662,6 +686,22 @@ addlib(char *obj)
|
||||||
libraryp++;
|
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
|
void
|
||||||
addhist(int32 line, int type)
|
addhist(int32 line, int type)
|
||||||
{
|
{
|
||||||
|
|
@ -679,6 +719,7 @@ addhist(int32 line, int type)
|
||||||
u->link = curhist;
|
u->link = curhist;
|
||||||
curhist = u;
|
curhist = u;
|
||||||
|
|
||||||
|
s->name[0] = 0;
|
||||||
j = 1;
|
j = 1;
|
||||||
for(i=0; i<histfrogp; i++) {
|
for(i=0; i<histfrogp; i++) {
|
||||||
k = histfrog[i]->value;
|
k = histfrog[i]->value;
|
||||||
|
|
@ -686,6 +727,8 @@ addhist(int32 line, int type)
|
||||||
s->name[j+1] = k;
|
s->name[j+1] = k;
|
||||||
j += 2;
|
j += 2;
|
||||||
}
|
}
|
||||||
|
s->name[j] = 0;
|
||||||
|
s->name[j+1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -746,35 +789,27 @@ nopout(Prog *p)
|
||||||
p->to.type = D_NONE;
|
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
|
void
|
||||||
ldobj(int f, int32 c, char *pn)
|
ldobj(Biobuf *f, int32 len, char *pn)
|
||||||
{
|
{
|
||||||
int32 ipc;
|
int32 ipc;
|
||||||
Prog *p, *t;
|
Prog *p, *t;
|
||||||
uchar *bloc, *bsize, *stop;
|
|
||||||
int v, o, r, skip;
|
int v, o, r, skip;
|
||||||
Sym *h[NSYM], *s, *di;
|
Sym *h[NSYM], *s, *di;
|
||||||
uint32 sig;
|
uint32 sig;
|
||||||
static int files;
|
static int files;
|
||||||
static char **filen;
|
static char **filen;
|
||||||
char **nfilen;
|
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){
|
if((files&15) == 0){
|
||||||
nfilen = malloc((files+16)*sizeof(char*));
|
nfilen = malloc((files+16)*sizeof(char*));
|
||||||
|
|
@ -782,12 +817,48 @@ ldobj(int f, int32 c, char *pn)
|
||||||
free(filen);
|
free(filen);
|
||||||
filen = nfilen;
|
filen = nfilen;
|
||||||
}
|
}
|
||||||
filen[files++] = strdup(pn);
|
pn = strdup(pn);
|
||||||
|
filen[files++] = pn;
|
||||||
|
|
||||||
bsize = buf.xbuf;
|
|
||||||
bloc = buf.xbuf;
|
|
||||||
di = S;
|
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:
|
newloop:
|
||||||
memset(h, 0, sizeof(h));
|
memset(h, 0, sizeof(h));
|
||||||
version++;
|
version++;
|
||||||
|
|
@ -796,61 +867,46 @@ newloop:
|
||||||
skip = 0;
|
skip = 0;
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
if(c <= 0)
|
if(f->state == Bracteof || Boffset(f) >= eof)
|
||||||
goto eof;
|
goto eof;
|
||||||
r = bsize - bloc;
|
o = Bgetc(f);
|
||||||
if(r < 100 && r < c) { /* enough for largest prog */
|
if(o == Beof)
|
||||||
bsize = readsome(f, buf.xbuf, bloc, bsize, c);
|
|
||||||
if(bsize == 0)
|
|
||||||
goto eof;
|
goto eof;
|
||||||
bloc = buf.xbuf;
|
o |= Bgetc(f) << 8;
|
||||||
goto loop;
|
|
||||||
}
|
|
||||||
o = bloc[0] | (bloc[1] << 8);
|
|
||||||
if(o <= AXXX || o >= ALAST) {
|
if(o <= AXXX || o >= ALAST) {
|
||||||
if(o < 0)
|
if(o < 0)
|
||||||
goto eof;
|
goto eof;
|
||||||
diag("%s: opcode out of range %d", pn, o);
|
diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
|
||||||
print(" probably not a .8 file\n");
|
print(" probably not a .%c file\n", thechar);
|
||||||
errorexit();
|
errorexit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(o == ANAME || o == ASIGNAME) {
|
if(o == ANAME || o == ASIGNAME) {
|
||||||
sig = 0;
|
sig = 0;
|
||||||
if(o == ASIGNAME) {
|
if(o == ASIGNAME)
|
||||||
sig = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24);
|
sig = Bget4(f);
|
||||||
bloc += 4;
|
v = Bgetc(f); /* type */
|
||||||
c -= 4;
|
o = Bgetc(f); /* sym */
|
||||||
}
|
|
||||||
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){
|
|
||||||
fprint(2, "%s: name too long\n", pn);
|
|
||||||
errorexit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v = bloc[2]; /* type */
|
|
||||||
o = bloc[3]; /* sym */
|
|
||||||
bloc += 4;
|
|
||||||
c -= 4;
|
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
if(v == D_STATIC)
|
if(v == D_STATIC)
|
||||||
r = version;
|
r = version;
|
||||||
s = lookup((char*)bloc, r);
|
name = Brdline(f, '\0');
|
||||||
c -= &stop[1] - bloc;
|
if(name == nil) {
|
||||||
bloc = stop + 1;
|
if(Blinelen(f) > 0) {
|
||||||
|
fprint(2, "%s: name too long\n", pn);
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
|
goto eof;
|
||||||
|
}
|
||||||
|
s = lookup(name, r);
|
||||||
|
|
||||||
if(debug['S'] && r == 0)
|
if(debug['S'] && r == 0)
|
||||||
sig = 1729;
|
sig = 1729;
|
||||||
if(sig != 0){
|
if(sig != 0){
|
||||||
if(s->sig != 0 && s->sig != sig)
|
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->sig = sig;
|
||||||
s->file = files-1;
|
s->file = files-1;
|
||||||
}
|
}
|
||||||
|
|
@ -877,12 +933,10 @@ loop:
|
||||||
|
|
||||||
p = mal(sizeof(*p));
|
p = mal(sizeof(*p));
|
||||||
p->as = o;
|
p->as = o;
|
||||||
p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24);
|
p->line = Bget4(f);
|
||||||
p->back = 2;
|
p->back = 2;
|
||||||
r = zaddr(bloc+6, &p->from, h) + 6;
|
zaddr(f, &p->from, h);
|
||||||
r += zaddr(bloc+r, &p->to, h);
|
zaddr(f, &p->to, h);
|
||||||
bloc += r;
|
|
||||||
c -= r;
|
|
||||||
|
|
||||||
if(debug['W'])
|
if(debug['W'])
|
||||||
print("%P\n", p);
|
print("%P\n", p);
|
||||||
|
|
@ -890,10 +944,12 @@ loop:
|
||||||
switch(p->as) {
|
switch(p->as) {
|
||||||
case AHISTORY:
|
case AHISTORY:
|
||||||
if(p->to.offset == -1) {
|
if(p->to.offset == -1) {
|
||||||
addlib(pn);
|
addlib(src, pn);
|
||||||
histfrogp = 0;
|
histfrogp = 0;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
if(src[0] == '\0')
|
||||||
|
copyhistfrog(src, sizeof src);
|
||||||
addhist(p->line, D_FILE); /* 'z' */
|
addhist(p->line, D_FILE); /* 'z' */
|
||||||
if(p->to.offset)
|
if(p->to.offset)
|
||||||
addhist(p->to.offset, D_FILE1); /* 'Z' */
|
addhist(p->to.offset, D_FILE1); /* 'Z' */
|
||||||
|
|
@ -906,9 +962,9 @@ loop:
|
||||||
curtext->to.autom = curauto;
|
curtext->to.autom = curauto;
|
||||||
curauto = 0;
|
curauto = 0;
|
||||||
curtext = P;
|
curtext = P;
|
||||||
if(c)
|
if(Boffset(f) == eof)
|
||||||
goto newloop;
|
|
||||||
return;
|
return;
|
||||||
|
goto newloop;
|
||||||
|
|
||||||
case AGLOBL:
|
case AGLOBL:
|
||||||
s = p->from.sym;
|
s = p->from.sym;
|
||||||
|
|
@ -983,6 +1039,17 @@ loop:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case ATEXT:
|
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) {
|
if(curtext != P) {
|
||||||
histtoauto();
|
histtoauto();
|
||||||
curtext->to.autom = curauto;
|
curtext->to.autom = curauto;
|
||||||
|
|
@ -990,11 +1057,6 @@ loop:
|
||||||
}
|
}
|
||||||
skip = 0;
|
skip = 0;
|
||||||
curtext = p;
|
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(s->type != 0 && s->type != SXREF) {
|
||||||
if(p->from.scale & DUPOK) {
|
if(p->from.scale & DUPOK) {
|
||||||
skip = 1;
|
skip = 1;
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,11 @@ uchar yml_rl[] =
|
||||||
Yml, Yrl, Zm_r, 1,
|
Yml, Yrl, Zm_r, 1,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
uchar yrb_mb[] =
|
||||||
|
{
|
||||||
|
Yrb, Ymb, Zr_m, 1,
|
||||||
|
0
|
||||||
|
};
|
||||||
uchar yrl_ml[] =
|
uchar yrl_ml[] =
|
||||||
{
|
{
|
||||||
Yrl, Yml, Zr_m, 1,
|
Yrl, Yml, Zr_m, 1,
|
||||||
|
|
@ -383,6 +388,9 @@ Optab optab[] =
|
||||||
{ ACMPSB, ynone, Pb, 0xa6 },
|
{ ACMPSB, ynone, Pb, 0xa6 },
|
||||||
{ ACMPSL, ynone, Px, 0xa7 },
|
{ ACMPSL, ynone, Px, 0xa7 },
|
||||||
{ ACMPSW, ynone, Pe, 0xa7 },
|
{ ACMPSW, ynone, Pe, 0xa7 },
|
||||||
|
{ ACMPXCHGB, yrb_mb, Pm, 0xb0 },
|
||||||
|
{ ACMPXCHGL, yrl_ml, Pm, 0xb1 },
|
||||||
|
{ ACMPXCHGW, yrl_ml, Pm, 0xb1 },
|
||||||
{ ADAA, ynone, Px, 0x27 },
|
{ ADAA, ynone, Px, 0x27 },
|
||||||
{ ADAS, ynone, Px, 0x2f },
|
{ ADAS, ynone, Px, 0x2f },
|
||||||
{ ADATA },
|
{ ADATA },
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ loop:
|
||||||
if(p->as == ATEXT)
|
if(p->as == ATEXT)
|
||||||
curtext = p;
|
curtext = p;
|
||||||
if(p->as == AJMP)
|
if(p->as == AJMP)
|
||||||
if((q = p->pcond) != P) {
|
if((q = p->pcond) != P && q->as != ATEXT) {
|
||||||
p->mark = 1;
|
p->mark = 1;
|
||||||
p = q;
|
p = q;
|
||||||
if(p->mark == 0)
|
if(p->mark == 0)
|
||||||
|
|
@ -331,14 +331,15 @@ patch(void)
|
||||||
for(p = firstp; p != P; p = p->link) {
|
for(p = firstp; p != P; p = p->link) {
|
||||||
if(p->as == ATEXT)
|
if(p->as == ATEXT)
|
||||||
curtext = p;
|
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;
|
s = p->to.sym;
|
||||||
if(s) {
|
if(s) {
|
||||||
if(debug['c'])
|
if(debug['c'])
|
||||||
Bprint(&bso, "%s calls %s\n", TNAME, s->name);
|
Bprint(&bso, "%s calls %s\n", TNAME, s->name);
|
||||||
switch(s->type) {
|
switch(s->type) {
|
||||||
default:
|
default:
|
||||||
diag("undefined: %s in %s", s->name, TNAME);
|
/* diag prints TNAME first */
|
||||||
|
diag("%s is undefined", s->name);
|
||||||
s->type = STEXT;
|
s->type = STEXT;
|
||||||
s->value = vexit;
|
s->value = vexit;
|
||||||
break; /* or fall through to set offset? */
|
break; /* or fall through to set offset? */
|
||||||
|
|
@ -440,9 +441,27 @@ brloop(Prog *p)
|
||||||
void
|
void
|
||||||
dostkoff(void)
|
dostkoff(void)
|
||||||
{
|
{
|
||||||
Prog *p, *q;
|
Prog *p, *q, *q1;
|
||||||
int32 autoffset, deltasp;
|
int32 autoffset, deltasp;
|
||||||
int a, f, curframe, curbecome, maxbecome;
|
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;
|
curframe = 0;
|
||||||
curbecome = 0;
|
curbecome = 0;
|
||||||
|
|
@ -521,11 +540,122 @@ dostkoff(void)
|
||||||
autoffset = p->to.offset;
|
autoffset = p->to.offset;
|
||||||
if(autoffset < 0)
|
if(autoffset < 0)
|
||||||
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) {
|
if(autoffset) {
|
||||||
p = appendp(p);
|
p = appendp(p);
|
||||||
p->as = AADJSP;
|
p->as = AADJSP;
|
||||||
p->from.type = D_CONST;
|
p->from.type = D_CONST;
|
||||||
p->from.offset = autoffset;
|
p->from.offset = autoffset;
|
||||||
|
if(q != P)
|
||||||
|
q->pcond = p;
|
||||||
}
|
}
|
||||||
deltasp = autoffset;
|
deltasp = autoffset;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,10 @@ xdefine(char *p, int t, int32 v)
|
||||||
void
|
void
|
||||||
putsymb(char *s, int t, int32 v, int ver)
|
putsymb(char *s, int t, int32 v, int ver)
|
||||||
{
|
{
|
||||||
int i, f;
|
int i, j, f;
|
||||||
|
char *go;
|
||||||
|
|
||||||
|
go = nil; // TODO
|
||||||
|
|
||||||
if(t == 'f')
|
if(t == 'f')
|
||||||
s++;
|
s++;
|
||||||
|
|
@ -172,7 +175,14 @@ putsymb(char *s, int t, int32 v, int ver)
|
||||||
cput(s[i]);
|
cput(s[i]);
|
||||||
cput(0);
|
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(debug['n']) {
|
||||||
if(t == 'z' || t == 'Z') {
|
if(t == 'z' || t == 'Z') {
|
||||||
|
|
@ -333,6 +343,24 @@ asmlc(void)
|
||||||
Bflush(&bso);
|
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
|
int
|
||||||
oclass(Adr *a)
|
oclass(Adr *a)
|
||||||
{
|
{
|
||||||
|
|
@ -447,6 +475,7 @@ oclass(Adr *a)
|
||||||
return Ym;
|
return Ym;
|
||||||
|
|
||||||
case D_CONST:
|
case D_CONST:
|
||||||
|
case D_CONST2:
|
||||||
case D_ADDR:
|
case D_ADDR:
|
||||||
if(a->sym == S) {
|
if(a->sym == S) {
|
||||||
v = a->offset;
|
v = a->offset;
|
||||||
|
|
@ -636,7 +665,7 @@ asmand(Adr *a, int r)
|
||||||
}
|
}
|
||||||
if(t >= D_INDIR) {
|
if(t >= D_INDIR) {
|
||||||
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);
|
*andptr++ = (0 << 6) | (5 << 0) | (r << 3);
|
||||||
put4(v);
|
put4(v);
|
||||||
return;
|
return;
|
||||||
|
|
@ -851,7 +880,14 @@ doasm(Prog *p)
|
||||||
Prog *q, pp;
|
Prog *q, pp;
|
||||||
uchar *t;
|
uchar *t;
|
||||||
int z, op, ft, tt;
|
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];
|
o = &optab[p->as];
|
||||||
ft = oclass(&p->from) * Ymax;
|
ft = oclass(&p->from) * Ymax;
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,7 @@ enum
|
||||||
ODWHILE,
|
ODWHILE,
|
||||||
OENUM,
|
OENUM,
|
||||||
OEQ,
|
OEQ,
|
||||||
|
OEXREG,
|
||||||
OFOR,
|
OFOR,
|
||||||
OFUNC,
|
OFUNC,
|
||||||
OGE,
|
OGE,
|
||||||
|
|
|
||||||
|
|
@ -638,6 +638,11 @@ tcomo(Node *n, int f)
|
||||||
n->addable = 1;
|
n->addable = 1;
|
||||||
if(n->class == CEXREG) {
|
if(n->class == CEXREG) {
|
||||||
n->op = OREGISTER;
|
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->reg = n->sym->offset;
|
||||||
n->xoffset = 0;
|
n->xoffset = 0;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1460,6 +1460,7 @@ Init onamesinit[] =
|
||||||
ODWHILE, 0, "DWHILE",
|
ODWHILE, 0, "DWHILE",
|
||||||
OENUM, 0, "ENUM",
|
OENUM, 0, "ENUM",
|
||||||
OEQ, 0, "EQ",
|
OEQ, 0, "EQ",
|
||||||
|
OEXREG, 0, "EXREG",
|
||||||
OFOR, 0, "FOR",
|
OFOR, 0, "FOR",
|
||||||
OFUNC, 0, "FUNC",
|
OFUNC, 0, "FUNC",
|
||||||
OGE, 0, "GE",
|
OGE, 0, "GE",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue