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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [mips-tfile.c] - Blame information for rev 859

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

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

powered by: WebSVN 2.1.0

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