summaryrefslogtreecommitdiff
path: root/sys/src
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2017-03-19 03:05:24 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2017-03-19 03:05:24 +0100
commitda9b38c75c11cc7f18415849b5bf14579ef8317c (patch)
tree427a69021fef7444f35b9880677c6bdce63e68d9 /sys/src
parentbd178b6dc6a6d6a81be05c0a1f7c03b352f833c1 (diff)
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.
Diffstat (limited to 'sys/src')
-rw-r--r--sys/src/cmd/5l/asm.c2
-rw-r--r--sys/src/cmd/5l/l.h1
-rw-r--r--sys/src/cmd/5l/obj.c3
-rw-r--r--sys/src/cmd/6l/asm.c2
-rw-r--r--sys/src/cmd/6l/l.h1
-rw-r--r--sys/src/cmd/6l/list.c1
-rw-r--r--sys/src/cmd/6l/obj.c4
-rw-r--r--sys/src/cmd/8l/asm.c2
-rw-r--r--sys/src/cmd/8l/l.h1
-rw-r--r--sys/src/cmd/8l/list.c1
-rw-r--r--sys/src/cmd/8l/obj.c3
-rw-r--r--sys/src/cmd/kl/asm.c2
-rw-r--r--sys/src/cmd/kl/l.h1
-rw-r--r--sys/src/cmd/kl/obj.c3
-rw-r--r--sys/src/cmd/ql/asm.c2
-rw-r--r--sys/src/cmd/ql/l.h1
-rw-r--r--sys/src/cmd/ql/obj.c3
-rw-r--r--sys/src/cmd/vl/asm.c2
-rw-r--r--sys/src/cmd/vl/l.h1
-rw-r--r--sys/src/cmd/vl/obj.c3
20 files changed, 33 insertions, 6 deletions
diff --git a/sys/src/cmd/5l/asm.c b/sys/src/cmd/5l/asm.c
index 81f5e7f55..1d3ecc68b 100644
--- a/sys/src/cmd/5l/asm.c
+++ b/sys/src/cmd/5l/asm.c
@@ -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);
diff --git a/sys/src/cmd/5l/l.h b/sys/src/cmd/5l/l.h
index 1db0ce9c6..24426e11b 100644
--- a/sys/src/cmd/5l/l.h
+++ b/sys/src/cmd/5l/l.h
@@ -82,6 +82,7 @@ struct Sym
short become;
short frame;
uchar subtype;
+ char dupok;
ushort file;
long value;
long sig;
diff --git a/sys/src/cmd/5l/obj.c b/sys/src/cmd/5l/obj.c
index 218579230..a185919b3 100644
--- a/sys/src/cmd/5l/obj.c
+++ b/sys/src/cmd/5l/obj.c
@@ -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;
}
diff --git a/sys/src/cmd/6l/asm.c b/sys/src/cmd/6l/asm.c
index 71e1bb67a..fef9a0ab4 100644
--- a/sys/src/cmd/6l/asm.c
+++ b/sys/src/cmd/6l/asm.c
@@ -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);
diff --git a/sys/src/cmd/6l/l.h b/sys/src/cmd/6l/l.h
index 39037c5a2..42dba0d17 100644
--- a/sys/src/cmd/6l/l.h
+++ b/sys/src/cmd/6l/l.h
@@ -79,6 +79,7 @@ struct Sym
short version;
short become;
short frame;
+ char dupok;
uchar subtype;
ushort file;
vlong value;
diff --git a/sys/src/cmd/6l/list.c b/sys/src/cmd/6l/list.c
index 6aefc0e15..658988251 100644
--- a/sys/src/cmd/6l/list.c
+++ b/sys/src/cmd/6l/list.c
@@ -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);
diff --git a/sys/src/cmd/6l/obj.c b/sys/src/cmd/6l/obj.c
index 0353e2c30..1c609b98f 100644
--- a/sys/src/cmd/6l/obj.c
+++ b/sys/src/cmd/6l/obj.c
@@ -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;
diff --git a/sys/src/cmd/8l/asm.c b/sys/src/cmd/8l/asm.c
index a1bb36ba6..129b3cd71 100644
--- a/sys/src/cmd/8l/asm.c
+++ b/sys/src/cmd/8l/asm.c
@@ -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);
diff --git a/sys/src/cmd/8l/l.h b/sys/src/cmd/8l/l.h
index fbb0a191b..2ca800342 100644
--- a/sys/src/cmd/8l/l.h
+++ b/sys/src/cmd/8l/l.h
@@ -80,6 +80,7 @@ struct Sym
short become;
short frame;
uchar subtype;
+ char dupok;
ushort file;
long value;
long sig;
diff --git a/sys/src/cmd/8l/list.c b/sys/src/cmd/8l/list.c
index 212b8ad3c..f6b1eda2e 100644
--- a/sys/src/cmd/8l/list.c
+++ b/sys/src/cmd/8l/list.c
@@ -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);
diff --git a/sys/src/cmd/8l/obj.c b/sys/src/cmd/8l/obj.c
index 2aeee6811..ba4571468 100644
--- a/sys/src/cmd/8l/obj.c
+++ b/sys/src/cmd/8l/obj.c
@@ -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;
diff --git a/sys/src/cmd/kl/asm.c b/sys/src/cmd/kl/asm.c
index 62fe60b70..e2ad134c1 100644
--- a/sys/src/cmd/kl/asm.c
+++ b/sys/src/cmd/kl/asm.c
@@ -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);
diff --git a/sys/src/cmd/kl/l.h b/sys/src/cmd/kl/l.h
index 2045e3207..94fa2b40f 100644
--- a/sys/src/cmd/kl/l.h
+++ b/sys/src/cmd/kl/l.h
@@ -65,6 +65,7 @@ struct Sym
short version;
short become;
short frame;
+ char dupok;
long value;
Sym *link;
};
diff --git a/sys/src/cmd/kl/obj.c b/sys/src/cmd/kl/obj.c
index 2608349b4..381bcf1dc 100644
--- a/sys/src/cmd/kl/obj.c
+++ b/sys/src/cmd/kl/obj.c
@@ -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;
}
diff --git a/sys/src/cmd/ql/asm.c b/sys/src/cmd/ql/asm.c
index 8930ddae8..b980aff8e 100644
--- a/sys/src/cmd/ql/asm.c
+++ b/sys/src/cmd/ql/asm.c
@@ -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);
diff --git a/sys/src/cmd/ql/l.h b/sys/src/cmd/ql/l.h
index 9556a20a6..fd56f6882 100644
--- a/sys/src/cmd/ql/l.h
+++ b/sys/src/cmd/ql/l.h
@@ -61,6 +61,7 @@ struct Sym
short become;
short frame;
uchar subtype;
+ char dupok;
ushort file;
long value;
long sig;
diff --git a/sys/src/cmd/ql/obj.c b/sys/src/cmd/ql/obj.c
index 9e4dcf02e..c6c4e26dc 100644
--- a/sys/src/cmd/ql/obj.c
+++ b/sys/src/cmd/ql/obj.c
@@ -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;
}
diff --git a/sys/src/cmd/vl/asm.c b/sys/src/cmd/vl/asm.c
index c18c5b408..20e9c0c28 100644
--- a/sys/src/cmd/vl/asm.c
+++ b/sys/src/cmd/vl/asm.c
@@ -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);
diff --git a/sys/src/cmd/vl/l.h b/sys/src/cmd/vl/l.h
index e8c6577b5..1ea12b15b 100644
--- a/sys/src/cmd/vl/l.h
+++ b/sys/src/cmd/vl/l.h
@@ -74,6 +74,7 @@ struct Sym
short version;
short become;
short frame;
+ char dupok;
long value;
Sym* link;
};
diff --git a/sys/src/cmd/vl/obj.c b/sys/src/cmd/vl/obj.c
index 6002b7417..5f6e7200c 100644
--- a/sys/src/cmd/vl/obj.c
+++ b/sys/src/cmd/vl/obj.c
@@ -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;
}