Commit 165a9903 authored by Russ Cox's avatar Russ Cox

ffi -> dynld.

move out of export data into its own section

R=r
DELTA=222  (71 added, 99 deleted, 52 changed)
OCL=33801
CL=33808
parent d66d65da
...@@ -119,7 +119,6 @@ struct Sym ...@@ -119,7 +119,6 @@ struct Sym
short frame; short frame;
uchar subtype; uchar subtype;
uchar reachable; uchar reachable;
uchar ffitype;
ushort file; ushort file;
int32 value; int32 value;
int32 sig; int32 sig;
...@@ -132,8 +131,8 @@ struct Sym ...@@ -132,8 +131,8 @@ struct Sym
Prog* text; Prog* text;
Prog* data; Prog* data;
Sym* gotype; Sym* gotype;
char* ffiname; char* dynldname;
char* ffilib; char* dynldlib;
}; };
#define SIGNINTERN (1729*325*1729) #define SIGNINTERN (1729*325*1729)
......
...@@ -232,18 +232,16 @@ outcode(void) ...@@ -232,18 +232,16 @@ outcode(void)
Binit(&b, f, OWRITE); Binit(&b, f, OWRITE);
Bprint(&b, "%s\n", thestring); Bprint(&b, "%s\n", thestring);
if(nffi > 0) { if(ndynld > 0) {
int i; int i;
if(package == nil) { Bprint(&b, "\n");
yyerror("#pragma ffi without #pragma package"); Bprint(&b, "$$ // exports\n\n");
package = "_ffi_"; Bprint(&b, "$$ // local types\n\n");
} Bprint(&b, "$$ // dynld\n", thestring);
Bprint(&b, "\n$$ // ffi\n", thestring); for(i=0; i<ndynld; i++)
Bprint(&b, "package %s\n", package); Bprint(&b, "dynld %s %s %s\n", dynld[i].local, dynld[i].remote, dynld[i].path);
for(i=0; i<nffi; i++) Bprint(&b, "$$\n\n");
Bprint(&b, "//ffi %c %s %s %s\n", ffi[i].type, ffi[i].local, ffi[i].remote, ffi[i].path);
Bprint(&b, "$$\n\n$$\n\n");
} }
Bprint(&b, "!\n"); Bprint(&b, "!\n");
......
...@@ -353,12 +353,12 @@ doelf(void) ...@@ -353,12 +353,12 @@ doelf(void)
dynamic = s; dynamic = s;
/* /*
* relocation entries for extern ffi symbols * relocation entries for dynld symbols
*/ */
nsym = 1; // sym 0 is reserved nsym = 1; // sym 0 is reserved
for(h=0; h<NHASH; h++) { for(h=0; h<NHASH; h++) {
for(s=hash[h]; s!=S; s=s->link) { for(s=hash[h]; s!=S; s=s->link) {
if(!s->reachable || (s->type != SDATA && s->type != SBSS) || s->ffiname == nil) if(!s->reachable || (s->type != SDATA && s->type != SBSS) || s->dynldname == nil)
continue; continue;
d = lookup(".rela", 0); d = lookup(".rela", 0);
...@@ -368,24 +368,17 @@ doelf(void) ...@@ -368,24 +368,17 @@ doelf(void)
nsym++; nsym++;
d = lookup(".dynsym", 0); d = lookup(".dynsym", 0);
adduint32(d, addstring(lookup(".dynstr", 0), s->ffiname)); adduint32(d, addstring(lookup(".dynstr", 0), s->dynldname));
t = STB_GLOBAL << 4; t = STB_GLOBAL << 4;
switch(s->ffitype) { t |= STT_OBJECT; // works for func too, empirically
case 'T':
t |= STT_FUNC;
break;
case 'D':
t |= STT_OBJECT;
break;
}
adduint8(d, t); adduint8(d, t);
adduint8(d, 0); /* reserved */ adduint8(d, 0); /* reserved */
adduint16(d, SHN_UNDEF); /* section where symbol is defined */ adduint16(d, SHN_UNDEF); /* section where symbol is defined */
adduint64(d, 0); /* value */ adduint64(d, 0); /* value */
adduint64(d, 0); /* size of object */ adduint64(d, 0); /* size of object */
if(needlib(s->ffilib)) if(needlib(s->dynldlib))
elfwritedynent(dynamic, DT_NEEDED, addstring(dynstr, s->ffilib)); elfwritedynent(dynamic, DT_NEEDED, addstring(dynstr, s->dynldlib));
} }
} }
......
...@@ -119,7 +119,6 @@ struct Sym ...@@ -119,7 +119,6 @@ struct Sym
uchar subtype; uchar subtype;
uchar dupok; uchar dupok;
uchar reachable; uchar reachable;
uchar ffitype;
vlong value; vlong value;
vlong size; vlong size;
int32 sig; int32 sig;
...@@ -127,8 +126,8 @@ struct Sym ...@@ -127,8 +126,8 @@ struct Sym
Prog* text; Prog* text;
Prog* data; Prog* data;
Sym* gotype; Sym* gotype;
char* ffiname; char* dynldname;
char* ffilib; char* dynldlib;
}; };
struct Optab struct Optab
{ {
......
...@@ -116,7 +116,6 @@ struct Sym ...@@ -116,7 +116,6 @@ struct Sym
uchar subtype; uchar subtype;
uchar dupok; uchar dupok;
uchar reachable; uchar reachable;
uchar ffitype;
ushort file; ushort file;
int32 value; int32 value;
int32 sig; int32 sig;
...@@ -124,9 +123,8 @@ struct Sym ...@@ -124,9 +123,8 @@ struct Sym
Prog* text; Prog* text;
Prog* data; Prog* data;
Sym* gotype; Sym* gotype;
char* ffiname; char* dynldname;
char* ffilib; char* dynldlib;
}; };
struct Optab struct Optab
{ {
......
...@@ -715,7 +715,9 @@ bad: ...@@ -715,7 +715,9 @@ bad:
return; return;
foundend: foundend:
if (start == 0 || end == 0) if (start == 0)
return;
if (end == 0)
goto bad; goto bad;
if (pkgstmt == nil) { if (pkgstmt == nil) {
/* this is the first package */ /* this is the first package */
...@@ -1550,7 +1552,6 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp) ...@@ -1550,7 +1552,6 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp)
// skip white space // skip white space
p = *pp; p = *pp;
again:
while(p < ep && (*p == ' ' || *p == '\t')) while(p < ep && (*p == ' ' || *p == '\t'))
p++; p++;
if(p == ep) if(p == ep)
...@@ -1570,13 +1571,7 @@ again: ...@@ -1570,13 +1571,7 @@ again:
p += 5; p += 5;
else if(strncmp(p, "const ", 6) == 0) else if(strncmp(p, "const ", 6) == 0)
p += 6; p += 6;
else if(strncmp(p, "//", 2) == 0) { else {
p = memchr(p, '\n', ep - p);
if(p == nil)
return 0;
p++;
goto again;
} else {
fprint(2, "ar: confused in pkg data near <<%.20s>>\n", p); fprint(2, "ar: confused in pkg data near <<%.20s>>\n", p);
errors++; errors++;
return -1; return -1;
......
...@@ -49,7 +49,7 @@ typedef struct Hist Hist; ...@@ -49,7 +49,7 @@ typedef struct Hist Hist;
typedef struct Term Term; typedef struct Term Term;
typedef struct Init Init; typedef struct Init Init;
typedef struct Bits Bits; typedef struct Bits Bits;
typedef struct Ffi Ffi; typedef struct Dynld Dynld;
#define NHUNK 50000L #define NHUNK 50000L
#define BUFSIZ 8192 #define BUFSIZ 8192
...@@ -437,17 +437,15 @@ struct Funct ...@@ -437,17 +437,15 @@ struct Funct
Sym* castfr[NTYPE]; Sym* castfr[NTYPE];
}; };
struct Ffi struct Dynld
{ {
char type;
char* local; char* local;
char* remote; char* remote;
char* path; char* path;
}; };
EXTERN Ffi *ffi; EXTERN Dynld *dynld;
EXTERN int nffi; EXTERN int ndynld;
EXTERN char* package;
EXTERN struct EXTERN struct
{ {
...@@ -753,8 +751,7 @@ void pragpack(void); ...@@ -753,8 +751,7 @@ void pragpack(void);
void pragfpround(void); void pragfpround(void);
void pragtextflag(void); void pragtextflag(void);
void pragincomplete(void); void pragincomplete(void);
void pragffi(void); void pragdynld(void);
void pragpackage(void);
/* /*
* calls to machine depend part * calls to machine depend part
......
...@@ -529,15 +529,11 @@ out: ...@@ -529,15 +529,11 @@ out:
} }
void void
pragffi(void) pragdynld(void)
{ {
Sym *local, *remote, *type; Sym *local, *remote;
char *path; char *path;
Ffi *f; Dynld *f;
type = getsym();
if(type == nil)
goto err;
local = getsym(); local = getsym();
if(local == nil) if(local == nil)
...@@ -551,40 +547,18 @@ pragffi(void) ...@@ -551,40 +547,18 @@ pragffi(void)
if(path == nil) if(path == nil)
goto err; goto err;
if(nffi%32 == 0) if(ndynld%32 == 0)
ffi = realloc(ffi, (nffi+32)*sizeof ffi[0]); dynld = realloc(dynld, (ndynld+32)*sizeof dynld[0]);
f = &ffi[nffi++]; f = &dynld[ndynld++];
f->type = type->name[0];
f->local = local->name; f->local = local->name;
f->remote = remote->name; f->remote = remote->name;
f->path = path; f->path = path;
goto out; goto out;
err: err:
yyerror("usage: #pragma ffi typechar local remote \"path\""); yyerror("usage: #pragma dynld local remote \"path\"");
out:
while(getnsc() != '\n')
;
}
void
pragpackage(void)
{
Sym *s;
s = getsym();
if(s == nil)
goto err;
package = s->name;
goto out;
err:
yyerror("malformed #pragma package");
out: out:
while(getnsc() != '\n') while(getnsc() != '\n')
; ;
} }
...@@ -47,14 +47,7 @@ pragvararg(void) ...@@ -47,14 +47,7 @@ pragvararg(void)
} }
void void
pragffi(void) pragdynld(void)
{
while(getnsc() != '\n')
;
}
void
pragpackage(void)
{ {
while(getnsc() != '\n') while(getnsc() != '\n')
; ;
......
...@@ -737,12 +737,8 @@ macprag(void) ...@@ -737,12 +737,8 @@ macprag(void)
pragincomplete(); pragincomplete();
return; return;
} }
if(s && strcmp(s->name, "ffi") == 0) { if(s && strcmp(s->name, "dynld") == 0) {
pragffi(); pragdynld();
return;
}
if(s && strcmp(s->name, "package") == 0) {
pragpackage();
return; return;
} }
while(getnsc() != '\n') while(getnsc() != '\n')
......
...@@ -63,6 +63,7 @@ ilookup(char *name) ...@@ -63,6 +63,7 @@ ilookup(char *name)
} }
static void loadpkgdata(char*, char*, int); static void loadpkgdata(char*, char*, int);
static void loaddynld(char*, char*, int);
static int parsemethod(char**, char*, char**); static int parsemethod(char**, char*, char**);
static int parsepkgdata(char*, char**, char*, char**, char**, char**); static int parsepkgdata(char*, char**, char*, char**, char**, char**);
...@@ -99,19 +100,21 @@ ldpkg(Biobuf *f, int64 len, char *filename) ...@@ -99,19 +100,21 @@ ldpkg(Biobuf *f, int64 len, char *filename)
fprint(2, "%s: cannot find end of exports in %s\n", argv0, filename); fprint(2, "%s: cannot find end of exports in %s\n", argv0, filename);
return; return;
} }
while(*p0 == ' ' || *p0 == '\t' || *p0 == '\n') while(p0 < p1 && (*p0 == ' ' || *p0 == '\t' || *p0 == '\n'))
p0++;
if(strncmp(p0, "package ", 8) != 0) {
fprint(2, "%s: bad package section in %s - %s\n", argv0, filename, p0);
return;
}
p0 += 8;
while(*p0 == ' ' || *p0 == '\t' || *p0 == '\n')
p0++;
while(*p0 != ' ' && *p0 != '\t' && *p0 != '\n')
p0++; p0++;
if(p0 < p1) {
if(strncmp(p0, "package ", 8) != 0) {
fprint(2, "%s: bad package section in %s - %s\n", argv0, filename, p0);
return;
}
p0 += 8;
while(*p0 == ' ' || *p0 == '\t' || *p0 == '\n')
p0++;
while(*p0 != ' ' && *p0 != '\t' && *p0 != '\n')
p0++;
loadpkgdata(filename, p0, p1 - p0); loadpkgdata(filename, p0, p1 - p0);
}
// local types begin where exports end. // local types begin where exports end.
// skip rest of line after $$ we found above // skip rest of line after $$ we found above
...@@ -127,6 +130,24 @@ ldpkg(Biobuf *f, int64 len, char *filename) ...@@ -127,6 +130,24 @@ ldpkg(Biobuf *f, int64 len, char *filename)
} }
loadpkgdata(filename, p0, p1 - p0); loadpkgdata(filename, p0, p1 - p0);
// look for dynld section
p0 = strstr(p1, "\n$$ // dynld");
if(p0 != nil) {
p0 = strchr(p0+1, '\n');
if(p0 == nil) {
fprint(2, "%s: found $$ // dynld but no newline in %s\n", argv0, filename);
return;
}
p1 = strstr(p0, "\n$$");
if(p1 == nil)
p1 = strstr(p0, "\n!\n");
if(p1 == nil) {
fprint(2, "%s: cannot find end of // dynld section in %s\n", argv0, filename);
return;
}
loaddynld(filename, p0 + 1, p1 - p0);
}
} }
/* /*
...@@ -190,7 +211,6 @@ parsepkgdata(char *file, char **pp, char *ep, char **prefixp, char **namep, char ...@@ -190,7 +211,6 @@ parsepkgdata(char *file, char **pp, char *ep, char **prefixp, char **namep, char
char *p, *prefix, *name, *def, *edef, *meth; char *p, *prefix, *name, *def, *edef, *meth;
int n; int n;
again:
// skip white space // skip white space
p = *pp; p = *pp;
while(p < ep && (*p == ' ' || *p == '\t' || *p == '\n')) while(p < ep && (*p == ' ' || *p == '\t' || *p == '\n'))
...@@ -210,45 +230,7 @@ again: ...@@ -210,45 +230,7 @@ again:
p += 5; p += 5;
else if(strncmp(p, "const ", 6) == 0) else if(strncmp(p, "const ", 6) == 0)
p += 6; p += 6;
else if(strncmp(p, "//ffi ", 6) == 0) { else {
Sym *s;
char type, *lib;
p += 6;
if(*p == 0 || *(p+1) != ' ')
goto err;
type = *p;
p += 2;
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;
p = strchr(lib, '\n');
if(p == nil)
goto err;
// successful parse: now can edit the line
*strchr(name, ' ') = 0;
*strchr(def, ' ') = 0;
*strchr(lib, '\n') = 0;
*pp = p+1;
s = lookup(name, 0);
s->ffitype = type;
s->ffilib = lib;
s->ffiname = def;
goto again;
} else {
err:
fprint(2, "%s: confused in pkg data near <<%.40s>>\n", argv0, prefix); fprint(2, "%s: confused in pkg data near <<%.40s>>\n", argv0, prefix);
nerrors++; nerrors++;
return -1; return -1;
...@@ -331,6 +313,54 @@ parsemethod(char **pp, char *ep, char **methp) ...@@ -331,6 +313,54 @@ parsemethod(char **pp, char *ep, char **methp)
return 1; return 1;
} }
static void
loaddynld(char *file, char *p, int n)
{
char *next, *name, *def, *p0, *lib;
Sym *s;
p[n] = '\0';
p0 = p;
for(; *p; p=next) {
next = strchr(p, '\n');
if(next == nil)
next = "";
else
*next++ = '\0';
p0 = p;
if(strncmp(p, "dynld ", 6) != 0)
goto err;
p += 6;
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;
s = lookup(name, 0);
s->dynldlib = lib;
s->dynldname = def;
}
return;
err:
fprint(2, "%s: invalid dynld line: %s\n", argv0, p0);
nerrors++;
}
static void mark(Sym*); static void mark(Sym*);
static int markdepth; static int markdepth;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment