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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [mips-tfile.c] - Blame information for rev 751

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

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

powered by: WebSVN 2.1.0

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