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