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