]> Cypherpunks repositories - gostls13.git/commitdiff
ld: fix implementation of -u
authorRuss Cox <rsc@golang.org>
Wed, 30 Jun 2010 01:59:48 +0000 (18:59 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 30 Jun 2010 01:59:48 +0000 (18:59 -0700)
R=r
CC=golang-dev
https://golang.org/cl/1678046

src/cmd/ld/go.c
src/cmd/ld/lib.c
src/cmd/ld/lib.h

index 2598a528f2f6e67ab8efd662efee30de0b207b11..015f34db21a1fd685712d833e21508c4d6c54062 100644 (file)
@@ -75,7 +75,7 @@ static int ndynexp;
 static Sym **dynexp;
 
 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;
 
@@ -100,7 +100,7 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename)
        // first \n$$ marks beginning of exports - skip rest of line
        p0 = strstr(data, "\n$$");
        if(p0 == nil) {
-               if(debug['u']) {
+               if(debug['u'] && whence != ArchiveObj) {
                        fprint(2, "%s: cannot find export data in %s\n", argv0, filename);
                        errorexit();
                }
@@ -133,20 +133,31 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename)
                name = p0;
                while(p0 < p1 && *p0 != ' ' && *p0 != '\t' && *p0 != '\n')
                        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);
                        errorexit();
                }
                if(p0 < p1) {
-                       *p0++ = '\0';
-                       if(strcmp(pkg, "main") == 0 && strcmp(name, "main") != 0)
-                               fprint(2, "%s: %s: not package main (package %s)\n", argv0, filename, name);
-                       else if(strcmp(pkg, "main") != 0 && strcmp(name, "main") == 0)
-                               fprint(2, "%s: %s: importing %s, found package main", argv0, filename, pkg);
+                       if(*p0 == '\n')
+                               *p0++ = '\0';
+                       else {
+                               *p0++ = '\0';
+                               while(p0 < p1 && *p0++ != '\n')
+                                       ;
+                       }
                }
+               if(strcmp(pkg, "main") == 0 && strcmp(name, "main") != 0)
+                       fprint(2, "%s: %s: not package main (package %s)\n", argv0, filename, name);
+               else if(strcmp(pkg, "main") != 0 && strcmp(name, "main") == 0)
+                       fprint(2, "%s: %s: importing %s, found package main", argv0, filename, pkg);
                loadpkgdata(filename, pkg, p0, p1 - p0);
        }
 
+       // The __.PKGDEF archive summary has no local types.
+       if(whence == Pkgdef)
+               return;
+
        // local types begin where exports end.
        // skip rest of line after $$ we found above
        p0 = p1 + 3;
@@ -245,7 +256,7 @@ expandpkg(char *t0, char *pkg)
        int n;
        char *p;
        char *w, *w0, *t;
-       
+
        n = 0;
        for(p=t0; (p=strstr(p, "\"\".")) != nil; p+=3)
                n++;
@@ -343,7 +354,7 @@ loop:
                memmove(edef, meth, n);
                edef += n;
        }
-       
+
        name = expandpkg(name, pkg);
        def = expandpkg(def, pkg);
 
index c13cd11c797310141fb6f6951503e3dcc0a44c88..1af9f7a41c492deb16cc4c8e35ae4ef8c5aacb12 100644 (file)
@@ -35,6 +35,7 @@
 int iconv(Fmt*);
 
 char   symname[]       = SYMDEF;
+char   pkgname[]       = "__.PKGDEF";
 char*  libdir[16];
 int    nlibdir = 0;
 int    cout = -1;
@@ -156,14 +157,14 @@ addlib(char *src, char *obj)
        }else
                strcpy(pname, name);
        cleanname(pname);
-       
+
        /* runtime.a -> runtime */
        if(strlen(name) > 2 && name[strlen(name)-2] == '.')
                name[strlen(name)-2] = '\0';
 
        if(debug['v'])
                Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname);
-       
+
        addlibpath(src, obj, pname, name);
 }
 
@@ -261,7 +262,7 @@ objfile(char *file, char *pkg)
        char name[100], pname[150];
        struct ar_hdr arhdr;
        char *e, *start, *stop, *x;
-       
+
        pkg = smprint("%i", pkg);
 
        if(file[0] == '-' && file[1] == 'l') {  // TODO: fix this
@@ -286,7 +287,7 @@ objfile(char *file, char *pkg)
                /* load it as a regular file */
                l = Bseek(f, 0L, 2);
                Bseek(f, 0L, 0);
-               ldobj(f, pkg, l, file);
+               ldobj(f, pkg, l, file, FileObj);
                Bterm(f);
                return;
        }
@@ -304,6 +305,25 @@ objfile(char *file, char *pkg)
        esym = SARMAG + SAR_HDR + atolwhex(arhdr.size);
        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
         */
@@ -350,7 +370,7 @@ objfile(char *file, char *pkg)
                                l--;
                        sprint(pname, "%s(%.*s)", file, l, arhdr.name);
                        l = atolwhex(arhdr.size);
-                       ldobj(f, pkg, l, pname);
+                       ldobj(f, pkg, l, pname, ArchiveObj);
                        if(s->type == SXREF) {
                                diag("%s: failed to load: %s", file, s->name);
                                errorexit();
@@ -368,7 +388,7 @@ out:
 }
 
 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 char **filen;
@@ -433,7 +453,7 @@ ldobj(Biobuf *f, char *pkg, int64 len, char *pn)
        import1 = Boffset(f);
 
        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);
 
        ldobj1(f, pkg, eof - Boffset(f), pn);
index 4307d2d41e62814467268d289b0b13f6248c5f54..652d845fb29d607a18201b7b16630d92c56ec134 100644 (file)
@@ -88,8 +88,8 @@ void  libinit(void);
 void   Lflag(char *arg);
 void   usage(void);
 void   ldobj1(Biobuf *f, char*, int64 len, char *pn);
-void   ldobj(Biobuf*, char*, int64, char*);
-void   ldpkg(Biobuf*, char*, int64, char*);
+void   ldobj(Biobuf*, char*, int64, char*, int);
+void   ldpkg(Biobuf*, char*, int64, char*, int);
 void   mark(Sym *s);
 char*  expandpkg(char*, char*);
 void   deadcode(void);
@@ -102,3 +102,10 @@ void       mywhatsys(void);
 extern char*   goroot;
 extern char*   goarch;
 extern char*   goos;
+
+/* whence for ldpkg */
+enum {
+       FileObj = 0,
+       ArchiveObj,
+       Pkgdef
+};