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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [mips-tfile.c] - Blame information for rev 193

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

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

powered by: WebSVN 2.1.0

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