summaryrefslogtreecommitdiff
path: root/src/cmd/6g/gobj.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6g/gobj.c')
-rw-r--r--src/cmd/6g/gobj.c174
1 files changed, 34 insertions, 140 deletions
diff --git a/src/cmd/6g/gobj.c b/src/cmd/6g/gobj.c
index b667ae48a..507764a3b 100644
--- a/src/cmd/6g/gobj.c
+++ b/src/cmd/6g/gobj.c
@@ -280,7 +280,7 @@ static Prog *estrdat;
static int gflag;
static Prog *savepc;
-static void
+void
data(void)
{
gflag = debug['g'];
@@ -297,7 +297,7 @@ data(void)
pc = estrdat;
}
-static void
+void
text(void)
{
if(!savepc)
@@ -322,6 +322,24 @@ dumpdata(void)
pc = estrdat;
}
+int
+dsname(Sym *s, int off, char *t, int n)
+{
+ Prog *p;
+
+ p = gins(ADATA, N, N);
+ p->from.type = D_EXTERN;
+ p->from.index = D_NONE;
+ p->from.offset = off;
+ p->from.scale = n;
+ p->from.sym = s;
+
+ p->to.type = D_SCONST;
+ p->to.index = D_NONE;
+ memmove(p->to.sval, t, n);
+ return off + n;
+}
+
/*
* make a refer to the data s, s+len
* emitting DATA if needed.
@@ -329,74 +347,13 @@ dumpdata(void)
void
datastring(char *s, int len, Addr *a)
{
- int w;
- Prog *p;
- Addr ac, ao;
- static int gen;
- struct {
- Strlit lit;
- char buf[100];
- } tmp;
-
- // string
- memset(&ao, 0, sizeof(ao));
- ao.type = D_STATIC;
- ao.index = D_NONE;
- ao.etype = TINT32;
- ao.offset = 0; // fill in
-
- // constant
- memset(&ac, 0, sizeof(ac));
- ac.type = D_CONST;
- ac.index = D_NONE;
- ac.offset = 0; // fill in
-
- // huge strings are made static to avoid long names.
- if(len > 100) {
- snprint(namebuf, sizeof(namebuf), ".string.%d", gen++);
- ao.sym = lookup(namebuf);
- ao.type = D_STATIC;
- } else {
- if(len > 0 && s[len-1] == '\0')
- len--;
- tmp.lit.len = len;
- memmove(tmp.lit.s, s, len);
- tmp.lit.s[len] = '\0';
- len++;
- snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
- ao.sym = pkglookup(namebuf, stringpkg);
- ao.type = D_EXTERN;
- }
- *a = ao;
-
- // only generate data the first time.
- if(ao.sym->flags & SymUniq)
- return;
- ao.sym->flags |= SymUniq;
-
- data();
- for(w=0; w<len; w+=8) {
- p = pc;
- gins(ADATA, N, N);
-
- // DATA s+w, [NSNAME], $"xxx"
- p->from = ao;
- p->from.offset = w;
-
- p->from.scale = NSNAME;
- if(w+8 > len)
- p->from.scale = len-w;
-
- p->to = ac;
- p->to.type = D_SCONST;
- p->to.offset = len;
- memmove(p->to.sval, s+w, p->from.scale);
- }
- p = pc;
- ggloblsym(ao.sym, len, ao.type == D_EXTERN);
- if(ao.type == D_STATIC)
- p->from.type = D_STATIC;
- text();
+ Sym *sym;
+
+ sym = stringsym(s, len);
+ a->type = D_EXTERN;
+ a->sym = sym;
+ a->offset = widthptr+4; // skip header
+ a->etype = TINT32;
}
/*
@@ -406,76 +363,13 @@ datastring(char *s, int len, Addr *a)
void
datagostring(Strlit *sval, Addr *a)
{
- Prog *p;
- Addr ac, ao, ap;
- int32 wi, wp;
- static int gen;
-
- memset(&ac, 0, sizeof(ac));
- memset(&ao, 0, sizeof(ao));
- memset(&ap, 0, sizeof(ap));
-
- // constant
- ac.type = D_CONST;
- ac.index = D_NONE;
- ac.offset = 0; // fill in
-
- // string len+ptr
- ao.type = D_STATIC; // fill in
- ao.index = D_NONE;
- ao.etype = TINT32;
- ao.sym = nil; // fill in
-
- // $string len+ptr
- datastring(sval->s, sval->len, &ap);
- ap.index = ap.type;
- ap.type = D_ADDR;
- ap.etype = TINT32;
-
- wi = types[TUINT32]->width;
- wp = types[tptr]->width;
-
- if(ap.index == D_STATIC) {
- // huge strings are made static to avoid long names
- snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
- ao.sym = lookup(namebuf);
- ao.type = D_STATIC;
- } else {
- // small strings get named by their contents,
- // so that multiple modules using the same string
- // can share it.
- snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
- ao.sym = pkglookup(namebuf, gostringpkg);
- ao.type = D_EXTERN;
- }
-
- *a = ao;
- if(ao.sym->flags & SymUniq)
- return;
- ao.sym->flags |= SymUniq;
-
- data();
- // DATA gostring, wp, $cstring
- p = pc;
- gins(ADATA, N, N);
- p->from = ao;
- p->from.scale = wp;
- p->to = ap;
-
- // DATA gostring+wp, wi, $len
- p = pc;
- gins(ADATA, N, N);
- p->from = ao;
- p->from.offset = wp;
- p->from.scale = wi;
- p->to = ac;
- p->to.offset = sval->len;
-
- p = pc;
- ggloblsym(ao.sym, types[TSTRING]->width, ao.type == D_EXTERN);
- if(ao.type == D_STATIC)
- p->from.type = D_STATIC;
- text();
+ Sym *sym;
+
+ sym = stringsym(sval->s, sval->len);
+ a->type = D_EXTERN;
+ a->sym = sym;
+ a->offset = 0; // header
+ a->etype = TINT32;
}
void