Annotation of GNUtools/cc/mips-tfile.c, revision 1.1

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

unix.superglobalmegacorp.com

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