Commit caa56474 authored by Russ Cox's avatar Russ Cox

ld: allow seek within write buffer

Reduces number of write+seek's from 88516 to 2080
when linking godoc with 6l.

Thanks to Alex Brainman for pointing out the
many small writes.

R=golang-dev, r, alex.brainman, robert.hencke
CC=golang-dev
https://golang.org/cl/4743043
parent 870fdd76
...@@ -307,12 +307,12 @@ asmb(void) ...@@ -307,12 +307,12 @@ asmb(void)
Bflush(&bso); Bflush(&bso);
sect = segtext.sect; sect = segtext.sect;
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
codeblk(sect->vaddr, sect->len); codeblk(sect->vaddr, sect->len);
/* output read-only data in text segment (rodata, gosymtab and pclntab) */ /* output read-only data in text segment (rodata, gosymtab and pclntab) */
for(sect = sect->next; sect != nil; sect = sect->next) { for(sect = sect->next; sect != nil; sect = sect->next) {
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
datblk(sect->vaddr, sect->len); datblk(sect->vaddr, sect->len);
} }
...@@ -320,12 +320,12 @@ asmb(void) ...@@ -320,12 +320,12 @@ asmb(void)
Bprint(&bso, "%5.2f datblk\n", cputime()); Bprint(&bso, "%5.2f datblk\n", cputime());
Bflush(&bso); Bflush(&bso);
seek(cout, segdata.fileoff, 0); cseek(segdata.fileoff);
datblk(segdata.vaddr, segdata.filelen); datblk(segdata.vaddr, segdata.filelen);
/* output read-only data in text segment */ /* output read-only data in text segment */
sect = segtext.sect->next; sect = segtext.sect->next;
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
datblk(sect->vaddr, sect->len); datblk(sect->vaddr, sect->len);
if(iself) { if(iself) {
...@@ -369,13 +369,13 @@ asmb(void) ...@@ -369,13 +369,13 @@ asmb(void)
symo = rnd(symo, INITRND); symo = rnd(symo, INITRND);
break; break;
} }
seek(cout, symo, 0); cseek(symo);
if(iself) { if(iself) {
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f elfsym\n", cputime()); Bprint(&bso, "%5.2f elfsym\n", cputime());
asmelfsym(); asmelfsym();
cflush(); cflush();
ewrite(cout, elfstrdat, elfstrsize); cwrite(elfstrdat, elfstrsize);
// if(debug['v']) // if(debug['v'])
// Bprint(&bso, "%5.2f dwarf\n", cputime()); // Bprint(&bso, "%5.2f dwarf\n", cputime());
...@@ -389,7 +389,7 @@ asmb(void) ...@@ -389,7 +389,7 @@ asmb(void)
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f header\n", cputime()); Bprint(&bso, "%5.2f header\n", cputime());
Bflush(&bso); Bflush(&bso);
seek(cout, 0L, 0); cseek(0L);
switch(HEADTYPE) { switch(HEADTYPE) {
case Hnoheader: /* no header */ case Hnoheader: /* no header */
break; break;
...@@ -628,7 +628,7 @@ asmb(void) ...@@ -628,7 +628,7 @@ asmb(void)
pph->memsz = pph->filesz; pph->memsz = pph->filesz;
} }
seek(cout, 0, 0); cseek(0);
a = 0; a = 0;
a += elfwritehdr(); a += elfwritehdr();
a += elfwritephdrs(); a += elfwritephdrs();
...@@ -649,16 +649,6 @@ asmb(void) ...@@ -649,16 +649,6 @@ asmb(void)
} }
} }
void
cput(int c)
{
cbp[0] = c;
cbp++;
cbc--;
if(cbc <= 0)
cflush();
}
/* /*
void void
cput(int32 c) cput(int32 c)
...@@ -708,19 +698,6 @@ lput(int32 l) ...@@ -708,19 +698,6 @@ lput(int32 l)
cflush(); cflush();
} }
void
cflush(void)
{
int n;
/* no bug if cbc < 0 since obuf(cbuf) followed by ibuf in buf! */
n = sizeof(buf.cbuf) - cbc;
if(n)
ewrite(cout, buf.cbuf, n);
cbp = buf.cbuf;
cbc = sizeof(buf.cbuf);
}
void void
nopstat(char *f, Count *c) nopstat(char *f, Count *c)
{ {
......
...@@ -264,19 +264,6 @@ enum ...@@ -264,19 +264,6 @@ enum
MINLC = 4, MINLC = 4,
}; };
EXTERN union
{
struct
{
uchar obuf[MAXIO]; /* output buffer */
uchar ibuf[MAXIO]; /* input buffer */
} u;
char dbuf[1];
} buf;
#define cbuf u.obuf
#define xbuf u.ibuf
#ifndef COFFCVT #ifndef COFFCVT
EXTERN int32 HEADR; /* length of header */ EXTERN int32 HEADR; /* length of header */
...@@ -286,10 +273,6 @@ EXTERN int32 INITRND; /* data round above text location */ ...@@ -286,10 +273,6 @@ EXTERN int32 INITRND; /* data round above text location */
EXTERN int32 INITTEXT; /* text location */ EXTERN int32 INITTEXT; /* text location */
EXTERN char* INITENTRY; /* entry point */ EXTERN char* INITENTRY; /* entry point */
EXTERN int32 autosize; EXTERN int32 autosize;
EXTERN Biobuf bso;
EXTERN int cbc;
EXTERN uchar* cbp;
EXTERN int cout;
EXTERN Auto* curauto; EXTERN Auto* curauto;
EXTERN Auto* curhist; EXTERN Auto* curhist;
EXTERN Prog* curp; EXTERN Prog* curp;
......
...@@ -84,7 +84,6 @@ main(int argc, char *argv[]) ...@@ -84,7 +84,6 @@ main(int argc, char *argv[])
char *p; char *p;
Binit(&bso, 1, OWRITE); Binit(&bso, 1, OWRITE);
cout = -1;
listinit(); listinit();
nerrors = 0; nerrors = 0;
outfile = "5.out"; outfile = "5.out";
......
...@@ -712,12 +712,12 @@ asmb(void) ...@@ -712,12 +712,12 @@ asmb(void)
Bflush(&bso); Bflush(&bso);
sect = segtext.sect; sect = segtext.sect;
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
codeblk(sect->vaddr, sect->len); codeblk(sect->vaddr, sect->len);
/* output read-only data in text segment (rodata, gosymtab and pclntab) */ /* output read-only data in text segment (rodata, gosymtab and pclntab) */
for(sect = sect->next; sect != nil; sect = sect->next) { for(sect = sect->next; sect != nil; sect = sect->next) {
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
datblk(sect->vaddr, sect->len); datblk(sect->vaddr, sect->len);
} }
...@@ -725,7 +725,7 @@ asmb(void) ...@@ -725,7 +725,7 @@ asmb(void)
Bprint(&bso, "%5.2f datblk\n", cputime()); Bprint(&bso, "%5.2f datblk\n", cputime());
Bflush(&bso); Bflush(&bso);
seek(cout, segdata.fileoff, 0); cseek(segdata.fileoff);
datblk(segdata.vaddr, segdata.filelen); datblk(segdata.vaddr, segdata.filelen);
machlink = 0; machlink = 0;
...@@ -785,14 +785,14 @@ asmb(void) ...@@ -785,14 +785,14 @@ asmb(void)
symo = rnd(symo, PEFILEALIGN); symo = rnd(symo, PEFILEALIGN);
break; break;
} }
seek(cout, symo, 0); cseek(symo);
switch(HEADTYPE) { switch(HEADTYPE) {
default: default:
if(iself) { if(iself) {
seek(cout, symo, 0); cseek(symo);
asmelfsym(); asmelfsym();
cflush(); cflush();
ewrite(cout, elfstrdat, elfstrsize); cwrite(elfstrdat, elfstrsize);
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f dwarf\n", cputime()); Bprint(&bso, "%5.2f dwarf\n", cputime());
...@@ -813,7 +813,7 @@ asmb(void) ...@@ -813,7 +813,7 @@ asmb(void)
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f headr\n", cputime()); Bprint(&bso, "%5.2f headr\n", cputime());
Bflush(&bso); Bflush(&bso);
seek(cout, 0L, 0); cseek(0L);
switch(HEADTYPE) { switch(HEADTYPE) {
default: default:
case Hplan9x32: /* plan9 */ case Hplan9x32: /* plan9 */
...@@ -1063,7 +1063,7 @@ asmb(void) ...@@ -1063,7 +1063,7 @@ asmb(void)
pph->filesz = eh->phnum * eh->phentsize; pph->filesz = eh->phnum * eh->phentsize;
pph->memsz = pph->filesz; pph->memsz = pph->filesz;
seek(cout, 0, 0); cseek(0);
a = 0; a = 0;
a += elfwritehdr(); a += elfwritehdr();
a += elfwritephdrs(); a += elfwritephdrs();
...@@ -1079,25 +1079,6 @@ asmb(void) ...@@ -1079,25 +1079,6 @@ asmb(void)
cflush(); cflush();
} }
void
cflush(void)
{
int n;
n = sizeof(buf.cbuf) - cbc;
if(n)
ewrite(cout, buf.cbuf, n);
cbp = buf.cbuf;
cbc = sizeof(buf.cbuf);
}
/* Current position in file */
vlong
cpos(void)
{
return seek(cout, 0, 1) + sizeof(buf.cbuf) - cbc;
}
vlong vlong
rnd(vlong v, vlong r) rnd(vlong v, vlong r)
{ {
......
...@@ -46,10 +46,6 @@ enum ...@@ -46,10 +46,6 @@ enum
#define P ((Prog*)0) #define P ((Prog*)0)
#define S ((Sym*)0) #define S ((Sym*)0)
#define TNAME (cursym?cursym->name:noname) #define TNAME (cursym?cursym->name:noname)
#define cput(c)\
{ *cbp++ = c;\
if(--cbc <= 0)\
cflush(); }
typedef struct Adr Adr; typedef struct Adr Adr;
typedef struct Prog Prog; typedef struct Prog Prog;
...@@ -286,19 +282,6 @@ enum ...@@ -286,19 +282,6 @@ enum
Maxand = 10, /* in -a output width of the byte codes */ Maxand = 10, /* in -a output width of the byte codes */
}; };
EXTERN union
{
struct
{
char obuf[MAXIO]; /* output buffer */
uchar ibuf[MAXIO]; /* input buffer */
} u;
char dbuf[1];
} buf;
#define cbuf u.obuf
#define xbuf u.ibuf
#pragma varargck type "A" uint #pragma varargck type "A" uint
#pragma varargck type "D" Adr* #pragma varargck type "D" Adr*
#pragma varargck type "I" uchar* #pragma varargck type "I" uchar*
...@@ -313,9 +296,6 @@ EXTERN int32 INITRND; ...@@ -313,9 +296,6 @@ EXTERN int32 INITRND;
EXTERN vlong INITTEXT; EXTERN vlong INITTEXT;
EXTERN vlong INITDAT; EXTERN vlong INITDAT;
EXTERN char* INITENTRY; /* entry point */ EXTERN char* INITENTRY; /* entry point */
EXTERN Biobuf bso;
EXTERN int cbc;
EXTERN char* cbp;
EXTERN char* pcstr; EXTERN char* pcstr;
EXTERN Auto* curauto; EXTERN Auto* curauto;
EXTERN Auto* curhist; EXTERN Auto* curhist;
...@@ -376,9 +356,7 @@ vlong atolwhex(char*); ...@@ -376,9 +356,7 @@ vlong atolwhex(char*);
Prog* brchain(Prog*); Prog* brchain(Prog*);
Prog* brloop(Prog*); Prog* brloop(Prog*);
void buildop(void); void buildop(void);
void cflush(void);
Prog* copyp(Prog*); Prog* copyp(Prog*);
vlong cpos(void);
double cputime(void); double cputime(void);
void datblk(int32, int32); void datblk(int32, int32);
void deadcode(void); void deadcode(void);
......
...@@ -80,7 +80,6 @@ main(int argc, char *argv[]) ...@@ -80,7 +80,6 @@ main(int argc, char *argv[])
int c; int c;
Binit(&bso, 1, OWRITE); Binit(&bso, 1, OWRITE);
cout = -1;
listinit(); listinit();
memset(debug, 0, sizeof(debug)); memset(debug, 0, sizeof(debug));
nerrors = 0; nerrors = 0;
......
...@@ -673,12 +673,12 @@ asmb(void) ...@@ -673,12 +673,12 @@ asmb(void)
Bflush(&bso); Bflush(&bso);
sect = segtext.sect; sect = segtext.sect;
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
codeblk(sect->vaddr, sect->len); codeblk(sect->vaddr, sect->len);
/* output read-only data in text segment (rodata, gosymtab and pclntab) */ /* output read-only data in text segment (rodata, gosymtab and pclntab) */
for(sect = sect->next; sect != nil; sect = sect->next) { for(sect = sect->next; sect != nil; sect = sect->next) {
seek(cout, sect->vaddr - segtext.vaddr + segtext.fileoff, 0); cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
datblk(sect->vaddr, sect->len); datblk(sect->vaddr, sect->len);
} }
...@@ -686,7 +686,7 @@ asmb(void) ...@@ -686,7 +686,7 @@ asmb(void)
Bprint(&bso, "%5.2f datblk\n", cputime()); Bprint(&bso, "%5.2f datblk\n", cputime());
Bflush(&bso); Bflush(&bso);
seek(cout, segdata.fileoff, 0); cseek(segdata.fileoff);
datblk(segdata.vaddr, segdata.filelen); datblk(segdata.vaddr, segdata.filelen);
machlink = 0; machlink = 0;
...@@ -743,7 +743,7 @@ asmb(void) ...@@ -743,7 +743,7 @@ asmb(void)
symo = rnd(symo, PEFILEALIGN); symo = rnd(symo, PEFILEALIGN);
break; break;
} }
seek(cout, symo, 0); cseek(symo);
switch(HEADTYPE) { switch(HEADTYPE) {
default: default:
if(iself) { if(iself) {
...@@ -751,7 +751,7 @@ asmb(void) ...@@ -751,7 +751,7 @@ asmb(void)
Bprint(&bso, "%5.2f elfsym\n", cputime()); Bprint(&bso, "%5.2f elfsym\n", cputime());
asmelfsym(); asmelfsym();
cflush(); cflush();
ewrite(cout, elfstrdat, elfstrsize); cwrite(elfstrdat, elfstrsize);
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f dwarf\n", cputime()); Bprint(&bso, "%5.2f dwarf\n", cputime());
...@@ -782,7 +782,7 @@ asmb(void) ...@@ -782,7 +782,7 @@ asmb(void)
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f headr\n", cputime()); Bprint(&bso, "%5.2f headr\n", cputime());
Bflush(&bso); Bflush(&bso);
seek(cout, 0L, 0); cseek(0L);
switch(HEADTYPE) { switch(HEADTYPE) {
default: default:
if(iself) if(iself)
...@@ -1138,7 +1138,7 @@ asmb(void) ...@@ -1138,7 +1138,7 @@ asmb(void)
pph->memsz = pph->filesz; pph->memsz = pph->filesz;
} }
seek(cout, 0, 0); cseek(0);
a = 0; a = 0;
a += elfwritehdr(); a += elfwritehdr();
a += elfwritephdrs(); a += elfwritephdrs();
...@@ -1166,25 +1166,6 @@ s8put(char *n) ...@@ -1166,25 +1166,6 @@ s8put(char *n)
cput(name[i]); cput(name[i]);
} }
void
cflush(void)
{
int n;
n = sizeof(buf.cbuf) - cbc;
if(n)
ewrite(cout, buf.cbuf, n);
cbp = buf.cbuf;
cbc = sizeof(buf.cbuf);
}
/* Current position in file */
vlong
cpos(void)
{
return seek(cout, 0, 1) + sizeof(buf.cbuf) - cbc;
}
int32 int32
rnd(int32 v, int32 r) rnd(int32 v, int32 r)
{ {
......
...@@ -247,19 +247,6 @@ enum ...@@ -247,19 +247,6 @@ enum
Pb = 0xfe, /* byte operands */ Pb = 0xfe, /* byte operands */
}; };
EXTERN union
{
struct
{
char obuf[MAXIO]; /* output buffer */
uchar ibuf[MAXIO]; /* input buffer */
} u;
char dbuf[1];
} buf;
#define cbuf u.obuf
#define xbuf u.ibuf
#pragma varargck type "A" int #pragma varargck type "A" int
#pragma varargck type "D" Adr* #pragma varargck type "D" Adr*
#pragma varargck type "I" uchar* #pragma varargck type "I" uchar*
...@@ -275,10 +262,7 @@ EXTERN int32 INITRND; ...@@ -275,10 +262,7 @@ EXTERN int32 INITRND;
EXTERN int32 INITTEXT; EXTERN int32 INITTEXT;
EXTERN int32 INITDAT; EXTERN int32 INITDAT;
EXTERN char* INITENTRY; /* entry point */ EXTERN char* INITENTRY; /* entry point */
EXTERN Biobuf bso;
EXTERN int32 casepc; EXTERN int32 casepc;
EXTERN int cbc;
EXTERN char* cbp;
EXTERN char* pcstr; EXTERN char* pcstr;
EXTERN Auto* curauto; EXTERN Auto* curauto;
EXTERN Auto* curhist; EXTERN Auto* curhist;
......
...@@ -85,7 +85,6 @@ main(int argc, char *argv[]) ...@@ -85,7 +85,6 @@ main(int argc, char *argv[])
int c; int c;
Binit(&bso, 1, OWRITE); Binit(&bso, 1, OWRITE);
cout = -1;
listinit(); listinit();
memset(debug, 0, sizeof(debug)); memset(debug, 0, sizeof(debug));
nerrors = 0; nerrors = 0;
......
...@@ -451,7 +451,7 @@ codeblk(int32 addr, int32 size) ...@@ -451,7 +451,7 @@ codeblk(int32 addr, int32 size)
uchar *q; uchar *q;
if(debug['a']) if(debug['a'])
Bprint(&bso, "codeblk [%#x,%#x) at offset %#llx\n", addr, addr+size, seek(cout, 0, 1)); Bprint(&bso, "codeblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos());
blk(textp, addr, size); blk(textp, addr, size);
...@@ -527,7 +527,7 @@ datblk(int32 addr, int32 size) ...@@ -527,7 +527,7 @@ datblk(int32 addr, int32 size)
uchar *p, *ep; uchar *p, *ep;
if(debug['a']) if(debug['a'])
Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\n", addr, addr+size, seek(cout, 0, 1)); Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos());
blk(datap, addr, size); blk(datap, addr, size);
......
...@@ -1816,15 +1816,13 @@ flushunit(DWDie *dwinfo, vlong pc, vlong unitstart, int32 header_length) ...@@ -1816,15 +1816,13 @@ flushunit(DWDie *dwinfo, vlong pc, vlong unitstart, int32 header_length)
cput(0); // start extended opcode cput(0); // start extended opcode
uleb128put(1); uleb128put(1);
cput(DW_LNE_end_sequence); cput(DW_LNE_end_sequence);
cflush();
here = cpos(); here = cpos();
seek(cout, unitstart, 0); cseek(unitstart);
LPUT(here - unitstart - sizeof(int32)); // unit_length LPUT(here - unitstart - sizeof(int32)); // unit_length
WPUT(3); // dwarf version WPUT(3); // dwarf version
LPUT(header_length); // header length starting here LPUT(header_length); // header length starting here
cflush(); cseek(here);
seek(cout, here, 0);
} }
} }
...@@ -2105,17 +2103,14 @@ writeframes(void) ...@@ -2105,17 +2103,14 @@ writeframes(void)
pad = rnd(fdesize, PtrSize) - fdesize; pad = rnd(fdesize, PtrSize) - fdesize;
strnput("", pad); strnput("", pad);
fdesize += pad; fdesize += pad;
cflush();
// Emit the FDE header for real, Section 6.4.1. // Emit the FDE header for real, Section 6.4.1.
seek(cout, fdeo, 0); cseek(fdeo);
LPUT(fdesize); LPUT(fdesize);
LPUT(0); LPUT(0);
addrput(p->pc); addrput(p->pc);
addrput(s->size); addrput(s->size);
cseek(fdeo + 4 + fdesize);
cflush();
seek(cout, fdeo + 4 + fdesize, 0);
} }
cflush(); cflush();
...@@ -2151,14 +2146,12 @@ writeinfo(void) ...@@ -2151,14 +2146,12 @@ writeinfo(void)
putdie(compunit); putdie(compunit);
cflush();
here = cpos(); here = cpos();
seek(cout, unitstart, 0); cseek(unitstart);
LPUT(here - unitstart - 4); // exclude the length field. LPUT(here - unitstart - 4); // exclude the length field.
cflush(); cseek(here);
seek(cout, here, 0);
} }
cflush();
} }
/* /*
...@@ -2213,12 +2206,10 @@ writepub(int (*ispub)(DWDie*)) ...@@ -2213,12 +2206,10 @@ writepub(int (*ispub)(DWDie*))
} }
LPUT(0); LPUT(0);
cflush();
here = cpos(); here = cpos();
seek(cout, sectionstart, 0); cseek(sectionstart);
LPUT(here - sectionstart - 4); // exclude the length field. LPUT(here - sectionstart - 4); // exclude the length field.
cflush(); cseek(here);
seek(cout, here, 0);
} }
...@@ -2358,7 +2349,7 @@ dwarfemitdebugsections(void) ...@@ -2358,7 +2349,7 @@ dwarfemitdebugsections(void)
if (fwdcount > 0) { if (fwdcount > 0) {
if (debug['v']) if (debug['v'])
Bprint(&bso, "%5.2f dwarf pass 2.\n", cputime()); Bprint(&bso, "%5.2f dwarf pass 2.\n", cputime());
seek(cout, infoo, 0); cseek(infoo);
writeinfo(); writeinfo();
if (fwdcount > 0) { if (fwdcount > 0) {
diag("dwarf: unresolved references after first dwarf info pass"); diag("dwarf: unresolved references after first dwarf info pass");
......
...@@ -313,8 +313,8 @@ elfwriteinterp(void) ...@@ -313,8 +313,8 @@ elfwriteinterp(void)
return 0; return 0;
n = strlen(interp)+1; n = strlen(interp)+1;
seek(cout, ELFRESERVE-n, 0); cseek(ELFRESERVE-n);
ewrite(cout, interp, n); cwrite(interp, n);
return n; return n;
} }
......
...@@ -41,7 +41,7 @@ char symname[] = SYMDEF; ...@@ -41,7 +41,7 @@ char symname[] = SYMDEF;
char pkgname[] = "__.PKGDEF"; char pkgname[] = "__.PKGDEF";
char* libdir[16]; char* libdir[16];
int nlibdir = 0; int nlibdir = 0;
int cout = -1; static int cout = -1;
char* goroot; char* goroot;
char* goarch; char* goarch;
...@@ -937,15 +937,6 @@ addsection(Segment *seg, char *name, int rwx) ...@@ -937,15 +937,6 @@ addsection(Segment *seg, char *name, int rwx)
return sect; return sect;
} }
void
ewrite(int fd, void *buf, int n)
{
if(write(fd, buf, n) < 0) {
diag("write error: %r");
errorexit();
}
}
void void
pclntab(void) pclntab(void)
{ {
...@@ -1359,3 +1350,71 @@ Yconv(Fmt *fp) ...@@ -1359,3 +1350,71 @@ Yconv(Fmt *fp)
return 0; return 0;
} }
vlong coutpos;
void
cflush(void)
{
int n;
if(cbpmax < cbp)
cbpmax = cbp;
n = cbpmax - buf.cbuf;
if(n) {
if(write(cout, buf.cbuf, n) != n) {
diag("write error: %r");
errorexit();
}
coutpos += n;
}
cbp = buf.cbuf;
cbc = sizeof(buf.cbuf);
cbpmax = cbp;
}
vlong
cpos(void)
{
return coutpos + cbp - buf.cbuf;
}
void
cseek(vlong p)
{
vlong start;
int delta;
if(cbpmax < cbp)
cbpmax = cbp;
start = coutpos;
if(start <= p && p <= start+(cbpmax - buf.cbuf)) {
//print("cseek %lld in [%lld,%lld] (%lld)\n", p, start, start+sizeof(buf.cbuf), cpos());
delta = p - (start + cbp - buf.cbuf);
cbp += delta;
cbc -= delta;
//print("now at %lld\n", cpos());
return;
}
cflush();
seek(cout, p, 0);
coutpos = p;
}
void
cwrite(void *buf, int n)
{
cflush();
if(write(cout, buf, n) != n) {
diag("write error: %r");
errorexit();
}
coutpos += n;
}
void
cseekend(void)
{
seek(cout, 0, 2);
}
...@@ -102,7 +102,6 @@ struct Section ...@@ -102,7 +102,6 @@ struct Section
extern char symname[]; extern char symname[];
extern char *libdir[]; extern char *libdir[];
extern int nlibdir; extern int nlibdir;
extern int cout;
EXTERN char* INITENTRY; EXTERN char* INITENTRY;
EXTERN char* thestring; EXTERN char* thestring;
...@@ -169,7 +168,6 @@ void mark(Sym *s); ...@@ -169,7 +168,6 @@ void mark(Sym *s);
void mkfwd(void); void mkfwd(void);
char* expandpkg(char*, char*); char* expandpkg(char*, char*);
void deadcode(void); void deadcode(void);
void ewrite(int, void*, int);
Reloc* addrel(Sym*); Reloc* addrel(Sym*);
void codeblk(int32, int32); void codeblk(int32, int32);
void datblk(int32, int32); void datblk(int32, int32);
...@@ -279,3 +277,27 @@ int headtype(char*); ...@@ -279,3 +277,27 @@ int headtype(char*);
int Yconv(Fmt*); int Yconv(Fmt*);
#pragma varargck type "Y" Sym* #pragma varargck type "Y" Sym*
// buffered output
EXTERN Biobuf bso;
EXTERN struct
{
char cbuf[MAXIO]; /* output buffer */
} buf;
EXTERN int cbc;
EXTERN char* cbp;
EXTERN char* cbpmax;
#define cput(c)\
{ *cbp++ = c;\
if(--cbc <= 0)\
cflush(); }
void cflush(void);
vlong cpos(void);
void cseek(vlong);
void cseekend(void);
void cwrite(void*, int);
...@@ -506,12 +506,12 @@ domacholink(void) ...@@ -506,12 +506,12 @@ domacholink(void)
if(size > 0) { if(size > 0) {
linkoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND); linkoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND);
seek(cout, linkoff, 0); cseek(linkoff);
ewrite(cout, s1->p, s1->size); cwrite(s1->p, s1->size);
ewrite(cout, s2->p, s2->size); cwrite(s2->p, s2->size);
ewrite(cout, s3->p, s3->size); cwrite(s3->p, s3->size);
ewrite(cout, s4->p, s4->size); cwrite(s4->p, s4->size);
} }
return rnd(size, INITRND); return rnd(size, INITRND);
......
...@@ -135,20 +135,20 @@ peinit(void) ...@@ -135,20 +135,20 @@ peinit(void)
static void static void
pewrite(void) pewrite(void)
{ {
seek(cout, 0, 0); cseek(0);
ewrite(cout, dosstub, sizeof dosstub); cwrite(dosstub, sizeof dosstub);
strnput("PE", 4); strnput("PE", 4);
cflush(); cflush();
// TODO: This code should not assume that the // TODO: This code should not assume that the
// memory representation is little-endian or // memory representation is little-endian or
// that the structs are packed identically to // that the structs are packed identically to
// their file representation. // their file representation.
ewrite(cout, &fh, sizeof fh); cwrite(&fh, sizeof fh);
if(pe64) if(pe64)
ewrite(cout, &oh64, sizeof oh64); cwrite(&oh64, sizeof oh64);
else else
ewrite(cout, &oh, sizeof oh); cwrite(&oh, sizeof oh);
ewrite(cout, sh, nsect * sizeof sh[0]); cwrite(sh, nsect * sizeof sh[0]);
} }
static void static void
...@@ -227,7 +227,7 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect) ...@@ -227,7 +227,7 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
n = 0; n = 0;
for(d = dr; d != nil; d = d->next) for(d = dr; d != nil; d = d->next)
n++; n++;
seek(cout, fileoff + sizeof(IMAGE_IMPORT_DESCRIPTOR) * (n + 1), 0); cseek(fileoff + sizeof(IMAGE_IMPORT_DESCRIPTOR) * (n + 1));
// write dll names // write dll names
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
...@@ -264,7 +264,7 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect) ...@@ -264,7 +264,7 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
// write FirstThunks (allocated in .data section) // write FirstThunks (allocated in .data section)
ftbase = dynamic->value - datsect->VirtualAddress - PEBASE; ftbase = dynamic->value - datsect->VirtualAddress - PEBASE;
seek(cout, datsect->PointerToRawData + ftbase, 0); cseek(datsect->PointerToRawData + ftbase);
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
for(m = d->ms; m != nil; m = m->next) for(m = d->ms; m != nil; m = m->next)
put(m->off); put(m->off);
...@@ -273,7 +273,7 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect) ...@@ -273,7 +273,7 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
cflush(); cflush();
// finally write import descriptor table // finally write import descriptor table
seek(cout, fileoff, 0); cseek(fileoff);
for(d = dr; d != nil; d = d->next) { for(d = dr; d != nil; d = d->next) {
lputl(isect->VirtualAddress + oftbase + d->thunkoff); lputl(isect->VirtualAddress + oftbase + d->thunkoff);
lputl(0); lputl(0);
...@@ -294,7 +294,7 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect) ...@@ -294,7 +294,7 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
dd[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE; dd[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE;
dd[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size; dd[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;
seek(cout, 0, 2); cseekend();
} }
static int static int
...@@ -348,7 +348,7 @@ addexports(vlong fileoff) ...@@ -348,7 +348,7 @@ addexports(vlong fileoff)
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va; dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va;
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize; dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize;
seek(cout, fileoff, 0); cseek(fileoff);
va_name = va + sizeof e + nexport*4; va_name = va + sizeof e + nexport*4;
va_addr = va + sizeof e; va_addr = va + sizeof e;
va_na = va + sizeof e + nexport*8; va_na = va + sizeof e + nexport*8;
...@@ -385,7 +385,7 @@ addexports(vlong fileoff) ...@@ -385,7 +385,7 @@ addexports(vlong fileoff)
strnput("", sect->SizeOfRawData - size); strnput("", sect->SizeOfRawData - size);
cflush(); cflush();
seek(cout, 0, 2); cseekend();
} }
void void
...@@ -491,7 +491,7 @@ addpersrc(void) ...@@ -491,7 +491,7 @@ addpersrc(void)
p[2] = val>>16; p[2] = val>>16;
p[3] = val>>24; p[3] = val>>24;
} }
ewrite(cout, rsrcsym->p, rsrcsym->size); cwrite(rsrcsym->p, rsrcsym->size);
strnput("", h->SizeOfRawData - rsrcsym->size); strnput("", h->SizeOfRawData - rsrcsym->size);
cflush(); cflush();
......
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