OSDN Git Service

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