15829Srrh /* 25829Srrh * Copyright (c) 1982 Regents of the University of California 3*13461Srrh * @(#)as.h 4.13 06/30/83 45829Srrh */ 5601Sbill #ifdef VMS 6601Sbill # define vax 1 7601Sbill # define VAX 1 8601Sbill #endif VMS 9601Sbill 105829Srrh #define reg register 115829Srrh 12635Shenry #include <sys/types.h> 13635Shenry #ifdef UNIX 14635Shenry 15635Shenry #ifdef FLEXNAMES 16635Shenry # include <a.out.h> 17635Shenry # include <stab.h> 18635Shenry #else not FLEXNAMES 191745Shenry # define ONLIST 201745Shenry # include "a.out.h" 21635Shenry # include <stab.h> 22635Shenry #endif FLEXNAMES 23635Shenry 24635Shenry #endif UNIX 25635Shenry #ifdef VMS 26635Shenry 27635Shenry #ifdef UNIXDEVEL 28635Shenry # include <a.out.h> 29635Shenry #else not UNIXDEVEL 30635Shenry # include <aout.h> 31635Shenry #endif not UNIXDEVEL 32635Shenry 33635Shenry #endif VMS 34635Shenry 35601Sbill #define readonly 36601Sbill #define NINST 300 37601Sbill 38601Sbill #define NEXP 20 /* max number of expr. terms per instruction */ 39601Sbill #define NARG 6 /* max number of args per instruction */ 40601Sbill #define NHASH 1103 /* hash table is dynamically extended */ 41626Shenry #define TNAMESIZE 32 /* maximum length of temporary file names */ 42601Sbill #define NLOC 4 /* number of location ctrs */ 43*13461Srrh /* 44*13461Srrh * Sizes for character buffers. 45*13461Srrh * what size #define name comments 46*13461Srrh * 47*13461Srrh * source file reads ASINBUFSIZ integral of BUFSIZ 48*13461Srrh * string assembly NCPString large for .stabs 49*13461Srrh * name assembly NCPName depends on FLEXNAMES 50*13461Srrh * string save STRPOOLDALLOP 51*13461Srrh * 52*13461Srrh * 53*13461Srrh * -source file reads should be integral of BUFSIZ for efficient reads 54*13461Srrh * -string saving is a simple first fit 55*13461Srrh */ 56*13461Srrh #ifndef ASINBUFSIZ 57*13461Srrh # define ASINBUFSIZ 4096 58*13461Srrh #endif not ASINBUFSIZ 59*13461Srrh #ifndef STRPOOLDALLOP 60*13461Srrh # define STRPOOLDALLOP 8192 61*13461Srrh #endif not STRPOOLDALLOP 62*13461Srrh #ifndef NCPString 63*13461Srrh # define NCPString 4080 64*13461Srrh #endif not NCPString 65601Sbill 66*13461Srrh #define NCPName NCPS 67601Sbill #ifdef UNIX 68*13461Srrh # ifndef FLEXNAMES 69*13461Srrh # ifndef NCPS 70*13461Srrh # undef NCPName 71*13461Srrh # define NCPName 8 72*13461Srrh # endif not NCPS 73*13461Srrh # else FLEXNAMES 74*13461Srrh # ifndef NCPS 75*13461Srrh # undef NCPName 76*13461Srrh # define NCPName 4096 77*13461Srrh # endif not NCPS 78*13461Srrh # endif FLEXNAMES 79601Sbill # endif UNIX 80601Sbill 81601Sbill # ifdef VMS 82*13461Srrh # define NCPName 15 83601Sbill # endif VMS 84601Sbill 85601Sbill /* 86*13461Srrh * Check sizes, and compiler error if sizes botch 87*13461Srrh */ 88*13461Srrh #if ((ASINBUFSIZ < NCPString) || (ASINBUFSIZ < NCPName) || (STRPOOLDALLOP < NCPString) || (STRPOOLDALLOP < NCPName)) 89*13461Srrh $$$botch with definition sizes 90*13461Srrh #endif test botches 91*13461Srrh /* 92601Sbill * Symbol types 93601Sbill */ 94601Sbill #define XUNDEF 0x0 95601Sbill #define XABS 0x2 96601Sbill #define XTEXT 0x4 97601Sbill #define XDATA 0x6 98601Sbill #define XBSS 0x8 99601Sbill 100601Sbill #define XXTRN 0x1 101601Sbill #define XTYPE 0x1E 102601Sbill 103601Sbill #define XFORW 0x20 /* Was forward-referenced when undefined */ 104601Sbill 105601Sbill #define ERR (-1) 106601Sbill #define NBPW 32 /* Bits per word */ 107601Sbill 108601Sbill #define AMASK 017 109601Sbill 110601Sbill /* 111601Sbill * Actual argument syntax types 112601Sbill */ 113626Shenry #define AREG 1 /* %r */ 114626Shenry #define ABASE 2 /* (%r) */ 115626Shenry #define ADECR 3 /* -(%r) */ 116626Shenry #define AINCR 4 /* (%r)+ */ 117626Shenry #define ADISP 5 /* expr(%r) */ 118626Shenry #define AEXP 6 /* expr */ 119626Shenry #define AIMM 7 /* $ expr */ 120626Shenry #define ASTAR 8 /* * */ 121626Shenry #define AINDX 16 /* [%r] */ 122601Sbill /* 1235829Srrh * Definitions for the things found in ``instrs'' 124601Sbill */ 1255829Srrh #define INSTTAB 1 1265829Srrh #include "instrs.h" 127601Sbill 128601Sbill /* 1295829Srrh * Tells outrel what it is relocating 1305829Srrh * RELOC_PCREL is an implicit argument to outrel; it is or'ed in 1315829Srrh * with a TYPX 132601Sbill */ 1335829Srrh #define RELOC_PCREL (1<<TYPLG) 134672Shenry /* 135672Shenry * reference types for loader 136672Shenry */ 137626Shenry #define PCREL 1 138626Shenry #define LEN1 2 139626Shenry #define LEN2 4 140626Shenry #define LEN4 6 141626Shenry #define LEN8 8 1425829Srrh #define LEN16 10 143601Sbill 144672Shenry extern int reflen[]; /* {LEN*+PCREL} ==> number of bytes */ 145672Shenry extern int lgreflen[]; /* {LEN*+PCREL} ==> lg number of bytes */ 1465829Srrh extern int len124[]; /* {1,2,4,8,16} ==> {LEN1, LEN2, LEN4, LEN8} */ 1475829Srrh extern char mod124[]; /* {1,2,4,8,16} ==> {bits to construct operands */ 1485829Srrh extern int type_124[]; /* {1,2,4,8,16} ==> {TYPB,TYPW,TYPL,TYPQ,TYPO} */ 1495829Srrh extern int ty_NORELOC[]; /* {TYPB..TYPH} ==> {1 if relocation not OK */ 1505829Srrh extern int ty_float[]; /* {TYPB..TYPH} ==> {1 if floating number */ 1515829Srrh extern int ty_LEN[]; /* {TYPB..TYPH} ==> {LEN1..LEN16} */ 1525829Srrh extern int ty_nbyte[]; /* {TYPB..TYPH} ==> {1,2,4,8,16} */ 1535829Srrh extern int ty_nlg[]; /* {TYPB..TYPH} ==> lg{1,2,4,8,16} */ 1545829Srrh extern char *ty_string[]; /* {TYPB..TYPH} ==> printable */ 155672Shenry 156601Sbill #define TMPC 7 1575829Srrh #define HW 0x1 1585829Srrh #define FW 0x3 1595829Srrh #define DW 0x7 1605829Srrh #define OW 0xF 161601Sbill 162601Sbill #ifdef VMS 163601Sbill # define PAGRND 0x1FFL 164601Sbill #endif VMS 165601Sbill 166601Sbill #define round(x,y) (((x)+(y)) & ~(y)) 167601Sbill 168601Sbill #define STABTYPS 0340 169626Shenry #define STABFLAG 0200 170601Sbill 171601Sbill /* 172601Sbill * Follows are the definitions for the symbol table tags, which are 173601Sbill * all unsigned characters.. 174601Sbill * High value tags are generated by the asembler for internal 175601Sbill * use. 176601Sbill * Low valued tags are the parser coded tokens the scanner returns. 177601Sbill * There are several pertinant bounds in this ordering: 178601Sbill * a) Symbols greater than JXQUESTIONABLE 179601Sbill * are used by the jxxx bumper, indicating that 180601Sbill * the symbol table entry is a jxxx entry 181601Sbill * that has yet to be bumped. 182601Sbill * b) Symbols greater than IGNOREBOUND are not 183601Sbill * bequeathed to the loader; they are truly 184601Sbill * for assembler internal use only. 185601Sbill * c) Symbols greater than OKTOBUMP represent 186601Sbill * indices into the program text that should 187601Sbill * be changed in preceeding jumps or aligns 188601Sbill * must get turned into their long form. 189601Sbill */ 190601Sbill 191626Shenry #define TAGMASK 0xFF 192601Sbill 193601Sbill # define JXACTIVE 0xFF /*jxxx size unknown*/ 194601Sbill # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ 195601Sbill # define JXALIGN 0xFD /*align jxxx entry*/ 196601Sbill # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ 197601Sbill 198626Shenry #define JXQUESTIONABLE 0xFB 199601Sbill 200601Sbill # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ 201601Sbill # define OBSOLETE 0xF9 /*erroneously entered symbol*/ 202601Sbill 203601Sbill #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ 204601Sbill # define STABFLOATING 0xF7 205601Sbill # define LABELID 0xF6 206601Sbill 207601Sbill #define OKTOBUMP 0xF5 208601Sbill # define STABFIXED 0xF4 209601Sbill 210601Sbill /* 211601Sbill * astoks.h contains reserved word codings the parser should 212601Sbill * know about 213601Sbill */ 214601Sbill #include "astoks.h" 215601Sbill 216601Sbill /* 217601Sbill * The structure for one symbol table entry. 218601Sbill * Symbol table entries are used for both user defined symbols, 219601Sbill * and symbol slots generated to create the jxxx jump from 220601Sbill * slots. 221635Shenry * Caution: the instructions are stored in a shorter version 222635Shenry * of the struct symtab, using all fields in sym_nm and 223635Shenry * tag. The fields used in sym_nm are carefully redeclared 224635Shenry * in struct Instab and struct instab (see below). 225635Shenry * If struct nlist gets changed, then Instab and instab may 226635Shenry * have to be changed. 227601Sbill */ 228601Sbill 229601Sbill struct symtab{ 230635Shenry struct nlist s_nm; 231635Shenry u_char s_tag; /* assembler tag */ 232635Shenry u_char s_ptype; /* if tag == NAME */ 233635Shenry u_char s_jxoveralign; /* if a JXXX, jumped over align */ 234635Shenry short s_index; /* which segment */ 235635Shenry struct symtab *s_dest; /* if JXXX, where going to */ 236601Sbill #ifdef DJXXX 237635Shenry short s_jxline; /* source line of the jump from */ 238601Sbill #endif 239601Sbill }; 240635Shenry /* 241635Shenry * Redefinitions of the fields in symtab for 242635Shenry * use when the symbol table entry marks a jxxx instruction. 243635Shenry */ 244635Shenry #define s_jxbump s_ptype /* tag == JX..., how far to expand */ 245635Shenry #define s_jxfear s_desc /* how far needs to be bumped */ 246635Shenry /* 247635Shenry * Redefinitions of fields in the struct nlist for symbols so that 248635Shenry * one saves typing, and so that they conform 249635Shenry * with the old naming conventions. 250635Shenry */ 251635Shenry #ifdef FLEXNAMES 252635Shenry #define s_name s_nm.n_un.n_name /* name pointer */ 253635Shenry #define s_nmx s_nm.n_un.n_strx /* string table index */ 254635Shenry #else not FLEXNAMES 255635Shenry #define s_name s_nm.n_name 256635Shenry #endif 257635Shenry #define s_type s_nm.n_type /* type of the symbol */ 258635Shenry #define s_other s_nm.n_other /* other information for sdb */ 259635Shenry #define s_desc s_nm.n_desc /* type descriptor */ 260635Shenry #define s_value s_nm.n_value /* value of the symbol, or sdb delta */ 261601Sbill 262635Shenry struct instab{ 263635Shenry struct nlist s_nm; /* instruction name, type (opcode) */ 264635Shenry u_char s_tag; 2655829Srrh u_char s_eopcode; 2665829Srrh char s_pad[2]; /* round to 20 bytes */ 267601Sbill }; 2685829Srrh typedef struct instab *Iptr; 269635Shenry /* 270635Shenry * The fields nm.n_desc and nm.n_value total 6 bytes; this is 271635Shenry * just enough for the 6 bytes describing the argument types. 272635Shenry * We use a macro to define access to these 6 bytes, assuming that 273635Shenry * they are allocated adjacently. 274635Shenry * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED. 275635Shenry * 2761745Shenry * Instab is cleverly declared to look very much like the combination of 277635Shenry * a struct symtab and a struct nlist. 278635Shenry */ 2795829Srrh /* 2805829Srrh * With the 1981 VAX architecture reference manual, 2815829Srrh * DEC defined and named two byte opcodes. 2825829Srrh * In addition, DEC defined four new one byte instructions for 2835829Srrh * queue manipulation. 2845829Srrh * The assembler was patched in 1982 to reflect this change. 2855829Srrh * 2865829Srrh * The two byte opcodes are preceded with an escape byte 2875829Srrh * (usually an ESCD) and an opcode byte. 2885829Srrh * For one byte opcodes, the opcode is called the primary opcode. 2895829Srrh * For two byte opcodes, the second opcode is called the primary opcode. 2905829Srrh * 2915829Srrh * We store the primary opcode in I_popcode, 2925829Srrh * and the escape opcode in I_eopcode. 2935829Srrh * 2945829Srrh * For one byte opcodes in the basic arhitecture, 2955829Srrh * I_eopcode is CORE 2965829Srrh * For one byte opcodes in the new architecture definition, 2975829Srrh * I_eopcode is NEW 2985829Srrh * For the two byte opcodes, I_eopcode is the escape byte. 2995829Srrh * 3005829Srrh * The assembler checks if a NEW or two byte opcode is used, 3015829Srrh * and issues a warning diagnostic. 3025829Srrh */ 3035829Srrh /* 3045829Srrh * For upward compatability reasons, we can't have the two opcodes 3055829Srrh * forming an operator specifier byte(s) be physically adjacent 3065829Srrh * in the instruction table. 3075829Srrh * We define a structure and a constructor that is used in 3085829Srrh * the instruction generator. 3095829Srrh */ 3105829Srrh struct Opcode{ 3115829Srrh u_char Op_eopcode; 3125829Srrh u_char Op_popcode; 3135829Srrh }; 3145829Srrh 3155829Srrh #define BADPOINT 0xAAAAAAAA 3165829Srrh /* 3175829Srrh * See if a structured opcode is bad 3185829Srrh */ 3195829Srrh #define ITABCHECK(o) ((itab[o.Op_eopcode] != (Iptr*)BADPOINT) && (itab[o.Op_eopcode][o.Op_popcode] != (Iptr)BADPOINT)) 3205829Srrh /* 3215829Srrh * Index the itab by a structured opcode 3225829Srrh */ 3235829Srrh #define ITABFETCH(o) itab[o.Op_eopcode][o.Op_popcode] 3245829Srrh 325635Shenry struct Instab{ 326635Shenry #ifdef FLEXNAMES 327635Shenry char *I_name; 328635Shenry #else not FLEXNAMES 329*13461Srrh char I_name[NCPName]; 330635Shenry #endif 3315829Srrh u_char I_popcode; /* basic op code */ 332635Shenry char I_nargs; 333635Shenry char I_args[6]; 334635Shenry u_char I_s_tag; 3355829Srrh u_char I_eopcode; 3365829Srrh char I_pad[2]; /* round to 20 bytes */ 337635Shenry }; 338635Shenry /* 339635Shenry * Redefinitions of fields in the struct nlist for instructions so that 340635Shenry * one saves typing, and conforms to the old naming conventions 341635Shenry */ 3425829Srrh #define i_popcode s_nm.n_type /* use the same field as symtab.type */ 3435829Srrh #define i_eopcode s_eopcode 344635Shenry #define i_nargs s_nm.n_other /* number of arguments */ 345635Shenry #define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n] 346601Sbill 347601Sbill struct arg { /*one argument to an instruction*/ 348635Shenry char a_atype; 349635Shenry char a_areg1; 350635Shenry char a_areg2; 351635Shenry char a_dispsize; /*usually d124, unless have B^, etc*/ 352635Shenry struct exp *a_xp; 353601Sbill }; 3545829Srrh /* 3555829Srrh * Definitions for numbers and expressions. 3565829Srrh */ 3575829Srrh #include "asnumber.h" 358601Sbill struct exp { 3595829Srrh Bignum e_number; /* 128 bits of #, plus tag */ 360635Shenry char e_xtype; 361635Shenry char e_xloc; 3625829Srrh struct symtab *e_xname; 363601Sbill }; 3645829Srrh #define e_xvalue e_number.num_num.numIl_int.Il_long 365601Sbill 3665829Srrh #define MINLIT 0 3675829Srrh #define MAXLIT 63 368601Sbill 3695829Srrh #define MINBYTE -128 3705829Srrh #define MAXBYTE 127 3715829Srrh #define MINUBYTE 0 3725829Srrh #define MAXUBYTE 255 373601Sbill 3745829Srrh #define MINWORD -32768 3755829Srrh #define MAXWORD 32767 3765829Srrh #define MINUWORD 0 3775829Srrh #define MAXUWORD 65535 378601Sbill 3795829Srrh #define ISLIT(x) (((x) >= MINLIT) && ((x) <= MAXLIT)) 3805829Srrh #define ISBYTE(x) (((x) >= MINBYTE) && ((x) <= MAXBYTE)) 3815829Srrh #define ISUBYTE(x) (((x) >= MINUBYTE) && ((x) <= MAXUBYTE)) 3825829Srrh #define ISWORD(x) (((x) >= MINWORD) && ((x) <= MAXWORD)) 3835829Srrh #define ISUWORD(x) (((x) >= MINUWORD) && ((x) <= MAXUWORD)) 384601Sbill 385601Sbill extern struct arg arglist[NARG]; /*building operands in instructions*/ 386601Sbill extern struct exp explist[NEXP]; /*building up a list of expressions*/ 387601Sbill extern struct exp *xp; /*current free expression*/ 388601Sbill /* 389601Sbill * Communication between the scanner and the jxxx handlers. 390601Sbill * lastnam: the last name seen on the input 391601Sbill * lastjxxx: pointer to the last symbol table entry for 392601Sbill * a jump from 393601Sbill */ 394601Sbill extern struct symtab *lastnam; 395601Sbill extern struct symtab *lastjxxx; 396601Sbill 397601Sbill #ifdef VMS 398635Shenry extern char *vms_obj_ptr; /* object buffer pointer */ 399635Shenry extern char sobuf[]; /* object buffer */ 400601Sbill extern int objfil; /* VMS object file descriptor */ 401601Sbill #endif VMS 402601Sbill 403601Sbill /* 404601Sbill * Lgensym is used to make up funny names for local labels. 405601Sbill * lgensym[i] is the current funny number to put after 406601Sbill * references to if, lgensym[i]-1 is for ib. 407601Sbill * genref[i] is set when the label is referenced before 408601Sbill * it is defined (i.e. 2f) so that we can be sure these 409601Sbill * labels are always defined to avoid weird diagnostics 410601Sbill * from the loader later. 411601Sbill */ 412601Sbill extern int lgensym[10]; 413601Sbill extern char genref[10]; 414601Sbill 415601Sbill extern char tmpn1[TNAMESIZE]; /* Interpass temporary */ 416601Sbill extern struct exp *dotp; /* the current dot location */ 417601Sbill extern int loctr; 418601Sbill 419601Sbill extern struct exec hdr; /* a.out header */ 420601Sbill extern u_long tsize; /* total text size */ 421601Sbill extern u_long dsize; /* total data size */ 422601Sbill extern u_long trsize; /* total text relocation size */ 423601Sbill extern u_long drsize; /* total data relocation size */ 424601Sbill extern u_long datbase; /* base of the data segment */ 425601Sbill /* 426601Sbill * Bitoff and bitfield keep track of the packing into 427601Sbill * bytes mandated by the expression syntax <expr> ':' <expr> 428601Sbill */ 429601Sbill extern int bitoff; 430601Sbill extern long bitfield; 431601Sbill 432601Sbill /* 433601Sbill * The lexical analyzer builds up symbols in yytext. Lookup 434601Sbill * expects its argument in this buffer 435601Sbill */ 436*13461Srrh extern char yytext[NCPName+2]; /* text buffer for lexical */ 437601Sbill /* 438601Sbill * Variables to manage the input assembler source file 439601Sbill */ 440601Sbill extern int lineno; /*the line number*/ 441601Sbill extern char *dotsname; /*the name of the as source*/ 442601Sbill 443601Sbill extern FILE *tmpfil; /* interpass communication*/ 444601Sbill 445601Sbill extern int passno; /* 1 or 2 */ 446601Sbill 4475829Srrh extern int anyerrs; /*errors as'ing arguments*/ 4485829Srrh extern int anywarnings; /*warnings as'ing arguments*/ 449601Sbill extern int silent; /*don't mention the errors*/ 450601Sbill extern int savelabels; /*save labels in a.out*/ 451601Sbill extern int orgwarn; /* questionable origin ? */ 452601Sbill extern int useVM; /*use virtual memory temp file*/ 453637Shenry extern int jxxxJUMP; /*use jmp instead of brw for jxxx */ 454639Sbill extern int readonlydata; /*initialized data into text space*/ 4555829Srrh extern int nGHnumbers; /* GH numbers used */ 4565829Srrh extern int nGHopcodes; /* GH opcodes used */ 4575829Srrh extern int nnewopcodes; /* new opcodes used */ 458601Sbill #ifdef DEBUG 459601Sbill extern int debug; 460601Sbill extern int toktrace; 461601Sbill #endif 462601Sbill /* 463601Sbill * Information about the instructions 464601Sbill */ 4655829Srrh extern struct instab **itab[NINST]; /*maps opcodes to instructions*/ 466635Shenry extern readonly struct Instab instab[]; 467601Sbill 468601Sbill extern int curlen; /*current literal storage size*/ 469601Sbill extern int d124; /*current pointer storage size*/ 470601Sbill 471601Sbill struct symtab **lookup(); /*argument in yytext*/ 472601Sbill struct symtab *symalloc(); 473601Sbill 4745829Srrh char *Calloc(); 4755829Srrh char *ClearCalloc(); 4765829Srrh 477635Shenry #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));} 478601Sbill 479635Shenry #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) 480601Sbill 4815829Srrh #ifdef UNIX 4825829Srrh #define Outb(o) outb(o) 4835829Srrh #endif UNIX 4845829Srrh 4855829Srrh #ifdef VMS 4865829Srrh #define Outb(o) {*vms_obj_ptr++=-1;*vms_obj_ptr++=(char)o;dotp->e_xvalue+=1;} 4875829Srrh #endif VMS 4885829Srrh 489601Sbill /* 490601Sbill * Most of the time, the argument to flushfield is a power of two constant, 491601Sbill * the calculations involving it can be optimized to shifts. 492601Sbill */ 493601Sbill #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) 494601Sbill 495601Sbill /* 496601Sbill * The biobuf structure and associated routines are used to write 497601Sbill * into one file at several places concurrently. Calling bopen 498601Sbill * with a biobuf structure sets it up to write ``biofd'' starting 499601Sbill * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' 500601Sbill * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. 501601Sbill * Calling bflush drains all the buffers and MUST be done before exit. 502601Sbill */ 503601Sbill struct biobuf { 504601Sbill short b_nleft; /* Number free spaces left in b_buf */ 505601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */ 506601Sbill char *b_ptr; /* Next place to stuff characters */ 507601Sbill char b_buf[BUFSIZ]; /* The buffer itself */ 508601Sbill off_t b_off; /* Current file offset */ 509601Sbill struct biobuf *b_link; /* Link in chain for bflush() */ 510601Sbill }; 511601Sbill #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \ 512601Sbill : bflushc(b, c)) 513601Sbill #define BFILE struct biobuf 514601Sbill 515601Sbill extern BFILE *biobufs; /* head of the block I/O buffer chain */ 516601Sbill extern int biofd; /* file descriptor for block I/O file */ 517601Sbill extern off_t boffset; /* physical position in logical file */ 518601Sbill 519601Sbill /* 520601Sbill * For each of the named .text .data segments 521601Sbill * (introduced by .text <expr>), we maintain 522601Sbill * the current value of the dot, and the BFILE where 523601Sbill * the information for each of the segments is placed 524601Sbill * during the second pass. 525601Sbill */ 526601Sbill extern struct exp usedot[NLOC + NLOC]; 527601Sbill extern BFILE *usefile[NLOC + NLOC]; 528601Sbill extern BFILE *txtfil;/* file for text and data: into usefile */ 529601Sbill /* 530601Sbill * Relocation information for each segment is accumulated 531601Sbill * seperately from the others. Writing the relocation 532601Sbill * information is logically viewed as writing to one 533601Sbill * relocation saving file for each segment; physically 534601Sbill * we have a bunch of buffers allocated internally that 535601Sbill * contain the relocation information. 536601Sbill */ 537601Sbill struct relbufdesc *rusefile[NLOC + NLOC]; 538601Sbill struct relbufdesc *relfil; 539