5l,6l,8l,kl,ql,vl: allow duplicate GLOBAL symbols (from Ori Bernstein)

The plan 9 assemblers support the DUPOK flag on text symbols. They parse and
ignore it on GLOBL symbols. This patch makes it work in the linkers.

The reason I ran into this is because my programming language (Myrddin) uses
data symbols to generate type information, and it's useful to avoid
duplicating all of the type info in every file that gets generated.
This commit is contained in:
cinap_lenrek 2017-03-19 03:05:24 +01:00
parent bd178b6dc6
commit da9b38c75c
20 changed files with 33 additions and 6 deletions

View file

@ -578,7 +578,7 @@ datblk(long s, long n, int str)
}
if(l >= n)
continue;
if(p->as != AINIT && p->as != ADYNT) {
if(p->as != AINIT && p->as != ADYNT && !p->from.sym->dupok) {
for(j=l+(c-i)-1; j>=l; j--)
if(buf.dbuf[j]) {
print("%P\n", p);

View file

@ -82,6 +82,7 @@ struct Sym
short become;
short frame;
uchar subtype;
char dupok;
ushort file;
long value;
long sig;

View file

@ -868,6 +868,8 @@ loop:
diag("GLOBL must have a name\n%P", p);
errorexit();
}
if(p->reg & DUPOK)
s->dupok = 1;
if(s->type == 0 || s->type == SXREF) {
s->type = SBSS;
s->value = 0;
@ -1113,6 +1115,7 @@ lookup(char *symb, int v)
s->version = v;
s->value = 0;
s->sig = 0;
s->dupok = 0;
hash[h] = s;
return s;
}

View file

@ -316,7 +316,7 @@ datblk(long s, long n)
}
if(l >= n)
continue;
if(p->as != AINIT && p->as != ADYNT) {
if(p->as != AINIT && p->as != ADYNT && !p->from.sym->dupok) {
for(j=l+(c-i)-1; j>=l; j--)
if(buf.dbuf[j]) {
print("%P\n", p);

View file

@ -79,6 +79,7 @@ struct Sym
short version;
short become;
short frame;
char dupok;
uchar subtype;
ushort file;
vlong value;

View file

@ -23,6 +23,7 @@ Pconv(Fmt *fp)
bigP = p;
switch(p->as) {
case ATEXT:
case AGLOBL:
if(p->from.scale) {
snprint(str, sizeof str, "(%ld) %A %D,%d,%D",
p->line, p->as, &p->from, p->from.scale, &p->to);

View file

@ -899,10 +899,13 @@ loop:
case AGLOBL:
s = p->from.sym;
if(p->from.scale & DUPOK)
s->dupok = 1;
if(s->type == 0 || s->type == SXREF) {
s->type = SBSS;
s->value = 0;
}
if(s->type != SBSS) {
diag("%s: redefinition: %s in %s",
pn, s->name, TNAME);
@ -1158,6 +1161,7 @@ lookup(char *symb, int v)
s->version = v;
s->value = 0;
s->sig = 0;
s->dupok = 0;
hash[h] = s;
nsymbol++;
return s;

View file

@ -421,7 +421,7 @@ datblk(long s, long n)
}
if(l >= n)
continue;
if(p->as != AINIT && p->as != ADYNT) {
if(p->as != AINIT && p->as != ADYNT && !p->from.sym->dupok) {
for(j=l+(c-i)-1; j>=l; j--)
if(buf.dbuf[j]) {
print("%P\n", p);

View file

@ -80,6 +80,7 @@ struct Sym
short become;
short frame;
uchar subtype;
char dupok;
ushort file;
long value;
long sig;

View file

@ -23,6 +23,7 @@ Pconv(Fmt *fp)
bigP = p;
switch(p->as) {
case ATEXT:
case AGLOBL:
if(p->from.scale) {
snprint(str, sizeof(str), "(%ld) %A %D,%d,%D",
p->line, p->as, &p->from, p->from.scale, &p->to);

View file

@ -885,6 +885,8 @@ loop:
case AGLOBL:
s = p->from.sym;
if(p->from.scale & DUPOK)
s->dupok = 1;
if(s->type == 0 || s->type == SXREF) {
s->type = SBSS;
s->value = 0;
@ -1134,6 +1136,7 @@ lookup(char *symb, int v)
s->version = v;
s->value = 0;
s->sig = 0;
s->dupok = 0;
hash[h] = s;
nsymbol++;
return s;

View file

@ -396,7 +396,7 @@ datblk(long s, long n)
}
if(l >= n)
continue;
if(p->as != AINIT && p->as != ADYNT) {
if(p->as != AINIT && p->as != ADYNT && !p->from.sym->dupok) {
for(j=l+(c-i)-1; j>=l; j--)
if(buf.dbuf[j]) {
print("%P\n", p);

View file

@ -65,6 +65,7 @@ struct Sym
short version;
short become;
short frame;
char dupok;
long value;
Sym *link;
};

View file

@ -737,6 +737,8 @@ loop:
diag("GLOBL must have a name\n%P", p);
errorexit();
}
if(p->reg & DUPOK)
s->dupok = 1;
if(s->type == 0 || s->type == SXREF) {
s->type = SBSS;
s->value = 0;
@ -951,6 +953,7 @@ lookup(char *symb, int v)
s->type = 0;
s->version = v;
s->value = 0;
s->dupok = 0;
hash[h] = s;
return s;
}

View file

@ -756,7 +756,7 @@ datblk(long s, long n)
}
if(l >= n)
continue;
if(p->as != AINIT && p->as != ADYNT) {
if(p->as != AINIT && p->as != ADYNT && !p->from.sym->dupok) {
for(j=l+(c-i)-1; j>=l; j--)
if(buf.dbuf[j]) {
print("%P\n", p);

View file

@ -61,6 +61,7 @@ struct Sym
short become;
short frame;
uchar subtype;
char dupok;
ushort file;
long value;
long sig;

View file

@ -849,6 +849,8 @@ loop:
diag("GLOBL must have a name\n%P", p);
errorexit();
}
if(p->reg & DUPOK)
s->dupok = 1;
if(s->type == 0 || s->type == SXREF) {
s->type = SBSS;
s->value = 0;
@ -1085,6 +1087,7 @@ lookup(char *symb, int v)
s->version = v;
s->value = 0;
s->sig = 0;
s->dupok = 0;
hash[h] = s;
return s;
}

View file

@ -708,7 +708,7 @@ datblk(long s, long n, int str)
}
if(l >= n)
continue;
if(p->as != AINIT && p->as != ADYNT) {
if(p->as != AINIT && p->as != ADYNT && !p->from.sym->dupok) {
for(j=l+(c-i)-1; j>=l; j--)
if(buf.dbuf[j]) {
print("%P\n", p);

View file

@ -74,6 +74,7 @@ struct Sym
short version;
short become;
short frame;
char dupok;
long value;
Sym* link;
};

View file

@ -803,6 +803,8 @@ loop:
diag("GLOBL must have a name\n%P", p);
errorexit();
}
if (p->reg & DUPOK)
s->dupok = 1;
if(s->type == 0 || s->type == SXREF) {
s->type = SBSS;
s->value = 0;
@ -1036,6 +1038,7 @@ lookup(char *symb, int v)
s->type = 0;
s->version = v;
s->value = 0;
s->dupok = 0;
hash[h] = s;
return s;
}