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