diff options
author | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
---|---|---|
committer | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
commit | f154da9e12608589e8d5f0508f908a0c3e88a1bb (patch) | |
tree | f8255d51e10c6f1e0ed69702200b966c9556a431 /src/cmd/ld/lib.c | |
parent | 8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff) | |
download | golang-upstream/1.4.tar.gz |
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'src/cmd/ld/lib.c')
-rw-r--r-- | src/cmd/ld/lib.c | 91 |
1 files changed, 78 insertions, 13 deletions
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c index da6194e4f..f889aba8a 100644 --- a/src/cmd/ld/lib.c +++ b/src/cmd/ld/lib.c @@ -33,8 +33,8 @@ #include "lib.h" #include "../ld/elf.h" #include "../ld/dwarf.h" -#include "../../pkg/runtime/stack.h" -#include "../../pkg/runtime/funcdata.h" +#include "../../runtime/stack.h" +#include "../../runtime/funcdata.h" #include <ar.h> #if !(defined(_WIN32) || defined(PLAN9)) @@ -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(); @@ -177,7 +181,7 @@ void loadlib(void) { int i, w, x; - LSym *s, *gmsym; + LSym *s, *tlsg; char* cgostrsym; if(flag_shared) { @@ -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) { @@ -226,6 +234,10 @@ loadlib(void) linkmode = LinkExternal; else linkmode = LinkInternal; + + // Force external linking for android. + if(strcmp(goos, "android") == 0) + linkmode = LinkExternal; } if(linkmode == LinkInternal) { @@ -244,12 +256,12 @@ loadlib(void) } } - gmsym = linklookup(ctxt, "runtime.tlsgm", 0); - gmsym->type = STLSBSS; - gmsym->size = 2*PtrSize; - gmsym->hide = 1; - gmsym->reachable = 1; - ctxt->gmsym = gmsym; + tlsg = linklookup(ctxt, "runtime.tlsg", 0); + tlsg->type = STLSBSS; + tlsg->size = PtrSize; + tlsg->hide = 1; + tlsg->reachable = 1; + ctxt->tlsg = tlsg; // Now that we know the link mode, trim the dynexp list. x = CgoExportDynamic; @@ -895,7 +907,7 @@ unmal(void *v, uint32 n) * escaping are %, ., and ", but we escape all control characters too. * * If you edit this, edit ../gc/subr.c:/^pathtoprefix too. - * If you edit this, edit ../../pkg/debug/goobj/read.go:/importPathToPrefix too. + * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too. */ static char* pathtoprefix(char *s) @@ -1345,10 +1357,10 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*)) // These symbols won't show up in the first loop below because we // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp. - s = linklookup(ctxt, "text", 0); + s = linklookup(ctxt, "runtime.text", 0); if(s->type == STEXT) put(s, s->name, 'T', s->value, s->size, s->version, 0); - s = linklookup(ctxt, "etext", 0); + s = linklookup(ctxt, "runtime.etext", 0); if(s->type == STEXT) put(s, s->name, 'T', s->value, s->size, s->version, 0); @@ -1550,3 +1562,56 @@ diag(char *fmt, ...) errorexit(); } } + +void +checkgo(void) +{ + LSym *s; + Reloc *r; + int i; + int changed; + + if(!debug['C']) + return; + + // TODO(rsc,khr): Eventually we want to get to no Go-called C functions at all, + // which would simplify this logic quite a bit. + + // Mark every Go-called C function with cfunc=2, recursively. + do { + changed = 0; + for(s = ctxt->textp; s != nil; s = s->next) { + if(s->cfunc == 0 || (s->cfunc == 2 && s->nosplit)) { + for(i=0; i<s->nr; i++) { + r = &s->r[i]; + if(r->sym == nil) + continue; + if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT) { + if(r->sym->cfunc == 1) { + changed = 1; + r->sym->cfunc = 2; + } + } + } + } + } + }while(changed); + + // Complain about Go-called C functions that can split the stack + // (that can be preempted for garbage collection or trigger a stack copy). + for(s = ctxt->textp; s != nil; s = s->next) { + if(s->cfunc == 0 || (s->cfunc == 2 && s->nosplit)) { + for(i=0; i<s->nr; i++) { + r = &s->r[i]; + if(r->sym == nil) + continue; + if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT) { + if(s->cfunc == 0 && r->sym->cfunc == 2 && !r->sym->nosplit) + print("Go %s calls C %s\n", s->name, r->sym->name); + else if(s->cfunc == 2 && s->nosplit && !r->sym->nosplit) + print("Go calls C %s calls %s\n", s->name, r->sym->name); + } + } + } + } +} |