summaryrefslogtreecommitdiff
path: root/src/cmd/ld/go.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ld/go.c')
-rw-r--r--src/cmd/ld/go.c64
1 files changed, 62 insertions, 2 deletions
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