Commit 26dde76c authored by Russ Cox's avatar Russ Cox

gopack: handle long lines in export data

Also, if the header is bad, exit with a non-zero status.

Other calls to Brdline in the tree, by category:

Reading symbol name from object file:
./cmd/5l/obj.c:486: 		name = Brdline(f, '\0');
./cmd/6l/obj.c:535: 		name = Brdline(f, '\0');
./cmd/8l/obj.c:564: 		name = Brdline(f, '\0');
./libmach/sym.c:292: 		cp = Brdline(bp, '\0');

Reading archive header line (fixed, short):
./cmd/gc/lex.c:287: 	if((a = Brdline(b, '\n')) == nil)
./cmd/gc/lex.c:303: 	if((p = Brdline(b, '\n')) == nil)

Reading object file header line (fixed, short):
./cmd/ld/lib.c:421: 	line = Brdline(f, '\n');

Reading undefined symbol list (unused code):
./cmd/ld/lib.c:773: 	while((l = Brdline(b, '\n')) != nil){

Implementing Brdstr:
./libbio/brdstr.c:36: 		p = Brdline(bp, delim);

The symbol names ones will cause a problem loudly if they
fail: they'll error out with symbol name too long.  This means
that you can't define an enormous struct without giving the
type a name and then stick it in an interface, because the
type's symbol name will be too long for the object file.
Since this will be a loud failure instead of a silent one,
I'm willing to wait until it comes up in practice.

R=r
CC=golang-dev
https://golang.org/cl/1982041
parent 14e0df34
...@@ -601,17 +601,21 @@ scanobj(Biobuf *b, Arfile *ap, long size) ...@@ -601,17 +601,21 @@ scanobj(Biobuf *b, Arfile *ap, long size)
if (obj < 0) { /* not an object file */ if (obj < 0) { /* not an object file */
if (!gflag || strcmp(file, pkgdef) != 0) { /* don't clear allobj if it's pkg defs */ if (!gflag || strcmp(file, pkgdef) != 0) { /* don't clear allobj if it's pkg defs */
fprint(2, "gopack: non-object file %s\n", file); fprint(2, "gopack: non-object file %s\n", file);
errors++;
allobj = 0; allobj = 0;
} }
d = dirfstat(Bfildes(b)); d = dirfstat(Bfildes(b));
if (d != nil && d->length == 0) if (d != nil && d->length == 0) {
fprint(2, "gopack: zero length file %s\n", file); fprint(2, "gopack: zero length file %s\n", file);
errors++;
}
free(d); free(d);
Bseek(b, offset, 0); Bseek(b, offset, 0);
return; return;
} }
if (lastobj >= 0 && obj != lastobj) { if (lastobj >= 0 && obj != lastobj) {
fprint(2, "gopack: inconsistent object file %s\n", file); fprint(2, "gopack: inconsistent object file %s\n", file);
errors++;
allobj = 0; allobj = 0;
Bseek(b, offset, 0); Bseek(b, offset, 0);
return; return;
...@@ -619,6 +623,7 @@ scanobj(Biobuf *b, Arfile *ap, long size) ...@@ -619,6 +623,7 @@ scanobj(Biobuf *b, Arfile *ap, long size)
lastobj = obj; lastobj = obj;
if (!readar(b, obj, offset+size, 0)) { if (!readar(b, obj, offset+size, 0)) {
fprint(2, "gopack: invalid symbol reference in file %s\n", file); fprint(2, "gopack: invalid symbol reference in file %s\n", file);
errors++;
allobj = 0; allobj = 0;
Bseek(b, offset, 0); Bseek(b, offset, 0);
return; return;
...@@ -718,8 +723,8 @@ foundstart: ...@@ -718,8 +723,8 @@ foundstart:
first = 1; first = 1;
start = end = 0; start = end = 0;
for (n=0; n<size; n+=Blinelen(b)) { for (n=0; n<size; n+=Blinelen(b)) {
line = Brdline(b, '\n'); line = Brdstr(b, '\n', 0);
if (line == 0) if (line == nil)
goto bad; goto bad;
if (first && strstrn(line, Blinelen(b), "package ")) { if (first && strstrn(line, Blinelen(b), "package ")) {
if (Blinelen(b) > sizeof(pkgbuf)-1) if (Blinelen(b) > sizeof(pkgbuf)-1)
...@@ -742,14 +747,19 @@ foundstart: ...@@ -742,14 +747,19 @@ foundstart:
safe = 0; safe = 0;
start = Boffset(b); // after package statement start = Boffset(b); // after package statement
first = 0; first = 0;
free(line);
continue; continue;
} }
if(line[0] == '$' && line[1] == '$') if(line[0] == '$' && line[1] == '$') {
free(line);
goto foundend; goto foundend;
}
end = Boffset(b); // before closing $$ end = Boffset(b); // before closing $$
free(line);
} }
bad: bad:
fprint(2, "gopack: bad package import section in %s\n", file); fprint(2, "gopack: bad package import section in %s\n", file);
errors++;
return; return;
foundend: foundend:
...@@ -795,6 +805,7 @@ objsym(Sym *s, void *p) ...@@ -795,6 +805,7 @@ objsym(Sym *s, void *p)
if(s->type == 'T' && duplicate(as->name, &ofile)) { if(s->type == 'T' && duplicate(as->name, &ofile)) {
dupfound = 1; dupfound = 1;
fprint(2, "duplicate text symbol: %s and %s: %s\n", as->file, ofile, as->name); fprint(2, "duplicate text symbol: %s and %s: %s\n", as->file, ofile, as->name);
errors++;
free(as->name); free(as->name);
free(as); free(as);
return; return;
......
...@@ -4,4 +4,9 @@ ...@@ -4,4 +4,9 @@
package main package main
// Check that the export information is correct in p.6.
import _ "./p" import _ "./p"
// Check that it's still correct in pp.a (which contains p.6).
import _ "./pp"
// $G $D/bug302.dir/p.go && $G $D/bug302.dir/main.go // $G $D/bug302.dir/p.go && gopack grc pp.a p.$A && $G $D/bug302.dir/main.go
// Copyright 2010 The Go Authors. All rights reserved. // Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
......
...@@ -101,7 +101,7 @@ done | # clean up some stack noise ...@@ -101,7 +101,7 @@ done | # clean up some stack noise
/Segmentation fault/d /Segmentation fault/d
/^qemu: uncaught target signal 11 (Segmentation fault) - exiting/d' > run.out /^qemu: uncaught target signal 11 (Segmentation fault) - exiting/d' > run.out
rm -f $RUNFILE $TMP1FILE $TMP2FILE *.$A $A.out rm -f $RUNFILE $TMP1FILE $TMP2FILE *.$A *.a $A.out
diffmsg="" diffmsg=""
if ! diff golden.out run.out if ! diff golden.out run.out
then then
......
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