+
+/*
+ * The biobuf structure and associated routines are used to write
+ * into one file at several places concurrently. Calling bopen
+ * with a biobuf structure sets it up to write ``biofd'' starting
+ * at the specified offset. You can then use ``bwrite'' and/or ``bputc''
+ * to stuff characters in the stream, much like ``fwrite'' and ``fputc''.
+ * Calling bflush drains all the buffers and MUST be done before exit.
+ */
+struct biobuf {
+ short b_nleft; /* Number free spaces left in b_buf */
+/* Initialize to be less than BUFSIZ initially, to boundary align in file */
+ char *b_ptr; /* Next place to stuff characters */
+ char b_buf[BUFSIZ]; /* The buffer itself */
+ off_t b_off; /* Current file offset */
+ struct biobuf *b_link; /* Link in chain for bflush() */
+};
+#define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \
+ : bflushc(b, c))
+#define BFILE struct biobuf
+
+ extern BFILE *biobufs; /* head of the block I/O buffer chain */
+ extern int biofd; /* file descriptor for block I/O file */
+ extern off_t boffset; /* physical position in logical file */
+
+ /*
+ * For each of the named .text .data segments
+ * (introduced by .text <expr>), we maintain
+ * the current value of the dot, and the BFILE where
+ * the information for each of the segments is placed
+ * during the second pass.
+ */
+ extern struct exp usedot[NLOC + NLOC];
+ extern BFILE *usefile[NLOC + NLOC];
+ extern BFILE *txtfil;/* file for text and data: into usefile */
+ /*
+ * Relocation information for each segment is accumulated
+ * seperately from the others. Writing the relocation
+ * information is logically viewed as writing to one
+ * relocation saving file for each segment; physically
+ * we have a bunch of buffers allocated internally that
+ * contain the relocation information.
+ */
+ struct relbufdesc *rusefile[NLOC + NLOC];
+ struct relbufdesc *relfil;