OSDN Git Service

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