1
0
mirror of https://github.com/golang/go synced 2024-11-25 08:57:58 -07:00

ld: fix implementation of -u

R=r
CC=golang-dev
https://golang.org/cl/1678046
This commit is contained in:
Russ Cox 2010-06-29 18:59:48 -07:00
parent 0046d51e06
commit 829896168c
3 changed files with 57 additions and 19 deletions

View File

@ -75,7 +75,7 @@ static int ndynexp;
static Sym **dynexp; static Sym **dynexp;
void void
ldpkg(Biobuf *f, char *pkg, int64 len, char *filename) ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence)
{ {
char *data, *p0, *p1, *name; char *data, *p0, *p1, *name;
@ -100,7 +100,7 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename)
// first \n$$ marks beginning of exports - skip rest of line // first \n$$ marks beginning of exports - skip rest of line
p0 = strstr(data, "\n$$"); p0 = strstr(data, "\n$$");
if(p0 == nil) { if(p0 == nil) {
if(debug['u']) { if(debug['u'] && whence != ArchiveObj) {
fprint(2, "%s: cannot find export data in %s\n", argv0, filename); fprint(2, "%s: cannot find export data in %s\n", argv0, filename);
errorexit(); errorexit();
} }
@ -133,20 +133,31 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename)
name = p0; name = p0;
while(p0 < p1 && *p0 != ' ' && *p0 != '\t' && *p0 != '\n') while(p0 < p1 && *p0 != ' ' && *p0 != '\t' && *p0 != '\n')
p0++; p0++;
if(debug['u'] && memcmp(p0, " safe\n", 6) != 0) { if(debug['u'] && whence != ArchiveObj &&
(p0+6 > p1 || memcmp(p0, " safe\n", 6) != 0)) {
fprint(2, "%s: load of unsafe package %s\n", argv0, filename); fprint(2, "%s: load of unsafe package %s\n", argv0, filename);
errorexit(); errorexit();
} }
if(p0 < p1) { if(p0 < p1) {
if(*p0 == '\n')
*p0++ = '\0'; *p0++ = '\0';
else {
*p0++ = '\0';
while(p0 < p1 && *p0++ != '\n')
;
}
}
if(strcmp(pkg, "main") == 0 && strcmp(name, "main") != 0) if(strcmp(pkg, "main") == 0 && strcmp(name, "main") != 0)
fprint(2, "%s: %s: not package main (package %s)\n", argv0, filename, name); fprint(2, "%s: %s: not package main (package %s)\n", argv0, filename, name);
else if(strcmp(pkg, "main") != 0 && strcmp(name, "main") == 0) else if(strcmp(pkg, "main") != 0 && strcmp(name, "main") == 0)
fprint(2, "%s: %s: importing %s, found package main", argv0, filename, pkg); fprint(2, "%s: %s: importing %s, found package main", argv0, filename, pkg);
}
loadpkgdata(filename, pkg, p0, p1 - p0); loadpkgdata(filename, pkg, p0, p1 - p0);
} }
// The __.PKGDEF archive summary has no local types.
if(whence == Pkgdef)
return;
// 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
p0 = p1 + 3; p0 = p1 + 3;

View File

@ -35,6 +35,7 @@
int iconv(Fmt*); int iconv(Fmt*);
char symname[] = SYMDEF; char symname[] = SYMDEF;
char pkgname[] = "__.PKGDEF";
char* libdir[16]; char* libdir[16];
int nlibdir = 0; int nlibdir = 0;
int cout = -1; int cout = -1;
@ -286,7 +287,7 @@ objfile(char *file, char *pkg)
/* load it as a regular file */ /* load it as a regular file */
l = Bseek(f, 0L, 2); l = Bseek(f, 0L, 2);
Bseek(f, 0L, 0); Bseek(f, 0L, 0);
ldobj(f, pkg, l, file); ldobj(f, pkg, l, file, FileObj);
Bterm(f); Bterm(f);
return; return;
} }
@ -304,6 +305,25 @@ objfile(char *file, char *pkg)
esym = SARMAG + SAR_HDR + atolwhex(arhdr.size); esym = SARMAG + SAR_HDR + atolwhex(arhdr.size);
off = SARMAG + SAR_HDR; off = SARMAG + SAR_HDR;
if(debug['u']) {
struct ar_hdr pkghdr;
int n;
// Read next ar header to check for package safe bit.
Bseek(f, esym+(esym&1), 0);
l = Bread(f, &pkghdr, SAR_HDR);
if(l != SAR_HDR) {
diag("%s: short read on second archive header", file);
goto out;
}
if(strncmp(pkghdr.name, pkgname, strlen(pkgname))) {
diag("%s: second entry not package header", file);
goto out;
}
n = atolwhex(pkghdr.size);
ldpkg(f, pkg, n, file, Pkgdef);
}
/* /*
* just bang the whole symbol file into memory * just bang the whole symbol file into memory
*/ */
@ -350,7 +370,7 @@ objfile(char *file, char *pkg)
l--; l--;
sprint(pname, "%s(%.*s)", file, l, arhdr.name); sprint(pname, "%s(%.*s)", file, l, arhdr.name);
l = atolwhex(arhdr.size); l = atolwhex(arhdr.size);
ldobj(f, pkg, l, pname); ldobj(f, pkg, l, pname, ArchiveObj);
if(s->type == SXREF) { if(s->type == SXREF) {
diag("%s: failed to load: %s", file, s->name); diag("%s: failed to load: %s", file, s->name);
errorexit(); errorexit();
@ -368,7 +388,7 @@ out:
} }
void void
ldobj(Biobuf *f, char *pkg, int64 len, char *pn) ldobj(Biobuf *f, char *pkg, int64 len, char *pn, int whence)
{ {
static int files; static int files;
static char **filen; static char **filen;
@ -433,7 +453,7 @@ ldobj(Biobuf *f, char *pkg, int64 len, char *pn)
import1 = Boffset(f); import1 = Boffset(f);
Bseek(f, import0, 0); Bseek(f, import0, 0);
ldpkg(f, pkg, import1 - import0 - 2, pn); // -2 for !\n ldpkg(f, pkg, import1 - import0 - 2, pn, whence); // -2 for !\n
Bseek(f, import1, 0); Bseek(f, import1, 0);
ldobj1(f, pkg, eof - Boffset(f), pn); ldobj1(f, pkg, eof - Boffset(f), pn);

View File

@ -88,8 +88,8 @@ void libinit(void);
void Lflag(char *arg); void Lflag(char *arg);
void usage(void); void usage(void);
void ldobj1(Biobuf *f, char*, int64 len, char *pn); void ldobj1(Biobuf *f, char*, int64 len, char *pn);
void ldobj(Biobuf*, char*, int64, char*); void ldobj(Biobuf*, char*, int64, char*, int);
void ldpkg(Biobuf*, char*, int64, char*); void ldpkg(Biobuf*, char*, int64, char*, int);
void mark(Sym *s); void mark(Sym *s);
char* expandpkg(char*, char*); char* expandpkg(char*, char*);
void deadcode(void); void deadcode(void);
@ -102,3 +102,10 @@ void mywhatsys(void);
extern char* goroot; extern char* goroot;
extern char* goarch; extern char* goarch;
extern char* goos; extern char* goos;
/* whence for ldpkg */
enum {
FileObj = 0,
ArchiveObj,
Pkgdef
};