Example #1
0
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++;
}
Example #2
0
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++;
}