aboutsummaryrefslogtreecommitdiff
path: root/src/liblink
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-10-03 12:22:19 -0400
committerRuss Cox <rsc@golang.org>2014-10-03 12:22:19 -0400
commit904ec0098137f742e0dd96da3bc033d6a0b615d1 (patch)
tree6a05a91443927524fcb78ac82df0142d8e6ae71f /src/liblink
parentd42328c9f749140adf947833e0381fc639c32737 (diff)
parentc65a47f890e33eeed6ee9d8b6d965a5534fb6e0e (diff)
downloadgo-904ec0098137f742e0dd96da3bc033d6a0b615d1.tar.xz
[dev.garbage] merge default into dev.garbage
Diffstat (limited to 'src/liblink')
-rw-r--r--src/liblink/obj5.c21
-rw-r--r--src/liblink/objfile.c36
2 files changed, 52 insertions, 5 deletions
diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c
index a571d8f166..d7f2714ed8 100644
--- a/src/liblink/obj5.c
+++ b/src/liblink/obj5.c
@@ -119,14 +119,30 @@ progedit(Link *ctxt, Prog *p)
ctxt->diag("%L: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p->lineno);
if(ctxt->goarm < 7) {
- // Replace it with BL runtime.read_tls_fallback(SB).
+ // Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
if(tlsfallback == nil)
tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
- // BL runtime.read_tls_fallback(SB)
+ // MOVW LR, R11
+ p->as = AMOVW;
+ p->from.type = D_REG;
+ p->from.reg = REGLINK;
+ p->to.type = D_REG;
+ p->to.reg = REGTMP;
+
+ // BL runtime.read_tls_fallback(SB)
+ p = appendp(ctxt, p);
p->as = ABL;
p->to.type = D_BRANCH;
p->to.sym = tlsfallback;
p->to.offset = 0;
+
+ // MOVW R11, LR
+ p = appendp(ctxt, p);
+ p->as = AMOVW;
+ p->from.type = D_REG;
+ p->from.reg = REGTMP;
+ p->to.type = D_REG;
+ p->to.reg = REGLINK;
break;
}
}
@@ -1061,6 +1077,7 @@ LinkArch linkarm = {
.D_PARAM = D_PARAM,
.D_SCONST = D_SCONST,
.D_STATIC = D_STATIC,
+ .D_OREG = D_OREG,
.ACALL = ABL,
.ADATA = ADATA,
diff --git a/src/liblink/objfile.c b/src/liblink/objfile.c
index 02cfae495a..b2478ec178 100644
--- a/src/liblink/objfile.c
+++ b/src/liblink/objfile.c
@@ -125,7 +125,7 @@ static LSym *rdsym(Link*, Biobuf*, char*);
void
writeobj(Link *ctxt, Biobuf *b)
{
- int flag;
+ int flag, found;
Hist *h;
LSym *s, *text, *etext, *curtext, *data, *edata;
Plist *pl;
@@ -251,6 +251,32 @@ writeobj(Link *ctxt, Biobuf *b)
s->etext = p;
}
}
+
+ // Add reference to Go arguments for C or assembly functions without them.
+ for(s = text; s != nil; s = s->next) {
+ if(strncmp(s->name, "\"\".", 3) != 0)
+ continue;
+ found = 0;
+ for(p = s->text; p != nil; p = p->link) {
+ if(p->as == ctxt->arch->AFUNCDATA && p->from.type == ctxt->arch->D_CONST && p->from.offset == FUNCDATA_ArgsPointerMaps) {
+ found = 1;
+ break;
+ }
+ }
+ if(!found) {
+ p = appendp(ctxt, s->text);
+ p->as = ctxt->arch->AFUNCDATA;
+ p->from.type = ctxt->arch->D_CONST;
+ p->from.offset = FUNCDATA_ArgsPointerMaps;
+ if(ctxt->arch->thechar == '6' || ctxt->arch->thechar == '8')
+ p->to.type = ctxt->arch->D_EXTERN;
+ else {
+ p->to.type = ctxt->arch->D_OREG;
+ p->to.name = ctxt->arch->D_EXTERN;
+ }
+ p->to.sym = linklookup(ctxt, smprint("%s.args_stackmap", s->name), s->version);
+ }
+ }
// Turn functions into machine code images.
for(s = text; s != nil; s = s->next) {
@@ -524,7 +550,7 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
static int ndup;
char *name;
Reloc *r;
- LSym *s, *dup;
+ LSym *s, *dup, *typ;
Pcln *pc;
Auto *a;
@@ -560,7 +586,11 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
s->type = t;
if(s->size < size)
s->size = size;
- s->gotype = rdsym(ctxt, f, pkg);
+ typ = rdsym(ctxt, f, pkg);
+ if(typ != nil) // if bss sym defined multiple times, take type from any one def
+ s->gotype = typ;
+ if(dup != nil && typ != nil)
+ dup->gotype = typ;
rddata(f, &s->p, &s->np);
s->maxp = s->np;
n = rdint(f);