]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/obj-ecoff.c
* config/obj-ecoff.h (ecoff_build_lineno): Make ilineMax in
[thirdparty/binutils-gdb.git] / gas / config / obj-ecoff.c
1 /* ECOFF object file format.
2 Copyright (C) 1993 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4 This file was put together by Ian Lance Taylor <ian@cygnus.com>. A
5 good deal of it comes directly from mips-tfile.c, by Michael
6 Meissner <meissner@osf.org>.
7
8 This file is part of GAS.
9
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
23
24 #include "as.h"
25 #include "coff/internal.h"
26 #include "coff/mips.h"
27 #include "coff/sym.h"
28 #include "coff/symconst.h"
29 #include "coff/ecoff-ext.h"
30 #include "aout/stab_gnu.h"
31 #include "../bfd/libecoff.h"
32
33 #include <ctype.h>
34
35 /* Why isn't this in coff/sym.h? */
36 #define ST_RFDESCAPE 0xfff
37
38 /* The ECOFF file format uses COFF style sections, but with a unique
39 debugging format. We just build generic BFD sections since BFD
40 knows how to write them out. The debugging format, however, we
41 must construct here; all BFD knows at the moment is to write it out
42 as a large block of data.
43
44 We support both COFF style debugging and stabs debugging (the stabs
45 symbols are encapsulated in COFF symbols). This should let us
46 handle anything the compiler might throw at us. Parsing the COFF
47 and stabs debugging information is similar to work done by COFF and
48 a.out targets, but since the result is completely different the
49 code is not shared. */
50
51 /* Here is a brief description of the MIPS ECOFF symbol table, by
52 Michael Meissner. The MIPS symbol table has the following pieces:
53
54 Symbolic Header
55 |
56 +-- Auxiliary Symbols
57 |
58 +-- Dense number table
59 |
60 +-- Optimizer Symbols
61 |
62 +-- External Strings
63 |
64 +-- External Symbols
65 |
66 +-- Relative file descriptors
67 |
68 +-- File table
69 |
70 +-- Procedure table
71 |
72 +-- Line number table
73 |
74 +-- Local Strings
75 |
76 +-- Local Symbols
77
78 The symbolic header points to each of the other tables, and also
79 contains the number of entries. It also contains a magic number
80 and MIPS compiler version number, such as 2.0.
81
82 The auxiliary table is a series of 32 bit integers, that are
83 referenced as needed from the local symbol table. Unlike standard
84 COFF, the aux. information does not follow the symbol that uses
85 it, but rather is a separate table. In theory, this would allow
86 the MIPS compilers to collapse duplicate aux. entries, but I've not
87 noticed this happening with the 1.31 compiler suite. The different
88 types of aux. entries are:
89
90 1) dnLow: Low bound on array dimension.
91
92 2) dnHigh: High bound on array dimension.
93
94 3) isym: Index to the local symbol which is the start of the
95 function for the end of function first aux. entry.
96
97 4) width: Width of structures and bitfields.
98
99 5) count: Count of ranges for variant part.
100
101 6) rndx: A relative index into the symbol table. The relative
102 index field has two parts: rfd which is a pointer into the
103 relative file index table or ST_RFDESCAPE which says the next
104 aux. entry is the file number, and index: which is the pointer
105 into the local symbol within a given file table. This is for
106 things like references to types defined in another file.
107
108 7) Type information: This is like the COFF type bits, except it
109 is 32 bits instead of 16; they still have room to add new
110 basic types; and they can handle more than 6 levels of array,
111 pointer, function, etc. Each type information field contains
112 the following structure members:
113
114 a) fBitfield: a bit that says this is a bitfield, and the
115 size in bits follows as the next aux. entry.
116
117 b) continued: a bit that says the next aux. entry is a
118 continuation of the current type information (in case
119 there are more than 6 levels of array/ptr/function).
120
121 c) bt: an integer containing the base type before adding
122 array, pointer, function, etc. qualifiers. The
123 current base types that I have documentation for are:
124
125 btNil -- undefined
126 btAdr -- address - integer same size as ptr
127 btChar -- character
128 btUChar -- unsigned character
129 btShort -- short
130 btUShort -- unsigned short
131 btInt -- int
132 btUInt -- unsigned int
133 btLong -- long
134 btULong -- unsigned long
135 btFloat -- float (real)
136 btDouble -- Double (real)
137 btStruct -- Structure (Record)
138 btUnion -- Union (variant)
139 btEnum -- Enumerated
140 btTypedef -- defined via a typedef isymRef
141 btRange -- subrange of int
142 btSet -- pascal sets
143 btComplex -- fortran complex
144 btDComplex -- fortran double complex
145 btIndirect -- forward or unnamed typedef
146 btFixedDec -- Fixed Decimal
147 btFloatDec -- Float Decimal
148 btString -- Varying Length Character String
149 btBit -- Aligned Bit String
150 btPicture -- Picture
151 btVoid -- Void (MIPS cc revision >= 2.00)
152
153 d) tq0 - tq5: type qualifier fields as needed. The
154 current type qualifier fields I have documentation for
155 are:
156
157 tqNil -- no more qualifiers
158 tqPtr -- pointer
159 tqProc -- procedure
160 tqArray -- array
161 tqFar -- 8086 far pointers
162 tqVol -- volatile
163
164
165 The dense number table is used in the front ends, and disappears by
166 the time the .o is created.
167
168 With the 1.31 compiler suite, the optimization symbols don't seem
169 to be used as far as I can tell.
170
171 The linker is the first entity that creates the relative file
172 descriptor table, and I believe it is used so that the individual
173 file table pointers don't have to be rewritten when the objects are
174 merged together into the program file.
175
176 Unlike COFF, the basic symbol & string tables are split into
177 external and local symbols/strings. The relocation information
178 only goes off of the external symbol table, and the debug
179 information only goes off of the internal symbol table. The
180 external symbols can have links to an appropriate file index and
181 symbol within the file to give it the appropriate type information.
182 Because of this, the external symbols are actually larger than the
183 internal symbols (to contain the link information), and contain the
184 local symbol structure as a member, though this member is not the
185 first member of the external symbol structure (!). I suspect this
186 split is to make strip easier to deal with.
187
188 Each file table has offsets for where the line numbers, local
189 strings, local symbols, and procedure table starts from within the
190 global tables, and the indexs are reset to 0 for each of those
191 tables for the file.
192
193 The procedure table contains the binary equivalents of the .ent
194 (start of the function address), .frame (what register is the
195 virtual frame pointer, constant offset from the register to obtain
196 the VFP, and what register holds the return address), .mask/.fmask
197 (bitmask of saved registers, and where the first register is stored
198 relative to the VFP) assembler directives. It also contains the
199 low and high bounds of the line numbers if debugging is turned on.
200
201 The line number table is a compressed form of the normal COFF line
202 table. Each line number entry is either 1 or 3 bytes long, and
203 contains a signed delta from the previous line, and an unsigned
204 count of the number of instructions this statement takes.
205
206 The local symbol table contains the following fields:
207
208 1) iss: index to the local string table giving the name of the
209 symbol.
210
211 2) value: value of the symbol (address, register number, etc.).
212
213 3) st: symbol type. The current symbol types are:
214
215 stNil -- Nuthin' special
216 stGlobal -- external symbol
217 stStatic -- static
218 stParam -- procedure argument
219 stLocal -- local variable
220 stLabel -- label
221 stProc -- External Procedure
222 stBlock -- beginning of block
223 stEnd -- end (of anything)
224 stMember -- member (of anything)
225 stTypedef -- type definition
226 stFile -- file name
227 stRegReloc -- register relocation
228 stForward -- forwarding address
229 stStaticProc -- Static procedure
230 stConstant -- const
231
232 4) sc: storage class. The current storage classes are:
233
234 scText -- text symbol
235 scData -- initialized data symbol
236 scBss -- un-initialized data symbol
237 scRegister -- value of symbol is register number
238 scAbs -- value of symbol is absolute
239 scUndefined -- who knows?
240 scCdbLocal -- variable's value is IN se->va.??
241 scBits -- this is a bit field
242 scCdbSystem -- value is IN debugger's address space
243 scRegImage -- register value saved on stack
244 scInfo -- symbol contains debugger information
245 scUserStruct -- addr in struct user for current process
246 scSData -- load time only small data
247 scSBss -- load time only small common
248 scRData -- load time only read only data
249 scVar -- Var parameter (fortranpascal)
250 scCommon -- common variable
251 scSCommon -- small common
252 scVarRegister -- Var parameter in a register
253 scVariant -- Variant record
254 scSUndefined -- small undefined(external) data
255 scInit -- .init section symbol
256
257 5) index: pointer to a local symbol or aux. entry.
258
259
260
261 For the following program:
262
263 #include <stdio.h>
264
265 main(){
266 printf("Hello World!\n");
267 return 0;
268 }
269
270 Mips-tdump produces the following information:
271
272 Global file header:
273 magic number 0x162
274 # sections 2
275 timestamp 645311799, Wed Jun 13 17:16:39 1990
276 symbolic header offset 284
277 symbolic header size 96
278 optional header 56
279 flags 0x0
280
281 Symbolic header, magic number = 0x7009, vstamp = 1.31:
282
283 Info Offset Number Bytes
284 ==== ====== ====== =====
285
286 Line numbers 380 4 4 [13]
287 Dense numbers 0 0 0
288 Procedures Tables 384 1 52
289 Local Symbols 436 16 192
290 Optimization Symbols 0 0 0
291 Auxiliary Symbols 628 39 156
292 Local Strings 784 80 80
293 External Strings 864 144 144
294 File Tables 1008 2 144
295 Relative Files 0 0 0
296 External Symbols 1152 20 320
297
298 File #0, "hello2.c"
299
300 Name index = 1 Readin = No
301 Merge = No Endian = LITTLE
302 Debug level = G2 Language = C
303 Adr = 0x00000000
304
305 Info Start Number Size Offset
306 ==== ===== ====== ==== ======
307 Local strings 0 15 15 784
308 Local symbols 0 6 72 436
309 Line numbers 0 13 13 380
310 Optimization symbols 0 0 0 0
311 Procedures 0 1 52 384
312 Auxiliary symbols 0 14 56 628
313 Relative Files 0 0 0 0
314
315 There are 6 local symbols, starting at 436
316
317 Symbol# 0: "hello2.c"
318 End+1 symbol = 6
319 String index = 1
320 Storage class = Text Index = 6
321 Symbol type = File Value = 0
322
323 Symbol# 1: "main"
324 End+1 symbol = 5
325 Type = int
326 String index = 10
327 Storage class = Text Index = 12
328 Symbol type = Proc Value = 0
329
330 Symbol# 2: ""
331 End+1 symbol = 4
332 String index = 0
333 Storage class = Text Index = 4
334 Symbol type = Block Value = 8
335
336 Symbol# 3: ""
337 First symbol = 2
338 String index = 0
339 Storage class = Text Index = 2
340 Symbol type = End Value = 28
341
342 Symbol# 4: "main"
343 First symbol = 1
344 String index = 10
345 Storage class = Text Index = 1
346 Symbol type = End Value = 52
347
348 Symbol# 5: "hello2.c"
349 First symbol = 0
350 String index = 1
351 Storage class = Text Index = 0
352 Symbol type = End Value = 0
353
354 There are 14 auxiliary table entries, starting at 628.
355
356 * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
357 * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
358 * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0]
359 * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0]
360 * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
361 * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0]
362 * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0]
363 * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0]
364 * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0]
365 * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0]
366 * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0]
367 * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0]
368 #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0]
369 #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
370
371 There are 1 procedure descriptor entries, starting at 0.
372
373 Procedure descriptor 0:
374 Name index = 10 Name = "main"
375 .mask 0x80000000,-4 .fmask 0x00000000,0
376 .frame $29,24,$31
377 Opt. start = -1 Symbols start = 1
378 First line # = 3 Last line # = 6
379 Line Offset = 0 Address = 0x00000000
380
381 There are 4 bytes holding line numbers, starting at 380.
382 Line 3, delta 0, count 2
383 Line 4, delta 1, count 3
384 Line 5, delta 1, count 2
385 Line 6, delta 1, count 6
386
387 File #1, "/usr/include/stdio.h"
388
389 Name index = 1 Readin = No
390 Merge = Yes Endian = LITTLE
391 Debug level = G2 Language = C
392 Adr = 0x00000000
393
394 Info Start Number Size Offset
395 ==== ===== ====== ==== ======
396 Local strings 15 65 65 799
397 Local symbols 6 10 120 508
398 Line numbers 0 0 0 380
399 Optimization symbols 0 0 0 0
400 Procedures 1 0 0 436
401 Auxiliary symbols 14 25 100 684
402 Relative Files 0 0 0 0
403
404 There are 10 local symbols, starting at 442
405
406 Symbol# 0: "/usr/include/stdio.h"
407 End+1 symbol = 10
408 String index = 1
409 Storage class = Text Index = 10
410 Symbol type = File Value = 0
411
412 Symbol# 1: "_iobuf"
413 End+1 symbol = 9
414 String index = 22
415 Storage class = Info Index = 9
416 Symbol type = Block Value = 20
417
418 Symbol# 2: "_cnt"
419 Type = int
420 String index = 29
421 Storage class = Info Index = 4
422 Symbol type = Member Value = 0
423
424 Symbol# 3: "_ptr"
425 Type = ptr to char
426 String index = 34
427 Storage class = Info Index = 15
428 Symbol type = Member Value = 32
429
430 Symbol# 4: "_base"
431 Type = ptr to char
432 String index = 39
433 Storage class = Info Index = 16
434 Symbol type = Member Value = 64
435
436 Symbol# 5: "_bufsiz"
437 Type = int
438 String index = 45
439 Storage class = Info Index = 4
440 Symbol type = Member Value = 96
441
442 Symbol# 6: "_flag"
443 Type = short
444 String index = 53
445 Storage class = Info Index = 3
446 Symbol type = Member Value = 128
447
448 Symbol# 7: "_file"
449 Type = char
450 String index = 59
451 Storage class = Info Index = 2
452 Symbol type = Member Value = 144
453
454 Symbol# 8: ""
455 First symbol = 1
456 String index = 0
457 Storage class = Info Index = 1
458 Symbol type = End Value = 0
459
460 Symbol# 9: "/usr/include/stdio.h"
461 First symbol = 0
462 String index = 1
463 Storage class = Text Index = 0
464 Symbol type = End Value = 0
465
466 There are 25 auxiliary table entries, starting at 642.
467
468 * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
469 #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
470 #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
471 * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0]
472 * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1]
473 * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
474 * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4]
475 * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
476 * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
477 * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0]
478 * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0]
479 * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
480 * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
481 * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
482 * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
483 * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
484 * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
485 * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
486 * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
487 * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
488 * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
489 * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
490 * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
491 * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
492 * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
493
494 There are 0 procedure descriptor entries, starting at 1.
495
496 There are 20 external symbols, starting at 1152
497
498 Symbol# 0: "_iob"
499 Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
500 String index = 0 Ifd = 1
501 Storage class = Nil Index = 17
502 Symbol type = Global Value = 60
503
504 Symbol# 1: "fopen"
505 String index = 5 Ifd = 1
506 Storage class = Nil Index = 1048575
507 Symbol type = Proc Value = 0
508
509 Symbol# 2: "fdopen"
510 String index = 11 Ifd = 1
511 Storage class = Nil Index = 1048575
512 Symbol type = Proc Value = 0
513
514 Symbol# 3: "freopen"
515 String index = 18 Ifd = 1
516 Storage class = Nil Index = 1048575
517 Symbol type = Proc Value = 0
518
519 Symbol# 4: "popen"
520 String index = 26 Ifd = 1
521 Storage class = Nil Index = 1048575
522 Symbol type = Proc Value = 0
523
524 Symbol# 5: "tmpfile"
525 String index = 32 Ifd = 1
526 Storage class = Nil Index = 1048575
527 Symbol type = Proc Value = 0
528
529 Symbol# 6: "ftell"
530 String index = 40 Ifd = 1
531 Storage class = Nil Index = 1048575
532 Symbol type = Proc Value = 0
533
534 Symbol# 7: "rewind"
535 String index = 46 Ifd = 1
536 Storage class = Nil Index = 1048575
537 Symbol type = Proc Value = 0
538
539 Symbol# 8: "setbuf"
540 String index = 53 Ifd = 1
541 Storage class = Nil Index = 1048575
542 Symbol type = Proc Value = 0
543
544 Symbol# 9: "setbuffer"
545 String index = 60 Ifd = 1
546 Storage class = Nil Index = 1048575
547 Symbol type = Proc Value = 0
548
549 Symbol# 10: "setlinebuf"
550 String index = 70 Ifd = 1
551 Storage class = Nil Index = 1048575
552 Symbol type = Proc Value = 0
553
554 Symbol# 11: "fgets"
555 String index = 81 Ifd = 1
556 Storage class = Nil Index = 1048575
557 Symbol type = Proc Value = 0
558
559 Symbol# 12: "gets"
560 String index = 87 Ifd = 1
561 Storage class = Nil Index = 1048575
562 Symbol type = Proc Value = 0
563
564 Symbol# 13: "ctermid"
565 String index = 92 Ifd = 1
566 Storage class = Nil Index = 1048575
567 Symbol type = Proc Value = 0
568
569 Symbol# 14: "cuserid"
570 String index = 100 Ifd = 1
571 Storage class = Nil Index = 1048575
572 Symbol type = Proc Value = 0
573
574 Symbol# 15: "tempnam"
575 String index = 108 Ifd = 1
576 Storage class = Nil Index = 1048575
577 Symbol type = Proc Value = 0
578
579 Symbol# 16: "tmpnam"
580 String index = 116 Ifd = 1
581 Storage class = Nil Index = 1048575
582 Symbol type = Proc Value = 0
583
584 Symbol# 17: "sprintf"
585 String index = 123 Ifd = 1
586 Storage class = Nil Index = 1048575
587 Symbol type = Proc Value = 0
588
589 Symbol# 18: "main"
590 Type = int
591 String index = 131 Ifd = 0
592 Storage class = Text Index = 1
593 Symbol type = Proc Value = 0
594
595 Symbol# 19: "printf"
596 String index = 136 Ifd = 0
597 Storage class = Undefined Index = 1048575
598 Symbol type = Proc Value = 0
599
600 The following auxiliary table entries were unused:
601
602 #0 0 0x00000000 void
603 #2 8 0x00000008 char
604 #3 16 0x00000010 short
605 #4 24 0x00000018 int
606 #5 32 0x00000020 long
607 #6 40 0x00000028 float
608 #7 44 0x0000002c double
609 #8 12 0x0000000c unsigned char
610 #9 20 0x00000014 unsigned short
611 #10 28 0x0000001c unsigned int
612 #11 36 0x00000024 unsigned long
613 #14 0 0x00000000 void
614 #15 24 0x00000018 int
615 #19 32 0x00000020 long
616 #20 40 0x00000028 float
617 #21 44 0x0000002c double
618 #22 12 0x0000000c unsigned char
619 #23 20 0x00000014 unsigned short
620 #24 28 0x0000001c unsigned int
621 #25 36 0x00000024 unsigned long
622 #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 }
623 \f
624 */
625 /* Redefinition of of storage classes as an enumeration for better
626 debugging. */
627
628 typedef enum sc {
629 sc_Nil = scNil, /* no storage class */
630 sc_Text = scText, /* text symbol */
631 sc_Data = scData, /* initialized data symbol */
632 sc_Bss = scBss, /* un-initialized data symbol */
633 sc_Register = scRegister, /* value of symbol is register number */
634 sc_Abs = scAbs, /* value of symbol is absolute */
635 sc_Undefined = scUndefined, /* who knows? */
636 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
637 sc_Bits = scBits, /* this is a bit field */
638 sc_CdbSystem = scCdbSystem, /* value is IN CDB's address space */
639 sc_RegImage = scRegImage, /* register value saved on stack */
640 sc_Info = scInfo, /* symbol contains debugger information */
641 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
642 sc_SData = scSData, /* load time only small data */
643 sc_SBss = scSBss, /* load time only small common */
644 sc_RData = scRData, /* load time only read only data */
645 sc_Var = scVar, /* Var parameter (fortran,pascal) */
646 sc_Common = scCommon, /* common variable */
647 sc_SCommon = scSCommon, /* small common */
648 sc_VarRegister = scVarRegister, /* Var parameter in a register */
649 sc_Variant = scVariant, /* Variant record */
650 sc_SUndefined = scSUndefined, /* small undefined(external) data */
651 sc_Init = scInit, /* .init section symbol */
652 sc_Max = scMax /* Max storage class+1 */
653 } sc_t;
654
655 /* Redefinition of symbol type. */
656
657 typedef enum st {
658 st_Nil = stNil, /* Nuthin' special */
659 st_Global = stGlobal, /* external symbol */
660 st_Static = stStatic, /* static */
661 st_Param = stParam, /* procedure argument */
662 st_Local = stLocal, /* local variable */
663 st_Label = stLabel, /* label */
664 st_Proc = stProc, /* " " Procedure */
665 st_Block = stBlock, /* beginning of block */
666 st_End = stEnd, /* end (of anything) */
667 st_Member = stMember, /* member (of anything - struct/union/enum */
668 st_Typedef = stTypedef, /* type definition */
669 st_File = stFile, /* file name */
670 st_RegReloc = stRegReloc, /* register relocation */
671 st_Forward = stForward, /* forwarding address */
672 st_StaticProc = stStaticProc, /* load time only static procs */
673 st_Constant = stConstant, /* const */
674 st_Str = stStr, /* string */
675 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
676 st_Expr = stExpr, /* 2+2 vs. 4 */
677 st_Type = stType, /* post-coercion SER */
678 st_Max = stMax /* max type+1 */
679 } st_t;
680
681 /* Redefinition of type qualifiers. */
682
683 typedef enum tq {
684 tq_Nil = tqNil, /* bt is what you see */
685 tq_Ptr = tqPtr, /* pointer */
686 tq_Proc = tqProc, /* procedure */
687 tq_Array = tqArray, /* duh */
688 tq_Far = tqFar, /* longer addressing - 8086/8 land */
689 tq_Vol = tqVol, /* volatile */
690 tq_Max = tqMax /* Max type qualifier+1 */
691 } tq_t;
692
693 /* Redefinition of basic types. */
694
695 typedef enum bt {
696 bt_Nil = btNil, /* undefined */
697 bt_Adr = btAdr, /* address - integer same size as pointer */
698 bt_Char = btChar, /* character */
699 bt_UChar = btUChar, /* unsigned character */
700 bt_Short = btShort, /* short */
701 bt_UShort = btUShort, /* unsigned short */
702 bt_Int = btInt, /* int */
703 bt_UInt = btUInt, /* unsigned int */
704 bt_Long = btLong, /* long */
705 bt_ULong = btULong, /* unsigned long */
706 bt_Float = btFloat, /* float (real) */
707 bt_Double = btDouble, /* Double (real) */
708 bt_Struct = btStruct, /* Structure (Record) */
709 bt_Union = btUnion, /* Union (variant) */
710 bt_Enum = btEnum, /* Enumerated */
711 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
712 bt_Range = btRange, /* subrange of int */
713 bt_Set = btSet, /* pascal sets */
714 bt_Complex = btComplex, /* fortran complex */
715 bt_DComplex = btDComplex, /* fortran double complex */
716 bt_Indirect = btIndirect, /* forward or unnamed typedef */
717 bt_FixedDec = btFixedDec, /* Fixed Decimal */
718 bt_FloatDec = btFloatDec, /* Float Decimal */
719 bt_String = btString, /* Varying Length Character String */
720 bt_Bit = btBit, /* Aligned Bit String */
721 bt_Picture = btPicture, /* Picture */
722 bt_Void = btVoid, /* Void */
723 bt_Max = btMax /* Max basic type+1 */
724 } bt_t;
725
726 #define N_TQ itqMax
727
728 /* States for whether to hash type or not. */
729 typedef enum hash_state {
730 hash_no = 0, /* don't hash type */
731 hash_yes = 1, /* ok to hash type, or use previous hash */
732 hash_record = 2 /* ok to record hash, but don't use prev. */
733 } hash_state_t;
734
735 /* Types of different sized allocation requests. */
736 enum alloc_type {
737 alloc_type_none, /* dummy value */
738 alloc_type_scope, /* nested scopes linked list */
739 alloc_type_vlinks, /* glue linking pages in varray */
740 alloc_type_shash, /* string hash element */
741 alloc_type_thash, /* type hash element */
742 alloc_type_tag, /* struct/union/tag element */
743 alloc_type_forward, /* element to hold unknown tag */
744 alloc_type_thead, /* head of type hash list */
745 alloc_type_varray, /* general varray allocation */
746 alloc_type_lineno, /* line number list */
747 alloc_type_last /* last+1 element for array bounds */
748 };
749
750 /* Types of auxiliary type information. */
751 enum aux_type {
752 aux_tir, /* TIR type information */
753 aux_rndx, /* relative index into symbol table */
754 aux_dnLow, /* low dimension */
755 aux_dnHigh, /* high dimension */
756 aux_isym, /* symbol table index (end of proc) */
757 aux_iss, /* index into string space (not used) */
758 aux_width, /* width for non-default sized struc fields */
759 aux_count /* count of ranges for variant arm */
760 };
761 \f
762 /* Structures to provide n-number of virtual arrays, each of which can
763 grow linearly, and which are written in the object file as
764 sequential pages. On systems with a BSD malloc, the
765 MAX_CLUSTER_PAGES should be 1 less than a power of two, since
766 malloc adds it's overhead, and rounds up to the next power of 2.
767 Pages are linked together via a linked list.
768
769 If PAGE_SIZE is > 4096, the string length in the shash_t structure
770 can't be represented (assuming there are strings > 4096 bytes). */
771
772 #ifndef PAGE_SIZE
773 #define PAGE_SIZE 4096 /* size of varray pages */
774 #endif
775
776 #define PAGE_USIZE ((unsigned long) PAGE_SIZE)
777
778
779 #ifndef MAX_CLUSTER_PAGES /* # pages to get from system */
780 #define MAX_CLUSTER_PAGES 63
781 #endif
782
783
784 /* Linked list connecting separate page allocations. */
785 typedef struct vlinks {
786 struct vlinks *prev; /* previous set of pages */
787 struct vlinks *next; /* next set of pages */
788 union page *datum; /* start of page */
789 unsigned long start_index; /* starting index # of page */
790 } vlinks_t;
791
792
793 /* Virtual array header. */
794 typedef struct varray {
795 vlinks_t *first; /* first page link */
796 vlinks_t *last; /* last page link */
797 unsigned long num_allocated; /* # objects allocated */
798 unsigned short object_size; /* size in bytes of each object */
799 unsigned short objects_per_page; /* # objects that can fit on a page */
800 unsigned short objects_last_page; /* # objects allocated on last page */
801 } varray_t;
802
803 #ifndef MALLOC_CHECK
804 #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
805 #else
806 #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
807 #endif
808
809 #define INIT_VARRAY(type) { /* macro to initialize a varray */ \
810 (vlinks_t *)0, /* first */ \
811 (vlinks_t *)0, /* last */ \
812 0, /* num_allocated */ \
813 sizeof (type), /* object_size */ \
814 OBJECTS_PER_PAGE (type), /* objects_per_page */ \
815 OBJECTS_PER_PAGE (type), /* objects_last_page */ \
816 }
817
818
819 /* Master type for indexes within the symbol table. */
820 typedef unsigned long symint_t;
821
822
823 /* Linked list support for nested scopes (file, block, structure, etc.). */
824 typedef struct scope {
825 struct scope *prev; /* previous scope level */
826 struct scope *free; /* free list pointer */
827 struct localsym *lsym; /* pointer to local symbol node */
828 st_t type; /* type of the node */
829 } scope_t;
830
831
832 /* For a local symbol we store a gas symbol as well as the debugging
833 information we generate. The gas symbol will be NULL if this is
834 only a debugging symbol. */
835 typedef struct localsym {
836 const char *name; /* symbol name */
837 symbolS *as_sym; /* symbol as seen by gas */
838 struct efdr *file_ptr; /* file pointer */
839 struct ecoff_proc *proc_ptr; /* proc pointer */
840 struct localsym *begin_ptr; /* symbol at start of block */
841 struct ecoff_aux *index_ptr; /* index value to be filled in */
842 struct forward *forward_ref; /* forward references to this symbol */
843 long sym_index; /* final symbol index */
844 SYMR ecoff_sym; /* ECOFF debugging symbol */
845 } localsym_t;
846
847
848 /* For aux information we keep the type and the data. */
849 typedef struct ecoff_aux {
850 enum aux_type type; /* aux type */
851 AUXU data; /* aux data */
852 } aux_t;
853
854 /* For a procedure we store the gas symbol as well as the PDR
855 debugging information. */
856 typedef struct ecoff_proc {
857 localsym_t *sym; /* associated symbol */
858 PDR pdr; /* ECOFF debugging info */
859 } proc_t;
860
861 /* Number of proc_t structures allocated. */
862 static unsigned long proc_cnt;
863
864
865 /* Forward reference list for tags referenced, but not yet defined. */
866 typedef struct forward {
867 struct forward *next; /* next forward reference */
868 struct forward *free; /* free list pointer */
869 aux_t *ifd_ptr; /* pointer to store file index */
870 aux_t *index_ptr; /* pointer to store symbol index */
871 } forward_t;
872
873
874 /* Linked list support for tags. The first tag in the list is always
875 the current tag for that block. */
876 typedef struct tag {
877 struct tag *free; /* free list pointer */
878 struct shash *hash_ptr; /* pointer to the hash table head */
879 struct tag *same_name; /* tag with same name in outer scope */
880 struct tag *same_block; /* next tag defined in the same block. */
881 struct forward *forward_ref; /* list of forward references */
882 bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
883 symint_t ifd; /* file # tag defined in */
884 localsym_t *sym; /* file's local symbols */
885 } tag_t;
886
887
888 /* Head of a block's linked list of tags. */
889 typedef struct thead {
890 struct thead *prev; /* previous block */
891 struct thead *free; /* free list pointer */
892 struct tag *first_tag; /* first tag in block defined */
893 } thead_t;
894
895
896 /* Union containing pointers to each the small structures which are freed up. */
897 typedef union small_free {
898 scope_t *f_scope; /* scope structure */
899 thead_t *f_thead; /* tag head structure */
900 tag_t *f_tag; /* tag element structure */
901 forward_t *f_forward; /* forward tag reference */
902 } small_free_t;
903
904
905 /* String hash table entry. */
906
907 typedef struct shash {
908 char *string; /* string we are hashing */
909 symint_t indx; /* index within string table */
910 EXTR *esym_ptr; /* global symbol pointer */
911 localsym_t *sym_ptr; /* local symbol pointer */
912 localsym_t *end_ptr; /* symbol pointer to end block */
913 tag_t *tag_ptr; /* tag pointer */
914 proc_t *proc_ptr; /* procedure descriptor pointer */
915 } shash_t;
916
917
918 /* Type hash table support. The size of the hash table must fit
919 within a page with the other extended file descriptor information.
920 Because unique types which are hashed are fewer in number than
921 strings, we use a smaller hash value. */
922
923 #define HASHBITS 30
924
925 #ifndef THASH_SIZE
926 #define THASH_SIZE 113
927 #endif
928
929 typedef struct thash {
930 struct thash *next; /* next hash value */
931 AUXU type; /* type we are hashing */
932 symint_t indx; /* index within string table */
933 } thash_t;
934
935
936 /* Extended file descriptor that contains all of the support necessary
937 to add things to each file separately. */
938 typedef struct efdr {
939 FDR fdr; /* File header to be written out */
940 FDR *orig_fdr; /* original file header */
941 char *name; /* filename */
942 symint_t void_type; /* aux. pointer to 'void' type */
943 symint_t int_type; /* aux. pointer to 'int' type */
944 scope_t *cur_scope; /* current nested scopes */
945 symint_t file_index; /* current file number */
946 int nested_scopes; /* # nested scopes */
947 varray_t strings; /* local strings */
948 varray_t symbols; /* local symbols */
949 varray_t procs; /* procedures */
950 varray_t aux_syms; /* auxiliary symbols */
951 struct efdr *next_file; /* next file descriptor */
952 /* string/type hash tables */
953 struct hash_control *str_hash; /* string hash table */
954 thash_t *thash_head[THASH_SIZE];
955 } efdr_t;
956
957 /* Pre-initialized extended file structure. */
958 static const efdr_t init_file =
959 {
960 { /* FDR structure */
961 0, /* adr: memory address of beginning of file */
962 0, /* rss: file name (of source, if known) */
963 0, /* issBase: file's string space */
964 0, /* cbSs: number of bytes in the ss */
965 0, /* isymBase: beginning of symbols */
966 0, /* csym: count file's of symbols */
967 0, /* ilineBase: file's line symbols */
968 0, /* cline: count of file's line symbols */
969 0, /* ioptBase: file's optimization entries */
970 0, /* copt: count of file's optimization entries */
971 0, /* ipdFirst: start of procedures for this file */
972 0, /* cpd: count of procedures for this file */
973 0, /* iauxBase: file's auxiliary entries */
974 0, /* caux: count of file's auxiliary entries */
975 0, /* rfdBase: index into the file indirect table */
976 0, /* crfd: count file indirect entries */
977 langC, /* lang: language for this file */
978 1, /* fMerge: whether this file can be merged */
979 0, /* fReadin: true if read in (not just created) */
980 #ifdef TARGET_BYTES_BIG_ENDIAN
981 1, /* fBigendian: if 1, compiled on big endian machine */
982 #else
983 0, /* fBigendian: if 1, compiled on big endian machine */
984 #endif
985 GLEVEL_2, /* glevel: level this file was compiled with */
986 0, /* reserved: reserved for future use */
987 0, /* cbLineOffset: byte offset from header for this file ln's */
988 0, /* cbLine: size of lines for this file */
989 },
990
991 (FDR *)0, /* orig_fdr: original file header pointer */
992 (char *)0, /* name: pointer to filename */
993 0, /* void_type: ptr to aux node for void type */
994 0, /* int_type: ptr to aux node for int type */
995 (scope_t *)0, /* cur_scope: current scope being processed */
996 0, /* file_index: current file # */
997 0, /* nested_scopes: # nested scopes */
998 INIT_VARRAY (char), /* strings: local string varray */
999 INIT_VARRAY (localsym_t), /* symbols: local symbols varray */
1000 INIT_VARRAY (proc_t), /* procs: procedure varray */
1001 INIT_VARRAY (aux_t), /* aux_syms: auxiliary symbols varray */
1002
1003 (struct efdr *)0, /* next_file: next file structure */
1004
1005 (struct hash_control *)0, /* str_hash: string hash table */
1006 { 0 }, /* thash_head: type hash table */
1007 };
1008
1009
1010 static efdr_t *first_file; /* first file descriptor */
1011 static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */
1012
1013
1014 /* Line number information is kept in a list until the assembly is
1015 finished. */
1016 typedef struct lineno_list {
1017 struct lineno_list *next; /* next element in list */
1018 efdr_t *file; /* file this line is in */
1019 proc_t *proc; /* procedure this line is in */
1020 fragS *frag; /* fragment this line number is in */
1021 unsigned long paddr; /* offset within fragment */
1022 long lineno; /* actual line number */
1023 } lineno_list_t;
1024
1025 static lineno_list_t *first_lineno;
1026 static lineno_list_t **last_lineno_ptr = &first_lineno;
1027
1028 /* Sometimes there will be some .loc statements before a .ent. We
1029 keep them in this list so that we can fill in the procedure pointer
1030 after we see the .ent. */
1031 static lineno_list_t *noproc_lineno;
1032
1033 /* Union of various things that are held in pages. */
1034 typedef union page {
1035 char byte [ PAGE_SIZE ];
1036 unsigned char ubyte [ PAGE_SIZE ];
1037 efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
1038 FDR ofile [ PAGE_SIZE / sizeof (FDR) ];
1039 proc_t proc [ PAGE_SIZE / sizeof (proc_t) ];
1040 localsym_t sym [ PAGE_SIZE / sizeof (localsym_t) ];
1041 aux_t aux [ PAGE_SIZE / sizeof (aux_t) ];
1042 DNR dense [ PAGE_SIZE / sizeof (DNR) ];
1043 scope_t scope [ PAGE_SIZE / sizeof (scope_t) ];
1044 vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ];
1045 shash_t shash [ PAGE_SIZE / sizeof (shash_t) ];
1046 thash_t thash [ PAGE_SIZE / sizeof (thash_t) ];
1047 tag_t tag [ PAGE_SIZE / sizeof (tag_t) ];
1048 forward_t forward [ PAGE_SIZE / sizeof (forward_t) ];
1049 thead_t thead [ PAGE_SIZE / sizeof (thead_t) ];
1050 lineno_list_t lineno [ PAGE_SIZE / sizeof (lineno_list_t) ];
1051 } page_t;
1052
1053
1054 /* Structure holding allocation information for small sized structures. */
1055 typedef struct alloc_info {
1056 char *alloc_name; /* name of this allocation type (must be first) */
1057 page_t *cur_page; /* current page being allocated from */
1058 small_free_t free_list; /* current free list if any */
1059 int unallocated; /* number of elements unallocated on page */
1060 int total_alloc; /* total number of allocations */
1061 int total_free; /* total number of frees */
1062 int total_pages; /* total number of pages allocated */
1063 } alloc_info_t;
1064
1065
1066 /* Type information collected together. */
1067 typedef struct type_info {
1068 bt_t basic_type; /* basic type */
1069 int orig_type; /* original COFF-based type */
1070 int num_tq; /* # type qualifiers */
1071 int num_dims; /* # dimensions */
1072 int num_sizes; /* # sizes */
1073 int extra_sizes; /* # extra sizes not tied with dims */
1074 tag_t * tag_ptr; /* tag pointer */
1075 int bitfield; /* symbol is a bitfield */
1076 tq_t type_qualifiers[N_TQ]; /* type qualifiers (ptr, func, array)*/
1077 symint_t dimensions [N_TQ]; /* dimensions for each array */
1078 symint_t sizes [N_TQ+2]; /* sizes of each array slice + size of
1079 struct/union/enum + bitfield size */
1080 } type_info_t;
1081
1082 /* Pre-initialized type_info struct. */
1083 static const type_info_t type_info_init = {
1084 bt_Nil, /* basic type */
1085 T_NULL, /* original COFF-based type */
1086 0, /* # type qualifiers */
1087 0, /* # dimensions */
1088 0, /* # sizes */
1089 0, /* sizes not tied with dims */
1090 NULL, /* ptr to tag */
1091 0, /* bitfield */
1092 { /* type qualifiers */
1093 tq_Nil,
1094 tq_Nil,
1095 tq_Nil,
1096 tq_Nil,
1097 tq_Nil,
1098 tq_Nil,
1099 },
1100 { /* dimensions */
1101 0,
1102 0,
1103 0,
1104 0,
1105 0,
1106 0
1107 },
1108 { /* sizes */
1109 0,
1110 0,
1111 0,
1112 0,
1113 0,
1114 0,
1115 0,
1116 0,
1117 },
1118 };
1119
1120 /* Global hash table for the tags table and global table for file
1121 descriptors. */
1122
1123 static varray_t file_desc = INIT_VARRAY (efdr_t);
1124
1125 static struct hash_control *tag_hash;
1126
1127 /* Static types for int and void. Also, remember the last function's
1128 type (which is set up when we encounter the declaration for the
1129 function, and used when the end block for the function is emitted. */
1130
1131 static type_info_t int_type_info;
1132 static type_info_t void_type_info;
1133 static type_info_t last_func_type_info;
1134 static symbolS *last_func_sym_value;
1135
1136
1137 /* Convert COFF basic type to ECOFF basic type. The T_NULL type
1138 really should use bt_Void, but this causes the current ecoff GDB to
1139 issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
1140 2.0) doesn't understand it, even though the compiler generates it.
1141 Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
1142 suite, but for now go with what works.
1143
1144 It would make sense for the .type and .scl directives to use the
1145 ECOFF numbers directly, rather than using the COFF numbers and
1146 mapping them. Unfortunately, this is historically what mips-tfile
1147 expects, and changing gcc now would be a considerable pain (the
1148 native compiler generates debugging information internally, rather
1149 than via the assembler, so it will never use .type or .scl). */
1150
1151 static const bt_t map_coff_types[] = {
1152 bt_Nil, /* T_NULL */
1153 bt_Nil, /* T_ARG */
1154 bt_Char, /* T_CHAR */
1155 bt_Short, /* T_SHORT */
1156 bt_Int, /* T_INT */
1157 bt_Long, /* T_LONG */
1158 bt_Float, /* T_FLOAT */
1159 bt_Double, /* T_DOUBLE */
1160 bt_Struct, /* T_STRUCT */
1161 bt_Union, /* T_UNION */
1162 bt_Enum, /* T_ENUM */
1163 bt_Enum, /* T_MOE */
1164 bt_UChar, /* T_UCHAR */
1165 bt_UShort, /* T_USHORT */
1166 bt_UInt, /* T_UINT */
1167 bt_ULong /* T_ULONG */
1168 };
1169
1170 /* Convert COFF storage class to ECOFF storage class. */
1171 static const sc_t map_coff_storage[] = {
1172 sc_Nil, /* 0: C_NULL */
1173 sc_Abs, /* 1: C_AUTO auto var */
1174 sc_Undefined, /* 2: C_EXT external */
1175 sc_Data, /* 3: C_STAT static */
1176 sc_Register, /* 4: C_REG register */
1177 sc_Undefined, /* 5: C_EXTDEF ??? */
1178 sc_Text, /* 6: C_LABEL label */
1179 sc_Text, /* 7: C_ULABEL user label */
1180 sc_Info, /* 8: C_MOS member of struct */
1181 sc_Abs, /* 9: C_ARG argument */
1182 sc_Info, /* 10: C_STRTAG struct tag */
1183 sc_Info, /* 11: C_MOU member of union */
1184 sc_Info, /* 12: C_UNTAG union tag */
1185 sc_Info, /* 13: C_TPDEF typedef */
1186 sc_Data, /* 14: C_USTATIC ??? */
1187 sc_Info, /* 15: C_ENTAG enum tag */
1188 sc_Info, /* 16: C_MOE member of enum */
1189 sc_Register, /* 17: C_REGPARM register parameter */
1190 sc_Bits, /* 18; C_FIELD bitfield */
1191 sc_Nil, /* 19 */
1192 sc_Nil, /* 20 */
1193 sc_Nil, /* 21 */
1194 sc_Nil, /* 22 */
1195 sc_Nil, /* 23 */
1196 sc_Nil, /* 24 */
1197 sc_Nil, /* 25 */
1198 sc_Nil, /* 26 */
1199 sc_Nil, /* 27 */
1200 sc_Nil, /* 28 */
1201 sc_Nil, /* 29 */
1202 sc_Nil, /* 30 */
1203 sc_Nil, /* 31 */
1204 sc_Nil, /* 32 */
1205 sc_Nil, /* 33 */
1206 sc_Nil, /* 34 */
1207 sc_Nil, /* 35 */
1208 sc_Nil, /* 36 */
1209 sc_Nil, /* 37 */
1210 sc_Nil, /* 38 */
1211 sc_Nil, /* 39 */
1212 sc_Nil, /* 40 */
1213 sc_Nil, /* 41 */
1214 sc_Nil, /* 42 */
1215 sc_Nil, /* 43 */
1216 sc_Nil, /* 44 */
1217 sc_Nil, /* 45 */
1218 sc_Nil, /* 46 */
1219 sc_Nil, /* 47 */
1220 sc_Nil, /* 48 */
1221 sc_Nil, /* 49 */
1222 sc_Nil, /* 50 */
1223 sc_Nil, /* 51 */
1224 sc_Nil, /* 52 */
1225 sc_Nil, /* 53 */
1226 sc_Nil, /* 54 */
1227 sc_Nil, /* 55 */
1228 sc_Nil, /* 56 */
1229 sc_Nil, /* 57 */
1230 sc_Nil, /* 58 */
1231 sc_Nil, /* 59 */
1232 sc_Nil, /* 60 */
1233 sc_Nil, /* 61 */
1234 sc_Nil, /* 62 */
1235 sc_Nil, /* 63 */
1236 sc_Nil, /* 64 */
1237 sc_Nil, /* 65 */
1238 sc_Nil, /* 66 */
1239 sc_Nil, /* 67 */
1240 sc_Nil, /* 68 */
1241 sc_Nil, /* 69 */
1242 sc_Nil, /* 70 */
1243 sc_Nil, /* 71 */
1244 sc_Nil, /* 72 */
1245 sc_Nil, /* 73 */
1246 sc_Nil, /* 74 */
1247 sc_Nil, /* 75 */
1248 sc_Nil, /* 76 */
1249 sc_Nil, /* 77 */
1250 sc_Nil, /* 78 */
1251 sc_Nil, /* 79 */
1252 sc_Nil, /* 80 */
1253 sc_Nil, /* 81 */
1254 sc_Nil, /* 82 */
1255 sc_Nil, /* 83 */
1256 sc_Nil, /* 84 */
1257 sc_Nil, /* 85 */
1258 sc_Nil, /* 86 */
1259 sc_Nil, /* 87 */
1260 sc_Nil, /* 88 */
1261 sc_Nil, /* 89 */
1262 sc_Nil, /* 90 */
1263 sc_Nil, /* 91 */
1264 sc_Nil, /* 92 */
1265 sc_Nil, /* 93 */
1266 sc_Nil, /* 94 */
1267 sc_Nil, /* 95 */
1268 sc_Nil, /* 96 */
1269 sc_Nil, /* 97 */
1270 sc_Nil, /* 98 */
1271 sc_Nil, /* 99 */
1272 sc_Text, /* 100: C_BLOCK block start/end */
1273 sc_Text, /* 101: C_FCN function start/end */
1274 sc_Info, /* 102: C_EOS end of struct/union/enum */
1275 sc_Nil, /* 103: C_FILE file start */
1276 sc_Nil, /* 104: C_LINE line number */
1277 sc_Nil, /* 105: C_ALIAS combined type info */
1278 sc_Nil, /* 106: C_HIDDEN ??? */
1279 };
1280
1281 /* Convert COFF storage class to ECOFF symbol type. */
1282 static const st_t map_coff_sym_type[] = {
1283 st_Nil, /* 0: C_NULL */
1284 st_Local, /* 1: C_AUTO auto var */
1285 st_Global, /* 2: C_EXT external */
1286 st_Static, /* 3: C_STAT static */
1287 st_Local, /* 4: C_REG register */
1288 st_Global, /* 5: C_EXTDEF ??? */
1289 st_Label, /* 6: C_LABEL label */
1290 st_Label, /* 7: C_ULABEL user label */
1291 st_Member, /* 8: C_MOS member of struct */
1292 st_Param, /* 9: C_ARG argument */
1293 st_Block, /* 10: C_STRTAG struct tag */
1294 st_Member, /* 11: C_MOU member of union */
1295 st_Block, /* 12: C_UNTAG union tag */
1296 st_Typedef, /* 13: C_TPDEF typedef */
1297 st_Static, /* 14: C_USTATIC ??? */
1298 st_Block, /* 15: C_ENTAG enum tag */
1299 st_Member, /* 16: C_MOE member of enum */
1300 st_Param, /* 17: C_REGPARM register parameter */
1301 st_Member, /* 18; C_FIELD bitfield */
1302 st_Nil, /* 19 */
1303 st_Nil, /* 20 */
1304 st_Nil, /* 21 */
1305 st_Nil, /* 22 */
1306 st_Nil, /* 23 */
1307 st_Nil, /* 24 */
1308 st_Nil, /* 25 */
1309 st_Nil, /* 26 */
1310 st_Nil, /* 27 */
1311 st_Nil, /* 28 */
1312 st_Nil, /* 29 */
1313 st_Nil, /* 30 */
1314 st_Nil, /* 31 */
1315 st_Nil, /* 32 */
1316 st_Nil, /* 33 */
1317 st_Nil, /* 34 */
1318 st_Nil, /* 35 */
1319 st_Nil, /* 36 */
1320 st_Nil, /* 37 */
1321 st_Nil, /* 38 */
1322 st_Nil, /* 39 */
1323 st_Nil, /* 40 */
1324 st_Nil, /* 41 */
1325 st_Nil, /* 42 */
1326 st_Nil, /* 43 */
1327 st_Nil, /* 44 */
1328 st_Nil, /* 45 */
1329 st_Nil, /* 46 */
1330 st_Nil, /* 47 */
1331 st_Nil, /* 48 */
1332 st_Nil, /* 49 */
1333 st_Nil, /* 50 */
1334 st_Nil, /* 51 */
1335 st_Nil, /* 52 */
1336 st_Nil, /* 53 */
1337 st_Nil, /* 54 */
1338 st_Nil, /* 55 */
1339 st_Nil, /* 56 */
1340 st_Nil, /* 57 */
1341 st_Nil, /* 58 */
1342 st_Nil, /* 59 */
1343 st_Nil, /* 60 */
1344 st_Nil, /* 61 */
1345 st_Nil, /* 62 */
1346 st_Nil, /* 63 */
1347 st_Nil, /* 64 */
1348 st_Nil, /* 65 */
1349 st_Nil, /* 66 */
1350 st_Nil, /* 67 */
1351 st_Nil, /* 68 */
1352 st_Nil, /* 69 */
1353 st_Nil, /* 70 */
1354 st_Nil, /* 71 */
1355 st_Nil, /* 72 */
1356 st_Nil, /* 73 */
1357 st_Nil, /* 74 */
1358 st_Nil, /* 75 */
1359 st_Nil, /* 76 */
1360 st_Nil, /* 77 */
1361 st_Nil, /* 78 */
1362 st_Nil, /* 79 */
1363 st_Nil, /* 80 */
1364 st_Nil, /* 81 */
1365 st_Nil, /* 82 */
1366 st_Nil, /* 83 */
1367 st_Nil, /* 84 */
1368 st_Nil, /* 85 */
1369 st_Nil, /* 86 */
1370 st_Nil, /* 87 */
1371 st_Nil, /* 88 */
1372 st_Nil, /* 89 */
1373 st_Nil, /* 90 */
1374 st_Nil, /* 91 */
1375 st_Nil, /* 92 */
1376 st_Nil, /* 93 */
1377 st_Nil, /* 94 */
1378 st_Nil, /* 95 */
1379 st_Nil, /* 96 */
1380 st_Nil, /* 97 */
1381 st_Nil, /* 98 */
1382 st_Nil, /* 99 */
1383 st_Block, /* 100: C_BLOCK block start/end */
1384 st_Proc, /* 101: C_FCN function start/end */
1385 st_End, /* 102: C_EOS end of struct/union/enum */
1386 st_File, /* 103: C_FILE file start */
1387 st_Nil, /* 104: C_LINE line number */
1388 st_Nil, /* 105: C_ALIAS combined type info */
1389 st_Nil, /* 106: C_HIDDEN ??? */
1390 };
1391
1392
1393 /* Keep track of different sized allocation requests. */
1394 static alloc_info_t alloc_counts[ (int)alloc_type_last ];
1395 \f
1396 /* Various statics. */
1397 static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */
1398 static proc_t *cur_proc_ptr = (proc_t *) 0; /* current procedure header */
1399 static thead_t *top_tag_head = (thead_t *) 0; /* top level tag head */
1400 static thead_t *cur_tag_head = (thead_t *) 0; /* current tag head */
1401 #ifdef ECOFF_DEBUG
1402 static int debug = 0; /* trace functions */
1403 #endif
1404 static int stabs_seen = 0; /* != 0 if stabs have been seen */
1405
1406
1407 /* Pseudo symbol to use when putting stabs into the symbol table. */
1408 #ifndef STABS_SYMBOL
1409 #define STABS_SYMBOL "@stabs"
1410 #endif
1411
1412 static char stabs_symbol[] = STABS_SYMBOL;
1413 \f
1414 /* Prototypes for functions defined in this file. */
1415
1416 static void add_varray_page PARAMS ((varray_t *vp));
1417 static symint_t add_string PARAMS ((varray_t *vp,
1418 struct hash_control *hash_tbl,
1419 const char *str,
1420 shash_t **ret_hash));
1421 static localsym_t *add_ecoff_symbol PARAMS ((const char *str, st_t type,
1422 sc_t storage, symbolS *sym,
1423 symint_t value,
1424 symint_t indx));
1425 static symint_t add_aux_sym_symint PARAMS ((symint_t aux_word));
1426 static symint_t add_aux_sym_rndx PARAMS ((int file_index,
1427 symint_t sym_index));
1428 static symint_t add_aux_sym_tir PARAMS ((type_info_t *t,
1429 hash_state_t state,
1430 thash_t **hash_tbl));
1431 static tag_t *get_tag PARAMS ((const char *tag, localsym_t *sym,
1432 bt_t basic_type));
1433 static void add_unknown_tag PARAMS ((tag_t *ptag));
1434 static void add_procedure PARAMS ((char *func));
1435 static void add_file PARAMS ((const char *file_name, int indx));
1436 #ifdef ECOFF_DEBUG
1437 static char *sc_to_string PARAMS ((sc_t storage_class));
1438 static char *st_to_string PARAMS ((st_t symbol_type));
1439 #endif
1440 static void obj_ecoff_def PARAMS ((int));
1441 static void obj_ecoff_dim PARAMS ((int));
1442 static void obj_ecoff_endef PARAMS ((int));
1443 static void obj_ecoff_file PARAMS ((int));
1444 static void obj_ecoff_scl PARAMS ((int));
1445 static void obj_ecoff_size PARAMS ((int));
1446 static void obj_ecoff_tag PARAMS ((int));
1447 static void obj_ecoff_type PARAMS ((int));
1448 static void obj_ecoff_val PARAMS ((int));
1449 static void obj_ecoff_stab PARAMS ((int));
1450 static void obj_ecoff_ent PARAMS ((int));
1451 static void obj_ecoff_begin PARAMS ((int));
1452 static void obj_ecoff_bend PARAMS ((int));
1453 static void obj_ecoff_end PARAMS ((int));
1454 static void obj_ecoff_fmask PARAMS ((int));
1455 static void obj_ecoff_frame PARAMS ((int));
1456 static void obj_ecoff_loc PARAMS ((int));
1457 static void obj_ecoff_mask PARAMS ((int));
1458 static void mark_stabs PARAMS ((int));
1459 static char *ecoff_add_bytes PARAMS ((char **buf, char **bufend,
1460 char *bufptr, long need));
1461 static long ecoff_longword_adjust PARAMS ((char **buf, char **bufend,
1462 long offset, char **bufptrptr));
1463 static long ecoff_build_lineno PARAMS ((char **buf, char **bufend,
1464 long offset, long *linecntptr));
1465 static long ecoff_build_symbols PARAMS ((char **buf, char **bufend,
1466 long offset,
1467 char **extbuf, char **extbufend,
1468 long *extoffset,
1469 varray_t *ext_strings,
1470 struct hash_control *ext_str_hash));
1471 static long ecoff_build_procs PARAMS ((char **buf, char **bufend,
1472 long offset));
1473 static long ecoff_build_aux PARAMS ((char **buf, char **bufend,
1474 long offset));
1475 static long ecoff_build_strings PARAMS ((char **buf, char **bufend,
1476 long offset,
1477 varray_t *vp));
1478 static long ecoff_build_ss PARAMS ((char **buf, char **bufend,
1479 long offset));
1480 static long ecoff_build_fdr PARAMS ((char **buf, char **bufend,
1481 long offset));
1482 static void ecoff_set_vma PARAMS ((void));
1483 static page_t *allocate_cluster PARAMS ((unsigned long npages));
1484 static page_t *allocate_page PARAMS ((void));
1485 static scope_t *allocate_scope PARAMS ((void));
1486 static void free_scope PARAMS ((scope_t *ptr));
1487 static vlinks_t *allocate_vlinks PARAMS ((void));
1488 static shash_t *allocate_shash PARAMS ((void));
1489 static thash_t *allocate_thash PARAMS ((void));
1490 static tag_t *allocate_tag PARAMS ((void));
1491 static void free_tag PARAMS ((tag_t *ptr));
1492 static forward_t *allocate_forward PARAMS ((void));
1493 static thead_t *allocate_thead PARAMS ((void));
1494 static void free_thead PARAMS ((thead_t *ptr));
1495 static lineno_list_t *allocate_lineno_list PARAMS ((void));
1496
1497 /* Why isn't this in some header file somewhere? In fact, is it even
1498 necessary? */
1499 #define SKIP_WHITESPACES() \
1500 do \
1501 { \
1502 while (*input_line_pointer == ' ' \
1503 || *input_line_pointer == '\t') \
1504 ++input_line_pointer; \
1505 } \
1506 while (0)
1507 \f
1508 /* These are the pseudo-ops we support in this file. Only those
1509 relating to debugging information are supported here.
1510
1511 The following pseudo-ops from the Kane and Heinrich MIPS book
1512 should be defined here, but are currently unsupported: .aent,
1513 .bgnb, .endb, .verstamp, .vreg.
1514
1515 The following pseudo-ops from the Kane and Heinrich MIPS book are
1516 MIPS CPU specific, and should be defined by tc-mips.c: .alias,
1517 .extern, .galive, .gjaldef, .gjrlive, .livereg, .noalias, .option,
1518 .rdata, .sdata, .set.
1519
1520 The following pseudo-ops from the Kane and Heinrich MIPS book are
1521 not MIPS CPU specific, but are also not ECOFF specific. I have
1522 only listed the ones which are not already in read.c. It's not
1523 completely clear where these should be defined, but tc-mips.c is
1524 probably the most reasonable place: .asciiz, .asm0, .endr, .err,
1525 .half, .lab, .repeat, .struct, .weakext. */
1526
1527 const pseudo_typeS obj_pseudo_table[] =
1528 {
1529 /* COFF style debugging information. .ln is not used; .loc is used
1530 instead. */
1531 { "def", obj_ecoff_def, 0 },
1532 { "dim", obj_ecoff_dim, 0 },
1533 { "endef", obj_ecoff_endef, 0 },
1534 { "file", obj_ecoff_file, 0 },
1535 { "scl", obj_ecoff_scl, 0 },
1536 { "size", obj_ecoff_size, 0 },
1537 { "tag", obj_ecoff_tag, 0 },
1538 { "type", obj_ecoff_type, 0 },
1539 { "val", obj_ecoff_val, 0 },
1540
1541 /* stabs debugging information. */
1542 { "stabd", obj_ecoff_stab, 'd' },
1543 { "stabn", obj_ecoff_stab, 'n' },
1544 { "stabs", obj_ecoff_stab, 's' },
1545
1546 /* ECOFF specific debugging information. */
1547 { "begin", obj_ecoff_begin, 0 },
1548 { "bend", obj_ecoff_bend, 0 },
1549 { "end", obj_ecoff_end, 0 },
1550 { "ent", obj_ecoff_ent, 0 },
1551 { "fmask", obj_ecoff_fmask, 0 },
1552 { "frame", obj_ecoff_frame, 0 },
1553 { "loc", obj_ecoff_loc, 0 },
1554 { "mask", obj_ecoff_mask, 0 },
1555
1556 /* Sentinel. */
1557 { NULL }
1558 };
1559 \f
1560 /* This function is called when the assembler starts up. */
1561
1562 void
1563 obj_read_begin_hook ()
1564 {
1565 tag_hash = hash_new ();
1566 if (tag_hash == (struct hash_control *) NULL)
1567 as_fatal ("Can't create hash table");
1568 top_tag_head = allocate_thead ();
1569 top_tag_head->first_tag = (tag_t *) NULL;
1570 top_tag_head->free = (thead_t *) NULL;
1571 top_tag_head->prev = cur_tag_head;
1572 cur_tag_head = top_tag_head;
1573 }
1574
1575 /* This function is called when a symbol is created. */
1576
1577 void
1578 obj_symbol_new_hook (symbolP)
1579 symbolS *symbolP;
1580 {
1581 symbolP->ecoff_file = cur_file_ptr;
1582 symbolP->ecoff_symbol = 0;
1583 symbolP->ecoff_undefined = 0;
1584 }
1585 \f
1586 /* Add a page to a varray object. */
1587
1588 static void
1589 add_varray_page (vp)
1590 varray_t *vp; /* varray to add page to */
1591 {
1592 vlinks_t *new_links = allocate_vlinks ();
1593
1594 #ifdef MALLOC_CHECK
1595 if (vp->object_size > 1)
1596 new_links->datum = (page_t *) xcalloc (1, vp->object_size);
1597 else
1598 #endif
1599 new_links->datum = allocate_page ();
1600
1601 alloc_counts[(int)alloc_type_varray].total_alloc++;
1602 alloc_counts[(int)alloc_type_varray].total_pages++;
1603
1604 new_links->start_index = vp->num_allocated;
1605 vp->objects_last_page = 0;
1606
1607 if (vp->first == (vlinks_t *) NULL) /* first allocation? */
1608 vp->first = vp->last = new_links;
1609 else
1610 { /* 2nd or greater allocation */
1611 new_links->prev = vp->last;
1612 vp->last->next = new_links;
1613 vp->last = new_links;
1614 }
1615 }
1616 \f
1617 /* Add a string (and null pad) to one of the string tables. */
1618
1619 static symint_t
1620 add_string (vp, hash_tbl, str, ret_hash)
1621 varray_t *vp; /* string obstack */
1622 struct hash_control *hash_tbl; /* ptr to hash table */
1623 const char *str; /* string */
1624 shash_t **ret_hash; /* return hash pointer */
1625 {
1626 register unsigned int len = strlen (str);
1627 register shash_t *hash_ptr;
1628
1629 if (len >= PAGE_USIZE)
1630 as_fatal ("String too big (%lu bytes)", len);
1631
1632 hash_ptr = (shash_t *) hash_find (hash_tbl, str);
1633 if (hash_ptr == (shash_t *) NULL)
1634 {
1635 register char *err;
1636
1637 if (vp->objects_last_page + len >= PAGE_USIZE)
1638 {
1639 vp->num_allocated =
1640 ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
1641 add_varray_page (vp);
1642 }
1643
1644 hash_ptr = allocate_shash ();
1645 hash_ptr->indx = vp->num_allocated;
1646
1647 hash_ptr->string = &vp->last->datum->byte[vp->objects_last_page];
1648
1649 vp->objects_last_page += len + 1;
1650 vp->num_allocated += len + 1;
1651
1652 strcpy (hash_ptr->string, str);
1653
1654 err = hash_insert (hash_tbl, str, (char *) hash_ptr);
1655 if (*err != '\0')
1656 as_fatal ("Inserting \"%s\" into string hash table: %s",
1657 str, err);
1658 }
1659
1660 if (ret_hash != (shash_t **) NULL)
1661 *ret_hash = hash_ptr;
1662
1663 return hash_ptr->indx;
1664 }
1665 \f
1666 /* Add debugging information for a symbol. */
1667
1668 static localsym_t *
1669 add_ecoff_symbol (str, type, storage, sym_value, value, indx)
1670 const char *str; /* symbol name */
1671 st_t type; /* symbol type */
1672 sc_t storage; /* storage class */
1673 symbolS *sym_value; /* associated symbol. */
1674 symint_t value; /* value of symbol */
1675 symint_t indx; /* index to local/aux. syms */
1676 {
1677 localsym_t *psym;
1678 register scope_t *pscope;
1679 register thead_t *ptag_head;
1680 register tag_t *ptag;
1681 register tag_t *ptag_next;
1682 register varray_t *vp = &cur_file_ptr->symbols;
1683 register int scope_delta = 0;
1684 shash_t *hash_ptr = (shash_t *) NULL;
1685
1686 if (cur_file_ptr == (efdr_t *) NULL)
1687 as_fatal ("no current file pointer");
1688
1689 vp = &cur_file_ptr->symbols;
1690
1691 if (vp->objects_last_page == vp->objects_per_page)
1692 add_varray_page (vp);
1693
1694 psym = &vp->last->datum->sym[ vp->objects_last_page++ ];
1695
1696 if (str == (const char *) NULL && sym_value != (symbolS *) NULL)
1697 psym->name = S_GET_NAME (sym_value);
1698 else
1699 psym->name = str;
1700 psym->as_sym = sym_value;
1701 if (sym_value != (symbolS *) NULL)
1702 sym_value->ecoff_symbol = 1;
1703 psym->file_ptr = cur_file_ptr;
1704 psym->proc_ptr = cur_proc_ptr;
1705 psym->begin_ptr = (localsym_t *) NULL;
1706 psym->index_ptr = (aux_t *) NULL;
1707 psym->forward_ref = (forward_t *) NULL;
1708 psym->sym_index = -1;
1709 psym->ecoff_sym.value = value;
1710 psym->ecoff_sym.st = (unsigned) type;
1711 psym->ecoff_sym.sc = (unsigned) storage;
1712 psym->ecoff_sym.index = indx;
1713
1714 /* If there is an associated symbol, we wait until the end of the
1715 assembly before deciding where to put the name (it may be just an
1716 external symbol). Otherwise, this is just a debugging symbol and
1717 the name should go with the current file. */
1718 if (sym_value == (symbolS *) NULL)
1719 psym->ecoff_sym.iss = ((str == (const char *) NULL)
1720 ? 0
1721 : add_string (&cur_file_ptr->strings,
1722 cur_file_ptr->str_hash,
1723 str,
1724 &hash_ptr));
1725
1726 ++vp->num_allocated;
1727
1728 if (MIPS_IS_STAB (&psym->ecoff_sym))
1729 return psym;
1730
1731 /* Save the symbol within the hash table if this is a static
1732 item, and it has a name. */
1733 if (hash_ptr != (shash_t *) NULL
1734 && (type == st_Global || type == st_Static || type == st_Label
1735 || type == st_Proc || type == st_StaticProc))
1736 hash_ptr->sym_ptr = psym;
1737
1738 /* push or pop a scope if appropriate. */
1739 switch (type)
1740 {
1741 default:
1742 break;
1743
1744 case st_File: /* beginning of file */
1745 case st_Proc: /* procedure */
1746 case st_StaticProc: /* static procedure */
1747 case st_Block: /* begin scope */
1748 pscope = allocate_scope ();
1749 pscope->prev = cur_file_ptr->cur_scope;
1750 pscope->lsym = psym;
1751 pscope->type = type;
1752 cur_file_ptr->cur_scope = pscope;
1753
1754 if (type != st_File)
1755 scope_delta = 1;
1756
1757 /* For every block type except file, struct, union, or
1758 enumeration blocks, push a level on the tag stack. We omit
1759 file types, so that tags can span file boundaries. */
1760 if (type != st_File && storage != sc_Info)
1761 {
1762 ptag_head = allocate_thead ();
1763 ptag_head->first_tag = 0;
1764 ptag_head->prev = cur_tag_head;
1765 cur_tag_head = ptag_head;
1766 }
1767 break;
1768
1769 case st_End:
1770 pscope = cur_file_ptr->cur_scope;
1771 if (pscope == (scope_t *) NULL)
1772 as_fatal ("too many st_End's");
1773 else
1774 {
1775 st_t begin_type = (st_t) pscope->lsym->ecoff_sym.st;
1776
1777 psym->begin_ptr = pscope->lsym;
1778
1779 if (begin_type != st_File)
1780 scope_delta = -1;
1781
1782 /* Except for file, structure, union, or enumeration end
1783 blocks remove all tags created within this scope. */
1784 if (begin_type != st_File && storage != sc_Info)
1785 {
1786 ptag_head = cur_tag_head;
1787 cur_tag_head = ptag_head->prev;
1788
1789 for (ptag = ptag_head->first_tag;
1790 ptag != (tag_t *) NULL;
1791 ptag = ptag_next)
1792 {
1793 if (ptag->forward_ref != (forward_t *) NULL)
1794 add_unknown_tag (ptag);
1795
1796 ptag_next = ptag->same_block;
1797 ptag->hash_ptr->tag_ptr = ptag->same_name;
1798 free_tag (ptag);
1799 }
1800
1801 free_thead (ptag_head);
1802 }
1803
1804 cur_file_ptr->cur_scope = pscope->prev;
1805
1806 /* block begin gets next sym #. This is set when we know
1807 the symbol index value. */
1808
1809 /* Functions push two or more aux words as follows:
1810 1st word: index+1 of the end symbol (filled in later).
1811 2nd word: type of the function (plus any aux words needed).
1812 Also, tie the external pointer back to the function begin symbol. */
1813 if (begin_type != st_File && begin_type != st_Block)
1814 {
1815 symint_t type;
1816 varray_t *vp = &cur_file_ptr->aux_syms;
1817
1818 pscope->lsym->ecoff_sym.index = add_aux_sym_symint (0);
1819 pscope->lsym->index_ptr =
1820 &vp->last->datum->aux[vp->objects_last_page - 1];
1821 type = add_aux_sym_tir (&last_func_type_info,
1822 hash_no,
1823 &cur_file_ptr->thash_head[0]);
1824 /*
1825 if (last_func_sym_value != (symbolS *) NULL)
1826 {
1827 last_func_sym_value->ifd = cur_file_ptr->file_index;
1828 last_func_sym_value->index = type;
1829 }
1830 */
1831 }
1832
1833 free_scope (pscope);
1834 }
1835 }
1836
1837 cur_file_ptr->nested_scopes += scope_delta;
1838
1839 #ifdef ECOFF_DEBUG
1840 if (debug && type != st_File
1841 && (debug > 2 || type == st_Block || type == st_End
1842 || type == st_Proc || type == st_StaticProc))
1843 {
1844 char *sc_str = sc_to_string (storage);
1845 char *st_str = st_to_string (type);
1846 int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
1847
1848 fprintf (stderr,
1849 "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
1850 value, depth, sc_str);
1851
1852 if (str_start && str_end_p1 - str_start > 0)
1853 fprintf (stderr, " st= %-11s name= %.*s\n", st_str, str_end_p1 - str_start, str_start);
1854 else
1855 {
1856 unsigned long len = strlen (st_str);
1857 fprintf (stderr, " st= %.*s\n", len-1, st_str);
1858 }
1859 }
1860 #endif
1861
1862 return psym;
1863 }
1864 \f
1865 /* Add an auxiliary symbol (passing a symint). This is actually used
1866 for integral aux types, not just symints. */
1867
1868 static symint_t
1869 add_aux_sym_symint (aux_word)
1870 symint_t aux_word; /* auxiliary information word */
1871 {
1872 register varray_t *vp;
1873 register aux_t *aux_ptr;
1874
1875 if (cur_file_ptr == (efdr_t *) NULL)
1876 as_fatal ("no current file pointer");
1877
1878 vp = &cur_file_ptr->aux_syms;
1879
1880 if (vp->objects_last_page == vp->objects_per_page)
1881 add_varray_page (vp);
1882
1883 aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
1884 aux_ptr->type = aux_isym;
1885 aux_ptr->data.isym = aux_word;
1886
1887 return vp->num_allocated++;
1888 }
1889
1890
1891 /* Add an auxiliary symbol (passing a file/symbol index combo). */
1892
1893 static symint_t
1894 add_aux_sym_rndx (file_index, sym_index)
1895 int file_index;
1896 symint_t sym_index;
1897 {
1898 register varray_t *vp;
1899 register aux_t *aux_ptr;
1900
1901 if (cur_file_ptr == (efdr_t *) NULL)
1902 as_fatal ("no current file pointer");
1903
1904 vp = &cur_file_ptr->aux_syms;
1905
1906 if (vp->objects_last_page == vp->objects_per_page)
1907 add_varray_page (vp);
1908
1909 aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
1910 aux_ptr->type = aux_rndx;
1911 aux_ptr->data.rndx.rfd = file_index;
1912 aux_ptr->data.rndx.index = sym_index;
1913
1914 return vp->num_allocated++;
1915 }
1916 \f
1917 /* Add an auxiliary symbol (passing the basic type and possibly
1918 type qualifiers). */
1919
1920 static symint_t
1921 add_aux_sym_tir (t, state, hash_tbl)
1922 type_info_t *t; /* current type information */
1923 hash_state_t state; /* whether to hash type or not */
1924 thash_t **hash_tbl; /* pointer to hash table to use */
1925 {
1926 register varray_t *vp;
1927 register aux_t *aux_ptr;
1928 static AUXU init_aux;
1929 symint_t ret;
1930 int i;
1931 AUXU aux;
1932
1933 if (cur_file_ptr == (efdr_t *) NULL)
1934 as_fatal ("no current file pointer");
1935
1936 vp = &cur_file_ptr->aux_syms;
1937
1938 aux = init_aux;
1939 aux.ti.bt = (int) t->basic_type;
1940 aux.ti.continued = 0;
1941 aux.ti.fBitfield = t->bitfield;
1942
1943 aux.ti.tq0 = (int) t->type_qualifiers[0];
1944 aux.ti.tq1 = (int) t->type_qualifiers[1];
1945 aux.ti.tq2 = (int) t->type_qualifiers[2];
1946 aux.ti.tq3 = (int) t->type_qualifiers[3];
1947 aux.ti.tq4 = (int) t->type_qualifiers[4];
1948 aux.ti.tq5 = (int) t->type_qualifiers[5];
1949
1950
1951 /* For anything that adds additional information, we must not hash,
1952 so check here, and reset our state. */
1953
1954 if (state != hash_no
1955 && (t->type_qualifiers[0] == tq_Array
1956 || t->type_qualifiers[1] == tq_Array
1957 || t->type_qualifiers[2] == tq_Array
1958 || t->type_qualifiers[3] == tq_Array
1959 || t->type_qualifiers[4] == tq_Array
1960 || t->type_qualifiers[5] == tq_Array
1961 || t->basic_type == bt_Struct
1962 || t->basic_type == bt_Union
1963 || t->basic_type == bt_Enum
1964 || t->bitfield
1965 || t->num_dims > 0))
1966 state = hash_no;
1967
1968 /* See if we can hash this type, and save some space, but some types
1969 can't be hashed (because they contain arrays or continuations),
1970 and others can be put into the hash list, but cannot use existing
1971 types because other aux entries precede this one. */
1972
1973 if (state != hash_no)
1974 {
1975 register thash_t *hash_ptr;
1976 register symint_t hi;
1977
1978 hi = aux.isym & ((1 << HASHBITS) - 1);
1979 hi %= THASH_SIZE;
1980
1981 for (hash_ptr = hash_tbl[hi];
1982 hash_ptr != (thash_t *)0;
1983 hash_ptr = hash_ptr->next)
1984 {
1985 if (aux.isym == hash_ptr->type.isym)
1986 break;
1987 }
1988
1989 if (hash_ptr != (thash_t *) NULL && state == hash_yes)
1990 return hash_ptr->indx;
1991
1992 if (hash_ptr == (thash_t *) NULL)
1993 {
1994 hash_ptr = allocate_thash ();
1995 hash_ptr->next = hash_tbl[hi];
1996 hash_ptr->type = aux;
1997 hash_ptr->indx = vp->num_allocated;
1998 hash_tbl[hi] = hash_ptr;
1999 }
2000 }
2001
2002 /* Everything is set up, add the aux symbol. */
2003 if (vp->objects_last_page == vp->objects_per_page)
2004 add_varray_page (vp);
2005
2006 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2007 aux_ptr->type = aux_tir;
2008 aux_ptr->data = aux;
2009
2010 ret = vp->num_allocated++;
2011
2012 /* Add bitfield length if it exists.
2013
2014 NOTE: Mips documentation claims bitfield goes at the end of the
2015 AUX record, but the DECstation compiler emits it here.
2016 (This would only make a difference for enum bitfields.)
2017
2018 Also note: We use the last size given since gcc may emit 2
2019 for an enum bitfield. */
2020
2021 if (t->bitfield)
2022 (void) add_aux_sym_symint ((symint_t)t->sizes[t->num_sizes-1]);
2023
2024
2025 /* Add tag information if needed. Structure, union, and enum
2026 references add 2 aux symbols: a [file index, symbol index]
2027 pointer to the structure type, and the current file index. */
2028
2029 if (t->basic_type == bt_Struct
2030 || t->basic_type == bt_Union
2031 || t->basic_type == bt_Enum)
2032 {
2033 register symint_t file_index = t->tag_ptr->ifd;
2034 register localsym_t *sym = t->tag_ptr->sym;
2035 register forward_t *forward_ref = allocate_forward ();
2036
2037 if (sym != (localsym_t *) NULL)
2038 {
2039 forward_ref->next = sym->forward_ref;
2040 sym->forward_ref = forward_ref;
2041 }
2042 else
2043 {
2044 forward_ref->next = t->tag_ptr->forward_ref;
2045 t->tag_ptr->forward_ref = forward_ref;
2046 }
2047
2048 (void) add_aux_sym_rndx (ST_RFDESCAPE, indexNil);
2049 forward_ref->index_ptr
2050 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2051
2052 (void) add_aux_sym_symint (file_index);
2053 forward_ref->ifd_ptr
2054 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2055 }
2056
2057 /* Add information about array bounds if they exist. */
2058 for (i = 0; i < t->num_dims; i++)
2059 {
2060 (void) add_aux_sym_rndx (ST_RFDESCAPE,
2061 cur_file_ptr->int_type);
2062
2063 (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/
2064 (void) add_aux_sym_symint ((symint_t) 0); /* low bound */
2065 (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/
2066 (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */
2067 ? 0
2068 : (t->sizes[i] * 8) / t->dimensions[i]);
2069 };
2070
2071 /* NOTE: Mips documentation claims that the bitfield width goes here.
2072 But it needs to be emitted earlier. */
2073
2074 return ret;
2075 }
2076 \f
2077 /* Add a tag to the tag table (unless it already exists). */
2078
2079 static tag_t *
2080 get_tag (tag, sym, basic_type)
2081 const char *tag; /* tag name */
2082 localsym_t *sym; /* tag start block */
2083 bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
2084 {
2085 shash_t *hash_ptr;
2086 char *err;
2087 tag_t *tag_ptr;
2088
2089 if (cur_file_ptr == (efdr_t *) NULL)
2090 as_fatal ("no current file pointer");
2091
2092 hash_ptr = (shash_t *) hash_find (tag_hash, tag);
2093
2094 if (hash_ptr != (shash_t *) NULL
2095 && hash_ptr->tag_ptr != (tag_t *) NULL)
2096 {
2097 tag_ptr = hash_ptr->tag_ptr;
2098 if (sym != (localsym_t *) NULL)
2099 {
2100 tag_ptr->basic_type = basic_type;
2101 tag_ptr->ifd = cur_file_ptr->file_index;
2102 tag_ptr->sym = sym;
2103 }
2104 return tag_ptr;
2105 }
2106
2107 if (hash_ptr == (shash_t *) NULL)
2108 {
2109 hash_ptr = allocate_shash ();
2110 err = hash_insert (tag_hash, tag, (char *) hash_ptr);
2111 if (*err != '\0')
2112 as_fatal ("Inserting \"%s\" into tag hash table: %s",
2113 tag, err);
2114 }
2115
2116 tag_ptr = allocate_tag ();
2117 tag_ptr->forward_ref = (forward_t *) NULL;
2118 tag_ptr->hash_ptr = hash_ptr;
2119 tag_ptr->same_name = hash_ptr->tag_ptr;
2120 tag_ptr->basic_type = basic_type;
2121 tag_ptr->sym = sym;
2122 tag_ptr->ifd = ((sym == (localsym_t *) NULL)
2123 ? -1
2124 : cur_file_ptr->file_index);
2125 tag_ptr->same_block = cur_tag_head->first_tag;
2126
2127 cur_tag_head->first_tag = tag_ptr;
2128 hash_ptr->tag_ptr = tag_ptr;
2129
2130 return tag_ptr;
2131 }
2132 \f
2133 /* Add an unknown {struct, union, enum} tag. */
2134
2135 static void
2136 add_unknown_tag (ptag)
2137 tag_t *ptag; /* pointer to tag information */
2138 {
2139 shash_t *hash_ptr = ptag->hash_ptr;
2140 char *name = hash_ptr->string;
2141 localsym_t *sym;
2142 forward_t **pf;
2143
2144 #ifdef ECOFF_DEBUG
2145 if (debug > 1)
2146 {
2147 char *agg_type = "{unknown aggregate type}";
2148 switch (ptag->basic_type)
2149 {
2150 case bt_Struct: agg_type = "struct"; break;
2151 case bt_Union: agg_type = "union"; break;
2152 case bt_Enum: agg_type = "enum"; break;
2153 default: break;
2154 }
2155
2156 fprintf (stderr, "unknown %s %.*s found\n", agg_type,
2157 hash_ptr->len, name_start);
2158 }
2159 #endif
2160
2161 sym = add_ecoff_symbol (name,
2162 st_Block,
2163 sc_Info,
2164 (symbolS *) NULL,
2165 (symint_t) 0,
2166 (symint_t) 0);
2167
2168 (void) add_ecoff_symbol (name,
2169 st_End,
2170 sc_Info,
2171 (symbolS *) NULL,
2172 (symint_t) 0,
2173 (symint_t) 0);
2174
2175 for (pf = &sym->forward_ref; *pf != (forward_t *) NULL; pf = &(*pf)->next)
2176 ;
2177 *pf = ptag->forward_ref;
2178 }
2179 \f
2180 /* Add a procedure to the current file's list of procedures, and record
2181 this is the current procedure. */
2182
2183 static void
2184 add_procedure (func)
2185 char *func; /* func name */
2186 {
2187 register varray_t *vp;
2188 register proc_t *new_proc_ptr;
2189
2190 #ifdef ECOFF_DEBUG
2191 if (debug)
2192 fputc ('\n', stderr);
2193 #endif
2194
2195 if (cur_file_ptr == (efdr_t *) NULL)
2196 as_fatal ("no current file pointer");
2197
2198 vp = &cur_file_ptr->procs;
2199
2200 if (vp->objects_last_page == vp->objects_per_page)
2201 add_varray_page (vp);
2202
2203 cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[vp->objects_last_page++];
2204
2205 vp->num_allocated++;
2206
2207 new_proc_ptr->pdr.isym = -1;
2208 new_proc_ptr->pdr.iline = -1;
2209 new_proc_ptr->pdr.lnLow = -1;
2210 new_proc_ptr->pdr.lnHigh = -1;
2211
2212 /* Push the start of the function. */
2213 new_proc_ptr->sym = add_ecoff_symbol ((const char *) NULL, st_Proc, sc_Text,
2214 symbol_find_or_make (func),
2215 (symint_t) 0, (symint_t) 0);
2216
2217 ++proc_cnt;
2218
2219 /* Fill in the linenos preceding the .ent, if any. */
2220 if (noproc_lineno != (lineno_list_t *) NULL)
2221 {
2222 lineno_list_t *l;
2223
2224 for (l = noproc_lineno; l != (lineno_list_t *) NULL; l = l->next)
2225 l->proc = new_proc_ptr;
2226 *last_lineno_ptr = noproc_lineno;
2227 while (*last_lineno_ptr != NULL)
2228 last_lineno_ptr = &(*last_lineno_ptr)->next;
2229 noproc_lineno = (lineno_list_t *) NULL;
2230 }
2231 }
2232 \f
2233 /* Add a new filename, and set up all of the file relative
2234 virtual arrays (strings, symbols, aux syms, etc.). Record
2235 where the current file structure lives. */
2236
2237 static void
2238 add_file (file_name, indx)
2239 const char *file_name; /* file name */
2240 int indx;
2241 {
2242 register int first_ch;
2243 register efdr_t *fil_ptr;
2244
2245 #ifdef ECOFF_DEBUG
2246 if (debug)
2247 fprintf (stderr, "\tfile\t%.*s\n", len, file_start);
2248 #endif
2249
2250 /* If the file name is NULL, then no .file symbol appeared, and we
2251 want to use the actual file name. Unfortunately, we don't have a
2252 clean way to access it. */
2253 if (file_name == (const char *) NULL)
2254 {
2255 extern char *logical_input_file;
2256 extern char *physical_input_file;
2257
2258 if (first_file != (efdr_t *) NULL)
2259 as_fatal ("fake .file after real one");
2260 file_name = logical_input_file;
2261 if (file_name == (const char *) NULL)
2262 {
2263 file_name = physical_input_file;
2264 if (file_name == (const char *) NULL)
2265 file_name = "UNKNOWN";
2266 }
2267 }
2268
2269 /* If we're creating stabs, then we don't actually make a new FDR.
2270 Instead, we just create a stabs symbol. */
2271 if (stabs_seen)
2272 {
2273 (void) add_ecoff_symbol (file_name, st_Nil, sc_Nil,
2274 symbol_new ("L0\001", now_seg,
2275 frag_now_fix (), frag_now),
2276 0, MIPS_MARK_STAB (N_SOL));
2277 return;
2278 }
2279
2280 first_ch = *file_name;
2281
2282 /* See if the file has already been created. */
2283 for (fil_ptr = first_file;
2284 fil_ptr != (efdr_t *) NULL;
2285 fil_ptr = fil_ptr->next_file)
2286 {
2287 if (first_ch == fil_ptr->name[0]
2288 && strcmp (file_name, fil_ptr->name) == 0)
2289 {
2290 cur_file_ptr = fil_ptr;
2291 break;
2292 }
2293 }
2294
2295 /* If this is a new file, create it. */
2296 if (fil_ptr == (efdr_t *) NULL)
2297 {
2298 if (file_desc.objects_last_page == file_desc.objects_per_page)
2299 add_varray_page (&file_desc);
2300
2301 fil_ptr = cur_file_ptr =
2302 &file_desc.last->datum->file[file_desc.objects_last_page++];
2303 *fil_ptr = init_file;
2304
2305 fil_ptr->file_index = indx;
2306 ++file_desc.num_allocated;
2307
2308 /* Allocate the string hash table. */
2309 fil_ptr->str_hash = hash_new ();
2310 if (fil_ptr->str_hash == (struct hash_control *) NULL)
2311 as_fatal ("Can't create hash table");
2312
2313 /* Make sure 0 byte in string table is null */
2314 add_string (&fil_ptr->strings,
2315 fil_ptr->str_hash,
2316 "",
2317 (shash_t **)0);
2318
2319 if (strlen (file_name) > PAGE_USIZE - 2)
2320 as_fatal ("Filename goes over one page boundary.");
2321
2322 /* Push the start of the filename. We assume that the filename
2323 will be stored at string offset 1. */
2324 (void) add_ecoff_symbol (file_name, st_File, sc_Text,
2325 (symbolS *) NULL,
2326 (symint_t) 0, (symint_t) 0);
2327 fil_ptr->fdr.rss = 1;
2328 fil_ptr->name = &fil_ptr->strings.last->datum->byte[1];
2329
2330 /* Update the linked list of file descriptors. */
2331 *last_file_ptr = fil_ptr;
2332 last_file_ptr = &fil_ptr->next_file;
2333
2334 /* Add void & int types to the file (void should be first to catch
2335 errant 0's within the index fields). */
2336 fil_ptr->void_type = add_aux_sym_tir (&void_type_info,
2337 hash_yes,
2338 &cur_file_ptr->thash_head[0]);
2339
2340 fil_ptr->int_type = add_aux_sym_tir (&int_type_info,
2341 hash_yes,
2342 &cur_file_ptr->thash_head[0]);
2343 }
2344 }
2345 \f
2346 #ifdef ECOFF_DEBUG
2347
2348 /* Convert storage class to string. */
2349
2350 static char *
2351 sc_to_string(storage_class)
2352 sc_t storage_class;
2353 {
2354 switch(storage_class)
2355 {
2356 case sc_Nil: return "Nil,";
2357 case sc_Text: return "Text,";
2358 case sc_Data: return "Data,";
2359 case sc_Bss: return "Bss,";
2360 case sc_Register: return "Register,";
2361 case sc_Abs: return "Abs,";
2362 case sc_Undefined: return "Undefined,";
2363 case sc_CdbLocal: return "CdbLocal,";
2364 case sc_Bits: return "Bits,";
2365 case sc_CdbSystem: return "CdbSystem,";
2366 case sc_RegImage: return "RegImage,";
2367 case sc_Info: return "Info,";
2368 case sc_UserStruct: return "UserStruct,";
2369 case sc_SData: return "SData,";
2370 case sc_SBss: return "SBss,";
2371 case sc_RData: return "RData,";
2372 case sc_Var: return "Var,";
2373 case sc_Common: return "Common,";
2374 case sc_SCommon: return "SCommon,";
2375 case sc_VarRegister: return "VarRegister,";
2376 case sc_Variant: return "Variant,";
2377 case sc_SUndefined: return "SUndefined,";
2378 case sc_Init: return "Init,";
2379 case sc_Max: return "Max,";
2380 }
2381
2382 return "???,";
2383 }
2384
2385 #endif /* DEBUG */
2386 \f
2387 #ifdef ECOFF_DEBUG
2388
2389 /* Convert symbol type to string. */
2390
2391 static char *
2392 st_to_string(symbol_type)
2393 st_t symbol_type;
2394 {
2395 switch(symbol_type)
2396 {
2397 case st_Nil: return "Nil,";
2398 case st_Global: return "Global,";
2399 case st_Static: return "Static,";
2400 case st_Param: return "Param,";
2401 case st_Local: return "Local,";
2402 case st_Label: return "Label,";
2403 case st_Proc: return "Proc,";
2404 case st_Block: return "Block,";
2405 case st_End: return "End,";
2406 case st_Member: return "Member,";
2407 case st_Typedef: return "Typedef,";
2408 case st_File: return "File,";
2409 case st_RegReloc: return "RegReloc,";
2410 case st_Forward: return "Forward,";
2411 case st_StaticProc: return "StaticProc,";
2412 case st_Constant: return "Constant,";
2413 case st_Str: return "String,";
2414 case st_Number: return "Number,";
2415 case st_Expr: return "Expr,";
2416 case st_Type: return "Type,";
2417 case st_Max: return "Max,";
2418 }
2419
2420 return "???,";
2421 }
2422
2423 #endif /* DEBUG */
2424 \f
2425 /* Parse .begin directives which have a label as the first argument
2426 which gives the location of the start of the block. */
2427
2428 static void
2429 obj_ecoff_begin (ignore)
2430 int ignore;
2431 {
2432 char *name;
2433 char name_end;
2434
2435 if (cur_file_ptr == (efdr_t *) NULL)
2436 {
2437 as_warn (".begin directive without a preceding .file directive");
2438 demand_empty_rest_of_line ();
2439 return;
2440 }
2441
2442 if (cur_proc_ptr == (proc_t *) NULL)
2443 {
2444 as_warn (".begin directive without a preceding .ent directive");
2445 demand_empty_rest_of_line ();
2446 return;
2447 }
2448
2449 name = input_line_pointer;
2450 name_end = get_symbol_end ();
2451
2452 (void) add_ecoff_symbol ((const char *) NULL, st_Block, sc_Text,
2453 symbol_find_or_make (name),
2454 (symint_t) 0, (symint_t) 0);
2455
2456 *input_line_pointer = name_end;
2457
2458 /* The line number follows, but we don't use it. */
2459 (void) get_absolute_expression ();
2460 demand_empty_rest_of_line ();
2461 }
2462 \f
2463 /* Parse .bend directives which have a label as the first argument
2464 which gives the location of the end of the block. */
2465
2466 static void
2467 obj_ecoff_bend (ignore)
2468 int ignore;
2469 {
2470 char *name;
2471 char name_end;
2472 symbolS *endsym;
2473
2474 if (cur_file_ptr == (efdr_t *) NULL)
2475 {
2476 as_warn (".bend directive without a preceding .file directive");
2477 demand_empty_rest_of_line ();
2478 return;
2479 }
2480
2481 if (cur_proc_ptr == (proc_t *) NULL)
2482 {
2483 as_warn (".bend directive without a preceding .ent directive");
2484 demand_empty_rest_of_line ();
2485 return;
2486 }
2487
2488 name = input_line_pointer;
2489 name_end = get_symbol_end ();
2490
2491 /* The value is the distance between the .bend directive and the
2492 corresponding symbol. We fill in the offset when we write out
2493 the symbol. */
2494 endsym = symbol_find (name);
2495 if (endsym == (symbolS *) NULL)
2496 as_warn (".bend directive names unknown symbol");
2497 else
2498 (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym,
2499 (symint_t) 0, (symint_t) 0);
2500
2501 *input_line_pointer = name_end;
2502
2503 /* The line number follows, but we don't use it. */
2504 (void) get_absolute_expression ();
2505 demand_empty_rest_of_line ();
2506 }
2507 \f
2508 /* COFF debugging information is provided as a series of directives
2509 (.def, .scl, etc.). We build up information as we read the
2510 directives in the following static variables, and file it away when
2511 we reach the .endef directive. */
2512 static char *coff_sym_name;
2513 static type_info_t coff_type;
2514 static sc_t coff_storage_class;
2515 static st_t coff_symbol_type;
2516 static int coff_is_function;
2517 static char *coff_tag;
2518 static long coff_value; /* FIXME: Might be 64 bits. */
2519 symbolS *coff_sym_value;
2520 static int coff_inside_enumeration;
2521
2522 /* Handle a .def directive: start defining a symbol. */
2523
2524 static void
2525 obj_ecoff_def (ignore)
2526 int ignore;
2527 {
2528 char *name;
2529 char name_end;
2530
2531 SKIP_WHITESPACES ();
2532
2533 name = input_line_pointer;
2534 name_end = get_symbol_end ();
2535
2536 if (coff_sym_name != (char *) NULL)
2537 as_warn (".def pseudo-op used inside of .def/.endef; ignored");
2538 else if (*name == '\0')
2539 as_warn ("Empty symbol name in .def; ignored");
2540 else
2541 {
2542 if (coff_sym_name != (char *) NULL)
2543 free (coff_sym_name);
2544 if (coff_tag != (char *) NULL)
2545 free (coff_tag);
2546 coff_sym_name = (char *) xmalloc (strlen (name) + 1);
2547 strcpy (coff_sym_name, name);
2548 coff_type = type_info_init;
2549 coff_storage_class = sc_Nil;
2550 coff_symbol_type = st_Nil;
2551 coff_is_function = 0;
2552 coff_tag = (char *) NULL;
2553 coff_value = 0;
2554 coff_sym_value = (symbolS *) NULL;
2555 }
2556
2557 *input_line_pointer = name_end;
2558
2559 demand_empty_rest_of_line ();
2560 }
2561
2562 /* Handle a .dim directive, used to give dimensions for an array. The
2563 arguments are comma separated numbers. mips-tfile assumes that
2564 there will not be more than 6 dimensions, and gdb won't read any
2565 more than that anyhow, so I will also make that assumption. */
2566
2567 static void
2568 obj_ecoff_dim (ignore)
2569 int ignore;
2570 {
2571 int dimens[N_TQ];
2572 int i;
2573
2574 if (coff_sym_name == (char *) NULL)
2575 {
2576 as_warn (".dim pseudo-op used outside of .def/.endef; ignored");
2577 demand_empty_rest_of_line ();
2578 return;
2579 }
2580
2581 for (i = 0; i < N_TQ; i++)
2582 {
2583 SKIP_WHITESPACES ();
2584 dimens[i] = get_absolute_expression ();
2585 if (*input_line_pointer == ',')
2586 ++input_line_pointer;
2587 else
2588 {
2589 if (*input_line_pointer != '\n'
2590 && *input_line_pointer != ';')
2591 as_warn ("Badly formed .dim directive");
2592 break;
2593 }
2594 }
2595
2596 if (i == N_TQ)
2597 --i;
2598
2599 /* The dimensions are stored away in reverse order. */
2600 for (; i >= 0; i--)
2601 {
2602 if (coff_type.num_dims >= N_TQ)
2603 {
2604 as_warn ("Too many .dim entries");
2605 break;
2606 }
2607 coff_type.dimensions[coff_type.num_dims] = dimens[i];
2608 ++coff_type.num_dims;
2609 }
2610
2611 demand_empty_rest_of_line ();
2612 }
2613
2614 /* Handle a .scl directive, which sets the COFF storage class of the
2615 symbol. */
2616
2617 static void
2618 obj_ecoff_scl (ignore)
2619 int ignore;
2620 {
2621 long val;
2622
2623 if (coff_sym_name == (char *) NULL)
2624 {
2625 as_warn (".scl pseudo-op used outside of .def/.endef; ignored");
2626 demand_empty_rest_of_line ();
2627 return;
2628 }
2629
2630 val = get_absolute_expression ();
2631
2632 coff_symbol_type = map_coff_sym_type[val];
2633 coff_storage_class = map_coff_storage[val];
2634
2635 demand_empty_rest_of_line ();
2636 }
2637
2638 /* Handle a .size directive. For some reason mips-tfile.c thinks that
2639 .size can have multiple arguments. We humor it, although gcc will
2640 never generate more than one argument. */
2641
2642 static void
2643 obj_ecoff_size (ignore)
2644 int ignore;
2645 {
2646 int sizes[N_TQ];
2647 int i;
2648
2649 if (coff_sym_name == (char *) NULL)
2650 {
2651 as_warn (".size pseudo-op used outside of .def/.endef; ignored");
2652 demand_empty_rest_of_line ();
2653 return;
2654 }
2655
2656 for (i = 0; i < N_TQ; i++)
2657 {
2658 SKIP_WHITESPACES ();
2659 sizes[i] = get_absolute_expression ();
2660 if (*input_line_pointer == ',')
2661 ++input_line_pointer;
2662 else
2663 {
2664 if (*input_line_pointer != '\n'
2665 && *input_line_pointer != ';')
2666 as_warn ("Badly formed .size directive");
2667 break;
2668 }
2669 }
2670
2671 if (i == N_TQ)
2672 --i;
2673
2674 /* The sizes are stored away in reverse order. */
2675 for (; i >= 0; i--)
2676 {
2677 if (coff_type.num_sizes >= N_TQ)
2678 {
2679 as_warn ("Too many .size entries");
2680 break;
2681 }
2682 coff_type.sizes[coff_type.num_sizes] = sizes[i];
2683 ++coff_type.num_sizes;
2684 }
2685
2686 demand_empty_rest_of_line ();
2687 }
2688
2689 /* Handle the .type directive, which gives the COFF type of the
2690 symbol. */
2691
2692 static void
2693 obj_ecoff_type (ignore)
2694 int ignore;
2695 {
2696 long val;
2697 tq_t *tq_ptr;
2698 tq_t *tq_shft;
2699
2700 if (coff_sym_name == (char *) NULL)
2701 {
2702 as_warn (".type pseudo-op used outside of .def/.endef; ignored");
2703 demand_empty_rest_of_line ();
2704 return;
2705 }
2706
2707 val = get_absolute_expression ();
2708
2709 coff_type.orig_type = BTYPE (val);
2710 coff_type.basic_type = map_coff_types[coff_type.orig_type];
2711
2712 tq_ptr = &coff_type.type_qualifiers[N_TQ];
2713 while (val &~ N_BTMASK)
2714 {
2715 if (tq_ptr == &coff_type.type_qualifiers[0])
2716 {
2717 as_warn ("Too derived values in .type argument");
2718 break;
2719 }
2720 if (ISPTR (val))
2721 *--tq_ptr = tq_Ptr;
2722 else if (ISFCN (val))
2723 *--tq_ptr = tq_Proc;
2724 else if (ISARY (val))
2725 *--tq_ptr = tq_Array;
2726 else
2727 as_fatal ("Unrecognized .type argument");
2728
2729 val = DECREF (val);
2730 }
2731
2732 tq_shft = &coff_type.type_qualifiers[0];
2733 while (tq_ptr != &coff_type.type_qualifiers[N_TQ])
2734 *tq_shft++ = *tq_ptr++;
2735
2736 if (tq_shft != &coff_type.type_qualifiers[0] && tq_shft[-1] == tq_Proc)
2737 {
2738 /* If this is a function, ignore it, so that we don't get two
2739 entries (one from the .ent, and one for the .def that
2740 precedes it). Save the type information so that the end
2741 block can properly add it after the begin block index. For
2742 MIPS knows what reason, we must strip off the function type
2743 at this point. */
2744 coff_is_function = 1;
2745 tq_shft[-1] = tq_Nil;
2746 }
2747
2748 while (tq_shft != &coff_type.type_qualifiers[N_TQ])
2749 *tq_shft++ = tq_Nil;
2750
2751 demand_empty_rest_of_line ();
2752 }
2753
2754 /* Handle the .tag directive, which gives the name of a structure,
2755 union or enum. */
2756
2757 static void
2758 obj_ecoff_tag (ignore)
2759 int ignore;
2760 {
2761 char *name;
2762 char name_end;
2763
2764 if (coff_sym_name == (char *) NULL)
2765 {
2766 as_warn (".tag pseudo-op used outside of .def/.endef; ignored");
2767 demand_empty_rest_of_line ();
2768 return;
2769 }
2770
2771 name = input_line_pointer;
2772 name_end = get_symbol_end ();
2773
2774 coff_tag = (char *) xmalloc (strlen (name) + 1);
2775 strcpy (coff_tag, name);
2776
2777 *input_line_pointer = name_end;
2778
2779 demand_empty_rest_of_line ();
2780 }
2781
2782 /* Handle the .val directive, which gives the value of the symbol. It
2783 may be the name of a static or global symbol. */
2784
2785 static void
2786 obj_ecoff_val (ignore)
2787 int ignore;
2788 {
2789 if (coff_sym_name == (char *) NULL)
2790 {
2791 as_warn (".val pseudo-op used outside of .def/.endef; ignored");
2792 demand_empty_rest_of_line ();
2793 return;
2794 }
2795
2796 if (! is_name_beginner ((unsigned char) *input_line_pointer))
2797 coff_value = get_absolute_expression ();
2798 else
2799 {
2800 char *name;
2801 char name_end;
2802
2803 name = input_line_pointer;
2804 name_end = get_symbol_end ();
2805
2806 if (strcmp (name, ".") == 0)
2807 as_warn ("`.val .' not supported");
2808 else
2809 coff_sym_value = symbol_find_or_make (name);
2810
2811 *input_line_pointer = name_end;
2812
2813 /* FIXME: gcc can generate address expressions here in unusual
2814 cases (search for "obscure" in sdbout.c), although this is
2815 very unlikely for a MIPS chip. */
2816 }
2817
2818 demand_empty_rest_of_line ();
2819 }
2820
2821 /* Handle the .endef directive, which terminates processing of COFF
2822 debugging information for a symbol. */
2823
2824 static void
2825 obj_ecoff_endef (ignore)
2826 int ignore;
2827 {
2828 char *name;
2829 symint_t indx;
2830 localsym_t *sym;
2831
2832 demand_empty_rest_of_line ();
2833
2834 if (coff_sym_name == (char *) NULL)
2835 {
2836 as_warn (".endef pseudo-op used before .def; ignored");
2837 return;
2838 }
2839
2840 name = coff_sym_name;
2841 coff_sym_name = (char *) NULL;
2842
2843 /* If the symbol is a static or external, we have already gotten the
2844 appropriate type and class, so make sure we don't override those
2845 values. This is needed because there are some type and classes
2846 that are not in COFF, such as short data, etc. */
2847 if (coff_sym_value != (symbolS *) NULL)
2848 {
2849 coff_symbol_type = st_Nil;
2850 coff_storage_class = sc_Nil;
2851 }
2852
2853 coff_type.extra_sizes = coff_tag != (char *) NULL;
2854 if (coff_type.num_dims > 0)
2855 {
2856 int diff = coff_type.num_dims - coff_type.num_sizes;
2857 int i = coff_type.num_dims - 1;
2858 int j;
2859
2860 if (coff_type.num_sizes != 1 || diff < 0)
2861 {
2862 as_warn ("Bad COFF debugging info");
2863 return;
2864 }
2865
2866 /* If this is an array, make sure the same number of dimensions
2867 and sizes were passed, creating extra sizes for multiply
2868 dimensioned arrays if not passed. */
2869 coff_type.extra_sizes = 0;
2870 if (diff)
2871 {
2872 j = (sizeof (coff_type.sizes) / sizeof (coff_type.sizes[0])) - 1;
2873 while (j >= 0)
2874 {
2875 coff_type.sizes[j] = (((j - diff) >= 0)
2876 ? coff_type.sizes[j - diff]
2877 : 0);
2878 j--;
2879 }
2880
2881 coff_type.num_sizes = i + 1;
2882 for (i--; i >= 0; i--)
2883 coff_type.sizes[i] = (coff_type.sizes[i + 1]
2884 / coff_type.dimensions[i + 1]);
2885 }
2886 }
2887 else if (coff_symbol_type == st_Member
2888 && coff_type.num_sizes - coff_type.extra_sizes == 1)
2889 {
2890 /* Is this a bitfield? This is indicated by a structure memeber
2891 having a size field that isn't an array. */
2892 coff_type.bitfield = 1;
2893 }
2894
2895 /* Except for enumeration members & begin/ending of scopes, put the
2896 type word in the aux. symbol table. */
2897 if (coff_symbol_type == st_Block || coff_symbol_type == st_End)
2898 indx = 0;
2899 else if (coff_inside_enumeration)
2900 indx = cur_file_ptr->void_type;
2901 else
2902 {
2903 if (coff_type.basic_type == bt_Struct
2904 || coff_type.basic_type == bt_Union
2905 || coff_type.basic_type == bt_Enum)
2906 {
2907 if (coff_tag == (char *) NULL)
2908 {
2909 as_warn ("No tag specified for %s", name);
2910 return;
2911 }
2912
2913 coff_type.tag_ptr = get_tag (coff_tag, (localsym_t *) NULL,
2914 coff_type.basic_type);
2915 }
2916
2917 if (coff_is_function)
2918 {
2919 last_func_type_info = coff_type;
2920 last_func_sym_value = coff_sym_value;
2921 return;
2922 }
2923
2924 indx = add_aux_sym_tir (&coff_type,
2925 hash_yes,
2926 &cur_file_ptr->thash_head[0]);
2927 }
2928
2929 /* Do any last minute adjustments that are necessary. */
2930 switch (coff_symbol_type)
2931 {
2932 default:
2933 break;
2934
2935 /* For the beginning of structs, unions, and enumerations, the
2936 size info needs to be passed in the value field. */
2937 case st_Block:
2938 if (coff_type.num_sizes - coff_type.num_dims - coff_type.extra_sizes
2939 != 1)
2940 {
2941 as_warn ("Bad COFF debugging information");
2942 return;
2943 }
2944 else
2945 coff_value = coff_type.sizes[0];
2946
2947 coff_inside_enumeration = (coff_type.orig_type == T_ENUM);
2948 break;
2949
2950 /* For the end of structs, unions, and enumerations, omit the
2951 name which is always ".eos". This needs to be done last, so
2952 that any error reporting above gives the correct name. */
2953 case st_End:
2954 free (name);
2955 name = (char *) NULL;
2956 coff_value = 0;
2957 coff_inside_enumeration = 0;
2958 break;
2959
2960 /* Members of structures and unions that aren't bitfields, need
2961 to adjust the value from a byte offset to a bit offset.
2962 Members of enumerations do not have the value adjusted, and
2963 can be distinguished by indx == indexNil. For enumerations,
2964 update the maximum enumeration value. */
2965 case st_Member:
2966 if (! coff_type.bitfield && ! coff_inside_enumeration)
2967 coff_value *= 8;
2968
2969 break;
2970 }
2971
2972 /* Add the symbol. */
2973 sym = add_ecoff_symbol (name,
2974 coff_symbol_type,
2975 coff_storage_class,
2976 coff_sym_value,
2977 coff_value,
2978 indx);
2979
2980 /* deal with struct, union, and enum tags. */
2981 if (coff_symbol_type == st_Block)
2982 {
2983 /* Create or update the tag information. */
2984 tag_t *tag_ptr = get_tag (name,
2985 sym,
2986 coff_type.basic_type);
2987 forward_t **pf;
2988
2989 /* Remember any forward references. */
2990 for (pf = &sym->forward_ref;
2991 *pf != (forward_t *) NULL;
2992 pf = &(*pf)->next)
2993 ;
2994 *pf = tag_ptr->forward_ref;
2995 tag_ptr->forward_ref = (forward_t *) NULL;
2996 }
2997 }
2998 \f
2999 /* Parse .end directives. */
3000
3001 static void
3002 obj_ecoff_end (ignore)
3003 int ignore;
3004 {
3005 char *name;
3006 char name_end;
3007 register int ch;
3008 symbolS *ent;
3009
3010 if (cur_file_ptr == (efdr_t *) NULL)
3011 {
3012 as_warn (".end directive without a preceding .file directive");
3013 demand_empty_rest_of_line ();
3014 return;
3015 }
3016
3017 if (cur_proc_ptr == (proc_t *) NULL)
3018 {
3019 as_warn (".end directive without a preceding .ent directive");
3020 demand_empty_rest_of_line ();
3021 return;
3022 }
3023
3024 name = input_line_pointer;
3025 name_end = get_symbol_end ();
3026
3027 ch = *name;
3028 if (! is_name_beginner (ch))
3029 {
3030 as_warn (".end directive has no name");
3031 *input_line_pointer = name_end;
3032 demand_empty_rest_of_line ();
3033 return;
3034 }
3035
3036 /* The value is the distance between the .end directive and the
3037 corresponding symbol. We create a fake symbol to hold the
3038 current location, and put in the offset when we write out the
3039 symbol. */
3040 ent = symbol_find (name);
3041 if (ent == (symbolS *) NULL)
3042 as_warn (".end directive names unknown symbol");
3043 else
3044 (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text,
3045 symbol_new ("L0\001", now_seg,
3046 frag_now_fix (), frag_now),
3047 (symint_t) 0, (symint_t) 0);
3048
3049 cur_proc_ptr = (proc_t *) NULL;
3050
3051 *input_line_pointer = name_end;
3052 demand_empty_rest_of_line ();
3053 }
3054 \f
3055 /* Parse .ent directives. */
3056
3057 static void
3058 obj_ecoff_ent (ignore)
3059 int ignore;
3060 {
3061 char *name;
3062 char name_end;
3063 register int ch;
3064
3065 if (cur_file_ptr == (efdr_t *) NULL)
3066 add_file ((const char *) NULL, 0);
3067
3068 if (cur_proc_ptr != (proc_t *) NULL)
3069 {
3070 as_warn ("second .ent directive found before .end directive");
3071 demand_empty_rest_of_line ();
3072 return;
3073 }
3074
3075 name = input_line_pointer;
3076 name_end = get_symbol_end ();
3077
3078 ch = *name;
3079 if (! is_name_beginner (ch))
3080 {
3081 as_warn (".ent directive has no name");
3082 *input_line_pointer = name_end;
3083 demand_empty_rest_of_line ();
3084 return;
3085 }
3086
3087 add_procedure (name);
3088
3089 *input_line_pointer = name_end;
3090 demand_empty_rest_of_line ();
3091 }
3092 \f
3093 /* Parse .file directives. */
3094
3095 static void
3096 obj_ecoff_file (ignore)
3097 int ignore;
3098 {
3099 int indx;
3100 char *name;
3101 int len;
3102
3103 if (cur_proc_ptr != (proc_t *) NULL)
3104 {
3105 as_warn ("No way to handle .file within .ent/.end section");
3106 demand_empty_rest_of_line ();
3107 return;
3108 }
3109
3110 indx = (int) get_absolute_expression ();
3111
3112 /* FIXME: we don't have to save the name here. */
3113 name = demand_copy_C_string (&len);
3114
3115 add_file (name, indx - 1);
3116
3117 demand_empty_rest_of_line ();
3118 }
3119 \f
3120 /* Parse .fmask directives. */
3121
3122 static void
3123 obj_ecoff_fmask (ignore)
3124 int ignore;
3125 {
3126 long val;
3127
3128 if (cur_proc_ptr == (proc_t *) NULL)
3129 {
3130 as_warn (".fmask outside of .ent");
3131 demand_empty_rest_of_line ();
3132 return;
3133 }
3134
3135 if (get_absolute_expression_and_terminator (&val) != ',')
3136 {
3137 as_warn ("Bad .fmask directive");
3138 --input_line_pointer;
3139 demand_empty_rest_of_line ();
3140 return;
3141 }
3142
3143 cur_proc_ptr->pdr.fregmask = val;
3144 cur_proc_ptr->pdr.fregoffset = get_absolute_expression ();
3145
3146 demand_empty_rest_of_line ();
3147 }
3148 \f
3149 /* Parse .frame directives. */
3150
3151 static void
3152 obj_ecoff_frame (ignore)
3153 int ignore;
3154 {
3155 long val;
3156
3157 if (cur_proc_ptr == (proc_t *) NULL)
3158 {
3159 as_warn (".frame outside of .ent");
3160 demand_empty_rest_of_line ();
3161 return;
3162 }
3163
3164 cur_proc_ptr->pdr.framereg = tc_get_register ();
3165
3166 SKIP_WHITESPACE ();
3167 if (*input_line_pointer++ != ','
3168 || get_absolute_expression_and_terminator (&val) != ',')
3169 {
3170 as_warn ("Bad .frame directive");
3171 --input_line_pointer;
3172 demand_empty_rest_of_line ();
3173 return;
3174 }
3175
3176 cur_proc_ptr->pdr.frameoffset = val;
3177
3178 cur_proc_ptr->pdr.pcreg = tc_get_register ();
3179
3180 demand_empty_rest_of_line ();
3181 }
3182 \f
3183 /* Parse .mask directives. */
3184
3185 static void
3186 obj_ecoff_mask (ignore)
3187 int ignore;
3188 {
3189 long val;
3190
3191 if (cur_proc_ptr == (proc_t *) NULL)
3192 {
3193 as_warn (".mask outside of .ent");
3194 demand_empty_rest_of_line ();
3195 return;
3196 }
3197
3198 if (get_absolute_expression_and_terminator (&val) != ',')
3199 {
3200 as_warn ("Bad .mask directive");
3201 --input_line_pointer;
3202 demand_empty_rest_of_line ();
3203 return;
3204 }
3205
3206 cur_proc_ptr->pdr.regmask = val;
3207 cur_proc_ptr->pdr.regoffset = get_absolute_expression ();
3208
3209 demand_empty_rest_of_line ();
3210 }
3211 \f
3212 /* Parse .loc directives. */
3213
3214 static void
3215 obj_ecoff_loc (ignore)
3216 int ignore;
3217 {
3218 lineno_list_t *list;
3219
3220 if (cur_file_ptr == (efdr_t *) NULL)
3221 {
3222 as_warn (".loc before .file");
3223 demand_empty_rest_of_line ();
3224 return;
3225 }
3226
3227 if (now_seg != text_section)
3228 {
3229 as_warn (".loc outside of .text");
3230 demand_empty_rest_of_line ();
3231 return;
3232 }
3233
3234 /* Skip the file number. */
3235 SKIP_WHITESPACE ();
3236 get_absolute_expression ();
3237 SKIP_WHITESPACE ();
3238
3239 /* If we're building stabs, then output a special label rather than
3240 ECOFF line number info. */
3241 if (stabs_seen)
3242 {
3243 (void) add_ecoff_symbol ((char *) NULL, st_Label, sc_Text,
3244 symbol_new ("L0\001", now_seg,
3245 frag_now_fix (), frag_now),
3246 0, get_absolute_expression ());
3247 return;
3248 }
3249
3250 list = allocate_lineno_list ();
3251
3252 list->next = (lineno_list_t *) NULL;
3253 list->file = cur_file_ptr;
3254 list->proc = cur_proc_ptr;
3255 list->frag = frag_now;
3256 list->paddr = frag_now_fix ();
3257 list->lineno = get_absolute_expression ();
3258
3259 /* A .loc directive will sometimes appear before a .ent directive,
3260 which means that cur_proc_ptr will be NULL here. Arrange to
3261 patch this up. */
3262 if (cur_proc_ptr == (proc_t *) NULL)
3263 {
3264 lineno_list_t **pl;
3265
3266 pl = &noproc_lineno;
3267 while (*pl != (lineno_list_t *) NULL)
3268 pl = &(*pl)->next;
3269 *pl = list;
3270 }
3271 else
3272 {
3273 *last_lineno_ptr = list;
3274 last_lineno_ptr = &list->next;
3275 }
3276 }
3277 \f
3278 /* Make sure the @stabs symbol is emitted. */
3279
3280 static void
3281 mark_stabs (ignore)
3282 int ignore;
3283 {
3284 if (! stabs_seen)
3285 {
3286 /* Add a dummy @stabs dymbol. */
3287 stabs_seen = 1;
3288 (void) add_ecoff_symbol (stabs_symbol, stNil, scInfo,
3289 (symbolS *) NULL,
3290 (symint_t) -1, MIPS_MARK_STAB (0));
3291 }
3292 }
3293 \f
3294 /* Parse .stabs directives.
3295
3296 .stabs directives have five fields:
3297 "string" a string, encoding the type information.
3298 code a numeric code, defined in <stab.h>
3299 0 a zero
3300 0 a zero or line number
3301 value a numeric value or an address.
3302
3303 If the value is relocatable, we transform this into:
3304 iss points as an index into string space
3305 value value from lookup of the name
3306 st st from lookup of the name
3307 sc sc from lookup of the name
3308 index code|CODE_MASK
3309
3310 If the value is not relocatable, we transform this into:
3311 iss points as an index into string space
3312 value value
3313 st st_Nil
3314 sc sc_Nil
3315 index code|CODE_MASK
3316
3317 .stabn directives have four fields (string is null):
3318 code a numeric code, defined in <stab.h>
3319 0 a zero
3320 0 a zero or a line number
3321 value a numeric value or an address. */
3322
3323 static void
3324 obj_ecoff_stab (type)
3325 int type;
3326 {
3327 char *string;
3328 efdr_t *save_file_ptr = cur_file_ptr;
3329 symint_t code;
3330 symint_t value;
3331 symbolS *sym;
3332 st_t st;
3333 sc_t sc;
3334
3335 if (stabs_seen == 0)
3336 mark_stabs (0);
3337
3338 if (type != 's')
3339 string = (char *) NULL;
3340 else
3341 {
3342 int len;
3343
3344 string = demand_copy_C_string (&len);
3345 SKIP_WHITESPACE ();
3346 if (*input_line_pointer == ',')
3347 input_line_pointer++;
3348 else
3349 {
3350 as_warn ("Bad .stab%c directive", type);
3351 demand_empty_rest_of_line ();
3352 return;
3353 }
3354 }
3355
3356 code = (symint_t) get_absolute_expression ();
3357
3358 SKIP_WHITESPACE ();
3359 if (*input_line_pointer++ != ',')
3360 {
3361 as_warn ("Bad .stab%c directive", type);
3362 --input_line_pointer;
3363 demand_empty_rest_of_line ();
3364 return;
3365 }
3366
3367 if (get_absolute_expression () != 0)
3368 {
3369 as_warn ("Bad .stab%c directive (expected 0)", type);
3370 demand_empty_rest_of_line ();
3371 return;
3372 }
3373
3374 SKIP_WHITESPACE ();
3375 if (*input_line_pointer++ != ',')
3376 {
3377 as_warn ("Bad .stab%c directive", type);
3378 --input_line_pointer;
3379 demand_empty_rest_of_line ();
3380 return;
3381 }
3382
3383 /* Line number stabs are handled differently, since they have two values,
3384 the line number and the address of the label. We use the index field
3385 (aka code) to hold the line number, and the value field to hold the
3386 address. The symbol type is st_Label, which should be different from
3387 the other stabs, so that gdb can recognize it. */
3388 if (code == N_SLINE)
3389 {
3390 SYMR dummy_symr;
3391 char *name;
3392 char name_end;
3393
3394 code = (symint_t) get_absolute_expression ();
3395
3396 if (*input_line_pointer++ != ',')
3397 {
3398 as_warn ("Bad .stab%c directive", type);
3399 --input_line_pointer;
3400 demand_empty_rest_of_line ();
3401 return;
3402 }
3403
3404 dummy_symr.index = code;
3405 if (dummy_symr.index != code)
3406 {
3407 as_warn ("Line number (%d) for .stab%c directive cannot fit in index field (20 bits)",
3408 code, type);
3409 demand_empty_rest_of_line ();
3410 return;
3411 }
3412
3413 SKIP_WHITESPACE ();
3414 name = input_line_pointer;
3415 name_end = get_symbol_end ();
3416
3417 sym = symbol_find_or_make (name);
3418 *input_line_pointer = name_end;
3419
3420 value = 0;
3421 st = st_Label;
3422 sc = sc_Text;
3423 }
3424 else
3425 {
3426 /* The next number is sometimes the line number of the
3427 declaration. We have nowhere to put it, so we just ignore
3428 it. */
3429 (void) get_absolute_expression ();
3430
3431 SKIP_WHITESPACE ();
3432 if (*input_line_pointer++ != ',')
3433 {
3434 as_warn ("Bad .stab%c directive", type);
3435 --input_line_pointer;
3436 demand_empty_rest_of_line ();
3437 return;
3438 }
3439
3440 SKIP_WHITESPACE ();
3441 if (isdigit (*input_line_pointer)
3442 || *input_line_pointer == '-'
3443 || *input_line_pointer == '+')
3444 {
3445 st = st_Nil;
3446 sc = sc_Nil;
3447 sym = (symbolS *) NULL;
3448 value = get_absolute_expression ();
3449 }
3450 else if (! is_name_beginner ((unsigned char) *input_line_pointer))
3451 {
3452 as_warn ("Illegal .stab%c directive, bad character", type);
3453 demand_empty_rest_of_line ();
3454 return;
3455 }
3456 else
3457 {
3458 char *name;
3459 char name_end;
3460
3461 name = input_line_pointer;
3462 name_end = get_symbol_end ();
3463
3464 sym = symbol_find_or_make (name);
3465
3466 sc = sc_Nil;
3467 st = st_Nil;
3468 value = 0;
3469
3470 *input_line_pointer = name_end;
3471 if (name_end == '+' || name_end == '-')
3472 {
3473 ++input_line_pointer;
3474 value = get_absolute_expression ();
3475 if (name_end == '-')
3476 value = - value;
3477 }
3478 }
3479
3480 code = MIPS_MARK_STAB (code);
3481 }
3482
3483 (void) add_ecoff_symbol (string, st, sc, sym, value, code);
3484
3485 /* Restore normal file type. */
3486 cur_file_ptr = save_file_ptr;
3487 }
3488 \f
3489 /* Add bytes to the symbolic information buffer. */
3490
3491 static char *
3492 ecoff_add_bytes (buf, bufend, bufptr, need)
3493 char **buf;
3494 char **bufend;
3495 char *bufptr;
3496 long need;
3497 {
3498 unsigned long at;
3499 unsigned long want;
3500
3501 at = bufptr - *buf;
3502 need -= *bufend - bufptr;
3503 if (need < PAGE_SIZE)
3504 need = PAGE_SIZE;
3505 want = (*bufend - *buf) + need;
3506 *buf = xrealloc (*buf, want);
3507 *bufend = *buf + want;
3508 return *buf + at;
3509 }
3510
3511 /* Adjust the symbolic information buffer to a longword boundary. */
3512
3513 static long
3514 ecoff_longword_adjust (buf, bufend, offset, bufptrptr)
3515 char **buf;
3516 char **bufend;
3517 long offset;
3518 char **bufptrptr;
3519 {
3520 if ((offset & 3) != 0)
3521 {
3522 long add;
3523
3524 add = 4 - (offset & 3);
3525 if (*bufend - (*buf + offset) < add)
3526 (void) ecoff_add_bytes (buf, bufend, *buf + offset, add);
3527 memset (*buf + offset, 0, add);
3528 offset += add;
3529 if (bufptrptr != (char **) NULL)
3530 *bufptrptr = *buf + offset;
3531 }
3532
3533 return offset;
3534 }
3535
3536 /* Build the line number information. */
3537
3538 static long
3539 ecoff_build_lineno (buf, bufend, offset, linecntptr)
3540 char **buf;
3541 char **bufend;
3542 long offset;
3543 long *linecntptr;
3544 {
3545 char *bufptr;
3546 register lineno_list_t *l;
3547 lineno_list_t *last;
3548 efdr_t *file;
3549 proc_t *proc;
3550 long c;
3551 long iline;
3552 long totcount;
3553
3554 bufptr = *buf + offset;
3555
3556 file = (efdr_t *) NULL;
3557 proc = (proc_t *) NULL;
3558 last = (lineno_list_t *) NULL;
3559 c = offset;
3560 iline = 0;
3561 totcount = 0;
3562 for (l = first_lineno; l != (lineno_list_t *) NULL; l = l->next)
3563 {
3564 long count;
3565 long delta;
3566
3567 /* Get the offset to the memory address of the next line number
3568 (in words). Do this first, so that we can skip ahead to the
3569 next useful line number entry. */
3570 if (l->next == (lineno_list_t *) NULL)
3571 count = 0;
3572 else
3573 {
3574 count = ((l->next->frag->fr_address + l->next->paddr
3575 - (l->frag->fr_address + l->paddr))
3576 >> 2);
3577 if (count <= 0)
3578 {
3579 /* Don't change last, so we still get the right delta. */
3580 continue;
3581 }
3582 }
3583
3584 if (l->file != file || l->proc != proc)
3585 {
3586 if (l->proc != proc && proc != (proc_t *) NULL)
3587 proc->pdr.lnHigh = last->lineno;
3588 if (l->file != file && file != (efdr_t *) NULL)
3589 {
3590 file->fdr.cbLine = c - file->fdr.cbLineOffset;
3591 /* The cline field is ill-documented. This is a guess
3592 at the right value. */
3593 file->fdr.cline = totcount + count;
3594 }
3595
3596 if (l->file != file)
3597 {
3598 file = l->file;
3599 file->fdr.ilineBase = iline;
3600 file->fdr.cbLineOffset = c;
3601 }
3602 if (l->proc != proc)
3603 {
3604 proc = l->proc;
3605 if (proc != (proc_t *) NULL)
3606 {
3607 proc->pdr.lnLow = l->lineno;
3608 proc->pdr.cbLineOffset = c - file->fdr.cbLineOffset;
3609 /* The iline field is ill-documented. This is a
3610 guess at the right value. */
3611 proc->pdr.iline = totcount;
3612 }
3613 }
3614
3615 last = (lineno_list_t *) NULL;
3616 }
3617
3618 totcount += count;
3619
3620 /* Get the offset to this line number. */
3621 if (last == (lineno_list_t *) NULL)
3622 delta = 0;
3623 else
3624 delta = l->lineno - last->lineno;
3625
3626 /* Put in the offset to this line number. */
3627 while (delta != 0)
3628 {
3629 int setcount;
3630
3631 /* 1 is added to each count read. */
3632 --count;
3633 /* We can only adjust the word count by up to 15 words at a
3634 time. */
3635 if (count <= 0x0f)
3636 {
3637 setcount = count;
3638 count = 0;
3639 }
3640 else
3641 {
3642 setcount = 0x0f;
3643 count -= 0x0f;
3644 }
3645 if (delta >= -7 && delta <= 7)
3646 {
3647 if (bufptr >= *bufend)
3648 bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
3649 *bufptr++ = setcount + (delta << 4);
3650 delta = 0;
3651 ++c;
3652 }
3653 else
3654 {
3655 int set;
3656
3657 if (*bufend - bufptr < 3)
3658 bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 3);
3659 *bufptr++ = setcount + (8 << 4);
3660 if (delta < -0x8000)
3661 {
3662 set = -0x8000;
3663 delta += 0x8000;
3664 }
3665 else if (delta > 0x7fff)
3666 {
3667 set = 0x7fff;
3668 delta -= 0x7fff;
3669 }
3670 else
3671 {
3672 set = delta;
3673 delta = 0;
3674 }
3675 *bufptr++ = set >> 8;
3676 *bufptr++ = set & 0xffff;
3677 c += 3;
3678 }
3679 }
3680
3681 /* Finish adjusting the count. */
3682 while (count > 0)
3683 {
3684 if (bufptr >= *bufend)
3685 bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
3686 /* 1 is added to each count read. */
3687 --count;
3688 if (count > 0x0f)
3689 {
3690 *bufptr++ = 0x0f;
3691 count -= 0x0f;
3692 }
3693 else
3694 {
3695 *bufptr++ = count;
3696 count = 0;
3697 }
3698 ++c;
3699 }
3700
3701 ++iline;
3702 last = l;
3703 }
3704
3705 if (proc != (proc_t *) NULL)
3706 proc->pdr.lnHigh = last->lineno;
3707 if (file != (efdr_t *) NULL)
3708 {
3709 file->fdr.cbLine = c - file->fdr.cbLineOffset;
3710 file->fdr.cline = totcount;
3711 }
3712
3713 c = ecoff_longword_adjust (buf, bufend, c, &bufptr);
3714
3715 if (linecntptr != (long *) NULL)
3716 *linecntptr = totcount;
3717
3718 return c;
3719 }
3720
3721 /* Build and swap out the symbols. */
3722
3723 static long
3724 ecoff_build_symbols (buf,
3725 bufend,
3726 offset,
3727 extbuf,
3728 extbufend,
3729 extoffset,
3730 ext_strings,
3731 ext_str_hash)
3732 char **buf;
3733 char **bufend;
3734 long offset;
3735 char **extbuf;
3736 char **extbufend;
3737 long *extoffset;
3738 varray_t *ext_strings;
3739 struct hash_control *ext_str_hash;
3740 {
3741 struct sym_ext *sym_out;
3742 struct ext_ext *ext_out;
3743 long isym;
3744 long iext;
3745 vlinks_t *file_link;
3746
3747 sym_out = (struct sym_ext *) (*buf + offset);
3748 ext_out = (struct ext_ext *) (*extbuf + *extoffset);
3749
3750 isym = 0;
3751 iext = 0;
3752
3753 /* The symbols are stored by file. */
3754 for (file_link = file_desc.first;
3755 file_link != (vlinks_t *) NULL;
3756 file_link = file_link->next)
3757 {
3758 int ifilesym;
3759 int fil_cnt;
3760 efdr_t *fil_ptr;
3761 efdr_t *fil_end;
3762
3763 if (file_link->next == (vlinks_t *) NULL)
3764 fil_cnt = file_desc.objects_last_page;
3765 else
3766 fil_cnt = file_desc.objects_per_page;
3767 fil_ptr = file_link->datum->file;
3768 fil_end = fil_ptr + fil_cnt;
3769 for (; fil_ptr < fil_end; fil_ptr++)
3770 {
3771 vlinks_t *sym_link;
3772
3773 fil_ptr->fdr.isymBase = isym;
3774 ifilesym = isym;
3775 for (sym_link = fil_ptr->symbols.first;
3776 sym_link != (vlinks_t *) NULL;
3777 sym_link = sym_link->next)
3778 {
3779 int sym_cnt;
3780 localsym_t *sym_ptr;
3781 localsym_t *sym_end;
3782
3783 if (sym_link->next == (vlinks_t *) NULL)
3784 sym_cnt = fil_ptr->symbols.objects_last_page;
3785 else
3786 sym_cnt = fil_ptr->symbols.objects_per_page;
3787 sym_ptr = sym_link->datum->sym;
3788 sym_end = sym_ptr + sym_cnt;
3789 for (; sym_ptr < sym_end; sym_ptr++)
3790 {
3791 int local;
3792 symbolS *as_sym;
3793 forward_t *f;
3794
3795 know (sym_ptr->file_ptr == fil_ptr);
3796
3797 /* If there is no associated gas symbol, then this
3798 is a pure debugging symbol. We have already
3799 added the name (if any) to fil_ptr->strings.
3800 Otherwise we must decide whether this is an
3801 external or a local symbol (actually, it may be
3802 both if the local provides additional debugging
3803 information for the external). */
3804 local = 1;
3805 as_sym = sym_ptr->as_sym;
3806 if (as_sym != (symbolS *) NULL)
3807 {
3808 symint_t indx;
3809
3810 /* The value of a block start symbol is the
3811 offset from the start of the procedure. For
3812 other symbols we just use the gas value. */
3813 if (sym_ptr->ecoff_sym.st == (int) st_Block
3814 && sym_ptr->ecoff_sym.sc == (int) sc_Text)
3815 {
3816 know (sym_ptr->proc_ptr != (proc_t *) NULL);
3817 sym_ptr->ecoff_sym.value =
3818 (S_GET_VALUE (as_sym)
3819 - S_GET_VALUE (sym_ptr->proc_ptr->sym->as_sym));
3820 }
3821 else
3822 sym_ptr->ecoff_sym.value = S_GET_VALUE (as_sym);
3823
3824 /* Get the type and storage class based on where
3825 the symbol actually wound up. Traditionally,
3826 N_LBRAC and N_RBRAC are *not* relocated. */
3827 indx = sym_ptr->ecoff_sym.index;
3828 if (sym_ptr->ecoff_sym.st == st_Nil
3829 && sym_ptr->ecoff_sym.sc == sc_Nil
3830 && (! MIPS_IS_STAB (&sym_ptr->ecoff_sym)
3831 || ((MIPS_UNMARK_STAB (indx) != N_LBRAC)
3832 && (MIPS_UNMARK_STAB (indx) != N_RBRAC))))
3833 {
3834 segT seg;
3835 const char *segname;
3836 st_t st;
3837 sc_t sc;
3838
3839 seg = S_GET_SEGMENT (as_sym);
3840 segname = segment_name (seg);
3841
3842 if (S_IS_EXTERNAL (as_sym)
3843 || ! S_IS_DEFINED (as_sym))
3844 st = st_Global;
3845 else if (seg == text_section)
3846 st = st_Label;
3847 else
3848 st = st_Static;
3849
3850 if (! S_IS_DEFINED (as_sym)
3851 || as_sym->ecoff_undefined)
3852 {
3853 if (S_GET_VALUE (as_sym) > 0
3854 && (S_GET_VALUE (as_sym)
3855 <= bfd_get_gp_size (stdoutput)))
3856 sc = sc_SUndefined;
3857 else
3858 sc = sc_Undefined;
3859 }
3860 else if (S_IS_COMMON (as_sym))
3861 {
3862 if (S_GET_VALUE (as_sym) > 0
3863 && (S_GET_VALUE (as_sym)
3864 <= bfd_get_gp_size (stdoutput)))
3865 sc = sc_SCommon;
3866 else
3867 sc = sc_Common;
3868 }
3869 else if (seg == text_section)
3870 sc = sc_Text;
3871 else if (seg == data_section)
3872 sc = sc_Data;
3873 else if (strcmp (segname, ".rdata") == 0)
3874 sc = sc_RData;
3875 else if (strcmp (segname, ".sdata") == 0)
3876 sc = sc_SData;
3877 else if (seg == bss_section)
3878 sc = sc_Bss;
3879 else if (strcmp (segname, ".sbss") == 0)
3880 sc = sc_SBss;
3881 else
3882 abort ();
3883
3884 sym_ptr->ecoff_sym.st = (int) st;
3885 sym_ptr->ecoff_sym.sc = (int) sc;
3886 }
3887
3888 /* This is just an external symbol if it is
3889 outside a procedure and it has a type.
3890 FIXME: g++ will generate symbols which have
3891 different names in the debugging information
3892 than the actual symbol. Should we handle
3893 them here? */
3894 if ((S_IS_EXTERNAL (as_sym)
3895 || ! S_IS_DEFINED (as_sym))
3896 && sym_ptr->proc_ptr == (proc_t *) NULL
3897 && sym_ptr->ecoff_sym.st != (int) st_Nil
3898 && ! MIPS_IS_STAB (&sym_ptr->ecoff_sym))
3899 local = 0;
3900
3901 /* If an st_end symbol has an associated gas
3902 symbol, then it is a local label created for
3903 a .bend or .end directive. Stabs line
3904 numbers will have \001 in the names. */
3905 if (local
3906 && sym_ptr->ecoff_sym.st != st_End
3907 && strchr (sym_ptr->name, '\001') == 0)
3908 sym_ptr->ecoff_sym.iss =
3909 add_string (&fil_ptr->strings,
3910 fil_ptr->str_hash,
3911 sym_ptr->name,
3912 (shash_t **) NULL);
3913 }
3914
3915 /* We now know the index of this symbol; fill in
3916 locations that have been waiting for that
3917 information. */
3918 if (sym_ptr->begin_ptr != (localsym_t *) NULL)
3919 {
3920 localsym_t *begin_ptr;
3921 st_t begin_type;
3922
3923 know (local);
3924 begin_ptr = sym_ptr->begin_ptr;
3925 know (begin_ptr->sym_index != -1);
3926 sym_ptr->ecoff_sym.index = begin_ptr->sym_index;
3927 if (sym_ptr->ecoff_sym.sc != (int) sc_Info)
3928 sym_ptr->ecoff_sym.iss = begin_ptr->ecoff_sym.iss;
3929
3930 begin_type = begin_ptr->ecoff_sym.st;
3931 if (begin_type == st_File
3932 || begin_type == st_Block)
3933 {
3934 begin_ptr->ecoff_sym.index = isym - ifilesym + 1;
3935 ecoff_swap_sym_out (stdoutput,
3936 &begin_ptr->ecoff_sym,
3937 (((struct sym_ext *)
3938 (*buf + offset))
3939 + begin_ptr->sym_index));
3940 }
3941 else
3942 {
3943 know (begin_ptr->index_ptr != (aux_t *) NULL);
3944 begin_ptr->index_ptr->data.isym =
3945 isym - ifilesym + 1;
3946 }
3947
3948 /* The value of the symbol marking the end of a
3949 procedure is the size of the procedure. The
3950 value of the symbol marking the end of a
3951 block is the offset from the start of the
3952 procedure to the block. */
3953 if (begin_type == st_Proc)
3954 {
3955 know (as_sym != (symbolS *) NULL);
3956 know (begin_ptr->as_sym != (symbolS *) NULL);
3957 sym_ptr->ecoff_sym.value =
3958 (S_GET_VALUE (as_sym)
3959 - S_GET_VALUE (begin_ptr->as_sym));
3960 }
3961 else if (begin_type == st_Block
3962 && sym_ptr->ecoff_sym.sc != (int) sc_Info)
3963 {
3964 know (as_sym != (symbolS *) NULL);
3965 know (sym_ptr->proc_ptr != (proc_t *) NULL);
3966 sym_ptr->ecoff_sym.value =
3967 (S_GET_VALUE (as_sym)
3968 - S_GET_VALUE (sym_ptr->proc_ptr->sym->as_sym));
3969 }
3970 }
3971
3972 for (f = sym_ptr->forward_ref;
3973 f != (forward_t *) NULL;
3974 f = f->next)
3975 {
3976 know (local);
3977 f->ifd_ptr->data.isym = fil_ptr->file_index;
3978 f->index_ptr->data.rndx.index = isym - ifilesym;
3979 }
3980
3981 if (local)
3982 {
3983 if (*bufend - (char *) sym_out < sizeof (struct sym_ext))
3984 sym_out = ((struct sym_ext *)
3985 ecoff_add_bytes (buf, bufend,
3986 (char *) sym_out,
3987 sizeof (struct sym_ext)));
3988 ecoff_swap_sym_out (stdoutput, &sym_ptr->ecoff_sym,
3989 sym_out);
3990 ++sym_out;
3991
3992 sym_ptr->sym_index = isym;
3993
3994 if (sym_ptr->proc_ptr != (proc_t *) NULL
3995 && sym_ptr->proc_ptr->sym == sym_ptr)
3996 sym_ptr->proc_ptr->pdr.isym = isym - ifilesym;
3997
3998 ++isym;
3999 }
4000
4001 /* If this is an external symbol, swap it out. */
4002 if (as_sym != (symbolS *) NULL
4003 && (S_IS_EXTERNAL (as_sym)
4004 || ! S_IS_DEFINED (as_sym))
4005 && ! MIPS_IS_STAB (&sym_ptr->ecoff_sym))
4006 {
4007 EXTR ext;
4008
4009 memset (&ext, 0, sizeof ext);
4010 ext.asym = sym_ptr->ecoff_sym;
4011 ext.ifd = fil_ptr->file_index;
4012 ext.asym.iss = add_string (ext_strings,
4013 ext_str_hash,
4014 S_GET_NAME (as_sym),
4015 (shash_t **) NULL);
4016 if (*extbufend - (char *) ext_out
4017 < sizeof (struct ext_ext))
4018 ext_out = ((struct ext_ext *)
4019 ecoff_add_bytes (extbuf, extbufend,
4020 (char *) ext_out,
4021 sizeof (struct ext_ext)));
4022 ecoff_swap_ext_out (stdoutput, &ext, ext_out);
4023 ecoff_set_sym_index (as_sym->bsym, iext);
4024 ++ext_out;
4025 ++iext;
4026 }
4027 }
4028 }
4029 fil_ptr->fdr.csym = isym - fil_ptr->fdr.isymBase;
4030 }
4031 }
4032
4033 *extoffset += iext * sizeof (struct ext_ext);
4034 return offset + isym * sizeof (struct sym_ext);
4035 }
4036
4037 /* Swap out the procedure information. */
4038
4039 static long
4040 ecoff_build_procs (buf, bufend, offset)
4041 char **buf;
4042 char **bufend;
4043 long offset;
4044 {
4045 struct pdr_ext *pdr_out;
4046 long iproc;
4047 vlinks_t *file_link;
4048
4049 pdr_out = (struct pdr_ext *) (*buf + offset);
4050
4051 iproc = 0;
4052
4053 /* The procedures are stored by file. */
4054 for (file_link = file_desc.first;
4055 file_link != (vlinks_t *) NULL;
4056 file_link = file_link->next)
4057 {
4058 int fil_cnt;
4059 efdr_t *fil_ptr;
4060 efdr_t *fil_end;
4061
4062 if (file_link->next == (vlinks_t *) NULL)
4063 fil_cnt = file_desc.objects_last_page;
4064 else
4065 fil_cnt = file_desc.objects_per_page;
4066 fil_ptr = file_link->datum->file;
4067 fil_end = fil_ptr + fil_cnt;
4068 for (; fil_ptr < fil_end; fil_ptr++)
4069 {
4070 vlinks_t *proc_link;
4071 int first;
4072
4073 fil_ptr->fdr.ipdFirst = iproc;
4074 first = 1;
4075 for (proc_link = fil_ptr->procs.first;
4076 proc_link != (vlinks_t *) NULL;
4077 proc_link = proc_link->next)
4078 {
4079 int proc_cnt;
4080 proc_t *proc_ptr;
4081 proc_t *proc_end;
4082
4083 if (proc_link->next == (vlinks_t *) NULL)
4084 proc_cnt = fil_ptr->procs.objects_last_page;
4085 else
4086 proc_cnt = fil_ptr->procs.objects_per_page;
4087 proc_ptr = proc_link->datum->proc;
4088 proc_end = proc_ptr + proc_cnt;
4089 for (; proc_ptr < proc_end; proc_ptr++)
4090 {
4091 unsigned long adr;
4092
4093 adr = S_GET_VALUE (proc_ptr->sym->as_sym);
4094 if (first)
4095 {
4096 fil_ptr->fdr.adr = adr;
4097 first = 0;
4098 }
4099 proc_ptr->pdr.adr = adr - fil_ptr->fdr.adr;
4100 if (*bufend - (char *) pdr_out < sizeof (struct pdr_ext))
4101 pdr_out = ((struct pdr_ext *)
4102 ecoff_add_bytes (buf, bufend,
4103 (char *) pdr_out,
4104 sizeof (struct pdr_ext)));
4105 ecoff_swap_pdr_out (stdoutput, &proc_ptr->pdr, pdr_out);
4106 ++pdr_out;
4107 ++iproc;
4108 }
4109 }
4110 fil_ptr->fdr.cpd = iproc - fil_ptr->fdr.ipdFirst;
4111 }
4112 }
4113
4114 return offset + iproc * sizeof (struct pdr_ext);
4115 }
4116
4117 /* Swap out the aux information. */
4118
4119 static long
4120 ecoff_build_aux (buf, bufend, offset)
4121 char **buf;
4122 char **bufend;
4123 long offset;
4124 {
4125 int bigendian;
4126 union aux_ext *aux_out;
4127 long iaux;
4128 vlinks_t *file_link;
4129
4130 bigendian = stdoutput->xvec->header_byteorder_big_p;
4131
4132 aux_out = (union aux_ext *) (*buf + offset);
4133
4134 iaux = 0;
4135
4136 /* The aux entries are stored by file. */
4137 for (file_link = file_desc.first;
4138 file_link != (vlinks_t *) NULL;
4139 file_link = file_link->next)
4140 {
4141 int fil_cnt;
4142 efdr_t *fil_ptr;
4143 efdr_t *fil_end;
4144
4145 if (file_link->next == (vlinks_t *) NULL)
4146 fil_cnt = file_desc.objects_last_page;
4147 else
4148 fil_cnt = file_desc.objects_per_page;
4149 fil_ptr = file_link->datum->file;
4150 fil_end = fil_ptr + fil_cnt;
4151 for (; fil_ptr < fil_end; fil_ptr++)
4152 {
4153 vlinks_t *aux_link;
4154
4155 fil_ptr->fdr.fBigendian = bigendian;
4156 fil_ptr->fdr.iauxBase = iaux;
4157 for (aux_link = fil_ptr->aux_syms.first;
4158 aux_link != (vlinks_t *) NULL;
4159 aux_link = aux_link->next)
4160 {
4161 int aux_cnt;
4162 aux_t *aux_ptr;
4163 aux_t *aux_end;
4164
4165 if (aux_link->next == (vlinks_t *) NULL)
4166 aux_cnt = fil_ptr->aux_syms.objects_last_page;
4167 else
4168 aux_cnt = fil_ptr->aux_syms.objects_per_page;
4169 aux_ptr = aux_link->datum->aux;
4170 aux_end = aux_ptr + aux_cnt;
4171 for (; aux_ptr < aux_end; aux_ptr++)
4172 {
4173 if (*bufend - (char *) aux_out < sizeof (union aux_ext))
4174 aux_out = ((union aux_ext *)
4175 ecoff_add_bytes (buf, bufend,
4176 (char *) aux_out,
4177 sizeof (union aux_ext)));
4178 switch (aux_ptr->type)
4179 {
4180 case aux_tir:
4181 ecoff_swap_tir_out (bigendian, &aux_ptr->data.ti,
4182 &aux_out->a_ti);
4183 break;
4184 case aux_rndx:
4185 ecoff_swap_rndx_out (bigendian, &aux_ptr->data.rndx,
4186 &aux_out->a_rndx);
4187 break;
4188 case aux_dnLow:
4189 AUX_PUT_DNLOW (bigendian, aux_ptr->data.dnLow,
4190 aux_out);
4191 break;
4192 case aux_dnHigh:
4193 AUX_PUT_DNHIGH (bigendian, aux_ptr->data.dnHigh,
4194 aux_out);
4195 break;
4196 case aux_isym:
4197 AUX_PUT_ISYM (bigendian, aux_ptr->data.isym,
4198 aux_out);
4199 break;
4200 case aux_iss:
4201 AUX_PUT_ISS (bigendian, aux_ptr->data.iss,
4202 aux_out);
4203 break;
4204 case aux_width:
4205 AUX_PUT_WIDTH (bigendian, aux_ptr->data.width,
4206 aux_out);
4207 break;
4208 case aux_count:
4209 AUX_PUT_COUNT (bigendian, aux_ptr->data.count,
4210 aux_out);
4211 break;
4212 }
4213
4214 ++aux_out;
4215 ++iaux;
4216 }
4217 }
4218 fil_ptr->fdr.caux = iaux - fil_ptr->fdr.iauxBase;
4219 }
4220 }
4221
4222 return offset + iaux * sizeof (union aux_ext);
4223 }
4224
4225 /* Copy out the strings from a varray_t. This returns the number of
4226 bytes copied, rather than the new offset. */
4227
4228 static long
4229 ecoff_build_strings (buf, bufend, offset, vp)
4230 char **buf;
4231 char **bufend;
4232 long offset;
4233 varray_t *vp;
4234 {
4235 long istr;
4236 char *str_out;
4237 vlinks_t *str_link;
4238
4239 str_out = *buf + offset;
4240
4241 istr = 0;
4242
4243 for (str_link = vp->first;
4244 str_link != (vlinks_t *) NULL;
4245 str_link = str_link->next)
4246 {
4247 long str_cnt;
4248
4249 if (str_link->next == (vlinks_t *) NULL)
4250 str_cnt = vp->objects_last_page;
4251 else
4252 str_cnt = vp->objects_per_page;
4253
4254 if (*bufend - str_out < str_cnt)
4255 str_out = ecoff_add_bytes (buf, bufend, str_out, str_cnt);
4256
4257 memcpy (str_out, str_link->datum->byte, str_cnt);
4258 str_out += str_cnt;
4259 istr += str_cnt;
4260 }
4261
4262 return istr;
4263 }
4264
4265 /* Dump out the local strings. */
4266
4267 static long
4268 ecoff_build_ss (buf, bufend, offset)
4269 char **buf;
4270 char **bufend;
4271 long offset;
4272 {
4273 long iss;
4274 vlinks_t *file_link;
4275
4276 iss = 0;
4277
4278 for (file_link = file_desc.first;
4279 file_link != (vlinks_t *) NULL;
4280 file_link = file_link->next)
4281 {
4282 int fil_cnt;
4283 efdr_t *fil_ptr;
4284 efdr_t *fil_end;
4285
4286 if (file_link->next == (vlinks_t *) NULL)
4287 fil_cnt = file_desc.objects_last_page;
4288 else
4289 fil_cnt = file_desc.objects_per_page;
4290 fil_ptr = file_link->datum->file;
4291 fil_end = fil_ptr + fil_cnt;
4292 for (; fil_ptr < fil_end; fil_ptr++)
4293 {
4294 long ss_cnt;
4295
4296 fil_ptr->fdr.issBase = iss;
4297 ss_cnt = ecoff_build_strings (buf, bufend, offset + iss,
4298 &fil_ptr->strings);
4299 fil_ptr->fdr.cbSs = ss_cnt;
4300 iss += ss_cnt;
4301 }
4302 }
4303
4304 return ecoff_longword_adjust (buf, bufend, offset + iss, (char **) NULL);
4305 }
4306
4307 /* Swap out the file descriptors. */
4308
4309 static long
4310 ecoff_build_fdr (buf, bufend, offset)
4311 char **buf;
4312 char **bufend;
4313 long offset;
4314 {
4315 long ifile;
4316 struct fdr_ext *fdr_out;
4317 vlinks_t *file_link;
4318
4319 ifile = 0;
4320
4321 fdr_out = (struct fdr_ext *) (*buf + offset);
4322
4323 for (file_link = file_desc.first;
4324 file_link != (vlinks_t *) NULL;
4325 file_link = file_link->next)
4326 {
4327 int fil_cnt;
4328 efdr_t *fil_ptr;
4329 efdr_t *fil_end;
4330
4331 if (file_link->next == (vlinks_t *) NULL)
4332 fil_cnt = file_desc.objects_last_page;
4333 else
4334 fil_cnt = file_desc.objects_per_page;
4335 fil_ptr = file_link->datum->file;
4336 fil_end = fil_ptr + fil_cnt;
4337 for (; fil_ptr < fil_end; fil_ptr++)
4338 {
4339 if (*bufend - (char *) fdr_out < sizeof (struct fdr_ext))
4340 fdr_out = ((struct fdr_ext *)
4341 ecoff_add_bytes (buf, bufend, (char *) fdr_out,
4342 sizeof (struct fdr_ext)));
4343 ecoff_swap_fdr_out (stdoutput, &fil_ptr->fdr, fdr_out);
4344 ++fdr_out;
4345 ++ifile;
4346 }
4347 }
4348
4349 return offset + ifile * sizeof (struct fdr_ext);
4350 }
4351
4352 /* Set the vma for all the sections. */
4353
4354 static void
4355 ecoff_set_vma ()
4356 {
4357 register bfd_vma addr;
4358 register asection *sec;
4359
4360 addr = 0;
4361 for (sec = stdoutput->sections; sec != (asection *) NULL; sec = sec->next)
4362 {
4363 bfd_set_section_vma (stdoutput, sec, addr);
4364 addr += bfd_section_size (stdoutput, sec);
4365 }
4366 }
4367
4368 /* Adjust the value of a symbol by the vma of the section. */
4369
4370 void
4371 ecoff_frob_symbol (sym)
4372 symbolS *sym;
4373 {
4374 static int setvma = 0;
4375
4376 if (! setvma)
4377 {
4378 ecoff_set_vma ();
4379 setvma = 1;
4380 }
4381
4382 S_SET_VALUE (sym,
4383 (S_GET_VALUE (sym)
4384 + bfd_get_section_vma (stdoutput,
4385 bfd_get_section (sym->bsym))));
4386 }
4387
4388 /* Swap out the symbols and debugging information for BFD. */
4389
4390 void
4391 ecoff_frob_file ()
4392 {
4393 tag_t *ptag;
4394 tag_t *ptag_next;
4395 efdr_t *fil_ptr;
4396 efdr_t *hold_file_ptr;
4397 proc_t * hold_proc_ptr;
4398 symbolS *sym;
4399 HDRR *hdr;
4400 char *buf;
4401 char *bufend;
4402 long offset;
4403 char *extbuf;
4404 char *extbufend;
4405 long extoffset;
4406 varray_t ext_strings;
4407 static varray_t init_ext_strings = INIT_VARRAY (char);
4408 struct hash_control *ext_str_hash;
4409 char *set;
4410
4411 /* Make sure we have a file. */
4412 if (first_file == (efdr_t *) NULL)
4413 add_file ((const char *) NULL, 0);
4414
4415 /* Handle any top level tags. */
4416 for (ptag = top_tag_head->first_tag;
4417 ptag != (tag_t *) NULL;
4418 ptag = ptag_next)
4419 {
4420 if (ptag->forward_ref != (forward_t *) NULL)
4421 add_unknown_tag (ptag);
4422
4423 ptag_next = ptag->same_block;
4424 ptag->hash_ptr->tag_ptr = ptag->same_name;
4425 free_tag (ptag);
4426 }
4427
4428 free_thead (top_tag_head);
4429
4430 /* Output an ending symbol for all the files. We have to do this
4431 here for the last file, so we may as well do it for all of the
4432 files. */
4433 for (fil_ptr = first_file;
4434 fil_ptr != (efdr_t *) NULL;
4435 fil_ptr = fil_ptr->next_file)
4436 {
4437 cur_file_ptr = fil_ptr;
4438 (void) add_ecoff_symbol ((const char *) NULL,
4439 st_End, sc_Text,
4440 (symbolS *) NULL,
4441 (symint_t) 0,
4442 (symint_t) 0);
4443 }
4444
4445 /* Look through the symbols. Add debugging information for each
4446 symbol that has not already received it. */
4447 hold_file_ptr = cur_file_ptr;
4448 hold_proc_ptr = cur_proc_ptr;
4449 cur_proc_ptr = (proc_t *) NULL;
4450 for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
4451 {
4452 if (sym->ecoff_symbol
4453 || sym->ecoff_file == (efdr_t *) NULL)
4454 continue;
4455
4456 cur_file_ptr = sym->ecoff_file;
4457 add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym,
4458 S_GET_VALUE (sym), indexNil);
4459 }
4460 cur_proc_ptr = hold_proc_ptr;
4461 cur_file_ptr = hold_file_ptr;
4462
4463 /* Build the symbolic information. */
4464 hdr = &ecoff_data (stdoutput)->symbolic_header;
4465 offset = 0;
4466 buf = xmalloc (PAGE_SIZE);
4467 bufend = buf + PAGE_SIZE;
4468
4469 /* Build the line number information. */
4470 hdr->cbLineOffset = offset;
4471 offset = ecoff_build_lineno (&buf, &bufend, offset, &hdr->ilineMax);
4472 hdr->cbLine = offset - hdr->cbLineOffset;
4473
4474 /* We don't use dense numbers at all. */
4475 hdr->idnMax = 0;
4476 hdr->cbDnOffset = 0;
4477
4478 /* We can't build the PDR table until we have built the symbols,
4479 because a PDR contains a symbol index. However, we set aside
4480 space at this point. */
4481 hdr->ipdMax = proc_cnt;
4482 hdr->cbPdOffset = offset;
4483 if (bufend - (buf + offset) < proc_cnt * sizeof (struct pdr_ext))
4484 (void) ecoff_add_bytes (&buf, &bufend, buf + offset,
4485 proc_cnt * sizeof (struct pdr_ext));
4486 offset += proc_cnt * sizeof (struct pdr_ext);
4487
4488 /* Build the symbols. It's convenient to build both the local and
4489 external symbols at the same time. We can put the local symbols
4490 directly into the buffer, but we have to hold the external
4491 symbols apart until we know where they are going to go. */
4492 extbuf = xmalloc (PAGE_SIZE);
4493 extbufend = extbuf + PAGE_SIZE;
4494 extoffset = 0;
4495 ext_strings = init_ext_strings;
4496 ext_str_hash = hash_new ();
4497 hdr->cbSymOffset = offset;
4498 offset = ecoff_build_symbols (&buf, &bufend, offset,
4499 &extbuf, &extbufend, &extoffset,
4500 &ext_strings, ext_str_hash);
4501 hdr->isymMax = (offset - hdr->cbSymOffset) / sizeof (struct sym_ext);
4502
4503 /* Building the symbols initializes the symbol index in the PDR's.
4504 Now we can swap out the PDR's. */
4505 (void) ecoff_build_procs (&buf, &bufend, hdr->cbPdOffset);
4506
4507 /* We don't use optimization symbols. */
4508 hdr->ioptMax = 0;
4509 hdr->cbOptOffset = 0;
4510
4511 /* Swap out the auxiliary type information. */
4512 hdr->cbAuxOffset = offset;
4513 offset = ecoff_build_aux (&buf, &bufend, offset);
4514 hdr->iauxMax = (offset - hdr->cbAuxOffset) / sizeof (union aux_ext);
4515
4516 /* Copy out the local strings. */
4517 hdr->cbSsOffset = offset;
4518 offset = ecoff_build_ss (&buf, &bufend, offset);
4519 hdr->issMax = offset - hdr->cbSsOffset;
4520
4521 /* Copy out the external strings. */
4522 hdr->cbSsExtOffset = offset;
4523 offset += ecoff_build_strings (&buf, &bufend, offset, &ext_strings);
4524 offset = ecoff_longword_adjust (&buf, &bufend, offset, (char **) NULL);
4525 hdr->issExtMax = offset - hdr->cbSsExtOffset;
4526
4527 /* We don't use relative file descriptors. */
4528 hdr->crfd = 0;
4529 hdr->cbRfdOffset = 0;
4530
4531 /* Swap out the file descriptors. */
4532 hdr->cbFdOffset = offset;
4533 offset = ecoff_build_fdr (&buf, &bufend, offset);
4534 hdr->ifdMax = (offset - hdr->cbFdOffset) / sizeof (struct fdr_ext);
4535
4536 /* Copy out the external symbols. */
4537 hdr->cbExtOffset = offset;
4538 if (bufend - (buf + offset) < extoffset)
4539 (void) ecoff_add_bytes (&buf, &bufend, buf + offset, extoffset);
4540 memcpy (buf + offset, extbuf, extoffset);
4541 offset += extoffset;
4542 hdr->iextMax = (offset - hdr->cbExtOffset) / sizeof (struct ext_ext);
4543
4544 know ((offset & 3) == 0);
4545
4546 /* That completes the symbolic debugging information. We must now
4547 finish up the symbolic header and the ecoff_tdata structure. */
4548 set = buf;
4549 #define SET(ptr, count, type) \
4550 ecoff_data (stdoutput)->ptr = (type *) set; \
4551 set += hdr->count * sizeof (type)
4552
4553 SET (line, cbLine, unsigned char);
4554 SET (external_dnr, idnMax, struct dnr_ext);
4555 SET (external_pdr, ipdMax, struct pdr_ext);
4556 SET (external_sym, isymMax, struct sym_ext);
4557 SET (external_opt, ioptMax, struct opt_ext);
4558 SET (external_aux, iauxMax, union aux_ext);
4559 SET (ss, issMax, char);
4560 SET (ssext, issExtMax, char);
4561 SET (external_rfd, crfd, struct rfd_ext);
4562 SET (external_fdr, ifdMax, struct fdr_ext);
4563 SET (external_ext, iextMax, struct ext_ext);
4564
4565 #undef SET
4566
4567 /* FIXME: set the register masks. */
4568
4569 ecoff_data (stdoutput)->raw_size = offset;
4570 ecoff_data (stdoutput)->raw_syments = buf;
4571
4572 hdr->magic = magicSym;
4573 /* FIXME: what should hdr->vstamp be? */
4574 }
4575 \f
4576 /* Allocate a cluster of pages. */
4577
4578 #ifndef MALLOC_CHECK
4579
4580 static page_t *
4581 allocate_cluster (npages)
4582 unsigned long npages;
4583 {
4584 register page_t *value = (page_t *) xmalloc (npages * PAGE_USIZE);
4585
4586 #ifdef ECOFF_DEBUG
4587 if (debug > 3)
4588 fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
4589 #endif
4590
4591 memset (value, 0, npages * PAGE_USIZE);
4592
4593 return value;
4594 }
4595
4596
4597 static page_t *cluster_ptr = NULL;
4598 static unsigned long pages_left = 0;
4599
4600 #endif /* MALLOC_CHECK */
4601
4602 /* Allocate one page (which is initialized to 0). */
4603
4604 static page_t *
4605 allocate_page ()
4606 {
4607 #ifndef MALLOC_CHECK
4608
4609 if (pages_left == 0)
4610 {
4611 pages_left = MAX_CLUSTER_PAGES;
4612 cluster_ptr = allocate_cluster (pages_left);
4613 }
4614
4615 pages_left--;
4616 return cluster_ptr++;
4617
4618 #else /* MALLOC_CHECK */
4619
4620 page_t *ptr;
4621
4622 ptr = xmalloc (PAGE_USIZE);
4623 memset (ptr, 0, PAGE_USIZE);
4624 return ptr;
4625
4626 #endif /* MALLOC_CHECK */
4627 }
4628 \f
4629 /* Allocate scoping information. */
4630
4631 static scope_t *
4632 allocate_scope ()
4633 {
4634 register scope_t *ptr;
4635 static scope_t initial_scope;
4636
4637 #ifndef MALLOC_CHECK
4638
4639 ptr = alloc_counts[(int)alloc_type_scope].free_list.f_scope;
4640 if (ptr != (scope_t *) NULL)
4641 alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr->free;
4642 else
4643 {
4644 register int unallocated = alloc_counts[(int)alloc_type_scope].unallocated;
4645 register page_t *cur_page = alloc_counts[(int)alloc_type_scope].cur_page;
4646
4647 if (unallocated == 0)
4648 {
4649 unallocated = PAGE_SIZE / sizeof (scope_t);
4650 alloc_counts[(int)alloc_type_scope].cur_page = cur_page = allocate_page ();
4651 alloc_counts[(int)alloc_type_scope].total_pages++;
4652 }
4653
4654 ptr = &cur_page->scope[--unallocated];
4655 alloc_counts[(int)alloc_type_scope].unallocated = unallocated;
4656 }
4657
4658 #else
4659
4660 ptr = (scope_t *) xmalloc (sizeof (scope_t));
4661
4662 #endif
4663
4664 alloc_counts[(int)alloc_type_scope].total_alloc++;
4665 *ptr = initial_scope;
4666 return ptr;
4667 }
4668
4669 /* Free scoping information. */
4670
4671 static void
4672 free_scope (ptr)
4673 scope_t *ptr;
4674 {
4675 alloc_counts[(int)alloc_type_scope].total_free++;
4676
4677 #ifndef MALLOC_CHECK
4678 ptr->free = alloc_counts[(int)alloc_type_scope].free_list.f_scope;
4679 alloc_counts[(int)alloc_type_scope].free_list.f_scope = ptr;
4680 #else
4681 free ((PTR) ptr);
4682 #endif
4683 }
4684 \f
4685 /* Allocate links for pages in a virtual array. */
4686
4687 static vlinks_t *
4688 allocate_vlinks ()
4689 {
4690 register vlinks_t *ptr;
4691 static vlinks_t initial_vlinks;
4692
4693 #ifndef MALLOC_CHECK
4694
4695 register int unallocated = alloc_counts[(int)alloc_type_vlinks].unallocated;
4696 register page_t *cur_page = alloc_counts[(int)alloc_type_vlinks].cur_page;
4697
4698 if (unallocated == 0)
4699 {
4700 unallocated = PAGE_SIZE / sizeof (vlinks_t);
4701 alloc_counts[(int)alloc_type_vlinks].cur_page = cur_page = allocate_page ();
4702 alloc_counts[(int)alloc_type_vlinks].total_pages++;
4703 }
4704
4705 ptr = &cur_page->vlinks[--unallocated];
4706 alloc_counts[(int)alloc_type_vlinks].unallocated = unallocated;
4707
4708 #else
4709
4710 ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
4711
4712 #endif
4713
4714 alloc_counts[(int)alloc_type_vlinks].total_alloc++;
4715 *ptr = initial_vlinks;
4716 return ptr;
4717 }
4718 \f
4719 /* Allocate string hash buckets. */
4720
4721 static shash_t *
4722 allocate_shash ()
4723 {
4724 register shash_t *ptr;
4725 static shash_t initial_shash;
4726
4727 #ifndef MALLOC_CHECK
4728
4729 register int unallocated = alloc_counts[(int)alloc_type_shash].unallocated;
4730 register page_t *cur_page = alloc_counts[(int)alloc_type_shash].cur_page;
4731
4732 if (unallocated == 0)
4733 {
4734 unallocated = PAGE_SIZE / sizeof (shash_t);
4735 alloc_counts[(int)alloc_type_shash].cur_page = cur_page = allocate_page ();
4736 alloc_counts[(int)alloc_type_shash].total_pages++;
4737 }
4738
4739 ptr = &cur_page->shash[--unallocated];
4740 alloc_counts[(int)alloc_type_shash].unallocated = unallocated;
4741
4742 #else
4743
4744 ptr = (shash_t *) xmalloc (sizeof (shash_t));
4745
4746 #endif
4747
4748 alloc_counts[(int)alloc_type_shash].total_alloc++;
4749 *ptr = initial_shash;
4750 return ptr;
4751 }
4752 \f
4753 /* Allocate type hash buckets. */
4754
4755 static thash_t *
4756 allocate_thash ()
4757 {
4758 register thash_t *ptr;
4759 static thash_t initial_thash;
4760
4761 #ifndef MALLOC_CHECK
4762
4763 register int unallocated = alloc_counts[(int)alloc_type_thash].unallocated;
4764 register page_t *cur_page = alloc_counts[(int)alloc_type_thash].cur_page;
4765
4766 if (unallocated == 0)
4767 {
4768 unallocated = PAGE_SIZE / sizeof (thash_t);
4769 alloc_counts[(int)alloc_type_thash].cur_page = cur_page = allocate_page ();
4770 alloc_counts[(int)alloc_type_thash].total_pages++;
4771 }
4772
4773 ptr = &cur_page->thash[--unallocated];
4774 alloc_counts[(int)alloc_type_thash].unallocated = unallocated;
4775
4776 #else
4777
4778 ptr = (thash_t *) xmalloc (sizeof (thash_t));
4779
4780 #endif
4781
4782 alloc_counts[(int)alloc_type_thash].total_alloc++;
4783 *ptr = initial_thash;
4784 return ptr;
4785 }
4786 \f
4787 /* Allocate structure, union, or enum tag information. */
4788
4789 static tag_t *
4790 allocate_tag ()
4791 {
4792 register tag_t *ptr;
4793 static tag_t initial_tag;
4794
4795 #ifndef MALLOC_CHECK
4796
4797 ptr = alloc_counts[(int)alloc_type_tag].free_list.f_tag;
4798 if (ptr != (tag_t *) NULL)
4799 alloc_counts[(int)alloc_type_tag].free_list.f_tag = ptr->free;
4800 else
4801 {
4802 register int unallocated = alloc_counts[(int)alloc_type_tag].unallocated;
4803 register page_t *cur_page = alloc_counts[(int)alloc_type_tag].cur_page;
4804
4805 if (unallocated == 0)
4806 {
4807 unallocated = PAGE_SIZE / sizeof (tag_t);
4808 alloc_counts[(int)alloc_type_tag].cur_page = cur_page = allocate_page ();
4809 alloc_counts[(int)alloc_type_tag].total_pages++;
4810 }
4811
4812 ptr = &cur_page->tag[--unallocated];
4813 alloc_counts[(int)alloc_type_tag].unallocated = unallocated;
4814 }
4815
4816 #else
4817
4818 ptr = (tag_t *) xmalloc (sizeof (tag_t));
4819
4820 #endif
4821
4822 alloc_counts[(int)alloc_type_tag].total_alloc++;
4823 *ptr = initial_tag;
4824 return ptr;
4825 }
4826
4827 /* Free scoping information. */
4828
4829 static void
4830 free_tag (ptr)
4831 tag_t *ptr;
4832 {
4833 alloc_counts[(int)alloc_type_tag].total_free++;
4834
4835 #ifndef MALLOC_CHECK
4836 ptr->free = alloc_counts[(int)alloc_type_tag].free_list.f_tag;
4837 alloc_counts[(int)alloc_type_tag].free_list.f_tag = ptr;
4838 #else
4839 free ((PTR_T) ptr);
4840 #endif
4841 }
4842 \f
4843 /* Allocate forward reference to a yet unknown tag. */
4844
4845 static forward_t *
4846 allocate_forward ()
4847 {
4848 register forward_t *ptr;
4849 static forward_t initial_forward;
4850
4851 #ifndef MALLOC_CHECK
4852
4853 register int unallocated = alloc_counts[(int)alloc_type_forward].unallocated;
4854 register page_t *cur_page = alloc_counts[(int)alloc_type_forward].cur_page;
4855
4856 if (unallocated == 0)
4857 {
4858 unallocated = PAGE_SIZE / sizeof (forward_t);
4859 alloc_counts[(int)alloc_type_forward].cur_page = cur_page = allocate_page ();
4860 alloc_counts[(int)alloc_type_forward].total_pages++;
4861 }
4862
4863 ptr = &cur_page->forward[--unallocated];
4864 alloc_counts[(int)alloc_type_forward].unallocated = unallocated;
4865
4866 #else
4867
4868 ptr = (forward_t *) xmalloc (sizeof (forward_t));
4869
4870 #endif
4871
4872 alloc_counts[(int)alloc_type_forward].total_alloc++;
4873 *ptr = initial_forward;
4874 return ptr;
4875 }
4876 \f
4877 /* Allocate head of type hash list. */
4878
4879 static thead_t *
4880 allocate_thead ()
4881 {
4882 register thead_t *ptr;
4883 static thead_t initial_thead;
4884
4885 #ifndef MALLOC_CHECK
4886
4887 ptr = alloc_counts[(int)alloc_type_thead].free_list.f_thead;
4888 if (ptr != (thead_t *) NULL)
4889 alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr->free;
4890 else
4891 {
4892 register int unallocated = alloc_counts[(int)alloc_type_thead].unallocated;
4893 register page_t *cur_page = alloc_counts[(int)alloc_type_thead].cur_page;
4894
4895 if (unallocated == 0)
4896 {
4897 unallocated = PAGE_SIZE / sizeof (thead_t);
4898 alloc_counts[(int)alloc_type_thead].cur_page = cur_page = allocate_page ();
4899 alloc_counts[(int)alloc_type_thead].total_pages++;
4900 }
4901
4902 ptr = &cur_page->thead[--unallocated];
4903 alloc_counts[(int)alloc_type_thead].unallocated = unallocated;
4904 }
4905
4906 #else
4907
4908 ptr = (thead_t *) xmalloc (sizeof (thead_t));
4909
4910 #endif
4911
4912 alloc_counts[(int)alloc_type_thead].total_alloc++;
4913 *ptr = initial_thead;
4914 return ptr;
4915 }
4916
4917 /* Free scoping information. */
4918
4919 static void
4920 free_thead (ptr)
4921 thead_t *ptr;
4922 {
4923 alloc_counts[(int)alloc_type_thead].total_free++;
4924
4925 #ifndef MALLOC_CHECK
4926 ptr->free = (thead_t *) alloc_counts[(int)alloc_type_thead].free_list.f_thead;
4927 alloc_counts[(int)alloc_type_thead].free_list.f_thead = ptr;
4928 #else
4929 free ((PTR_T) ptr);
4930 #endif
4931 }
4932 \f
4933 static lineno_list_t *
4934 allocate_lineno_list ()
4935 {
4936 register lineno_list_t *ptr;
4937 static lineno_list_t initial_lineno_list;
4938
4939 #ifndef MALLOC_CHECK
4940
4941 register int unallocated = alloc_counts[(int)alloc_type_lineno].unallocated;
4942 register page_t *cur_page = alloc_counts[(int)alloc_type_lineno].cur_page;
4943
4944 if (unallocated == 0)
4945 {
4946 unallocated = PAGE_SIZE / sizeof (lineno_list_t);
4947 alloc_counts[(int)alloc_type_lineno].cur_page = cur_page = allocate_page ();
4948 alloc_counts[(int)alloc_type_lineno].total_pages++;
4949 }
4950
4951 ptr = &cur_page->lineno[--unallocated];
4952 alloc_counts[(int)alloc_type_lineno].unallocated = unallocated;
4953
4954 #else
4955
4956 ptr = (lineno_list_t *) xmalloc (sizeof (lineno_list_t));
4957
4958 #endif
4959
4960 alloc_counts[(int)alloc_type_lineno].total_alloc++;
4961 *ptr = initial_lineno_list;
4962 return ptr;
4963 }