diff options
-rw-r--r-- | src/cmd/5c/swt.c | 4 | ||||
-rw-r--r-- | src/cmd/5l/obj.c | 1 | ||||
-rw-r--r-- | src/cmd/6c/swt.c | 4 | ||||
-rw-r--r-- | src/cmd/6l/obj.c | 1 | ||||
-rw-r--r-- | src/cmd/8c/swt.c | 4 | ||||
-rw-r--r-- | src/cmd/8l/obj.c | 1 | ||||
-rw-r--r-- | src/cmd/cc/cc.h | 2 | ||||
-rw-r--r-- | src/cmd/cc/dpchk.c | 17 | ||||
-rw-r--r-- | src/cmd/cc/lexbody | 7 | ||||
-rw-r--r-- | src/cmd/cc/macbody | 4 | ||||
-rw-r--r-- | src/cmd/cgo/out.go | 6 | ||||
-rw-r--r-- | src/cmd/ld/go.c | 64 |
12 files changed, 113 insertions, 2 deletions
diff --git a/src/cmd/5c/swt.c b/src/cmd/5c/swt.c index f8fbb1354..dea28cf6f 100644 --- a/src/cmd/5c/swt.c +++ b/src/cmd/5c/swt.c @@ -405,6 +405,10 @@ outcode(void) Bprint(&outbuf, "\n$$ // dynexport\n"); for(i=0; i<ndynexp; i++) Bprint(&outbuf, "dynexport %s %s\n", dynexp[i].local, dynexp[i].remote); + Bprint(&outbuf, "\n$$ // dynlinker\n"); + if(dynlinker != nil) { + Bprint(&outbuf, "dynlinker %s\n", dynlinker); + } Bprint(&outbuf, "\n$$\n\n"); } Bprint(&outbuf, "!\n"); diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c index 7dc5b899b..b57ef6edf 100644 --- a/src/cmd/5l/obj.c +++ b/src/cmd/5l/obj.c @@ -106,6 +106,7 @@ main(int argc, char *argv[]) INITENTRY = EARGF(usage()); break; case 'I': + debug['I'] = 1; // denote cmdline interpreter override interpreter = EARGF(usage()); break; case 'L': diff --git a/src/cmd/6c/swt.c b/src/cmd/6c/swt.c index 272cce259..2c5b3e604 100644 --- a/src/cmd/6c/swt.c +++ b/src/cmd/6c/swt.c @@ -259,6 +259,10 @@ outcode(void) Bprint(&b, "\n$$ // dynexport\n"); for(i=0; i<ndynexp; i++) Bprint(&b, "dynexport %s %s\n", dynexp[i].local, dynexp[i].remote); + Bprint(&b, "\n$$ // dynlinker\n"); + if(dynlinker != nil) { + Bprint(&b, "dynlinker %s\n", dynlinker); + } Bprint(&b, "\n$$\n\n"); } Bprint(&b, "!\n"); diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c index 692cab7b8..64d173084 100644 --- a/src/cmd/6l/obj.c +++ b/src/cmd/6l/obj.c @@ -114,6 +114,7 @@ main(int argc, char *argv[]) HEADTYPE = headtype(EARGF(usage())); break; case 'I': + debug['I'] = 1; // denote cmdline interpreter override interpreter = EARGF(usage()); break; case 'L': diff --git a/src/cmd/8c/swt.c b/src/cmd/8c/swt.c index 5a6f22e0b..18611ea1e 100644 --- a/src/cmd/8c/swt.c +++ b/src/cmd/8c/swt.c @@ -263,6 +263,10 @@ outcode(void) Bprint(&b, "\n$$ // dynexport\n"); for(i=0; i<ndynexp; i++) Bprint(&b, "dynexport %s %s\n", dynexp[i].local, dynexp[i].remote); + Bprint(&b, "\n$$ // dynlinker\n"); + if(dynlinker != nil) { + Bprint(&b, "dynlinker %s\n", dynlinker); + } Bprint(&b, "\n$$\n\n"); } Bprint(&b, "!\n"); diff --git a/src/cmd/8l/obj.c b/src/cmd/8l/obj.c index af4bc844f..823d0a22d 100644 --- a/src/cmd/8l/obj.c +++ b/src/cmd/8l/obj.c @@ -119,6 +119,7 @@ main(int argc, char *argv[]) HEADTYPE = headtype(EARGF(usage())); break; case 'I': + debug['I'] = 1; // denote cmdline interpreter override interpreter = EARGF(usage()); break; case 'L': diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h index 2ee03ae1f..3a0147e9f 100644 --- a/src/cmd/cc/cc.h +++ b/src/cmd/cc/cc.h @@ -774,6 +774,8 @@ void pragtextflag(void); void pragincomplete(void); void pragdynimport(void); void pragdynexport(void); +void pragdynlinker(void); +EXTERN char *dynlinker; /* * calls to machine depend part diff --git a/src/cmd/cc/dpchk.c b/src/cmd/cc/dpchk.c index c579e20d9..ea2e81dee 100644 --- a/src/cmd/cc/dpchk.c +++ b/src/cmd/cc/dpchk.c @@ -725,3 +725,20 @@ out: while(getnsc() != '\n') ; } + +void +pragdynlinker(void) +{ + dynlinker = getquoted(); + if(dynlinker == nil) + goto err; + + goto out; + +err: + yyerror("usage: #pragma dynlinker \"path\""); + +out: + while(getnsc() != '\n') + ; +} diff --git a/src/cmd/cc/lexbody b/src/cmd/cc/lexbody index d339cf9a2..51d2e9396 100644 --- a/src/cmd/cc/lexbody +++ b/src/cmd/cc/lexbody @@ -61,6 +61,13 @@ pragdynexport(void) } void +pragdynlinker(void) +{ + while(getnsc() != '\n') + ; +} + +void pragfpround(void) { while(getnsc() != '\n') diff --git a/src/cmd/cc/macbody b/src/cmd/cc/macbody index 874e82d25..e9b4ba9fb 100644 --- a/src/cmd/cc/macbody +++ b/src/cmd/cc/macbody @@ -751,6 +751,10 @@ macprag(void) pragdynexport(); return; } + if(s && strcmp(s->name, "dynlinker") == 0) { + pragdynlinker(); + return; + } while(getnsc() != '\n') ; return; diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go index acd1e0b43..290b37ac5 100644 --- a/src/cmd/cgo/out.go +++ b/src/cmd/cgo/out.go @@ -128,6 +128,12 @@ func dynimport(obj string) { } if f, err := elf.Open(obj); err == nil { + if sec := f.Section(".interp"); sec != nil { + if data, err := sec.Data(); err == nil && len(data) > 1 { + // skip trailing \0 in data + fmt.Fprintf(stdout, "#pragma dynlinker %q\n", string(data[:len(data)-1])) + } + } sym, err := f.ImportedSymbols() if err != nil { fatalf("cannot load imported symbols from ELF file %s: %v", obj, err) diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c index 3271be1f5..78f76bf12 100644 --- a/src/cmd/ld/go.c +++ b/src/cmd/ld/go.c @@ -69,6 +69,7 @@ ilookup(char *name) static void loadpkgdata(char*, char*, char*, int); static void loaddynimport(char*, char*, char*, int); static void loaddynexport(char*, char*, char*, int); +static void loaddynlinker(char*, char*, char*, int); static int parsemethod(char**, char*, char**); static int parsepkgdata(char*, char*, char**, char*, char**, char**, char**); @@ -204,7 +205,7 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence) if(p0 != nil) { p0 = strchr(p0+1, '\n'); if(p0 == nil) { - fprint(2, "%s: found $$ // dynexporg but no newline in %s\n", argv0, filename); + fprint(2, "%s: found $$ // dynexport but no newline in %s\n", argv0, filename); if(debug['u']) errorexit(); return; @@ -213,13 +214,34 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence) if(p1 == nil) p1 = strstr(p0, "\n!\n"); if(p1 == nil) { - fprint(2, "%s: cannot find end of // dynexporg section in %s\n", argv0, filename); + fprint(2, "%s: cannot find end of // dynexport section in %s\n", argv0, filename); if(debug['u']) errorexit(); return; } loaddynexport(filename, pkg, p0 + 1, p1 - (p0+1)); } + + p0 = strstr(p1, "\n$$ // dynlinker"); + if(p0 != nil) { + p0 = strchr(p0+1, '\n'); + if(p0 == nil) { + fprint(2, "%s: found $$ // dynlinker but no newline in %s\n", argv0, filename); + if(debug['u']) + errorexit(); + return; + } + p1 = strstr(p0, "\n$$"); + if(p1 == nil) + p1 = strstr(p0, "\n!\n"); + if(p1 == nil) { + fprint(2, "%s: cannot find end of // dynlinker section in %s\n", argv0, filename); + if(debug['u']) + errorexit(); + return; + } + loaddynlinker(filename, pkg, p0 + 1, p1 - (p0+1)); + } } static void @@ -551,6 +573,44 @@ err: nerrors++; } +static void +loaddynlinker(char *file, char *pkg, char *p, int n) +{ + char *pend, *next, *dynlinker, *p0; + + USED(file); + pend = p + n; + for(; p<pend; p=next) { + next = strchr(p, '\n'); + if(next == nil) + next = ""; + else + *next++ = '\0'; + p0 = p; + if(strncmp(p, "dynlinker ", 10) != 0) + goto err; + p += 10; + dynlinker = p; + + if(*dynlinker == '\0') + goto err; + if(!debug['I']) { // not overrided by cmdline + if(interpreter != nil && strcmp(interpreter, dynlinker) != 0) { + fprint(2, "%s: conflict dynlinker: %s and %s\n", argv0, interpreter, dynlinker); + nerrors++; + return; + } + free(interpreter); + interpreter = strdup(dynlinker); + } + } + return; + +err: + fprint(2, "%s: invalid dynlinker line: %s\n", argv0, p0); + nerrors++; +} + static int markdepth; static void |