OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [mips-tfile.c] - Blame information for rev 16

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.