Commit a570eaab authored by Russ Cox's avatar Russ Cox

6l:

	use libbio instead of maintaining own buffer

libbio:
	always use vlong offsets; die if off_t is too small

R=r
DELTA=163  (23 added, 63 deleted, 77 changed)
OCL=17508
CL=17512
parent baac04b5
...@@ -26,14 +26,13 @@ THE SOFTWARE. ...@@ -26,14 +26,13 @@ THE SOFTWARE.
#ifndef _BIO_H_ #ifndef _BIO_H_
#define _BIO_H_ 1 #define _BIO_H_ 1
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
#ifdef AUTOLIB #ifdef AUTOLIB
AUTOLIB(bio) AUTOLIB(bio)
#endif #endif
#include <sys/types.h> /* for off_t */
#include <fcntl.h> /* for O_RDONLY, O_WRONLY */ #include <fcntl.h> /* for O_RDONLY, O_WRONLY */
typedef struct Biobuf Biobuf; typedef struct Biobuf Biobuf;
...@@ -63,7 +62,7 @@ struct Biobuf ...@@ -63,7 +62,7 @@ struct Biobuf
int state; /* r/w/inactive */ int state; /* r/w/inactive */
int fid; /* open file */ int fid; /* open file */
int flag; /* magic if malloc'ed */ int flag; /* magic if malloc'ed */
off_t offset; /* offset of buffer in file */ vlong offset; /* offset of buffer in file */
int bsize; /* size of buffer */ int bsize; /* size of buffer */
unsigned char* bbuf; /* pointer to beginning of buffer */ unsigned char* bbuf; /* pointer to beginning of buffer */
unsigned char* ebuf; /* pointer to end of buffer */ unsigned char* ebuf; /* pointer to end of buffer */
...@@ -96,7 +95,7 @@ long Bgetrune(Biobuf*); ...@@ -96,7 +95,7 @@ long Bgetrune(Biobuf*);
int Binit(Biobuf*, int, int); int Binit(Biobuf*, int, int);
int Binits(Biobuf*, int, int, unsigned char*, int); int Binits(Biobuf*, int, int, unsigned char*, int);
int Blinelen(Biobuf*); int Blinelen(Biobuf*);
off_t Boffset(Biobuf*); vlong Boffset(Biobuf*);
Biobuf* Bopen(char*, int); Biobuf* Bopen(char*, int);
int Bprint(Biobuf*, char*, ...); int Bprint(Biobuf*, char*, ...);
int Bputc(Biobuf*, int); int Bputc(Biobuf*, int);
...@@ -104,7 +103,7 @@ int Bputrune(Biobuf*, long); ...@@ -104,7 +103,7 @@ int Bputrune(Biobuf*, long);
void* Brdline(Biobuf*, int); void* Brdline(Biobuf*, int);
char* Brdstr(Biobuf*, int, int); char* Brdstr(Biobuf*, int, int);
long Bread(Biobuf*, void*, long); long Bread(Biobuf*, void*, long);
off_t Bseek(Biobuf*, off_t, int); vlong Bseek(Biobuf*, vlong, int);
int Bterm(Biobuf*); int Bterm(Biobuf*);
int Bungetc(Biobuf*); int Bungetc(Biobuf*);
int Bungetrune(Biobuf*); int Bungetrune(Biobuf*);
......
...@@ -422,7 +422,7 @@ vlong vaddr(Adr*); ...@@ -422,7 +422,7 @@ vlong vaddr(Adr*);
void wput(ushort); void wput(ushort);
void xdefine(char*, int, vlong); void xdefine(char*, int, vlong);
void xfol(Prog*); void xfol(Prog*);
int zaddr(uchar*, Adr*, Sym*[]); void zaddr(Biobuf*, Adr*, Sym*[]);
void zerosig(char*); void zerosig(char*);
void machseg(char*, vlong, vlong, vlong, vlong, uint32, uint32, uint32, uint32); void machseg(char*, vlong, vlong, vlong, vlong, uint32, uint32, uint32, uint32);
......
...@@ -558,75 +558,69 @@ out: ...@@ -558,75 +558,69 @@ out:
Bterm(f); Bterm(f);
} }
int int32
zaddr(uchar *p, Adr *a, Sym *h[]) Bget4(Biobuf *f)
{ {
int c, t, i; uchar p[4];
if(Bread(f, p, 4) != 4)
return 0;
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
}
void
zaddr(Biobuf *f, Adr *a, Sym *h[])
{
int t;
int32 l; int32 l;
Sym *s; Sym *s;
Auto *u; Auto *u;
t = p[0]; t = Bgetc(f);
c = 1;
if(t & T_INDEX) { if(t & T_INDEX) {
a->index = p[c]; a->index = Bgetc(f);
a->scale = p[c+1]; a->scale = Bgetc(f);
c += 2;
} else { } else {
a->index = D_NONE; a->index = D_NONE;
a->scale = 0; a->scale = 0;
} }
a->offset = 0; a->offset = 0;
if(t & T_OFFSET) { if(t & T_OFFSET) {
/* a->offset = Bget4(f);
* Hack until Charles fixes the compiler.
a->offset = (int32)(p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24));
*/
l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);
a->offset = l;
c += 4;
if(t & T_64) { if(t & T_64) {
l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); a->offset &= 0xFFFFFFFFULL;
a->offset = ((vlong)l<<32) | (a->offset & 0xFFFFFFFFUL); a->offset |= (vlong)Bget4(f) << 32;
c += 4;
} }
} }
a->sym = S; a->sym = S;
if(t & T_SYM) { if(t & T_SYM)
a->sym = h[p[c]]; a->sym = h[Bgetc(f)];
c++;
}
a->type = D_NONE; a->type = D_NONE;
if(t & T_FCONST) { if(t & T_FCONST) {
a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24); a->ieee.l = Bget4(f);
a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24); a->ieee.h = Bget4(f);
c += 8;
a->type = D_FCONST; a->type = D_FCONST;
} else } else
if(t & T_SCONST) { if(t & T_SCONST) {
for(i=0; i<NSNAME; i++) Bread(f, a->scon, NSNAME);
a->scon[i] = p[c+i];
c += NSNAME;
a->type = D_SCONST; a->type = D_SCONST;
} }
if(t & T_TYPE) { if(t & T_TYPE)
a->type = p[c]; a->type = Bgetc(f);
c++;
}
s = a->sym; s = a->sym;
if(s == S) if(s == S)
return c; return;
t = a->type; t = a->type;
if(t != D_AUTO && t != D_PARAM) if(t != D_AUTO && t != D_PARAM)
return c; return;
l = a->offset; l = a->offset;
for(u=curauto; u; u=u->link) { for(u=curauto; u; u=u->link) {
if(u->asym == s) if(u->asym == s)
if(u->type == t) { if(u->type == t) {
if(u->aoffset > l) if(u->aoffset > l)
u->aoffset = l; u->aoffset = l;
return c; return;
} }
} }
...@@ -636,7 +630,6 @@ zaddr(uchar *p, Adr *a, Sym *h[]) ...@@ -636,7 +630,6 @@ zaddr(uchar *p, Adr *a, Sym *h[])
u->asym = s; u->asym = s;
u->aoffset = l; u->aoffset = l;
u->type = t; u->type = t;
return c;
} }
void void
...@@ -791,36 +784,21 @@ nopout(Prog *p) ...@@ -791,36 +784,21 @@ nopout(Prog *p)
p->to.type = D_NONE; p->to.type = D_NONE;
} }
uchar*
readsome(Biobuf *f, uchar *buf, uchar *good, uchar *stop, int max)
{
int n;
n = stop - good;
memmove(buf, good, stop - good);
stop = buf + n;
n = MAXIO - n;
if(n > max)
n = max;
n = Bread(f, stop, n);
if(n <= 0)
return 0;
return stop + n;
}
void void
ldobj(Biobuf *f, int32 c, char *pn) ldobj(Biobuf *f, int32 len, char *pn)
{ {
vlong ipc; vlong ipc;
Prog *p, *t; Prog *p, *t;
uchar *bloc, *bsize, *stop;
int v, o, r, skip, mode; int v, o, r, skip, mode;
Sym *h[NSYM], *s, *di; Sym *h[NSYM], *s, *di;
uint32 sig; uint32 sig;
static int files; static int files;
static char **filen; static char **filen;
char **nfilen; char **nfilen, *line, *name;
int ntext; int ntext, n, c1, c2, c3;
vlong eof;
eof = Boffset(f) + len;
ntext = 0; ntext = 0;
...@@ -835,37 +813,33 @@ ldobj(Biobuf *f, int32 c, char *pn) ...@@ -835,37 +813,33 @@ ldobj(Biobuf *f, int32 c, char *pn)
di = S; di = S;
/* check the header */ /* check the header */
bsize = readsome(f, buf.xbuf, buf.xbuf, buf.xbuf, c); line = Brdline(f, '\n');
if(bsize == 0) if(line == nil) {
goto eof; if(Blinelen(f) > 0) {
bloc = buf.xbuf; diag("%s: malformed object file", pn);
r = bsize - bloc; return;
if(r < 7) }
goto eof; goto eof;
if(memcmp(bloc, thestring, strlen(thestring)) != 0) { }
diag("file not %s\n", thestring); n = Blinelen(f) - 1;
if(n != strlen(thestring) || strncmp(line, thestring, n) != 0) {
if(line)
line[n] = '\0';
diag("file not %s [%s]\n", thestring, line);
return; return;
} }
hloop: /* skip over exports and other info -- ends with \n!\n */
/* skip over exports */ c1 = '\n'; // the last line ended in \n
while(bloc+3 <= bsize) { c2 = Bgetc(f);
if(bloc[0] == '\n' && bloc[1] == '!' && bloc[2] == '\n') { c3 = Bgetc(f);
bloc += 3; while(c1 != '\n' || c2 != '!' || c3 != '\n') {
c -= 3; c1 = c2;
goto newloop; c2 = c3;
} c3 = Bgetc(f);
bloc++; if(c3 == Beof)
c--; goto eof;
} }
bsize = readsome(f, buf.xbuf, bloc, bsize, c);
if(bsize == 0)
goto eof;
bloc = buf.xbuf;
r = bsize - bloc;
if(r < 3)
goto eof;
goto hloop;
newloop: newloop:
memset(h, 0, sizeof(h)); memset(h, 0, sizeof(h));
...@@ -876,55 +850,38 @@ newloop: ...@@ -876,55 +850,38 @@ newloop:
mode = 64; mode = 64;
loop: loop:
if(c <= 0) if(f->state == Bracteof || Boffset(f) >= eof)
goto eof; goto eof;
r = bsize - bloc; o = Bgetc(f);
if(r < 100 && r < c) { /* enough for largest prog */ if(o == Beof)
bsize = readsome(f, buf.xbuf, bloc, bsize, c); goto eof;
if(bsize == 0) o |= Bgetc(f) << 8;
goto eof;
bloc = buf.xbuf;
goto loop;
}
o = bloc[0] | (bloc[1] << 8);
if(o <= AXXX || o >= ALAST) { if(o <= AXXX || o >= ALAST) {
if(o < 0) if(o < 0)
goto eof; goto eof;
diag("%s: opcode out of range %d", pn, o); diag("%s:#%lld: opcode out of range: %#ux", pn, Boffset(f), o);
print(" probably not a .6 file\n"); print(" probably not a .6 file\n");
errorexit(); errorexit();
} }
if(o == ANAME || o == ASIGNAME) { if(o == ANAME || o == ASIGNAME) {
sig = 0; sig = 0;
if(o == ASIGNAME) { if(o == ASIGNAME)
sig = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24); sig = Bget4(f);
bloc += 4; v = Bgetc(f); /* type */
c -= 4; o = Bgetc(f); /* sym */
} r = 0;
stop = memchr(&bloc[4], 0, bsize-&bloc[4]); if(v == D_STATIC)
if(stop == 0){ r = version;
bsize = readsome(f, buf.xbuf, bloc, bsize, c); name = Brdline(f, '\0');
if(bsize == 0) if(name == nil) {
goto eof; if(Blinelen(f) > 0) {
bloc = buf.xbuf;
stop = memchr(&bloc[4], 0, bsize-&bloc[4]);
if(stop == 0){
fprint(2, "%s: name too long\n", pn); fprint(2, "%s: name too long\n", pn);
errorexit(); errorexit();
} }
goto eof;
} }
v = bloc[2]; /* type */ s = lookup(name, r);
o = bloc[3]; /* sym */
bloc += 4;
c -= 4;
r = 0;
if(v == D_STATIC)
r = version;
s = lookup((char*)bloc, r);
c -= &stop[1] - bloc;
bloc = stop + 1;
if(debug['S'] && r == 0) if(debug['S'] && r == 0)
sig = 1729; sig = 1729;
...@@ -959,13 +916,11 @@ loop: ...@@ -959,13 +916,11 @@ loop:
p = mal(sizeof(*p)); p = mal(sizeof(*p));
p->as = o; p->as = o;
p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24); p->line = Bget4(f);
p->back = 2; p->back = 2;
p->mode = mode; p->mode = mode;
r = zaddr(bloc+6, &p->from, h) + 6; zaddr(f, &p->from, h);
r += zaddr(bloc+r, &p->to, h); zaddr(f, &p->to, h);
bloc += r;
c -= r;
if(debug['W']) if(debug['W'])
print("%P\n", p); print("%P\n", p);
...@@ -989,9 +944,9 @@ loop: ...@@ -989,9 +944,9 @@ loop:
curtext->to.autom = curauto; curtext->to.autom = curauto;
curauto = 0; curauto = 0;
curtext = P; curtext = P;
if(c) if(Boffset(f) == eof)
goto newloop; return;
return; goto newloop;
case AGLOBL: case AGLOBL:
s = p->from.sym; s = p->from.sym;
......
...@@ -23,13 +23,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ...@@ -23,13 +23,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
#include "lib9.h" #include <u.h>
#include <libc.h>
#include <bio.h> #include <bio.h>
off_t vlong
Boffset(Biobuf *bp) Boffset(Biobuf *bp)
{ {
off_t n; vlong n;
switch(bp->state) { switch(bp->state) {
default: default:
......
...@@ -23,15 +23,21 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ...@@ -23,15 +23,21 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
#include "lib9.h" #include <u.h>
#include <libc.h>
#include <bio.h> #include <bio.h>
off_t vlong
Bseek(Biobuf *bp, off_t offset, int base) Bseek(Biobuf *bp, vlong offset, int base)
{ {
vlong n, d; vlong n, d;
int bufsz; int bufsz;
if(sizeof(offset) != sizeof(off_t)) {
fprint(2, "Bseek: libbio compiled with %d-byte offset\n", sizeof(off_t));
abort();
}
switch(bp->state) { switch(bp->state) {
default: default:
fprint(2, "Bseek: unknown state %d\n", bp->state); fprint(2, "Bseek: unknown state %d\n", bp->state);
......
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