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