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