mirror of
https://github.com/golang/go
synced 2024-11-20 10:24:40 -07:00
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
This commit is contained in:
parent
d66d65da96
commit
165a99038f
@ -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
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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:
|
|||||||
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)
|
|||||||
|
|
||||||
// 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:
|
|||||||
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;
|
|||||||
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
|
|||||||
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);
|
|||||||
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:
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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:
|
out:
|
||||||
while(getnsc() != '\n')
|
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:
|
|
||||||
while(getnsc() != '\n')
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -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)
|
|||||||
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')
|
||||||
|
132
src/cmd/ld/go.c
132
src/cmd/ld/go.c
@ -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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
|||||||
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:
|
|||||||
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)
|
|||||||
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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user