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