15829Srrh /* 25829Srrh * Copyright (c) 1982 Regents of the University of California 3*13523Srrh * @(#)as.h 4.17 06/30/83 45829Srrh */ 55829Srrh #define reg register 65829Srrh 7635Shenry #include <sys/types.h> 8*13523Srrh #include <a.out.h> 9*13523Srrh #include <stab.h> 10635Shenry 11601Sbill #define readonly 12601Sbill #define NINST 300 13601Sbill 14601Sbill #define NEXP 20 /* max number of expr. terms per instruction */ 15601Sbill #define NARG 6 /* max number of args per instruction */ 16601Sbill #define NHASH 1103 /* hash table is dynamically extended */ 17626Shenry #define TNAMESIZE 32 /* maximum length of temporary file names */ 18601Sbill #define NLOC 4 /* number of location ctrs */ 1913461Srrh /* 2013461Srrh * Sizes for character buffers. 2113461Srrh * what size #define name comments 2213461Srrh * 2313461Srrh * source file reads ASINBUFSIZ integral of BUFSIZ 2413461Srrh * string assembly NCPString large for .stabs 25*13523Srrh * name assembly NCPName 2613461Srrh * string save STRPOOLDALLOP 2713461Srrh * 2813461Srrh * 2913461Srrh * -source file reads should be integral of BUFSIZ for efficient reads 3013461Srrh * -string saving is a simple first fit 3113461Srrh */ 3213461Srrh #ifndef ASINBUFSIZ 3313461Srrh # define ASINBUFSIZ 4096 3413461Srrh #endif not ASINBUFSIZ 3513461Srrh #ifndef STRPOOLDALLOP 3613461Srrh # define STRPOOLDALLOP 8192 3713461Srrh #endif not STRPOOLDALLOP 3813461Srrh #ifndef NCPString 3913461Srrh # define NCPString 4080 4013461Srrh #endif not NCPString 41601Sbill 4213461Srrh #define NCPName NCPS 43*13523Srrh #ifndef NCPS 44*13523Srrh # undef NCPName 45*13523Srrh # define NCPName 4096 46*13523Srrh #endif not NCPS 47601Sbill /* 4813461Srrh * Check sizes, and compiler error if sizes botch 4913461Srrh */ 5013466Srrh #if ((STRPOOLDALLOP < NCPString) || (STRPOOLDALLOP < NCPName)) 5113461Srrh $$$botch with definition sizes 5213461Srrh #endif test botches 5313461Srrh /* 54601Sbill * Symbol types 55601Sbill */ 56601Sbill #define XUNDEF 0x0 57601Sbill #define XABS 0x2 58601Sbill #define XTEXT 0x4 59601Sbill #define XDATA 0x6 60601Sbill #define XBSS 0x8 61601Sbill 62601Sbill #define XXTRN 0x1 63601Sbill #define XTYPE 0x1E 64601Sbill 65601Sbill #define XFORW 0x20 /* Was forward-referenced when undefined */ 66601Sbill 67601Sbill #define ERR (-1) 68601Sbill #define NBPW 32 /* Bits per word */ 69601Sbill 70601Sbill #define AMASK 017 71601Sbill 72601Sbill /* 73601Sbill * Actual argument syntax types 74601Sbill */ 75626Shenry #define AREG 1 /* %r */ 76626Shenry #define ABASE 2 /* (%r) */ 77626Shenry #define ADECR 3 /* -(%r) */ 78626Shenry #define AINCR 4 /* (%r)+ */ 79626Shenry #define ADISP 5 /* expr(%r) */ 80626Shenry #define AEXP 6 /* expr */ 81626Shenry #define AIMM 7 /* $ expr */ 82626Shenry #define ASTAR 8 /* * */ 83626Shenry #define AINDX 16 /* [%r] */ 84601Sbill /* 855829Srrh * Definitions for the things found in ``instrs'' 86601Sbill */ 875829Srrh #define INSTTAB 1 885829Srrh #include "instrs.h" 89601Sbill 90601Sbill /* 915829Srrh * Tells outrel what it is relocating 925829Srrh * RELOC_PCREL is an implicit argument to outrel; it is or'ed in 935829Srrh * with a TYPX 94601Sbill */ 955829Srrh #define RELOC_PCREL (1<<TYPLG) 96672Shenry /* 97672Shenry * reference types for loader 98672Shenry */ 99626Shenry #define PCREL 1 100626Shenry #define LEN1 2 101626Shenry #define LEN2 4 102626Shenry #define LEN4 6 103626Shenry #define LEN8 8 1045829Srrh #define LEN16 10 105601Sbill 106672Shenry extern int reflen[]; /* {LEN*+PCREL} ==> number of bytes */ 107672Shenry extern int lgreflen[]; /* {LEN*+PCREL} ==> lg number of bytes */ 1085829Srrh extern int len124[]; /* {1,2,4,8,16} ==> {LEN1, LEN2, LEN4, LEN8} */ 1095829Srrh extern char mod124[]; /* {1,2,4,8,16} ==> {bits to construct operands */ 1105829Srrh extern int type_124[]; /* {1,2,4,8,16} ==> {TYPB,TYPW,TYPL,TYPQ,TYPO} */ 1115829Srrh extern int ty_NORELOC[]; /* {TYPB..TYPH} ==> {1 if relocation not OK */ 1125829Srrh extern int ty_float[]; /* {TYPB..TYPH} ==> {1 if floating number */ 1135829Srrh extern int ty_LEN[]; /* {TYPB..TYPH} ==> {LEN1..LEN16} */ 1145829Srrh extern int ty_nbyte[]; /* {TYPB..TYPH} ==> {1,2,4,8,16} */ 1155829Srrh extern int ty_nlg[]; /* {TYPB..TYPH} ==> lg{1,2,4,8,16} */ 1165829Srrh extern char *ty_string[]; /* {TYPB..TYPH} ==> printable */ 117672Shenry 118601Sbill #define TMPC 7 1195829Srrh #define HW 0x1 1205829Srrh #define FW 0x3 1215829Srrh #define DW 0x7 1225829Srrh #define OW 0xF 123601Sbill 124601Sbill #define round(x,y) (((x)+(y)) & ~(y)) 125601Sbill 126601Sbill #define STABTYPS 0340 127626Shenry #define STABFLAG 0200 128601Sbill 129601Sbill /* 130601Sbill * Follows are the definitions for the symbol table tags, which are 131601Sbill * all unsigned characters.. 132601Sbill * High value tags are generated by the asembler for internal 133601Sbill * use. 134601Sbill * Low valued tags are the parser coded tokens the scanner returns. 135601Sbill * There are several pertinant bounds in this ordering: 136601Sbill * a) Symbols greater than JXQUESTIONABLE 137601Sbill * are used by the jxxx bumper, indicating that 138601Sbill * the symbol table entry is a jxxx entry 139601Sbill * that has yet to be bumped. 140601Sbill * b) Symbols greater than IGNOREBOUND are not 141601Sbill * bequeathed to the loader; they are truly 142601Sbill * for assembler internal use only. 143601Sbill * c) Symbols greater than OKTOBUMP represent 144601Sbill * indices into the program text that should 145601Sbill * be changed in preceeding jumps or aligns 146601Sbill * must get turned into their long form. 147601Sbill */ 148601Sbill 149626Shenry #define TAGMASK 0xFF 150601Sbill 151601Sbill # define JXACTIVE 0xFF /*jxxx size unknown*/ 152601Sbill # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ 153601Sbill # define JXALIGN 0xFD /*align jxxx entry*/ 154601Sbill # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ 155601Sbill 156626Shenry #define JXQUESTIONABLE 0xFB 157601Sbill 158601Sbill # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ 159601Sbill # define OBSOLETE 0xF9 /*erroneously entered symbol*/ 160601Sbill 161601Sbill #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ 162601Sbill # define STABFLOATING 0xF7 163601Sbill # define LABELID 0xF6 164601Sbill 165601Sbill #define OKTOBUMP 0xF5 166601Sbill # define STABFIXED 0xF4 167601Sbill 168601Sbill /* 169601Sbill * astoks.h contains reserved word codings the parser should 170601Sbill * know about 171601Sbill */ 172601Sbill #include "astoks.h" 173601Sbill 174601Sbill /* 175601Sbill * The structure for one symbol table entry. 176601Sbill * Symbol table entries are used for both user defined symbols, 177601Sbill * and symbol slots generated to create the jxxx jump from 178601Sbill * slots. 179635Shenry * Caution: the instructions are stored in a shorter version 180635Shenry * of the struct symtab, using all fields in sym_nm and 181635Shenry * tag. The fields used in sym_nm are carefully redeclared 182635Shenry * in struct Instab and struct instab (see below). 183635Shenry * If struct nlist gets changed, then Instab and instab may 184635Shenry * have to be changed. 185601Sbill */ 186601Sbill 187601Sbill struct symtab{ 188635Shenry struct nlist s_nm; 189635Shenry u_char s_tag; /* assembler tag */ 190635Shenry u_char s_ptype; /* if tag == NAME */ 191635Shenry u_char s_jxoveralign; /* if a JXXX, jumped over align */ 192635Shenry short s_index; /* which segment */ 193635Shenry struct symtab *s_dest; /* if JXXX, where going to */ 194601Sbill #ifdef DJXXX 195635Shenry short s_jxline; /* source line of the jump from */ 196601Sbill #endif 197601Sbill }; 198635Shenry /* 199635Shenry * Redefinitions of the fields in symtab for 200635Shenry * use when the symbol table entry marks a jxxx instruction. 201635Shenry */ 202635Shenry #define s_jxbump s_ptype /* tag == JX..., how far to expand */ 203635Shenry #define s_jxfear s_desc /* how far needs to be bumped */ 204635Shenry /* 205635Shenry * Redefinitions of fields in the struct nlist for symbols so that 206635Shenry * one saves typing, and so that they conform 207635Shenry * with the old naming conventions. 208635Shenry */ 20913515Srrh #define s_name s_nm.n_un.n_name 21013515Srrh #define i_name s_name 21113515Srrh #define FETCHNAME(sp) (((struct strdesc *)(sp)->s_name)->sd_string) 21213515Srrh #define STRLEN(sp) (((struct strdesc *)(sp)->s_name)->sd_strlen) 21313515Srrh #define STROFF(sp) (((struct strdesc *)(sp)->s_name)->sd_stroff) 214635Shenry #define s_nmx s_nm.n_un.n_strx /* string table index */ 215635Shenry #define s_type s_nm.n_type /* type of the symbol */ 216635Shenry #define s_other s_nm.n_other /* other information for sdb */ 217635Shenry #define s_desc s_nm.n_desc /* type descriptor */ 218635Shenry #define s_value s_nm.n_value /* value of the symbol, or sdb delta */ 219601Sbill 220635Shenry struct instab{ 221635Shenry struct nlist s_nm; /* instruction name, type (opcode) */ 222635Shenry u_char s_tag; 2235829Srrh u_char s_eopcode; 2245829Srrh char s_pad[2]; /* round to 20 bytes */ 225601Sbill }; 2265829Srrh typedef struct instab *Iptr; 227635Shenry /* 228635Shenry * The fields nm.n_desc and nm.n_value total 6 bytes; this is 229635Shenry * just enough for the 6 bytes describing the argument types. 230635Shenry * We use a macro to define access to these 6 bytes, assuming that 231635Shenry * they are allocated adjacently. 232635Shenry * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED. 233635Shenry * 2341745Shenry * Instab is cleverly declared to look very much like the combination of 235635Shenry * a struct symtab and a struct nlist. 236635Shenry */ 2375829Srrh /* 2385829Srrh * With the 1981 VAX architecture reference manual, 2395829Srrh * DEC defined and named two byte opcodes. 2405829Srrh * In addition, DEC defined four new one byte instructions for 2415829Srrh * queue manipulation. 2425829Srrh * The assembler was patched in 1982 to reflect this change. 2435829Srrh * 2445829Srrh * The two byte opcodes are preceded with an escape byte 2455829Srrh * (usually an ESCD) and an opcode byte. 2465829Srrh * For one byte opcodes, the opcode is called the primary opcode. 2475829Srrh * For two byte opcodes, the second opcode is called the primary opcode. 2485829Srrh * 2495829Srrh * We store the primary opcode in I_popcode, 2505829Srrh * and the escape opcode in I_eopcode. 2515829Srrh * 2525829Srrh * For one byte opcodes in the basic arhitecture, 2535829Srrh * I_eopcode is CORE 2545829Srrh * For one byte opcodes in the new architecture definition, 2555829Srrh * I_eopcode is NEW 2565829Srrh * For the two byte opcodes, I_eopcode is the escape byte. 2575829Srrh * 2585829Srrh * The assembler checks if a NEW or two byte opcode is used, 2595829Srrh * and issues a warning diagnostic. 2605829Srrh */ 2615829Srrh /* 2625829Srrh * For upward compatability reasons, we can't have the two opcodes 2635829Srrh * forming an operator specifier byte(s) be physically adjacent 2645829Srrh * in the instruction table. 2655829Srrh * We define a structure and a constructor that is used in 2665829Srrh * the instruction generator. 2675829Srrh */ 2685829Srrh struct Opcode{ 2695829Srrh u_char Op_eopcode; 2705829Srrh u_char Op_popcode; 2715829Srrh }; 2725829Srrh 2735829Srrh #define BADPOINT 0xAAAAAAAA 2745829Srrh /* 2755829Srrh * See if a structured opcode is bad 2765829Srrh */ 2775829Srrh #define ITABCHECK(o) ((itab[o.Op_eopcode] != (Iptr*)BADPOINT) && (itab[o.Op_eopcode][o.Op_popcode] != (Iptr)BADPOINT)) 2785829Srrh /* 2795829Srrh * Index the itab by a structured opcode 2805829Srrh */ 2815829Srrh #define ITABFETCH(o) itab[o.Op_eopcode][o.Op_popcode] 2825829Srrh 283635Shenry struct Instab{ 284635Shenry char *I_name; 2855829Srrh u_char I_popcode; /* basic op code */ 286635Shenry char I_nargs; 287635Shenry char I_args[6]; 288635Shenry u_char I_s_tag; 2895829Srrh u_char I_eopcode; 2905829Srrh char I_pad[2]; /* round to 20 bytes */ 291635Shenry }; 292635Shenry /* 293635Shenry * Redefinitions of fields in the struct nlist for instructions so that 294635Shenry * one saves typing, and conforms to the old naming conventions 295635Shenry */ 2965829Srrh #define i_popcode s_nm.n_type /* use the same field as symtab.type */ 2975829Srrh #define i_eopcode s_eopcode 298635Shenry #define i_nargs s_nm.n_other /* number of arguments */ 299635Shenry #define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n] 300601Sbill 301601Sbill struct arg { /*one argument to an instruction*/ 302635Shenry char a_atype; 303635Shenry char a_areg1; 304635Shenry char a_areg2; 305635Shenry char a_dispsize; /*usually d124, unless have B^, etc*/ 306635Shenry struct exp *a_xp; 307601Sbill }; 3085829Srrh /* 3095829Srrh * Definitions for numbers and expressions. 3105829Srrh */ 3115829Srrh #include "asnumber.h" 312601Sbill struct exp { 3135829Srrh Bignum e_number; /* 128 bits of #, plus tag */ 314635Shenry char e_xtype; 315635Shenry char e_xloc; 3165829Srrh struct symtab *e_xname; 317601Sbill }; 3185829Srrh #define e_xvalue e_number.num_num.numIl_int.Il_long 319601Sbill 3205829Srrh #define MINLIT 0 3215829Srrh #define MAXLIT 63 322601Sbill 3235829Srrh #define MINBYTE -128 3245829Srrh #define MAXBYTE 127 3255829Srrh #define MINUBYTE 0 3265829Srrh #define MAXUBYTE 255 327601Sbill 3285829Srrh #define MINWORD -32768 3295829Srrh #define MAXWORD 32767 3305829Srrh #define MINUWORD 0 3315829Srrh #define MAXUWORD 65535 332601Sbill 3335829Srrh #define ISLIT(x) (((x) >= MINLIT) && ((x) <= MAXLIT)) 3345829Srrh #define ISBYTE(x) (((x) >= MINBYTE) && ((x) <= MAXBYTE)) 3355829Srrh #define ISUBYTE(x) (((x) >= MINUBYTE) && ((x) <= MAXUBYTE)) 3365829Srrh #define ISWORD(x) (((x) >= MINWORD) && ((x) <= MAXWORD)) 3375829Srrh #define ISUWORD(x) (((x) >= MINUWORD) && ((x) <= MAXUWORD)) 33813515Srrh /* 33913515Srrh * Definitions for strings. 34013515Srrh * 34113515Srrh * Strings are stored in the string pool; see strsave(str, length) 34213515Srrh * Strings are known by their length and values. 34313515Srrh * A string pointer points to the beginning of the value bytes; 34413515Srrh * 34513515Srrh * If this structure is changed, change insts also. 34613515Srrh */ 34713515Srrh struct strdesc{ 34813515Srrh int sd_stroff; /* offset into string file */ 34913515Srrh short sd_place; /* where string is */ 35013515Srrh u_short sd_strlen; /* string length */ 35113515Srrh char sd_string[1]; /* the string itself, flexible length */ 35213515Srrh }; 35313515Srrh /* 35413515Srrh * Where a string can be. If these are changed, also change instrs. 35513515Srrh */ 35613515Srrh #define STR_FILE 0x1 35713515Srrh #define STR_CORE 0x2 35813515Srrh #define STR_BOTH 0x3 359601Sbill 36013515Srrh struct strdesc *savestr(); 36113515Srrh 36213515Srrh /* 36313515Srrh * Global variables 36413515Srrh */ 365601Sbill extern struct arg arglist[NARG]; /*building operands in instructions*/ 366601Sbill extern struct exp explist[NEXP]; /*building up a list of expressions*/ 367601Sbill extern struct exp *xp; /*current free expression*/ 368601Sbill /* 369601Sbill * Communication between the scanner and the jxxx handlers. 370601Sbill * lastnam: the last name seen on the input 371601Sbill * lastjxxx: pointer to the last symbol table entry for 372601Sbill * a jump from 373601Sbill */ 374601Sbill extern struct symtab *lastnam; 375601Sbill extern struct symtab *lastjxxx; 376601Sbill /* 377601Sbill * Lgensym is used to make up funny names for local labels. 378601Sbill * lgensym[i] is the current funny number to put after 379601Sbill * references to if, lgensym[i]-1 is for ib. 380601Sbill * genref[i] is set when the label is referenced before 381601Sbill * it is defined (i.e. 2f) so that we can be sure these 382601Sbill * labels are always defined to avoid weird diagnostics 383601Sbill * from the loader later. 384601Sbill */ 385601Sbill extern int lgensym[10]; 386601Sbill extern char genref[10]; 387601Sbill 388601Sbill extern struct exp *dotp; /* the current dot location */ 389601Sbill extern int loctr; 390601Sbill 391601Sbill extern struct exec hdr; /* a.out header */ 392601Sbill extern u_long tsize; /* total text size */ 393601Sbill extern u_long dsize; /* total data size */ 394601Sbill extern u_long trsize; /* total text relocation size */ 395601Sbill extern u_long drsize; /* total data relocation size */ 396601Sbill extern u_long datbase; /* base of the data segment */ 397601Sbill /* 398601Sbill * Bitoff and bitfield keep track of the packing into 399601Sbill * bytes mandated by the expression syntax <expr> ':' <expr> 400601Sbill */ 401601Sbill extern int bitoff; 402601Sbill extern long bitfield; 403601Sbill 404601Sbill /* 405601Sbill * The lexical analyzer builds up symbols in yytext. Lookup 406601Sbill * expects its argument in this buffer 407601Sbill */ 40813461Srrh extern char yytext[NCPName+2]; /* text buffer for lexical */ 409601Sbill /* 410601Sbill * Variables to manage the input assembler source file 411601Sbill */ 412601Sbill extern int lineno; /*the line number*/ 413601Sbill extern char *dotsname; /*the name of the as source*/ 414601Sbill 41513515Srrh extern FILE *tokfile; /* temp token communication*/ 41613515Srrh extern FILE *strfile; /* temp string file*/ 41713515Srrh extern char tokfilename[TNAMESIZE]; /* token file name */ 41813515Srrh extern char strfilename[TNAMESIZE]; /* string file name */ 41913515Srrh extern int strfilepos; /* position in string file */ 420601Sbill 421601Sbill extern int passno; /* 1 or 2 */ 422601Sbill 4235829Srrh extern int anyerrs; /*errors as'ing arguments*/ 4245829Srrh extern int anywarnings; /*warnings as'ing arguments*/ 425601Sbill extern int silent; /*don't mention the errors*/ 426601Sbill extern int savelabels; /*save labels in a.out*/ 427601Sbill extern int orgwarn; /* questionable origin ? */ 428601Sbill extern int useVM; /*use virtual memory temp file*/ 429637Shenry extern int jxxxJUMP; /*use jmp instead of brw for jxxx */ 430639Sbill extern int readonlydata; /*initialized data into text space*/ 4315829Srrh extern int nGHnumbers; /* GH numbers used */ 4325829Srrh extern int nGHopcodes; /* GH opcodes used */ 4335829Srrh extern int nnewopcodes; /* new opcodes used */ 434601Sbill #ifdef DEBUG 435601Sbill extern int debug; 436601Sbill extern int toktrace; 437601Sbill #endif 438601Sbill /* 439601Sbill * Information about the instructions 440601Sbill */ 4415829Srrh extern struct instab **itab[NINST]; /*maps opcodes to instructions*/ 442635Shenry extern readonly struct Instab instab[]; 443601Sbill 444601Sbill extern int curlen; /*current literal storage size*/ 445601Sbill extern int d124; /*current pointer storage size*/ 446601Sbill 447601Sbill struct symtab **lookup(); /*argument in yytext*/ 448601Sbill struct symtab *symalloc(); 449601Sbill 4505829Srrh char *Calloc(); 4515829Srrh char *ClearCalloc(); 4525829Srrh 453635Shenry #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));} 454601Sbill 455635Shenry #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) 456601Sbill 4575829Srrh #define Outb(o) outb(o) 458601Sbill /* 459601Sbill * Most of the time, the argument to flushfield is a power of two constant, 460601Sbill * the calculations involving it can be optimized to shifts. 461601Sbill */ 462601Sbill #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) 463601Sbill 464601Sbill /* 465601Sbill * The biobuf structure and associated routines are used to write 466601Sbill * into one file at several places concurrently. Calling bopen 467601Sbill * with a biobuf structure sets it up to write ``biofd'' starting 468601Sbill * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' 469601Sbill * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. 470601Sbill * Calling bflush drains all the buffers and MUST be done before exit. 471601Sbill */ 472601Sbill struct biobuf { 473601Sbill short b_nleft; /* Number free spaces left in b_buf */ 474601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */ 475601Sbill char *b_ptr; /* Next place to stuff characters */ 476601Sbill char b_buf[BUFSIZ]; /* The buffer itself */ 477601Sbill off_t b_off; /* Current file offset */ 478601Sbill struct biobuf *b_link; /* Link in chain for bflush() */ 479601Sbill }; 480601Sbill #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \ 481601Sbill : bflushc(b, c)) 482601Sbill #define BFILE struct biobuf 483601Sbill 484601Sbill extern BFILE *biobufs; /* head of the block I/O buffer chain */ 485601Sbill extern int biofd; /* file descriptor for block I/O file */ 486601Sbill extern off_t boffset; /* physical position in logical file */ 487601Sbill 488601Sbill /* 489601Sbill * For each of the named .text .data segments 490601Sbill * (introduced by .text <expr>), we maintain 491601Sbill * the current value of the dot, and the BFILE where 492601Sbill * the information for each of the segments is placed 493601Sbill * during the second pass. 494601Sbill */ 495601Sbill extern struct exp usedot[NLOC + NLOC]; 496601Sbill extern BFILE *usefile[NLOC + NLOC]; 497601Sbill extern BFILE *txtfil;/* file for text and data: into usefile */ 498601Sbill /* 499601Sbill * Relocation information for each segment is accumulated 500601Sbill * seperately from the others. Writing the relocation 501601Sbill * information is logically viewed as writing to one 502601Sbill * relocation saving file for each segment; physically 503601Sbill * we have a bunch of buffers allocated internally that 504601Sbill * contain the relocation information. 505601Sbill */ 506601Sbill struct relbufdesc *rusefile[NLOC + NLOC]; 507601Sbill struct relbufdesc *relfil; 508