1*40582Sbostic /* 2*40582Sbostic * Copyright (c) 1982 Regents of the University of California 3*40582Sbostic * @(#)as.h 4.19 8/11/83 4*40582Sbostic */ 5*40582Sbostic #define reg register 6*40582Sbostic 7*40582Sbostic #include <sys/types.h> 8*40582Sbostic #include <a.out.h> 9*40582Sbostic #include <stab.h> 10*40582Sbostic 11*40582Sbostic #define readonly 12*40582Sbostic #define NINST 300 13*40582Sbostic 14*40582Sbostic #define NEXP 20 /* max number of expr. terms per instruction */ 15*40582Sbostic #define NARG 6 /* max number of args per instruction */ 16*40582Sbostic #define NHASH 1103 /* hash table is dynamically extended */ 17*40582Sbostic #define TNAMESIZE 32 /* maximum length of temporary file names */ 18*40582Sbostic #define NLOC 4 /* number of location ctrs */ 19*40582Sbostic /* 20*40582Sbostic * Sizes for character buffers. 21*40582Sbostic * what size #define name comments 22*40582Sbostic * 23*40582Sbostic * name assembly NCPName 24*40582Sbostic * name save STRPOOLDALLOP 25*40582Sbostic * 26*40582Sbostic * -name saving is a simple first fit 27*40582Sbostic */ 28*40582Sbostic #ifndef STRPOOLDALLOP 29*40582Sbostic # define STRPOOLDALLOP 8192 30*40582Sbostic #endif not STRPOOLDALLOP 31*40582Sbostic 32*40582Sbostic /* #define STR_LEN STRPOOLDALLOP */ 33*40582Sbostic #define STR_LEN 4 34*40582Sbostic #define NCPName NCPS 35*40582Sbostic #ifndef NCPS 36*40582Sbostic # undef NCPName 37*40582Sbostic # define NCPName 4096 38*40582Sbostic #endif not NCPS 39*40582Sbostic /* 40*40582Sbostic * Check sizes, and compiler error if sizes botch 41*40582Sbostic */ 42*40582Sbostic #if STRPOOLDALLOP < NCPName 43*40582Sbostic $$$botch with definition sizes 44*40582Sbostic #endif test botches 45*40582Sbostic /* 46*40582Sbostic * Symbol types 47*40582Sbostic */ 48*40582Sbostic #define XUNDEF 0x0 49*40582Sbostic #define XABS 0x2 50*40582Sbostic #define XTEXT 0x4 51*40582Sbostic #define XDATA 0x6 52*40582Sbostic #define XBSS 0x8 53*40582Sbostic 54*40582Sbostic #define XXTRN 0x1 55*40582Sbostic #define XTYPE 0x1E 56*40582Sbostic 57*40582Sbostic #define XFORW 0x20 /* Was forward-referenced when undefined */ 58*40582Sbostic 59*40582Sbostic #define ERR (-1) 60*40582Sbostic #define NBPW 32 /* Bits per word */ 61*40582Sbostic 62*40582Sbostic #define AMASK 017 63*40582Sbostic 64*40582Sbostic /* 65*40582Sbostic * Actual argument syntax types 66*40582Sbostic */ 67*40582Sbostic #define AREG 1 /* %r */ 68*40582Sbostic #define ABASE 2 /* (%r) */ 69*40582Sbostic #define ADECR 3 /* -(%r) */ 70*40582Sbostic #define AINCR 4 /* (%r)+ */ 71*40582Sbostic #define ADISP 5 /* expr(%r) */ 72*40582Sbostic #define AEXP 6 /* expr */ 73*40582Sbostic #define AIMM 7 /* $ expr */ 74*40582Sbostic #define ASTAR 8 /* * */ 75*40582Sbostic #define AINDX 16 /* [%r] */ 76*40582Sbostic /* 77*40582Sbostic * Definitions for the things found in ``instrs'' 78*40582Sbostic */ 79*40582Sbostic #define INSTTAB 1 80*40582Sbostic #include "instrs.h" 81*40582Sbostic 82*40582Sbostic /* 83*40582Sbostic * Tells outrel what it is relocating 84*40582Sbostic * RELOC_PCREL is an implicit argument to outrel; it is or'ed in 85*40582Sbostic * with a TYPX 86*40582Sbostic */ 87*40582Sbostic #define RELOC_PCREL (1<<TYPLG) 88*40582Sbostic /* 89*40582Sbostic * reference types for loader 90*40582Sbostic */ 91*40582Sbostic #define PCREL 1 92*40582Sbostic #define LEN1 2 93*40582Sbostic #define LEN2 4 94*40582Sbostic #define LEN4 6 95*40582Sbostic #define LEN8 8 96*40582Sbostic 97*40582Sbostic extern int reflen[]; /* {LEN*+PCREL} ==> number of bytes */ 98*40582Sbostic extern int lgreflen[]; /* {LEN*+PCREL} ==> lg number of bytes */ 99*40582Sbostic extern int len124[]; /* {1,2,4,8} ==> {LEN1, LEN2, LEN4, LEN8} */ 100*40582Sbostic extern char mod124[]; /* {1,2,4,8} ==> {bits to construct operands */ 101*40582Sbostic extern int type_124[]; /* {1,2,4,8} ==> {TYPB,TYPW,TYPL,TYPQ} */ 102*40582Sbostic extern int ty_NORELOC[]; /* {TYPB..TYPD} ==> {1 if relocation not OK */ 103*40582Sbostic extern int ty_float[]; /* {TYPB..TYPD} ==> {1 if floating number */ 104*40582Sbostic extern int ty_LEN[]; /* {TYPB..TYPD} ==> {LEN1..LEN8} */ 105*40582Sbostic extern int ty_nbyte[]; /* {TYPB..TYPD} ==> {1,2,4,8} */ 106*40582Sbostic extern int ty_nlg[]; /* {TYPB..TYPD} ==> lg{1,2,4,8} */ 107*40582Sbostic extern char *ty_string[]; /* {TYPB..TYPD} ==> printable */ 108*40582Sbostic extern int num_type; /* one of TYPD, TYPF, TYPQ for big numbers */ 109*40582Sbostic 110*40582Sbostic #define TMPC 7 111*40582Sbostic #define HW 0x1 112*40582Sbostic #define FW 0x3 113*40582Sbostic #define DW 0x7 114*40582Sbostic #define OW 0xF 115*40582Sbostic 116*40582Sbostic #define round(x,y) (((x)+(y)) & ~(y)) 117*40582Sbostic 118*40582Sbostic #define STABTYPS 0340 119*40582Sbostic #define STABFLAG 0200 120*40582Sbostic 121*40582Sbostic /* 122*40582Sbostic * Follows are the definitions for the symbol table tags, which are 123*40582Sbostic * all unsigned characters.. 124*40582Sbostic * High value tags are generated by the asembler for internal 125*40582Sbostic * use. 126*40582Sbostic * Low valued tags are the parser coded tokens the scanner returns. 127*40582Sbostic * There are several pertinant bounds in this ordering: 128*40582Sbostic * a) Symbols greater than JXQUESTIONABLE 129*40582Sbostic * are used by the jxxx bumper, indicating that 130*40582Sbostic * the symbol table entry is a jxxx entry 131*40582Sbostic * that has yet to be bumped. 132*40582Sbostic * b) Symbols greater than IGNOREBOUND are not 133*40582Sbostic * bequeathed to the loader; they are truly 134*40582Sbostic * for assembler internal use only. 135*40582Sbostic * c) Symbols greater than OKTOBUMP represent 136*40582Sbostic * indices into the program text that should 137*40582Sbostic * be changed in preceeding jumps or aligns 138*40582Sbostic * must get turned into their long form. 139*40582Sbostic */ 140*40582Sbostic 141*40582Sbostic #define TAGMASK 0xFF 142*40582Sbostic 143*40582Sbostic # define JXACTIVE 0xFF /*jxxx size unknown*/ 144*40582Sbostic # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ 145*40582Sbostic # define JXALIGN 0xFD /*align jxxx entry*/ 146*40582Sbostic # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ 147*40582Sbostic 148*40582Sbostic #define JXQUESTIONABLE 0xFB 149*40582Sbostic 150*40582Sbostic # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ 151*40582Sbostic # define OBSOLETE 0xF9 /*erroneously entered symbol*/ 152*40582Sbostic 153*40582Sbostic #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ 154*40582Sbostic # define STABFLOATING 0xF7 155*40582Sbostic # define LABELID 0xF6 156*40582Sbostic 157*40582Sbostic #define OKTOBUMP 0xF5 158*40582Sbostic # define STABFIXED 0xF4 159*40582Sbostic 160*40582Sbostic /* 161*40582Sbostic * astoks.h contains reserved word codings the parser should 162*40582Sbostic * know about 163*40582Sbostic */ 164*40582Sbostic #include "astoks.h" 165*40582Sbostic 166*40582Sbostic /* 167*40582Sbostic * The structure for one symbol table entry. 168*40582Sbostic * Symbol table entries are used for both user defined symbols, 169*40582Sbostic * and symbol slots generated to create the jxxx jump from 170*40582Sbostic * slots. 171*40582Sbostic * Caution: the instructions are stored in a shorter version 172*40582Sbostic * of the struct symtab, using all fields in sym_nm and 173*40582Sbostic * tag. The fields used in sym_nm are carefully redeclared 174*40582Sbostic * in struct Instab and struct instab (see below). 175*40582Sbostic * If struct nlist gets changed, then Instab and instab may 176*40582Sbostic * have to be changed. 177*40582Sbostic */ 178*40582Sbostic 179*40582Sbostic struct symtab{ 180*40582Sbostic struct nlist s_nm; 181*40582Sbostic u_char s_tag; /* assembler tag */ 182*40582Sbostic u_char s_ptype; /* if tag == NAME */ 183*40582Sbostic u_char s_jxoveralign; /* if a JXXX, jumped over align */ 184*40582Sbostic short s_index; /* which segment */ 185*40582Sbostic struct symtab *s_dest; /* if JXXX, where going to */ 186*40582Sbostic #ifdef DJXXX 187*40582Sbostic short s_jxline; /* source line of the jump from */ 188*40582Sbostic #endif 189*40582Sbostic }; 190*40582Sbostic /* 191*40582Sbostic * Redefinitions of the fields in symtab for 192*40582Sbostic * use when the symbol table entry marks a jxxx instruction. 193*40582Sbostic */ 194*40582Sbostic #define s_jxbump s_ptype /* tag == JX..., how far to expand */ 195*40582Sbostic #define s_jxfear s_desc /* how far needs to be bumped */ 196*40582Sbostic /* 197*40582Sbostic * Redefinitions of fields in the struct nlist for symbols so that 198*40582Sbostic * one saves typing, and so that they conform 199*40582Sbostic * with the old naming conventions. 200*40582Sbostic */ 201*40582Sbostic #define s_name s_nm.n_un.n_name 202*40582Sbostic #define i_name s_name 203*40582Sbostic #define FETCHNAME(sp) (((struct strdesc *)(sp)->s_name)->sd_string) 204*40582Sbostic #define STRLEN(sp) (((struct strdesc *)(sp)->s_name)->sd_strlen) 205*40582Sbostic #define STROFF(sp) (((struct strdesc *)(sp)->s_name)->sd_stroff) 206*40582Sbostic #define STRPLACE(sp) (((struct strdesc *)(sp)->s_name)->sd_place) 207*40582Sbostic #define s_nmx s_nm.n_un.n_strx /* string table index */ 208*40582Sbostic #define s_type s_nm.n_type /* type of the symbol */ 209*40582Sbostic #define s_other s_nm.n_other /* other information for sdb */ 210*40582Sbostic #define s_desc s_nm.n_desc /* type descriptor */ 211*40582Sbostic #define s_value s_nm.n_value /* value of the symbol, or sdb delta */ 212*40582Sbostic 213*40582Sbostic struct instab{ 214*40582Sbostic struct nlist s_nm; /* instruction name, type (opcode) */ 215*40582Sbostic u_char s_tag; 216*40582Sbostic char s_pad[3]; /* round to 20 bytes */ 217*40582Sbostic }; 218*40582Sbostic typedef struct instab *Iptr; 219*40582Sbostic /* 220*40582Sbostic * The fields nm.n_desc and nm.n_value total 6 bytes; this is 221*40582Sbostic * just enough for the 6 bytes describing the argument types. 222*40582Sbostic * We use a macro to define access to these 6 bytes, assuming that 223*40582Sbostic * they are allocated adjacently. 224*40582Sbostic * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED. 225*40582Sbostic * 226*40582Sbostic * Instab is cleverly declared to look very much like the combination of 227*40582Sbostic * a struct symtab and a struct nlist. 228*40582Sbostic */ 229*40582Sbostic 230*40582Sbostic /* 231*40582Sbostic * Index the itab by a structured opcode 232*40582Sbostic */ 233*40582Sbostic #define ITABFETCH(op) itab[op] 234*40582Sbostic 235*40582Sbostic struct Instab{ 236*40582Sbostic char *I_name; 237*40582Sbostic u_char I_opcode; /* basic op code */ 238*40582Sbostic char I_nargs; 239*40582Sbostic char I_args[6]; 240*40582Sbostic u_char I_s_tag; 241*40582Sbostic char I_pad[3]; /* round to 20 bytes */ 242*40582Sbostic }; 243*40582Sbostic /* 244*40582Sbostic * Redefinitions of fields in the struct nlist for instructions so that 245*40582Sbostic * one saves typing, and conforms to the old naming conventions 246*40582Sbostic */ 247*40582Sbostic #define i_opcode s_nm.n_type /* use the same field as symtab.type */ 248*40582Sbostic #define i_nargs s_nm.n_other /* number of arguments */ 249*40582Sbostic #define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n] 250*40582Sbostic 251*40582Sbostic struct arg { /*one argument to an instruction*/ 252*40582Sbostic char a_atype; 253*40582Sbostic char a_areg1; 254*40582Sbostic char a_areg2; 255*40582Sbostic char a_dispsize; /*usually d124, unless have B^, etc*/ 256*40582Sbostic struct exp *a_xp; 257*40582Sbostic }; 258*40582Sbostic /* 259*40582Sbostic * Definitions for numbers and expressions. 260*40582Sbostic */ 261*40582Sbostic #include "asnumber.h" 262*40582Sbostic struct exp { 263*40582Sbostic Bignum e_number; /* 64 bits of #, plus tag */ 264*40582Sbostic char e_xtype; 265*40582Sbostic char e_xloc; 266*40582Sbostic struct symtab *e_xname; 267*40582Sbostic }; 268*40582Sbostic #define e_xvalue e_number.num_num.numIl_int.Il_long 269*40582Sbostic #define e_yvalue e_number.num_num.numIq_int.Iq_ulong[1] 270*40582Sbostic 271*40582Sbostic #define MINLIT 0 272*40582Sbostic #define MAXLIT 63 273*40582Sbostic 274*40582Sbostic #define MINBYTE -128 275*40582Sbostic #define MAXBYTE 127 276*40582Sbostic #define MINUBYTE 0 277*40582Sbostic #define MAXUBYTE 255 278*40582Sbostic 279*40582Sbostic #define MINWORD -32768 280*40582Sbostic #define MAXWORD 32767 281*40582Sbostic #define MINUWORD 0 282*40582Sbostic #define MAXUWORD 65535 283*40582Sbostic 284*40582Sbostic #define ISLIT(x) (((x) >= MINLIT) && ((x) <= MAXLIT)) 285*40582Sbostic #define ISBYTE(x) (((x) >= MINBYTE) && ((x) <= MAXBYTE)) 286*40582Sbostic #define ISUBYTE(x) (((x) >= MINUBYTE) && ((x) <= MAXUBYTE)) 287*40582Sbostic #define ISWORD(x) (((x) >= MINWORD) && ((x) <= MAXWORD)) 288*40582Sbostic #define ISUWORD(x) (((x) >= MINUWORD) && ((x) <= MAXUWORD)) 289*40582Sbostic 290*40582Sbostic #define LITFLTMASK 0x000043F0 /*really magic*/ 291*40582Sbostic /* 292*40582Sbostic * Is the floating point double word in xp a 293*40582Sbostic * short literal floating point number? 294*40582Sbostic */ 295*40582Sbostic #define slitflt(xp) \ 296*40582Sbostic ( (xp->e_yvalue == 0) \ 297*40582Sbostic && ( (xp->e_xvalue & LITFLTMASK) \ 298*40582Sbostic == xp->e_xvalue) ) 299*40582Sbostic /* 300*40582Sbostic * If it is a slitflt, then extract the 6 interesting bits 301*40582Sbostic */ 302*40582Sbostic #define extlitflt(xp) \ 303*40582Sbostic xp->e_xvalue >> 4 304*40582Sbostic 305*40582Sbostic /* 306*40582Sbostic * Definitions for strings. 307*40582Sbostic * 308*40582Sbostic * Strings are stored in the string pool; see strsave(str, length) 309*40582Sbostic * Strings are known by their length and values. 310*40582Sbostic * A string pointer points to the beginning of the value bytes; 311*40582Sbostic * 312*40582Sbostic * If this structure is changed, change insts also. 313*40582Sbostic */ 314*40582Sbostic struct strdesc{ 315*40582Sbostic int sd_stroff; /* offset into string file */ 316*40582Sbostic short sd_place; /* where string is */ 317*40582Sbostic u_short sd_strlen; /* string length */ 318*40582Sbostic char sd_string[STR_LEN]; /* the string itself */ 319*40582Sbostic }; 320*40582Sbostic /* 321*40582Sbostic * Where a string can be. If these are changed, also change instrs. 322*40582Sbostic */ 323*40582Sbostic #define STR_FILE 0x1 324*40582Sbostic #define STR_CORE 0x2 325*40582Sbostic #define STR_BOTH 0x3 326*40582Sbostic 327*40582Sbostic struct strdesc *savestr(); 328*40582Sbostic 329*40582Sbostic /* 330*40582Sbostic * Global variables 331*40582Sbostic */ 332*40582Sbostic extern struct arg arglist[NARG]; /*building operands in instructions*/ 333*40582Sbostic extern struct exp explist[NEXP]; /*building up a list of expressions*/ 334*40582Sbostic extern struct exp *xp; /*current free expression*/ 335*40582Sbostic /* 336*40582Sbostic * Communication between the scanner and the jxxx handlers. 337*40582Sbostic * lastnam: the last name seen on the input 338*40582Sbostic * lastjxxx: pointer to the last symbol table entry for 339*40582Sbostic * a jump from 340*40582Sbostic */ 341*40582Sbostic extern struct symtab *lastnam; 342*40582Sbostic extern struct symtab *lastjxxx; 343*40582Sbostic /* 344*40582Sbostic * Lgensym is used to make up funny names for local labels. 345*40582Sbostic * lgensym[i] is the current funny number to put after 346*40582Sbostic * references to if, lgensym[i]-1 is for ib. 347*40582Sbostic * genref[i] is set when the label is referenced before 348*40582Sbostic * it is defined (i.e. 2f) so that we can be sure these 349*40582Sbostic * labels are always defined to avoid weird diagnostics 350*40582Sbostic * from the loader later. 351*40582Sbostic */ 352*40582Sbostic extern int lgensym[10]; 353*40582Sbostic extern char genref[10]; 354*40582Sbostic 355*40582Sbostic extern struct exp *dotp; /* the current dot location */ 356*40582Sbostic extern int loctr; 357*40582Sbostic 358*40582Sbostic extern struct exec hdr; /* a.out header */ 359*40582Sbostic extern u_long tsize; /* total text size */ 360*40582Sbostic extern u_long dsize; /* total data size */ 361*40582Sbostic extern u_long trsize; /* total text relocation size */ 362*40582Sbostic extern u_long drsize; /* total data relocation size */ 363*40582Sbostic extern u_long datbase; /* base of the data segment */ 364*40582Sbostic /* 365*40582Sbostic * Bitoff and bitfield keep track of the packing into 366*40582Sbostic * bytes mandated by the expression syntax <expr> ':' <expr> 367*40582Sbostic */ 368*40582Sbostic extern int bitoff; 369*40582Sbostic extern long bitfield; 370*40582Sbostic 371*40582Sbostic /* 372*40582Sbostic * The lexical analyzer builds up symbols in yytext. Lookup 373*40582Sbostic * expects its argument in this buffer 374*40582Sbostic */ 375*40582Sbostic extern char yytext[NCPName+2]; /* text buffer for lexical */ 376*40582Sbostic /* 377*40582Sbostic * Variables to manage the input assembler source file 378*40582Sbostic */ 379*40582Sbostic extern int lineno; /*the line number*/ 380*40582Sbostic extern FILE *source; /*current source for listing */ 381*40582Sbostic extern long sourcepos; /*source position in file */ 382*40582Sbostic extern char layout[400]; /*layout bytes */ 383*40582Sbostic extern char *layoutpos; /*layout position in layout */ 384*40582Sbostic #define LHEAD 18 /* layout list header length */ 385*40582Sbostic #define LLEN 25 /* layout list length */ 386*40582Sbostic extern int ninfiles; 387*40582Sbostic extern char **innames; 388*40582Sbostic extern int ind; /* innames index */ 389*40582Sbostic extern int endofsource; /*end of current source file */ 390*40582Sbostic extern char *dotsname; /*the name of the as source*/ 391*40582Sbostic 392*40582Sbostic extern FILE *tokfile; /* temp token communication*/ 393*40582Sbostic extern FILE *strfile; /* temp string file*/ 394*40582Sbostic extern char tokfilename[TNAMESIZE]; /* token file name */ 395*40582Sbostic extern char strfilename[TNAMESIZE]; /* string file name */ 396*40582Sbostic extern int strfilepos; /* position in string file */ 397*40582Sbostic 398*40582Sbostic extern int passno; /* 1 or 2 */ 399*40582Sbostic 400*40582Sbostic extern int anyerrs; /*errors as'ing arguments*/ 401*40582Sbostic extern int anywarnings; /*warnings as'ing arguments*/ 402*40582Sbostic extern int silent; /*don't mention the errors*/ 403*40582Sbostic extern int savelabels; /*save labels in a.out*/ 404*40582Sbostic extern int orgwarn; /* questionable origin ? */ 405*40582Sbostic extern int useVM; /*use virtual memory temp file*/ 406*40582Sbostic extern int jxxxJUMP; /*use jmp instead of brw for jxxx */ 407*40582Sbostic extern int readonlydata; /*initialized data into text space*/ 408*40582Sbostic #ifdef DEBUG 409*40582Sbostic extern int debug; 410*40582Sbostic extern int toktrace; 411*40582Sbostic #endif 412*40582Sbostic /* 413*40582Sbostic * Information about the instructions 414*40582Sbostic */ 415*40582Sbostic extern struct instab *itab[NINST]; /*maps opcodes to instructions*/ 416*40582Sbostic extern readonly struct Instab instab[]; 417*40582Sbostic 418*40582Sbostic extern int curlen; /*current literal storage size*/ 419*40582Sbostic extern int d124; /*current pointer storage size*/ 420*40582Sbostic 421*40582Sbostic struct symtab **lookup(); /*argument in yytext*/ 422*40582Sbostic struct symtab *symalloc(); 423*40582Sbostic 424*40582Sbostic char *Calloc(); 425*40582Sbostic char *ClearCalloc(); 426*40582Sbostic 427*40582Sbostic #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));} 428*40582Sbostic 429*40582Sbostic #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) 430*40582Sbostic 431*40582Sbostic #define Outb(o) outb(o) 432*40582Sbostic /* 433*40582Sbostic * Most of the time, the argument to flushfield is a power of two constant, 434*40582Sbostic * the calculations involving it can be optimized to shifts. 435*40582Sbostic */ 436*40582Sbostic #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) 437*40582Sbostic 438*40582Sbostic /* 439*40582Sbostic * The biobuf structure and associated routines are used to write 440*40582Sbostic * into one file at several places concurrently. Calling bopen 441*40582Sbostic * with a biobuf structure sets it up to write ``biofd'' starting 442*40582Sbostic * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' 443*40582Sbostic * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. 444*40582Sbostic * Calling bflush drains all the buffers and MUST be done before exit. 445*40582Sbostic */ 446*40582Sbostic struct biobuf { 447*40582Sbostic short b_nleft; /* Number free spaces left in b_buf */ 448*40582Sbostic /* Initialize to be less than BUFSIZ initially, to boundary align in file */ 449*40582Sbostic char *b_ptr; /* Next place to stuff characters */ 450*40582Sbostic char b_buf[BUFSIZ]; /* The buffer itself */ 451*40582Sbostic off_t b_off; /* Current file offset */ 452*40582Sbostic struct biobuf *b_link; /* Link in chain for bflush() */ 453*40582Sbostic }; 454*40582Sbostic #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, \ 455*40582Sbostic *(b)->b_ptr++ = (char) ((int)(c) & 0xff) ) \ 456*40582Sbostic : bflushc(b, c)) 457*40582Sbostic #define BFILE struct biobuf 458*40582Sbostic 459*40582Sbostic extern BFILE *biobufs; /* head of the block I/O buffer chain */ 460*40582Sbostic extern int biofd; /* file descriptor for block I/O file */ 461*40582Sbostic extern off_t boffset; /* physical position in logical file */ 462*40582Sbostic 463*40582Sbostic /* 464*40582Sbostic * For each of the named .text .data segments 465*40582Sbostic * (introduced by .text <expr>), we maintain 466*40582Sbostic * the current value of the dot, and the BFILE where 467*40582Sbostic * the information for each of the segments is placed 468*40582Sbostic * during the second pass. 469*40582Sbostic */ 470*40582Sbostic extern struct exp usedot[NLOC + NLOC]; 471*40582Sbostic extern BFILE *usefile[NLOC + NLOC]; 472*40582Sbostic extern BFILE *txtfil;/* file for text and data: into usefile */ 473*40582Sbostic /* 474*40582Sbostic * Relocation information for each segment is accumulated 475*40582Sbostic * seperately from the others. Writing the relocation 476*40582Sbostic * information is logically viewed as writing to one 477*40582Sbostic * relocation saving file for each segment; physically 478*40582Sbostic * we have a bunch of buffers allocated internally that 479*40582Sbostic * contain the relocation information. 480*40582Sbostic */ 481*40582Sbostic struct relbufdesc *rusefile[NLOC + NLOC]; 482*40582Sbostic struct relbufdesc *relfil; 483*40582Sbostic 484*40582Sbostic FILE *listfile; /* listing file descriptor */ 485*40582Sbostic int liston; /* is listing required */ 486