15829Srrh /* 218713Sdist * Copyright (c) 1982 Regents of the University of California. 318713Sdist * All rights reserved. The Berkeley software License Agreement 418713Sdist * specifies the terms and conditions for redistribution. 518713Sdist * 6*23849Sbloom * @(#)as.h 5.3 (Berkeley) 07/06/85 75829Srrh */ 818713Sdist 95829Srrh #define reg register 105829Srrh 11635Shenry #include <sys/types.h> 1213523Srrh #include <a.out.h> 1313523Srrh #include <stab.h> 14635Shenry 15601Sbill #define readonly 16601Sbill #define NINST 300 17601Sbill 18601Sbill #define NEXP 20 /* max number of expr. terms per instruction */ 19601Sbill #define NARG 6 /* max number of args per instruction */ 20601Sbill #define NHASH 1103 /* hash table is dynamically extended */ 21*23849Sbloom #define TNAMESIZE 256 /* maximum length of temporary file names */ 22601Sbill #define NLOC 4 /* number of location ctrs */ 2313461Srrh /* 2413461Srrh * Sizes for character buffers. 2513461Srrh * what size #define name comments 2613461Srrh * 2713523Srrh * name assembly NCPName 2813574Srrh * name save STRPOOLDALLOP 2913461Srrh * 3013574Srrh * -name saving is a simple first fit 3113461Srrh */ 3213461Srrh #ifndef STRPOOLDALLOP 3313461Srrh # define STRPOOLDALLOP 8192 3413461Srrh #endif not STRPOOLDALLOP 35601Sbill 3613461Srrh #define NCPName NCPS 3713523Srrh #ifndef NCPS 3813523Srrh # undef NCPName 3913523Srrh # define NCPName 4096 4013523Srrh #endif not NCPS 41601Sbill /* 4213461Srrh * Check sizes, and compiler error if sizes botch 4313461Srrh */ 4413574Srrh #if STRPOOLDALLOP < NCPName 4513461Srrh $$$botch with definition sizes 4613461Srrh #endif test botches 4713461Srrh /* 48601Sbill * Symbol types 49601Sbill */ 50601Sbill #define XUNDEF 0x0 51601Sbill #define XABS 0x2 52601Sbill #define XTEXT 0x4 53601Sbill #define XDATA 0x6 54601Sbill #define XBSS 0x8 55601Sbill 56601Sbill #define XXTRN 0x1 57601Sbill #define XTYPE 0x1E 58601Sbill 59601Sbill #define XFORW 0x20 /* Was forward-referenced when undefined */ 60601Sbill 61601Sbill #define ERR (-1) 6223577Smckusick #define NBWD 32 /* Bits per word */ 63601Sbill 64601Sbill #define AMASK 017 65601Sbill 66601Sbill /* 67601Sbill * Actual argument syntax types 68601Sbill */ 69626Shenry #define AREG 1 /* %r */ 70626Shenry #define ABASE 2 /* (%r) */ 71626Shenry #define ADECR 3 /* -(%r) */ 72626Shenry #define AINCR 4 /* (%r)+ */ 73626Shenry #define ADISP 5 /* expr(%r) */ 74626Shenry #define AEXP 6 /* expr */ 75626Shenry #define AIMM 7 /* $ expr */ 76626Shenry #define ASTAR 8 /* * */ 77626Shenry #define AINDX 16 /* [%r] */ 78601Sbill /* 795829Srrh * Definitions for the things found in ``instrs'' 80601Sbill */ 815829Srrh #define INSTTAB 1 825829Srrh #include "instrs.h" 83601Sbill 84601Sbill /* 855829Srrh * Tells outrel what it is relocating 865829Srrh * RELOC_PCREL is an implicit argument to outrel; it is or'ed in 875829Srrh * with a TYPX 88601Sbill */ 895829Srrh #define RELOC_PCREL (1<<TYPLG) 90672Shenry /* 91672Shenry * reference types for loader 92672Shenry */ 93626Shenry #define PCREL 1 94626Shenry #define LEN1 2 95626Shenry #define LEN2 4 96626Shenry #define LEN4 6 97626Shenry #define LEN8 8 985829Srrh #define LEN16 10 99601Sbill 100672Shenry extern int reflen[]; /* {LEN*+PCREL} ==> number of bytes */ 101672Shenry extern int lgreflen[]; /* {LEN*+PCREL} ==> lg number of bytes */ 1025829Srrh extern int len124[]; /* {1,2,4,8,16} ==> {LEN1, LEN2, LEN4, LEN8} */ 1035829Srrh extern char mod124[]; /* {1,2,4,8,16} ==> {bits to construct operands */ 1045829Srrh extern int type_124[]; /* {1,2,4,8,16} ==> {TYPB,TYPW,TYPL,TYPQ,TYPO} */ 1055829Srrh extern int ty_NORELOC[]; /* {TYPB..TYPH} ==> {1 if relocation not OK */ 1065829Srrh extern int ty_float[]; /* {TYPB..TYPH} ==> {1 if floating number */ 1075829Srrh extern int ty_LEN[]; /* {TYPB..TYPH} ==> {LEN1..LEN16} */ 1085829Srrh extern int ty_nbyte[]; /* {TYPB..TYPH} ==> {1,2,4,8,16} */ 1095829Srrh extern int ty_nlg[]; /* {TYPB..TYPH} ==> lg{1,2,4,8,16} */ 1105829Srrh extern char *ty_string[]; /* {TYPB..TYPH} ==> printable */ 111672Shenry 112601Sbill #define TMPC 7 1135829Srrh #define HW 0x1 1145829Srrh #define FW 0x3 1155829Srrh #define DW 0x7 1165829Srrh #define OW 0xF 117601Sbill 118601Sbill #define round(x,y) (((x)+(y)) & ~(y)) 119601Sbill 120601Sbill #define STABTYPS 0340 121626Shenry #define STABFLAG 0200 122601Sbill 123601Sbill /* 124601Sbill * Follows are the definitions for the symbol table tags, which are 125601Sbill * all unsigned characters.. 126601Sbill * High value tags are generated by the asembler for internal 127601Sbill * use. 128601Sbill * Low valued tags are the parser coded tokens the scanner returns. 129601Sbill * There are several pertinant bounds in this ordering: 130601Sbill * a) Symbols greater than JXQUESTIONABLE 131601Sbill * are used by the jxxx bumper, indicating that 132601Sbill * the symbol table entry is a jxxx entry 133601Sbill * that has yet to be bumped. 134601Sbill * b) Symbols greater than IGNOREBOUND are not 135601Sbill * bequeathed to the loader; they are truly 136601Sbill * for assembler internal use only. 137601Sbill * c) Symbols greater than OKTOBUMP represent 138601Sbill * indices into the program text that should 139601Sbill * be changed in preceeding jumps or aligns 140601Sbill * must get turned into their long form. 141601Sbill */ 142601Sbill 143626Shenry #define TAGMASK 0xFF 144601Sbill 145601Sbill # define JXACTIVE 0xFF /*jxxx size unknown*/ 146601Sbill # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ 147601Sbill # define JXALIGN 0xFD /*align jxxx entry*/ 148601Sbill # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ 149601Sbill 150626Shenry #define JXQUESTIONABLE 0xFB 151601Sbill 152601Sbill # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ 153601Sbill # define OBSOLETE 0xF9 /*erroneously entered symbol*/ 154601Sbill 155601Sbill #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ 156601Sbill # define STABFLOATING 0xF7 157601Sbill # define LABELID 0xF6 158601Sbill 159601Sbill #define OKTOBUMP 0xF5 160601Sbill # define STABFIXED 0xF4 161601Sbill 162601Sbill /* 163601Sbill * astoks.h contains reserved word codings the parser should 164601Sbill * know about 165601Sbill */ 166601Sbill #include "astoks.h" 167601Sbill 168601Sbill /* 169601Sbill * The structure for one symbol table entry. 170601Sbill * Symbol table entries are used for both user defined symbols, 171601Sbill * and symbol slots generated to create the jxxx jump from 172601Sbill * slots. 173635Shenry * Caution: the instructions are stored in a shorter version 174635Shenry * of the struct symtab, using all fields in sym_nm and 175635Shenry * tag. The fields used in sym_nm are carefully redeclared 176635Shenry * in struct Instab and struct instab (see below). 177635Shenry * If struct nlist gets changed, then Instab and instab may 178635Shenry * have to be changed. 179601Sbill */ 180601Sbill 181601Sbill struct symtab{ 182635Shenry struct nlist s_nm; 183635Shenry u_char s_tag; /* assembler tag */ 184635Shenry u_char s_ptype; /* if tag == NAME */ 185635Shenry u_char s_jxoveralign; /* if a JXXX, jumped over align */ 186635Shenry short s_index; /* which segment */ 187635Shenry struct symtab *s_dest; /* if JXXX, where going to */ 18815233Sralph #ifdef DEBUG 189635Shenry short s_jxline; /* source line of the jump from */ 190601Sbill #endif 191601Sbill }; 192635Shenry /* 193635Shenry * Redefinitions of the fields in symtab for 194635Shenry * use when the symbol table entry marks a jxxx instruction. 195635Shenry */ 196635Shenry #define s_jxbump s_ptype /* tag == JX..., how far to expand */ 197635Shenry #define s_jxfear s_desc /* how far needs to be bumped */ 198635Shenry /* 199635Shenry * Redefinitions of fields in the struct nlist for symbols so that 200635Shenry * one saves typing, and so that they conform 201635Shenry * with the old naming conventions. 202635Shenry */ 20313515Srrh #define s_name s_nm.n_un.n_name 20413515Srrh #define i_name s_name 20513515Srrh #define FETCHNAME(sp) (((struct strdesc *)(sp)->s_name)->sd_string) 20613515Srrh #define STRLEN(sp) (((struct strdesc *)(sp)->s_name)->sd_strlen) 20713515Srrh #define STROFF(sp) (((struct strdesc *)(sp)->s_name)->sd_stroff) 20814449Srrh #define STRPLACE(sp) (((struct strdesc *)(sp)->s_name)->sd_place) 209635Shenry #define s_nmx s_nm.n_un.n_strx /* string table index */ 210635Shenry #define s_type s_nm.n_type /* type of the symbol */ 211635Shenry #define s_other s_nm.n_other /* other information for sdb */ 212635Shenry #define s_desc s_nm.n_desc /* type descriptor */ 213635Shenry #define s_value s_nm.n_value /* value of the symbol, or sdb delta */ 214601Sbill 215635Shenry struct instab{ 216635Shenry struct nlist s_nm; /* instruction name, type (opcode) */ 217635Shenry u_char s_tag; 2185829Srrh u_char s_eopcode; 2195829Srrh char s_pad[2]; /* round to 20 bytes */ 220601Sbill }; 2215829Srrh typedef struct instab *Iptr; 222635Shenry /* 223635Shenry * The fields nm.n_desc and nm.n_value total 6 bytes; this is 224635Shenry * just enough for the 6 bytes describing the argument types. 225635Shenry * We use a macro to define access to these 6 bytes, assuming that 226635Shenry * they are allocated adjacently. 227635Shenry * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED. 228635Shenry * 2291745Shenry * Instab is cleverly declared to look very much like the combination of 230635Shenry * a struct symtab and a struct nlist. 231635Shenry */ 2325829Srrh /* 2335829Srrh * With the 1981 VAX architecture reference manual, 2345829Srrh * DEC defined and named two byte opcodes. 2355829Srrh * In addition, DEC defined four new one byte instructions for 2365829Srrh * queue manipulation. 2375829Srrh * The assembler was patched in 1982 to reflect this change. 2385829Srrh * 2395829Srrh * The two byte opcodes are preceded with an escape byte 2405829Srrh * (usually an ESCD) and an opcode byte. 2415829Srrh * For one byte opcodes, the opcode is called the primary opcode. 2425829Srrh * For two byte opcodes, the second opcode is called the primary opcode. 2435829Srrh * 2445829Srrh * We store the primary opcode in I_popcode, 2455829Srrh * and the escape opcode in I_eopcode. 2465829Srrh * 2475829Srrh * For one byte opcodes in the basic arhitecture, 2485829Srrh * I_eopcode is CORE 2495829Srrh * For one byte opcodes in the new architecture definition, 2505829Srrh * I_eopcode is NEW 2515829Srrh * For the two byte opcodes, I_eopcode is the escape byte. 2525829Srrh * 2535829Srrh * The assembler checks if a NEW or two byte opcode is used, 2545829Srrh * and issues a warning diagnostic. 2555829Srrh */ 2565829Srrh /* 2575829Srrh * For upward compatability reasons, we can't have the two opcodes 2585829Srrh * forming an operator specifier byte(s) be physically adjacent 2595829Srrh * in the instruction table. 2605829Srrh * We define a structure and a constructor that is used in 2615829Srrh * the instruction generator. 2625829Srrh */ 2635829Srrh struct Opcode{ 2645829Srrh u_char Op_eopcode; 2655829Srrh u_char Op_popcode; 2665829Srrh }; 2675829Srrh 2685829Srrh #define BADPOINT 0xAAAAAAAA 2695829Srrh /* 2705829Srrh * See if a structured opcode is bad 2715829Srrh */ 2725829Srrh #define ITABCHECK(o) ((itab[o.Op_eopcode] != (Iptr*)BADPOINT) && (itab[o.Op_eopcode][o.Op_popcode] != (Iptr)BADPOINT)) 2735829Srrh /* 2745829Srrh * Index the itab by a structured opcode 2755829Srrh */ 2765829Srrh #define ITABFETCH(o) itab[o.Op_eopcode][o.Op_popcode] 2775829Srrh 278635Shenry struct Instab{ 279635Shenry char *I_name; 2805829Srrh u_char I_popcode; /* basic op code */ 281635Shenry char I_nargs; 282635Shenry char I_args[6]; 283635Shenry u_char I_s_tag; 2845829Srrh u_char I_eopcode; 2855829Srrh char I_pad[2]; /* round to 20 bytes */ 286635Shenry }; 287635Shenry /* 288635Shenry * Redefinitions of fields in the struct nlist for instructions so that 289635Shenry * one saves typing, and conforms to the old naming conventions 290635Shenry */ 2915829Srrh #define i_popcode s_nm.n_type /* use the same field as symtab.type */ 2925829Srrh #define i_eopcode s_eopcode 293635Shenry #define i_nargs s_nm.n_other /* number of arguments */ 294635Shenry #define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n] 295601Sbill 296601Sbill struct arg { /*one argument to an instruction*/ 297635Shenry char a_atype; 298635Shenry char a_areg1; 299635Shenry char a_areg2; 300635Shenry char a_dispsize; /*usually d124, unless have B^, etc*/ 301635Shenry struct exp *a_xp; 302601Sbill }; 3035829Srrh /* 3045829Srrh * Definitions for numbers and expressions. 3055829Srrh */ 3065829Srrh #include "asnumber.h" 307601Sbill struct exp { 3085829Srrh Bignum e_number; /* 128 bits of #, plus tag */ 309635Shenry char e_xtype; 310635Shenry char e_xloc; 3115829Srrh struct symtab *e_xname; 312601Sbill }; 3135829Srrh #define e_xvalue e_number.num_num.numIl_int.Il_long 314601Sbill 3155829Srrh #define MINLIT 0 3165829Srrh #define MAXLIT 63 317601Sbill 3185829Srrh #define MINBYTE -128 3195829Srrh #define MAXBYTE 127 3205829Srrh #define MINUBYTE 0 3215829Srrh #define MAXUBYTE 255 322601Sbill 3235829Srrh #define MINWORD -32768 3245829Srrh #define MAXWORD 32767 3255829Srrh #define MINUWORD 0 3265829Srrh #define MAXUWORD 65535 327601Sbill 3285829Srrh #define ISLIT(x) (((x) >= MINLIT) && ((x) <= MAXLIT)) 3295829Srrh #define ISBYTE(x) (((x) >= MINBYTE) && ((x) <= MAXBYTE)) 3305829Srrh #define ISUBYTE(x) (((x) >= MINUBYTE) && ((x) <= MAXUBYTE)) 3315829Srrh #define ISWORD(x) (((x) >= MINWORD) && ((x) <= MAXWORD)) 3325829Srrh #define ISUWORD(x) (((x) >= MINUWORD) && ((x) <= MAXUWORD)) 33313515Srrh /* 33413515Srrh * Definitions for strings. 33513515Srrh * 33613515Srrh * Strings are stored in the string pool; see strsave(str, length) 33713515Srrh * Strings are known by their length and values. 33813515Srrh * A string pointer points to the beginning of the value bytes; 33913515Srrh * 34013515Srrh * If this structure is changed, change insts also. 34113515Srrh */ 34213515Srrh struct strdesc{ 34313515Srrh int sd_stroff; /* offset into string file */ 34413515Srrh short sd_place; /* where string is */ 34513515Srrh u_short sd_strlen; /* string length */ 34613515Srrh char sd_string[1]; /* the string itself, flexible length */ 34713515Srrh }; 34813515Srrh /* 34913515Srrh * Where a string can be. If these are changed, also change instrs. 35013515Srrh */ 35113515Srrh #define STR_FILE 0x1 35213515Srrh #define STR_CORE 0x2 35313515Srrh #define STR_BOTH 0x3 354601Sbill 35513515Srrh struct strdesc *savestr(); 35613515Srrh 35713515Srrh /* 35813515Srrh * Global variables 35913515Srrh */ 360601Sbill extern struct arg arglist[NARG]; /*building operands in instructions*/ 361601Sbill extern struct exp explist[NEXP]; /*building up a list of expressions*/ 362601Sbill extern struct exp *xp; /*current free expression*/ 363601Sbill /* 364601Sbill * Communication between the scanner and the jxxx handlers. 365601Sbill * lastnam: the last name seen on the input 366601Sbill * lastjxxx: pointer to the last symbol table entry for 367601Sbill * a jump from 368601Sbill */ 369601Sbill extern struct symtab *lastnam; 370601Sbill extern struct symtab *lastjxxx; 371601Sbill /* 372601Sbill * Lgensym is used to make up funny names for local labels. 373601Sbill * lgensym[i] is the current funny number to put after 374601Sbill * references to if, lgensym[i]-1 is for ib. 375601Sbill * genref[i] is set when the label is referenced before 376601Sbill * it is defined (i.e. 2f) so that we can be sure these 377601Sbill * labels are always defined to avoid weird diagnostics 378601Sbill * from the loader later. 379601Sbill */ 380601Sbill extern int lgensym[10]; 381601Sbill extern char genref[10]; 382601Sbill 383601Sbill extern struct exp *dotp; /* the current dot location */ 384601Sbill extern int loctr; 385601Sbill 386601Sbill extern struct exec hdr; /* a.out header */ 387601Sbill extern u_long tsize; /* total text size */ 388601Sbill extern u_long dsize; /* total data size */ 389601Sbill extern u_long trsize; /* total text relocation size */ 390601Sbill extern u_long drsize; /* total data relocation size */ 391601Sbill extern u_long datbase; /* base of the data segment */ 392601Sbill /* 393601Sbill * Bitoff and bitfield keep track of the packing into 394601Sbill * bytes mandated by the expression syntax <expr> ':' <expr> 395601Sbill */ 396601Sbill extern int bitoff; 397601Sbill extern long bitfield; 398601Sbill 399601Sbill /* 400601Sbill * The lexical analyzer builds up symbols in yytext. Lookup 401601Sbill * expects its argument in this buffer 402601Sbill */ 40313461Srrh extern char yytext[NCPName+2]; /* text buffer for lexical */ 404601Sbill /* 405601Sbill * Variables to manage the input assembler source file 406601Sbill */ 407601Sbill extern int lineno; /*the line number*/ 408601Sbill extern char *dotsname; /*the name of the as source*/ 409601Sbill 41013515Srrh extern FILE *tokfile; /* temp token communication*/ 41113515Srrh extern FILE *strfile; /* temp string file*/ 41213515Srrh extern char tokfilename[TNAMESIZE]; /* token file name */ 41313515Srrh extern char strfilename[TNAMESIZE]; /* string file name */ 41413515Srrh extern int strfilepos; /* position in string file */ 415601Sbill 416601Sbill extern int passno; /* 1 or 2 */ 417601Sbill 4185829Srrh extern int anyerrs; /*errors as'ing arguments*/ 4195829Srrh extern int anywarnings; /*warnings as'ing arguments*/ 420601Sbill extern int silent; /*don't mention the errors*/ 421601Sbill extern int savelabels; /*save labels in a.out*/ 422601Sbill extern int orgwarn; /* questionable origin ? */ 423601Sbill extern int useVM; /*use virtual memory temp file*/ 424637Shenry extern int jxxxJUMP; /*use jmp instead of brw for jxxx */ 425639Sbill extern int readonlydata; /*initialized data into text space*/ 4265829Srrh extern int nGHnumbers; /* GH numbers used */ 4275829Srrh extern int nGHopcodes; /* GH opcodes used */ 4285829Srrh extern int nnewopcodes; /* new opcodes used */ 429601Sbill #ifdef DEBUG 430601Sbill extern int debug; 431601Sbill extern int toktrace; 432601Sbill #endif 433601Sbill /* 434601Sbill * Information about the instructions 435601Sbill */ 4365829Srrh extern struct instab **itab[NINST]; /*maps opcodes to instructions*/ 437635Shenry extern readonly struct Instab instab[]; 438601Sbill 439601Sbill extern int curlen; /*current literal storage size*/ 440601Sbill extern int d124; /*current pointer storage size*/ 44115561Srrh extern int maxalign; /*maximum .align allowed*/ 442601Sbill 443601Sbill struct symtab **lookup(); /*argument in yytext*/ 444601Sbill struct symtab *symalloc(); 445601Sbill 4465829Srrh char *Calloc(); 4475829Srrh char *ClearCalloc(); 4485829Srrh 449635Shenry #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));} 450601Sbill 451635Shenry #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) 452601Sbill 4535829Srrh #define Outb(o) outb(o) 454601Sbill /* 455601Sbill * Most of the time, the argument to flushfield is a power of two constant, 456601Sbill * the calculations involving it can be optimized to shifts. 457601Sbill */ 458601Sbill #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) 459601Sbill 460601Sbill /* 461601Sbill * The biobuf structure and associated routines are used to write 462601Sbill * into one file at several places concurrently. Calling bopen 463601Sbill * with a biobuf structure sets it up to write ``biofd'' starting 464601Sbill * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' 465601Sbill * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. 466601Sbill * Calling bflush drains all the buffers and MUST be done before exit. 467601Sbill */ 468601Sbill struct biobuf { 469601Sbill short b_nleft; /* Number free spaces left in b_buf */ 470601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */ 471601Sbill char *b_ptr; /* Next place to stuff characters */ 47216069Sralph char *b_buf; /* Pointer to the buffer */ 473601Sbill off_t b_off; /* Current file offset */ 474601Sbill struct biobuf *b_link; /* Link in chain for bflush() */ 475601Sbill }; 476601Sbill #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \ 477601Sbill : bflushc(b, c)) 478601Sbill #define BFILE struct biobuf 479601Sbill 480601Sbill extern BFILE *biobufs; /* head of the block I/O buffer chain */ 481601Sbill extern int biofd; /* file descriptor for block I/O file */ 48216069Sralph extern int biobufsize; /* optimal block size for I/O */ 483601Sbill extern off_t boffset; /* physical position in logical file */ 484601Sbill 485601Sbill /* 486601Sbill * For each of the named .text .data segments 487601Sbill * (introduced by .text <expr>), we maintain 488601Sbill * the current value of the dot, and the BFILE where 489601Sbill * the information for each of the segments is placed 490601Sbill * during the second pass. 491601Sbill */ 492601Sbill extern struct exp usedot[NLOC + NLOC]; 493601Sbill extern BFILE *usefile[NLOC + NLOC]; 494601Sbill extern BFILE *txtfil;/* file for text and data: into usefile */ 495601Sbill /* 496601Sbill * Relocation information for each segment is accumulated 497601Sbill * seperately from the others. Writing the relocation 498601Sbill * information is logically viewed as writing to one 499601Sbill * relocation saving file for each segment; physically 500601Sbill * we have a bunch of buffers allocated internally that 501601Sbill * contain the relocation information. 502601Sbill */ 503601Sbill struct relbufdesc *rusefile[NLOC + NLOC]; 504601Sbill struct relbufdesc *relfil; 505