OSDN Git Service

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