OSDN Git Service

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