aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ld')
-rw-r--r--src/cmd/ld/data.c21
-rw-r--r--src/cmd/ld/lib.c10
-rw-r--r--src/cmd/ld/pobj.c9
3 files changed, 35 insertions, 5 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 71624c3304..9983a9281c 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -620,22 +620,28 @@ addstrdata(char *name, char *value)
{
LSym *s, *sp;
char *p;
+ uchar reachable;
p = smprint("%s.str", name);
sp = linklookup(ctxt, p, 0);
free(p);
addstring(sp, value);
+ sp->type = SRODATA;
s = linklookup(ctxt, name, 0);
s->size = 0;
s->dupok = 1;
+ reachable = s->reachable;
addaddr(ctxt, s, sp);
adduint32(ctxt, s, strlen(value));
if(PtrSize == 8)
adduint32(ctxt, s, 0); // round struct to pointer width
- // in case reachability has already been computed
- sp->reachable = s->reachable;
+ // addstring, addaddr, etc., mark the symbols as reachable.
+ // In this case that is not necessarily true, so stick to what
+ // we know before entering this function.
+ s->reachable = reachable;
+ sp->reachable = reachable;
}
vlong
@@ -816,8 +822,15 @@ proggenaddsym(ProgGen *g, LSym *s)
proggenskip(g, g->pos, s->value - g->pos);
g->pos += s->value - g->pos;
- if(s->gotype == nil && s->size >= PtrSize) {
+ // The test for names beginning with . here is meant
+ // to keep .dynamic and .dynsym from turning up as
+ // conservative symbols. They should be marked SELFSECT
+ // and not SDATA, but sometimes that doesn't happen.
+ // Leave debugging the SDATA issue for the Go rewrite.
+
+ if(s->gotype == nil && s->size >= PtrSize && s->name[0] != '.') {
// conservative scan
+ diag("missing Go type information for global symbol: %s size %d", s->name, (int)s->size);
if((s->size%PtrSize) || (g->pos%PtrSize))
diag("proggenaddsym: unaligned conservative symbol %s: size=%lld pos=%lld",
s->name, s->size, g->pos);
@@ -833,7 +846,7 @@ proggenaddsym(ProgGen *g, LSym *s)
proggenarrayend(g);
}
g->pos = s->value + size;
- } else if(s->gotype == nil || decodetype_noptr(s->gotype) || s->size < PtrSize) {
+ } else if(s->gotype == nil || decodetype_noptr(s->gotype) || s->size < PtrSize || s->name[0] == '.') {
// no scan
if(s->size < 32*PtrSize) {
// Emit small symbols as data.
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c
index 651705a2e6..f889aba8a9 100644
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -144,6 +144,10 @@ libinit(void)
void
errorexit(void)
{
+ if(cout >= 0) {
+ // For rmtemp run at atexit time on Windows.
+ close(cout);
+ }
if(nerrors) {
if(cout >= 0)
mayberemoveoutfile();
@@ -217,8 +221,12 @@ loadlib(void)
// Provided by the code that imports the package.
// Since we are simulating the import, we have to provide this string.
cgostrsym = "go.string.\"runtime/cgo\"";
- if(linkrlookup(ctxt, cgostrsym, 0) == nil)
+ if(linkrlookup(ctxt, cgostrsym, 0) == nil) {
+ s = linklookup(ctxt, cgostrsym, 0);
+ s->type = SRODATA;
+ s->reachable = 1;
addstrdata(cgostrsym, "runtime/cgo");
+ }
}
if(linkmode == LinkAuto) {
diff --git a/src/cmd/ld/pobj.c b/src/cmd/ld/pobj.c
index 54c5ef2472..63460df30a 100644
--- a/src/cmd/ld/pobj.c
+++ b/src/cmd/ld/pobj.c
@@ -45,6 +45,8 @@ char* paramspace = "FP";
void
main(int argc, char *argv[])
{
+ int i;
+
linkarchinit();
ctxt = linknew(thelinkarch);
ctxt->thechar = thechar;
@@ -64,6 +66,13 @@ main(int argc, char *argv[])
INITENTRY = 0;
linkmode = LinkAuto;
+ // For testing behavior of go command when tools crash.
+ // Undocumented, not in standard flag parser to avoid
+ // exposing in usage message.
+ for(i=1; i<argc; i++)
+ if(strcmp(argv[i], "-crash_for_testing") == 0)
+ *(volatile int*)0 = 0;
+
if(thechar == '5' && ctxt->goarm == 5)
debug['F'] = 1;