mirror of https://github.com/golang/go.git
linker work
* use //ffi comments in package import data
to generate relocation entries and library loads.
* call initffi in rt0.s if present
R=r
DELTA=117 (91 added, 3 deleted, 23 changed)
OCL=33739
CL=33750
This commit is contained in:
parent
ef3e6810b8
commit
1f177cd8b2
|
|
@ -119,6 +119,7 @@ struct Sym
|
|||
short frame;
|
||||
uchar subtype;
|
||||
uchar reachable;
|
||||
uchar ffitype;
|
||||
ushort file;
|
||||
int32 value;
|
||||
int32 sig;
|
||||
|
|
@ -131,6 +132,8 @@ struct Sym
|
|||
Prog* text;
|
||||
Prog* data;
|
||||
Sym* gotype;
|
||||
char* ffiname;
|
||||
char* ffilib;
|
||||
};
|
||||
|
||||
#define SIGNINTERN (1729*325*1729)
|
||||
|
|
|
|||
|
|
@ -258,10 +258,27 @@ enum {
|
|||
|
||||
vlong elfstr[NElfStr];
|
||||
|
||||
static int
|
||||
needlib(char *name)
|
||||
{
|
||||
char *p;
|
||||
Sym *s;
|
||||
|
||||
/* reuse hash code in symbol table */
|
||||
p = smprint(".elfload.%s", name);
|
||||
s = lookup(p, 0);
|
||||
if(s->type == 0) {
|
||||
s->type = 100; // avoid SDATA, etc.
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
doelf(void)
|
||||
{
|
||||
Sym *s, *shstrtab;
|
||||
Sym *s, *shstrtab, *dynamic, *dynstr, *d;
|
||||
int h, nsym, t;
|
||||
|
||||
if(HEADTYPE != 7)
|
||||
return;
|
||||
|
|
@ -279,8 +296,6 @@ doelf(void)
|
|||
elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab");
|
||||
|
||||
if(!debug['d']) { /* -d suppresses dynamic loader format */
|
||||
Sym *dynamic, *dynstr;
|
||||
|
||||
elfstr[ElfStrInterp] = addstring(shstrtab, ".interp");
|
||||
elfstr[ElfStrHash] = addstring(shstrtab, ".hash");
|
||||
elfstr[ElfStrGot] = addstring(shstrtab, ".got");
|
||||
|
|
@ -338,28 +353,45 @@ doelf(void)
|
|||
dynamic = s;
|
||||
|
||||
/*
|
||||
* relocation demo - overwrite go func
|
||||
* var main.extern_c_fib with fib symbol from fib.so
|
||||
* relocation entries for extern ffi symbols
|
||||
*/
|
||||
Sym *fib;
|
||||
fib = lookup("main·extern_c_fib", 0);
|
||||
if(fib->type == SDATA || fib->type == SBSS) {
|
||||
s = lookup(".rela", 0);
|
||||
addaddr(s, fib);
|
||||
adduint64(s, ELF64_R_INFO(1, R_X86_64_64)); // 1 = first symbol in dynsym
|
||||
adduint64(s, 0);
|
||||
nsym = 1; // sym 0 is reserved
|
||||
for(h=0; h<NHASH; h++) {
|
||||
for(s=hash[h]; s!=S; s=s->link) {
|
||||
if(!s->reachable || (s->type != SDATA && s->type != SBSS) || s->ffiname == nil)
|
||||
continue;
|
||||
|
||||
s = lookup(".dynsym", 0);
|
||||
adduint32(s, addstring(lookup(".dynstr", 0), "fib"));
|
||||
adduint8(s, (STB_GLOBAL<<4) | STT_FUNC);
|
||||
adduint8(s, 0); /* reserved */
|
||||
adduint16(s, SHN_UNDEF); /* section where symbol is defined */
|
||||
adduint64(s, 0); /* value */
|
||||
adduint64(s, 0); /* size of object */
|
||||
d = lookup(".rela", 0);
|
||||
addaddr(d, s);
|
||||
adduint64(d, ELF64_R_INFO(nsym, R_X86_64_64));
|
||||
adduint64(d, 0);
|
||||
nsym++;
|
||||
|
||||
elfwritedynent(dynamic, DT_NEEDED, addstring(dynstr, "fib.so"));
|
||||
d = lookup(".dynsym", 0);
|
||||
adduint32(d, addstring(lookup(".dynstr", 0), s->ffiname));
|
||||
t = STB_GLOBAL << 4;
|
||||
switch(s->ffitype) {
|
||||
case 'T':
|
||||
t |= STT_FUNC;
|
||||
break;
|
||||
case 'D':
|
||||
t |= STT_OBJECT;
|
||||
break;
|
||||
}
|
||||
adduint8(d, t);
|
||||
adduint8(d, 0); /* reserved */
|
||||
adduint16(d, SHN_UNDEF); /* section where symbol is defined */
|
||||
adduint64(d, 0); /* value */
|
||||
adduint64(d, 0); /* size of object */
|
||||
|
||||
if(needlib(s->ffilib))
|
||||
elfwritedynent(dynamic, DT_NEEDED, addstring(dynstr, s->ffilib));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* .dynamic table
|
||||
*/
|
||||
s = dynamic;
|
||||
elfwritedynentsym(s, DT_HASH, lookup(".hash", 0));
|
||||
elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0));
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ struct Sym
|
|||
uchar subtype;
|
||||
uchar dupok;
|
||||
uchar reachable;
|
||||
uchar ffitype;
|
||||
vlong value;
|
||||
vlong size;
|
||||
int32 sig;
|
||||
|
|
@ -126,6 +127,8 @@ struct Sym
|
|||
Prog* text;
|
||||
Prog* data;
|
||||
Sym* gotype;
|
||||
char* ffiname;
|
||||
char* ffilib;
|
||||
};
|
||||
struct Optab
|
||||
{
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ struct Sym
|
|||
uchar subtype;
|
||||
uchar dupok;
|
||||
uchar reachable;
|
||||
uchar ffitype;
|
||||
ushort file;
|
||||
int32 value;
|
||||
int32 sig;
|
||||
|
|
@ -123,6 +124,9 @@ struct Sym
|
|||
Prog* text;
|
||||
Prog* data;
|
||||
Sym* gotype;
|
||||
char* ffiname;
|
||||
char* ffilib;
|
||||
|
||||
};
|
||||
struct Optab
|
||||
{
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ parsepkgdata(char *file, char **pp, char *ep, char **prefixp, char **namep, char
|
|||
char *p, *prefix, *name, *def, *edef, *meth;
|
||||
int n;
|
||||
|
||||
again:
|
||||
// skip white space
|
||||
p = *pp;
|
||||
while(p < ep && (*p == ' ' || *p == '\t' || *p == '\n'))
|
||||
|
|
@ -211,8 +212,46 @@ parsepkgdata(char *file, char **pp, char *ep, char **prefixp, char **namep, char
|
|||
p += 5;
|
||||
else if(strncmp(p, "const ", 6) == 0)
|
||||
p += 6;
|
||||
else{
|
||||
fprint(2, "%s: confused in pkg data near <<%.20s>>\n", argv0, p);
|
||||
else if(strncmp(p, "//ffi ", 6) == 0) {
|
||||
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 <<%.20s>>\n", argv0, prefix);
|
||||
nerrors++;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,5 +5,12 @@
|
|||
// Darwin and Linux use the same linkage to main
|
||||
|
||||
TEXT _rt0_amd64_linux(SB),7,$-8
|
||||
MOVQ _initffi(SB), AX
|
||||
TESTQ AX, AX
|
||||
JZ 2(PC)
|
||||
CALL AX
|
||||
|
||||
MOVQ $_rt0_amd64(SB), AX
|
||||
JMP AX
|
||||
|
||||
GLOBL _initffi(SB), $8
|
||||
|
|
|
|||
Loading…
Reference in New Issue