commit 167b6dca703cf1999b50833640e9468e330820b7
parent d023bdaa6b493686f7e9be7ac200ee4ac37d351f
Author: Roberto E. Vargas Caballero <roberto.vargas@midokura.com>
Date: Wed, 29 Jun 2022 18:09:08 +0200
Add common linkage attribute
This allows you to explicitly mark a symbol as common.
Diffstat:
4 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/all.h b/all.h
@@ -365,6 +365,7 @@ struct Lnk {
char export;
char thread;
char align;
+ char common;
char *sec;
char *secf;
};
diff --git a/emit.c b/emit.c
@@ -72,7 +72,7 @@ emitdat(Dat *d, FILE *f)
switch (d->type) {
case DStart:
- zero = 0;
+ zero = d->lnk->common ? -1 : 0;
break;
case DEnd:
if (zero != -1) {
@@ -83,6 +83,8 @@ emitdat(Dat *d, FILE *f)
case DZ:
if (zero != -1)
zero += d->u.num;
+ else if (d->lnk->common)
+ fprintf(f, "\t.comm %s,%"PRId64"\n", d->name, d->u.num);
else
fprintf(f, "\t.fill %"PRId64",1,0\n", d->u.num);
break;
diff --git a/parse.c b/parse.c
@@ -51,6 +51,7 @@ enum Token {
Tfunc,
Ttype,
Tdata,
+ Tcommon,
Tsection,
Talign,
Tdbgfile,
@@ -109,6 +110,7 @@ static char *kwmap[Ntok] = {
[Tfunc] = "function",
[Ttype] = "type",
[Tdata] = "data",
+ [Tcommon] = "common",
[Tsection] = "section",
[Talign] = "align",
[Tdbgfile] = "dbgfile",
@@ -132,7 +134,7 @@ enum {
TMask = 16383, /* for temps hash */
BMask = 8191, /* for blocks hash */
- K = 9583425, /* found using tools/lexh.c */
+ K = 11183273, /* found using tools/lexh.c */
M = 23,
};
@@ -1072,7 +1074,7 @@ static void
parsedat(void cb(Dat *), Lnk *lnk)
{
char name[NString] = {0};
- int t;
+ int t, n;
Dat d;
if (nextnl() != Tglo || nextnl() != Teq)
@@ -1093,7 +1095,9 @@ parsedat(void cb(Dat *), Lnk *lnk)
if (t != Tlbrace)
err("expected data contents in { .. }");
- for (;;) {
+ for (n = 0;; n++) {
+ if (lnk->common && n > 0)
+ err("common can be used only with one z");
switch (nextnl()) {
default: err("invalid size specifier %c in data", tokval.chr);
case Trbrace: goto Done;
@@ -1105,6 +1109,8 @@ parsedat(void cb(Dat *), Lnk *lnk)
case Td: d.type = DL; break;
case Tz: d.type = DZ; break;
}
+ if (lnk->common && d.type != DZ)
+ err("common can be used only with z");
t = nextnl();
do {
d.isstr = 0;
@@ -1148,6 +1154,9 @@ parselnk(Lnk *lnk)
case Tthread:
lnk->thread = 1;
break;
+ case Tcommon:
+ lnk->common = 1;
+ break;
case Tsection:
if (lnk->sec)
err("only one section allowed");
@@ -1164,6 +1173,10 @@ parselnk(Lnk *lnk)
err("only data may have thread linkage");
if (haslnk && t != Tdata && t != Tfunc)
err("only data and function have linkage");
+ if (lnk->common && lnk->sec)
+ err("common symbols cannot have section declarations");
+ if (lnk->common && t != Tdata)
+ err("common symbols only can be used for data");
return t;
}
}
diff --git a/tools/lexh.c b/tools/lexh.c
@@ -26,7 +26,7 @@ char *tok[] = {
"vaarg", "vastart", "...", "env", "dbgloc",
"call", "phi", "jmp", "jnz", "ret", "hlt", "export",
- "function", "type", "data", "section", "align", "dbgfile",
+ "function", "type", "data", "section", "common", "align", "dbgfile",
"blit", "l", "w", "sh", "uh", "h", "sb", "ub", "b",
"d", "s", "z", "loadw", "loadl", "loads", "loadd",
"alloc1", "alloc2",