OSDN Git Service

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