static void loaddynimport(char *file, char *pkg, char *p, int n) { char *pend, *next, *name, *def, *p0, *lib, *q; Sym *s; pend = p + n; p0 = p; for(; p<pend; p=next) { next = strchr(p, '\n'); if(next == nil) next = ""; else *next++ = '\0'; p0 = p; if(strncmp(p, "dynimport ", 10) != 0) goto err; p += 10; name = p; p = strchr(name, ' '); if(p == nil) goto err; while(*p == ' ') p++; def = p; p = strchr(def, ' '); if(p == nil) goto err; while(*p == ' ') p++; lib = p; // successful parse: now can edit the line *strchr(name, ' ') = 0; *strchr(def, ' ') = 0; if(debug['d']) { fprint(2, "%s: %s: cannot use dynamic imports with -d flag\n", argv0, file); nerrors++; return; } if(strcmp(name, "_") == 0 && strcmp(def, "_") == 0) { // allow #pragma dynimport _ _ "foo.so" // to force a link of foo.so. havedynamic = 1; adddynlib(lib); continue; } name = expandpkg(name, pkg); q = strchr(def, '@'); if(q) *q++ = '\0'; s = lookup(name, 0); if(s->type == 0 || s->type == SXREF) { s->dynimplib = lib; s->dynimpname = def; s->dynimpvers = q; s->type = SDYNIMPORT; havedynamic = 1; } } return; err: fprint(2, "%s: %s: invalid dynimport line: %s\n", argv0, file, p0); nerrors++; }
static void loadcgo(char *file, char *pkg, char *p, int n) { char *pend, *next, *p0, *q; char *f[10], *local, *remote, *lib; int nf; Sym *s; USED(file); pend = p + n; p0 = nil; for(; p<pend; p=next) { next = strchr(p, '\n'); if(next == nil) next = ""; else *next++ = '\0'; free(p0); p0 = estrdup(p); // save for error message nf = tokenize(p, f, nelem(f)); if(strcmp(f[0], "cgo_import_dynamic") == 0) { if(nf < 2 || nf > 4) goto err; local = f[1]; remote = local; if(nf > 2) remote = f[2]; lib = ""; if(nf > 3) lib = f[3]; if(debug['d']) { fprint(2, "%s: %s: cannot use dynamic imports with -d flag\n", argv0, file); nerrors++; return; } if(strcmp(local, "_") == 0 && strcmp(remote, "_") == 0) { // allow #pragma dynimport _ _ "foo.so" // to force a link of foo.so. havedynamic = 1; adddynlib(lib); continue; } local = expandpkg(local, pkg); q = strchr(remote, '#'); if(q) *q++ = '\0'; s = lookup(local, 0); if(local != f[1]) free(local); if(s->type == 0 || s->type == SXREF || s->type == SHOSTOBJ) { s->dynimplib = lib; s->extname = remote; s->dynimpvers = q; if(s->type != SHOSTOBJ) s->type = SDYNIMPORT; havedynamic = 1; } continue; } if(strcmp(f[0], "cgo_import_static") == 0) { if(nf != 2) goto err; local = f[1]; s = lookup(local, 0); s->type = SHOSTOBJ; s->size = 0; continue; } if(strcmp(f[0], "cgo_export_static") == 0 || strcmp(f[0], "cgo_export_dynamic") == 0) { // TODO: Remove once we know Windows is okay. if(strcmp(f[0], "cgo_export_static") == 0 && HEADTYPE == Hwindows) continue; if(nf < 2 || nf > 3) goto err; local = f[1]; if(nf > 2) remote = f[2]; else remote = local; local = expandpkg(local, pkg); s = lookup(local, 0); if(flag_shared && s == lookup("main", 0)) continue; // export overrides import, for openbsd/cgo. // see issue 4878. if(s->dynimplib != nil) { s->dynimplib = nil; s->extname = nil; s->dynimpvers = nil; s->type = 0; } if(s->cgoexport == 0) { s->extname = remote; if(ndynexp%32 == 0) dynexp = erealloc(dynexp, (ndynexp+32)*sizeof dynexp[0]); dynexp[ndynexp++] = s; } else if(strcmp(s->extname, remote) != 0) { fprint(2, "%s: conflicting cgo_export directives: %s as %s and %s\n", argv0, s->name, s->extname, remote); nerrors++; return; } if(strcmp(f[0], "cgo_export_static") == 0) s->cgoexport |= CgoExportStatic; else s->cgoexport |= CgoExportDynamic; if(local != f[1]) free(local); continue; } if(strcmp(f[0], "cgo_dynamic_linker") == 0) { if(nf != 2) goto err; if(!debug['I']) { // not overridden by command line if(interpreter != nil && strcmp(interpreter, f[1]) != 0) { fprint(2, "%s: conflict dynlinker: %s and %s\n", argv0, interpreter, f[1]); nerrors++; return; } free(interpreter); interpreter = estrdup(f[1]); } continue; } if(strcmp(f[0], "cgo_ldflag") == 0) { if(nf != 2) goto err; if(nldflag%32 == 0) ldflag = erealloc(ldflag, (nldflag+32)*sizeof ldflag[0]); ldflag[nldflag++] = estrdup(f[1]); continue; } } free(p0); return; err: fprint(2, "%s: %s: invalid dynimport line: %s\n", argv0, file, p0); nerrors++; }