Annotation of gcc/mips-tfile.c, revision 1.1.1.7

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.