Back to index

cell-binutils  2.17cvs20070401
ecoff.c
Go to the documentation of this file.
00001 /* ECOFF debugging support.
00002    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
00003    2003, 2004, 2005, 2006
00004    Free Software Foundation, Inc.
00005    Contributed by Cygnus Support.
00006    This file was put together by Ian Lance Taylor <ian@cygnus.com>.  A
00007    good deal of it comes directly from mips-tfile.c, by Michael
00008    Meissner <meissner@osf.org>.
00009 
00010    This file is part of GAS.
00011 
00012    GAS is free software; you can redistribute it and/or modify
00013    it under the terms of the GNU General Public License as published by
00014    the Free Software Foundation; either version 2, or (at your option)
00015    any later version.
00016 
00017    GAS is distributed in the hope that it will be useful,
00018    but WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020    GNU General Public License for more details.
00021 
00022    You should have received a copy of the GNU General Public License
00023    along with GAS; see the file COPYING.  If not, write to the Free
00024    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00025    02110-1301, USA.  */
00026 
00027 #include "as.h"
00028 
00029 /* This file is compiled conditionally for those targets which use
00030    ECOFF debugging information (e.g., MIPS ECOFF, MIPS ELF, Alpha
00031    ECOFF).  */
00032 
00033 #include "ecoff.h"
00034 
00035 #ifdef ECOFF_DEBUGGING
00036 
00037 #include "coff/internal.h"
00038 #include "coff/symconst.h"
00039 #include "aout/stab_gnu.h"
00040 
00041 #include "safe-ctype.h"
00042 
00043 /* Why isn't this in coff/sym.h?  */
00044 #define ST_RFDESCAPE 0xfff
00045 
00046 /* This file constructs the information used by the ECOFF debugging
00047    format.  It just builds a large block of data.
00048 
00049    We support both ECOFF style debugging and stabs debugging (the
00050    stabs symbols are encapsulated in ECOFF symbols).  This should let
00051    us handle anything the compiler might throw at us.  */
00052 
00053 /* Here is a brief description of the MIPS ECOFF symbol table, by
00054    Michael Meissner.  The MIPS symbol table has the following pieces:
00055 
00056        Symbolic Header
00057            |
00058            +--       Auxiliary Symbols
00059            |
00060            +--       Dense number table
00061            |
00062            +--       Optimizer Symbols
00063            |
00064            +--       External Strings
00065            |
00066            +--       External Symbols
00067            |
00068            +--       Relative file descriptors
00069            |
00070            +--       File table
00071                   |
00072                   +--       Procedure table
00073                   |
00074                   +--       Line number table
00075                   |
00076                   +--       Local Strings
00077                   |
00078                   +--       Local Symbols
00079 
00080    The symbolic header points to each of the other tables, and also
00081    contains the number of entries.  It also contains a magic number
00082    and MIPS compiler version number, such as 2.0.
00083 
00084    The auxiliary table is a series of 32 bit integers, that are
00085    referenced as needed from the local symbol table.  Unlike standard
00086    COFF, the aux.  information does not follow the symbol that uses
00087    it, but rather is a separate table.  In theory, this would allow
00088    the MIPS compilers to collapse duplicate aux. entries, but I've not
00089    noticed this happening with the 1.31 compiler suite.  The different
00090    types of aux. entries are:
00091 
00092     1) dnLow: Low bound on array dimension.
00093 
00094     2) dnHigh: High bound on array dimension.
00095 
00096     3) isym: Index to the local symbol which is the start of the
00097        function for the end of function first aux. entry.
00098 
00099     4) width: Width of structures and bitfields.
00100 
00101     5) count: Count of ranges for variant part.
00102 
00103     6) rndx: A relative index into the symbol table.  The relative
00104        index field has two parts: rfd which is a pointer into the
00105        relative file index table or ST_RFDESCAPE which says the next
00106        aux. entry is the file number, and index: which is the pointer
00107        into the local symbol within a given file table.  This is for
00108        things like references to types defined in another file.
00109 
00110     7) Type information: This is like the COFF type bits, except it
00111        is 32 bits instead of 16; they still have room to add new
00112        basic types; and they can handle more than 6 levels of array,
00113        pointer, function, etc.  Each type information field contains
00114        the following structure members:
00115 
00116            a) fBitfield: a bit that says this is a bitfield, and the
00117               size in bits follows as the next aux. entry.
00118 
00119            b) continued: a bit that says the next aux. entry is a
00120               continuation of the current type information (in case
00121               there are more than 6 levels of array/ptr/function).
00122 
00123            c) bt: an integer containing the base type before adding
00124               array, pointer, function, etc. qualifiers.  The
00125               current base types that I have documentation for are:
00126 
00127                      btNil         -- undefined
00128                      btAdr         -- address - integer same size as ptr
00129                      btChar        -- character
00130                      btUChar              -- unsigned character
00131                      btShort              -- short
00132                      btUShort      -- unsigned short
00133                      btInt         -- int
00134                      btUInt        -- unsigned int
00135                      btLong        -- long
00136                      btULong              -- unsigned long
00137                      btFloat              -- float (real)
00138                      btDouble      -- Double (real)
00139                      btStruct      -- Structure (Record)
00140                      btUnion              -- Union (variant)
00141                      btEnum        -- Enumerated
00142                      btTypedef     -- defined via a typedef isymRef
00143                      btRange              -- subrange of int
00144                      btSet         -- pascal sets
00145                      btComplex     -- fortran complex
00146                      btDComplex    -- fortran double complex
00147                      btIndirect    -- forward or unnamed typedef
00148                      btFixedDec    -- Fixed Decimal
00149                      btFloatDec    -- Float Decimal
00150                      btString      -- Varying Length Character String
00151                      btBit         -- Aligned Bit String
00152                      btPicture     -- Picture
00153                      btVoid        -- Void (MIPS cc revision >= 2.00)
00154 
00155            d) tq0 - tq5: type qualifier fields as needed.  The
00156               current type qualifier fields I have documentation for
00157               are:
00158 
00159                      tqNil         -- no more qualifiers
00160                      tqPtr         -- pointer
00161                      tqProc        -- procedure
00162                      tqArray              -- array
00163                      tqFar         -- 8086 far pointers
00164                      tqVol         -- volatile
00165 
00166    The dense number table is used in the front ends, and disappears by
00167    the time the .o is created.
00168 
00169    With the 1.31 compiler suite, the optimization symbols don't seem
00170    to be used as far as I can tell.
00171 
00172    The linker is the first entity that creates the relative file
00173    descriptor table, and I believe it is used so that the individual
00174    file table pointers don't have to be rewritten when the objects are
00175    merged together into the program file.
00176 
00177    Unlike COFF, the basic symbol & string tables are split into
00178    external and local symbols/strings.  The relocation information
00179    only goes off of the external symbol table, and the debug
00180    information only goes off of the internal symbol table.  The
00181    external symbols can have links to an appropriate file index and
00182    symbol within the file to give it the appropriate type information.
00183    Because of this, the external symbols are actually larger than the
00184    internal symbols (to contain the link information), and contain the
00185    local symbol structure as a member, though this member is not the
00186    first member of the external symbol structure (!).  I suspect this
00187    split is to make strip easier to deal with.
00188 
00189    Each file table has offsets for where the line numbers, local
00190    strings, local symbols, and procedure table starts from within the
00191    global tables, and the indexs are reset to 0 for each of those
00192    tables for the file.
00193 
00194    The procedure table contains the binary equivalents of the .ent
00195    (start of the function address), .frame (what register is the
00196    virtual frame pointer, constant offset from the register to obtain
00197    the VFP, and what register holds the return address), .mask/.fmask
00198    (bitmask of saved registers, and where the first register is stored
00199    relative to the VFP) assembler directives.  It also contains the
00200    low and high bounds of the line numbers if debugging is turned on.
00201 
00202    The line number table is a compressed form of the normal COFF line
00203    table.  Each line number entry is either 1 or 3 bytes long, and
00204    contains a signed delta from the previous line, and an unsigned
00205    count of the number of instructions this statement takes.
00206 
00207    The local symbol table contains the following fields:
00208 
00209     1) iss: index to the local string table giving the name of the
00210        symbol.
00211 
00212     2) value: value of the symbol (address, register number, etc.).
00213 
00214     3) st: symbol type.  The current symbol types are:
00215 
00216            stNil       -- Nuthin' special
00217            stGlobal    -- external symbol
00218            stStatic    -- static
00219            stParam     -- procedure argument
00220            stLocal     -- local variable
00221            stLabel     -- label
00222            stProc      -- External Procedure
00223            stBlock     -- beginning of block
00224            stEnd       -- end (of anything)
00225            stMember    -- member (of anything)
00226            stTypedef   -- type definition
00227            stFile      -- file name
00228            stRegReloc         -- register relocation
00229            stForward   -- forwarding address
00230            stStaticProc  -- Static procedure
00231            stConstant         -- const
00232 
00233     4) sc: storage class.  The current storage classes are:
00234 
00235            scText      -- text symbol
00236            scData      -- initialized data symbol
00237            scBss       -- un-initialized data symbol
00238            scRegister         -- value of symbol is register number
00239            scAbs       -- value of symbol is absolute
00240            scUndefined   -- who knows?
00241            scCdbLocal         -- variable's value is IN se->va.??
00242            scBits      -- this is a bit field
00243            scCdbSystem        -- value is IN debugger's address space
00244            scRegImage         -- register value saved on stack
00245            scInfo      -- symbol contains debugger information
00246            scUserStruct  -- addr in struct user for current process
00247            scSData     -- load time only small data
00248            scSBss      -- load time only small common
00249            scRData     -- load time only read only data
00250            scVar       -- Var parameter (fortranpascal)
00251            scCommon    -- common variable
00252            scSCommon   -- small common
00253            scVarRegister -- Var parameter in a register
00254            scVariant   -- Variant record
00255            scSUndefined  -- small undefined(external) data
00256            scInit      -- .init section symbol
00257 
00258     5) index: pointer to a local symbol or aux. entry.
00259 
00260    For the following program:
00261 
00262        #include <stdio.h>
00263 
00264        main(){
00265               printf("Hello World!\n");
00266               return 0;
00267        }
00268 
00269    Mips-tdump produces the following information:
00270 
00271    Global file header:
00272        magic number             0x162
00273        # sections               2
00274        timestamp                645311799, Wed Jun 13 17:16:39 1990
00275        symbolic header offset   284
00276        symbolic header size     96
00277        optional header          56
00278        flags                    0x0
00279 
00280    Symbolic header, magic number = 0x7009, vstamp = 1.31:
00281 
00282        Info                      Offset      Number       Bytes
00283        ====                      ======      ======      =====
00284 
00285        Line numbers                 380           4           4 [13]
00286        Dense numbers                  0           0           0
00287        Procedures Tables            384           1          52
00288        Local Symbols                436          16         192
00289        Optimization Symbols           0           0           0
00290        Auxiliary Symbols            628          39         156
00291        Local Strings                784          80          80
00292        External Strings             864         144         144
00293        File Tables                 1008           2         144
00294        Relative Files                 0           0           0
00295        External Symbols            1152          20         320
00296 
00297    File #0, "hello2.c"
00298 
00299        Name index  = 1          Readin      = No
00300        Merge       = No         Endian      = LITTLE
00301        Debug level = G2         Language    = C
00302        Adr         = 0x00000000
00303 
00304        Info                       Start      Number        Size      Offset
00305        ====                       =====      ======        ====      ======
00306        Local strings                  0          15          15         784
00307        Local symbols                  0           6          72         436
00308        Line numbers                   0          13          13         380
00309        Optimization symbols           0           0           0           0
00310        Procedures                     0           1          52         384
00311        Auxiliary symbols              0          14          56         628
00312        Relative Files                 0           0           0           0
00313 
00314     There are 6 local symbols, starting at 436
00315 
00316        Symbol# 0: "hello2.c"
00317            End+1 symbol  = 6
00318            String index  = 1
00319            Storage class = Text        Index  = 6
00320            Symbol type   = File        Value  = 0
00321 
00322        Symbol# 1: "main"
00323            End+1 symbol  = 5
00324            Type          = int
00325            String index  = 10
00326            Storage class = Text        Index  = 12
00327            Symbol type   = Proc        Value  = 0
00328 
00329        Symbol# 2: ""
00330            End+1 symbol  = 4
00331            String index  = 0
00332            Storage class = Text        Index  = 4
00333            Symbol type   = Block       Value  = 8
00334 
00335        Symbol# 3: ""
00336            First symbol  = 2
00337            String index  = 0
00338            Storage class = Text        Index  = 2
00339            Symbol type   = End         Value  = 28
00340 
00341        Symbol# 4: "main"
00342            First symbol  = 1
00343            String index  = 10
00344            Storage class = Text        Index  = 1
00345            Symbol type   = End         Value  = 52
00346 
00347        Symbol# 5: "hello2.c"
00348            First symbol  = 0
00349            String index  = 1
00350            Storage class = Text        Index  = 0
00351            Symbol type   = End         Value  = 0
00352 
00353     There are 14 auxiliary table entries, starting at 628.
00354 
00355        * #0               0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00356        * #1              24, [  24/      0], [ 6 0:0 0:0:0:0:0:0]
00357        * #2               8, [   8/      0], [ 2 0:0 0:0:0:0:0:0]
00358        * #3              16, [  16/      0], [ 4 0:0 0:0:0:0:0:0]
00359        * #4              24, [  24/      0], [ 6 0:0 0:0:0:0:0:0]
00360        * #5              32, [  32/      0], [ 8 0:0 0:0:0:0:0:0]
00361        * #6              40, [  40/      0], [10 0:0 0:0:0:0:0:0]
00362        * #7              44, [  44/      0], [11 0:0 0:0:0:0:0:0]
00363        * #8              12, [  12/      0], [ 3 0:0 0:0:0:0:0:0]
00364        * #9              20, [  20/      0], [ 5 0:0 0:0:0:0:0:0]
00365        * #10             28, [  28/      0], [ 7 0:0 0:0:0:0:0:0]
00366        * #11             36, [  36/      0], [ 9 0:0 0:0:0:0:0:0]
00367          #12              5, [   5/      0], [ 1 1:0 0:0:0:0:0:0]
00368          #13             24, [  24/      0], [ 6 0:0 0:0:0:0:0:0]
00369 
00370     There are 1 procedure descriptor entries, starting at 0.
00371 
00372        Procedure descriptor 0:
00373            Name index   = 10          Name          = "main"
00374            .mask 0x80000000,-4        .fmask 0x00000000,0
00375            .frame $29,24,$31
00376            Opt. start   = -1          Symbols start = 1
00377            First line # = 3           Last line #   = 6
00378            Line Offset  = 0           Address       = 0x00000000
00379 
00380        There are 4 bytes holding line numbers, starting at 380.
00381            Line           3,   delta     0,   count  2
00382            Line           4,   delta     1,   count  3
00383            Line           5,   delta     1,   count  2
00384            Line           6,   delta     1,   count  6
00385 
00386    File #1, "/usr/include/stdio.h"
00387 
00388     Name index  = 1          Readin      = No
00389     Merge       = Yes        Endian      = LITTLE
00390     Debug level = G2         Language    = C
00391     Adr         = 0x00000000
00392 
00393     Info                       Start      Number        Size      Offset
00394     ====                       =====      ======        ====      ======
00395     Local strings                 15          65          65         799
00396     Local symbols                  6          10         120         508
00397     Line numbers                   0           0           0         380
00398     Optimization symbols           0           0           0           0
00399     Procedures                     1           0           0         436
00400     Auxiliary symbols             14          25         100         684
00401     Relative Files                 0           0           0           0
00402 
00403     There are 10 local symbols, starting at 442
00404 
00405        Symbol# 0: "/usr/include/stdio.h"
00406            End+1 symbol  = 10
00407            String index  = 1
00408            Storage class = Text        Index  = 10
00409            Symbol type   = File        Value  = 0
00410 
00411        Symbol# 1: "_iobuf"
00412            End+1 symbol  = 9
00413            String index  = 22
00414            Storage class = Info        Index  = 9
00415            Symbol type   = Block       Value  = 20
00416 
00417        Symbol# 2: "_cnt"
00418            Type          = int
00419            String index  = 29
00420            Storage class = Info        Index  = 4
00421            Symbol type   = Member      Value  = 0
00422 
00423        Symbol# 3: "_ptr"
00424            Type          = ptr to char
00425            String index  = 34
00426            Storage class = Info        Index  = 15
00427            Symbol type   = Member      Value  = 32
00428 
00429        Symbol# 4: "_base"
00430            Type          = ptr to char
00431            String index  = 39
00432            Storage class = Info        Index  = 16
00433            Symbol type   = Member      Value  = 64
00434 
00435        Symbol# 5: "_bufsiz"
00436            Type          = int
00437            String index  = 45
00438            Storage class = Info        Index  = 4
00439            Symbol type   = Member      Value  = 96
00440 
00441        Symbol# 6: "_flag"
00442            Type          = short
00443            String index  = 53
00444            Storage class = Info        Index  = 3
00445            Symbol type   = Member      Value  = 128
00446 
00447        Symbol# 7: "_file"
00448            Type          = char
00449            String index  = 59
00450            Storage class = Info        Index  = 2
00451            Symbol type   = Member      Value  = 144
00452 
00453        Symbol# 8: ""
00454            First symbol  = 1
00455            String index  = 0
00456            Storage class = Info        Index  = 1
00457            Symbol type   = End         Value  = 0
00458 
00459        Symbol# 9: "/usr/include/stdio.h"
00460            First symbol  = 0
00461            String index  = 1
00462            Storage class = Text        Index  = 0
00463            Symbol type   = End         Value  = 0
00464 
00465     There are 25 auxiliary table entries, starting at 642.
00466 
00467        * #14             -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
00468          #15          65544, [   8/     16], [ 2 0:0 1:0:0:0:0:0]
00469          #16          65544, [   8/     16], [ 2 0:0 1:0:0:0:0:0]
00470        * #17         196656, [  48/     48], [12 0:0 3:0:0:0:0:0]
00471        * #18           8191, [4095/      1], [63 1:1 0:0:0:0:f:1]
00472        * #19              1, [   1/      0], [ 0 1:0 0:0:0:0:0:0]
00473        * #20          20479, [4095/      4], [63 1:1 0:0:0:0:f:4]
00474        * #21              1, [   1/      0], [ 0 1:0 0:0:0:0:0:0]
00475        * #22              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00476        * #23              2, [   2/      0], [ 0 0:1 0:0:0:0:0:0]
00477        * #24            160, [ 160/      0], [40 0:0 0:0:0:0:0:0]
00478        * #25              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00479        * #26              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00480        * #27              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00481        * #28              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00482        * #29              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00483        * #30              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00484        * #31              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00485        * #32              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00486        * #33              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00487        * #34              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00488        * #35              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00489        * #36              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00490        * #37              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00491        * #38              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
00492 
00493     There are 0 procedure descriptor entries, starting at 1.
00494 
00495    There are 20 external symbols, starting at 1152
00496 
00497        Symbol# 0: "_iob"
00498            Type          = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
00499            String index  = 0           Ifd    = 1
00500            Storage class = Nil         Index  = 17
00501            Symbol type   = Global      Value  = 60
00502 
00503        Symbol# 1: "fopen"
00504            String index  = 5           Ifd    = 1
00505            Storage class = Nil         Index  = 1048575
00506            Symbol type   = Proc        Value  = 0
00507 
00508        Symbol# 2: "fdopen"
00509            String index  = 11          Ifd    = 1
00510            Storage class = Nil         Index  = 1048575
00511            Symbol type   = Proc        Value  = 0
00512 
00513        Symbol# 3: "freopen"
00514            String index  = 18          Ifd    = 1
00515            Storage class = Nil         Index  = 1048575
00516            Symbol type   = Proc        Value  = 0
00517 
00518        Symbol# 4: "popen"
00519            String index  = 26          Ifd    = 1
00520            Storage class = Nil         Index  = 1048575
00521            Symbol type   = Proc        Value  = 0
00522 
00523        Symbol# 5: "tmpfile"
00524            String index  = 32          Ifd    = 1
00525            Storage class = Nil         Index  = 1048575
00526            Symbol type   = Proc        Value  = 0
00527 
00528        Symbol# 6: "ftell"
00529            String index  = 40          Ifd    = 1
00530            Storage class = Nil         Index  = 1048575
00531            Symbol type   = Proc        Value  = 0
00532 
00533        Symbol# 7: "rewind"
00534            String index  = 46          Ifd    = 1
00535            Storage class = Nil         Index  = 1048575
00536            Symbol type   = Proc        Value  = 0
00537 
00538        Symbol# 8: "setbuf"
00539            String index  = 53          Ifd    = 1
00540            Storage class = Nil         Index  = 1048575
00541            Symbol type   = Proc        Value  = 0
00542 
00543        Symbol# 9: "setbuffer"
00544            String index  = 60          Ifd    = 1
00545            Storage class = Nil         Index  = 1048575
00546            Symbol type   = Proc        Value  = 0
00547 
00548        Symbol# 10: "setlinebuf"
00549            String index  = 70          Ifd    = 1
00550            Storage class = Nil         Index  = 1048575
00551            Symbol type   = Proc        Value  = 0
00552 
00553        Symbol# 11: "fgets"
00554            String index  = 81          Ifd    = 1
00555            Storage class = Nil         Index  = 1048575
00556            Symbol type   = Proc        Value  = 0
00557 
00558        Symbol# 12: "gets"
00559            String index  = 87          Ifd    = 1
00560            Storage class = Nil         Index  = 1048575
00561            Symbol type   = Proc        Value  = 0
00562 
00563        Symbol# 13: "ctermid"
00564            String index  = 92          Ifd    = 1
00565            Storage class = Nil         Index  = 1048575
00566            Symbol type   = Proc        Value  = 0
00567 
00568        Symbol# 14: "cuserid"
00569            String index  = 100         Ifd    = 1
00570            Storage class = Nil         Index  = 1048575
00571            Symbol type   = Proc        Value  = 0
00572 
00573        Symbol# 15: "tempnam"
00574            String index  = 108         Ifd    = 1
00575            Storage class = Nil         Index  = 1048575
00576            Symbol type   = Proc        Value  = 0
00577 
00578        Symbol# 16: "tmpnam"
00579            String index  = 116         Ifd    = 1
00580            Storage class = Nil         Index  = 1048575
00581            Symbol type   = Proc        Value  = 0
00582 
00583        Symbol# 17: "sprintf"
00584            String index  = 123         Ifd    = 1
00585            Storage class = Nil         Index  = 1048575
00586            Symbol type   = Proc        Value  = 0
00587 
00588        Symbol# 18: "main"
00589            Type          = int
00590            String index  = 131         Ifd    = 0
00591            Storage class = Text        Index  = 1
00592            Symbol type   = Proc        Value  = 0
00593 
00594        Symbol# 19: "printf"
00595            String index  = 136         Ifd    = 0
00596            Storage class = Undefined   Index  = 1048575
00597            Symbol type   = Proc        Value  = 0
00598 
00599    The following auxiliary table entries were unused:
00600 
00601     #0               0  0x00000000  void
00602     #2               8  0x00000008  char
00603     #3              16  0x00000010  short
00604     #4              24  0x00000018  int
00605     #5              32  0x00000020  long
00606     #6              40  0x00000028  float
00607     #7              44  0x0000002c  double
00608     #8              12  0x0000000c  unsigned char
00609     #9              20  0x00000014  unsigned short
00610     #10             28  0x0000001c  unsigned int
00611     #11             36  0x00000024  unsigned long
00612     #14              0  0x00000000  void
00613     #15             24  0x00000018  int
00614     #19             32  0x00000020  long
00615     #20             40  0x00000028  float
00616     #21             44  0x0000002c  double
00617     #22             12  0x0000000c  unsigned char
00618     #23             20  0x00000014  unsigned short
00619     #24             28  0x0000001c  unsigned int
00620     #25             36  0x00000024  unsigned long
00621     #26             48  0x00000030  struct no name { ifd = -1, index = 1048575 }
00622 */
00623 
00624 /* Redefinition of of storage classes as an enumeration for better
00625    debugging.  */
00626 
00627 typedef enum sc {
00628   sc_Nil       = scNil,       /* no storage class */
00629   sc_Text      = scText,      /* text symbol */
00630   sc_Data      = scData,      /* initialized data symbol */
00631   sc_Bss       = scBss,       /* un-initialized data symbol */
00632   sc_Register  = scRegister,         /* value of symbol is register number */
00633   sc_Abs       = scAbs,       /* value of symbol is absolute */
00634   sc_Undefined        = scUndefined,        /* who knows? */
00635   sc_CdbLocal  = scCdbLocal,         /* variable's value is IN se->va.?? */
00636   sc_Bits      = scBits,      /* this is a bit field */
00637   sc_CdbSystem        = scCdbSystem,        /* value is IN CDB's address space */
00638   sc_RegImage  = scRegImage,         /* register value saved on stack */
00639   sc_Info      = scInfo,      /* symbol contains debugger information */
00640   sc_UserStruct       = scUserStruct,  /* addr in struct user for current process */
00641   sc_SData     = scSData,     /* load time only small data */
00642   sc_SBss      = scSBss,      /* load time only small common */
00643   sc_RData     = scRData,     /* load time only read only data */
00644   sc_Var       = scVar,       /* Var parameter (fortran,pascal) */
00645   sc_Common    = scCommon,    /* common variable */
00646   sc_SCommon   = scSCommon,   /* small common */
00647   sc_VarRegister = scVarRegister, /* Var parameter in a register */
00648   sc_Variant   = scVariant,   /* Variant record */
00649   sc_SUndefined       = scSUndefined,  /* small undefined(external) data */
00650   sc_Init      = scInit,      /* .init section symbol */
00651   sc_Max       = scMax        /* Max storage class+1 */
00652 } sc_t;
00653 
00654 /* Redefinition of symbol type.  */
00655 
00656 typedef enum st {
00657   st_Nil      = stNil,      /* Nuthin' special */
00658   st_Global   = stGlobal,   /* external symbol */
00659   st_Static   = stStatic,   /* static */
00660   st_Param    = stParam,    /* procedure argument */
00661   st_Local    = stLocal,    /* local variable */
00662   st_Label    = stLabel,    /* label */
00663   st_Proc     = stProc,     /*     "      "       Procedure */
00664   st_Block    = stBlock,    /* beginning of block */
00665   st_End      = stEnd,      /* end (of anything) */
00666   st_Member   = stMember,   /* member (of anything      - struct/union/enum */
00667   st_Typedef  = stTypedef,  /* type definition */
00668   st_File     = stFile,     /* file name */
00669   st_RegReloc = stRegReloc, /* register relocation */
00670   st_Forward  = stForward,  /* forwarding address */
00671   st_StaticProc      = stStaticProc,      /* load time only static procs */
00672   st_Constant = stConstant, /* const */
00673   st_Str      = stStr,      /* string */
00674   st_Number   = stNumber,   /* pure number (ie. 4 NOR 2+2) */
00675   st_Expr     = stExpr,     /* 2+2 vs. 4 */
00676   st_Type     = stType,     /* post-coercion SER */
00677   st_Max      = stMax              /* max type+1 */
00678 } st_t;
00679 
00680 /* Redefinition of type qualifiers.  */
00681 
00682 typedef enum tq {
00683   tq_Nil      = tqNil,      /* bt is what you see */
00684   tq_Ptr      = tqPtr,      /* pointer */
00685   tq_Proc     = tqProc,     /* procedure */
00686   tq_Array    = tqArray,    /* duh */
00687   tq_Far      = tqFar,      /* longer addressing - 8086/8 land */
00688   tq_Vol      = tqVol,      /* volatile */
00689   tq_Max      = tqMax              /* Max type qualifier+1 */
00690 } tq_t;
00691 
00692 /* Redefinition of basic types.  */
00693 
00694 typedef enum bt {
00695   bt_Nil      = btNil,      /* undefined */
00696   bt_Adr      = btAdr,      /* address - integer same size as pointer */
00697   bt_Char     = btChar,     /* character */
00698   bt_UChar    = btUChar,    /* unsigned character */
00699   bt_Short    = btShort,    /* short */
00700   bt_UShort   = btUShort,   /* unsigned short */
00701   bt_Int      = btInt,      /* int */
00702   bt_UInt     = btUInt,     /* unsigned int */
00703   bt_Long     = btLong,     /* long */
00704   bt_ULong    = btULong,    /* unsigned long */
00705   bt_Float    = btFloat,    /* float (real) */
00706   bt_Double   = btDouble,   /* Double (real) */
00707   bt_Struct   = btStruct,   /* Structure (Record) */
00708   bt_Union    = btUnion,    /* Union (variant) */
00709   bt_Enum     = btEnum,     /* Enumerated */
00710   bt_Typedef  = btTypedef,  /* defined via a typedef, isymRef points */
00711   bt_Range    = btRange,    /* subrange of int */
00712   bt_Set      = btSet,      /* pascal sets */
00713   bt_Complex  = btComplex,  /* fortran complex */
00714   bt_DComplex = btDComplex, /* fortran double complex */
00715   bt_Indirect = btIndirect, /* forward or unnamed typedef */
00716   bt_FixedDec = btFixedDec, /* Fixed Decimal */
00717   bt_FloatDec = btFloatDec, /* Float Decimal */
00718   bt_String   = btString,   /* Varying Length Character String */
00719   bt_Bit      = btBit,      /* Aligned Bit String */
00720   bt_Picture  = btPicture,  /* Picture */
00721   bt_Void     = btVoid,     /* Void */
00722   bt_Max      = btMax              /* Max basic type+1 */
00723 } bt_t;
00724 
00725 #define N_TQ itqMax
00726 
00727 /* States for whether to hash type or not.  */
00728 typedef enum hash_state {
00729   hash_no     = 0,          /* Don't hash type */
00730   hash_yes    = 1,          /* OK to hash type, or use previous hash */
00731   hash_record = 2           /* OK to record hash, but don't use prev.  */
00732 } hash_state_t;
00733 
00734 /* Types of different sized allocation requests.  */
00735 enum alloc_type {
00736   alloc_type_none,          /* dummy value */
00737   alloc_type_scope,         /* nested scopes linked list */
00738   alloc_type_vlinks,        /* glue linking pages in varray */
00739   alloc_type_shash,         /* string hash element */
00740   alloc_type_thash,         /* type hash element */
00741   alloc_type_tag,           /* struct/union/tag element */
00742   alloc_type_forward,              /* element to hold unknown tag */
00743   alloc_type_thead,         /* head of type hash list */
00744   alloc_type_varray,        /* general varray allocation */
00745   alloc_type_lineno,        /* line number list */
00746   alloc_type_last           /* last+1 element for array bounds */
00747 };
00748 
00749 /* Types of auxiliary type information.  */
00750 enum aux_type {
00751   aux_tir,                  /* TIR type information */
00752   aux_rndx,                 /* relative index into symbol table */
00753   aux_dnLow,                /* low dimension */
00754   aux_dnHigh,               /* high dimension */
00755   aux_isym,                 /* symbol table index (end of proc) */
00756   aux_iss,                  /* index into string space (not used) */
00757   aux_width,                /* width for non-default sized struc fields */
00758   aux_count                 /* count of ranges for variant arm */
00759 };
00760 
00761 /* Structures to provide n-number of virtual arrays, each of which can
00762    grow linearly, and which are written in the object file as
00763    sequential pages.  On systems with a BSD malloc, the
00764    MAX_CLUSTER_PAGES should be 1 less than a power of two, since
00765    malloc adds it's overhead, and rounds up to the next power of 2.
00766    Pages are linked together via a linked list.
00767 
00768    If PAGE_SIZE is > 4096, the string length in the shash_t structure
00769    can't be represented (assuming there are strings > 4096 bytes).  */
00770 
00771 /* FIXME: Yes, there can be such strings while emitting C++ class debug
00772    info.  Templates are the offender here, the test case in question
00773    having a mangled class name of
00774 
00775      t7rb_tree4Z4xkeyZt4pair2ZC4xkeyZt7xsocket1Z4UserZt9select1st2Zt4pair\
00776      2ZC4xkeyZt7xsocket1Z4UserZ4xkeyZt4less1Z4xkey
00777 
00778    Repeat that a couple dozen times while listing the class members and
00779    you've got strings over 4k.  Hack around this for now by increasing
00780    the page size.  A proper solution would abandon this structure scheme
00781    certainly for very large strings, and possibly entirely.  */
00782 
00783 #ifndef PAGE_SIZE
00784 #define PAGE_SIZE (8*1024)  /* size of varray pages */
00785 #endif
00786 
00787 #define PAGE_USIZE ((unsigned long) PAGE_SIZE)
00788 
00789 #ifndef MAX_CLUSTER_PAGES   /* # pages to get from system */
00790 #define MAX_CLUSTER_PAGES 63
00791 #endif
00792 
00793 /* Linked list connecting separate page allocations.  */
00794 typedef struct vlinks {
00795   struct vlinks      *prev;        /* previous set of pages */
00796   struct vlinks *next;             /* next set of pages */
00797   union  page   *datum;            /* start of page */
00798   unsigned long       start_index; /* starting index # of page */
00799 } vlinks_t;
00800 
00801 /* Virtual array header.  */
00802 typedef struct varray {
00803   vlinks_t    *first;                     /* first page link */
00804   vlinks_t    *last;               /* last page link */
00805   unsigned long       num_allocated;             /* # objects allocated */
00806   unsigned short object_size;             /* size in bytes of each object */
00807   unsigned short objects_per_page; /* # objects that can fit on a page */
00808   unsigned short objects_last_page;       /* # objects allocated on last page */
00809 } varray_t;
00810 
00811 #ifndef MALLOC_CHECK
00812 #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
00813 #else
00814 #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
00815 #endif
00816 
00817 #define INIT_VARRAY(type) { /* macro to initialize a varray */ \
00818   (vlinks_t *)0,            /* first */                        \
00819   (vlinks_t *)0,            /* last */                         \
00820   0,                        /* num_allocated */                \
00821   sizeof (type),            /* object_size */                  \
00822   OBJECTS_PER_PAGE (type),  /* objects_per_page */                    \
00823   OBJECTS_PER_PAGE (type),  /* objects_last_page */                   \
00824 }
00825 
00826 /* Master type for indexes within the symbol table.  */
00827 typedef unsigned long symint_t;
00828 
00829 /* Linked list support for nested scopes (file, block, structure, etc.).  */
00830 typedef struct scope {
00831   struct scope       *prev;        /* previous scope level */
00832   struct scope       *free;        /* free list pointer */
00833   struct localsym *lsym;    /* pointer to local symbol node */
00834   st_t         type;        /* type of the node */
00835 } scope_t;
00836 
00837 /* For a local symbol we store a gas symbol as well as the debugging
00838    information we generate.  The gas symbol will be NULL if this is
00839    only a debugging symbol.  */
00840 typedef struct localsym {
00841   const char *name;         /* symbol name */
00842   symbolS *as_sym;          /* symbol as seen by gas */
00843   bfd_vma addend;           /* addend to as_sym value */
00844   struct efdr *file_ptr;    /* file pointer */
00845   struct ecoff_proc *proc_ptr;     /* proc pointer */
00846   struct localsym *begin_ptr;      /* symbol at start of block */
00847   struct ecoff_aux *index_ptr;     /* index value to be filled in */
00848   struct forward *forward_ref;     /* forward references to this symbol */
00849   long sym_index;           /* final symbol index */
00850   EXTR ecoff_sym;           /* ECOFF debugging symbol */
00851 } localsym_t;
00852 
00853 /* For aux information we keep the type and the data.  */
00854 typedef struct ecoff_aux {
00855   enum aux_type type;              /* aux type */
00856   AUXU data;                /* aux data */
00857 } aux_t;
00858 
00859 /* For a procedure we store the gas symbol as well as the PDR
00860    debugging information.  */
00861 typedef struct ecoff_proc {
00862   localsym_t *sym;          /* associated symbol */
00863   PDR pdr;                  /* ECOFF debugging info */
00864 } proc_t;
00865 
00866 /* Number of proc_t structures allocated.  */
00867 static unsigned long proc_cnt;
00868 
00869 /* Forward reference list for tags referenced, but not yet defined.  */
00870 typedef struct forward {
00871   struct forward *next;            /* next forward reference */
00872   struct forward *free;            /* free list pointer */
00873   aux_t               *ifd_ptr;    /* pointer to store file index */
00874   aux_t               *index_ptr;  /* pointer to store symbol index */
00875 } forward_t;
00876 
00877 /* Linked list support for tags.  The first tag in the list is always
00878    the current tag for that block.  */
00879 typedef struct tag {
00880   struct tag   *free;              /* free list pointer */
00881   struct shash        *hash_ptr;   /* pointer to the hash table head */
00882   struct tag   *same_name;  /* tag with same name in outer scope */
00883   struct tag   *same_block; /* next tag defined in the same block.  */
00884   struct forward *forward_ref;     /* list of forward references */
00885   bt_t          basic_type; /* bt_Struct, bt_Union, or bt_Enum */
00886   symint_t      ifd;        /* file # tag defined in */
00887   localsym_t   *sym;        /* file's local symbols */
00888 } tag_t;
00889 
00890 /* Head of a block's linked list of tags.  */
00891 typedef struct thead {
00892   struct thead       *prev;        /* previous block */
00893   struct thead       *free;        /* free list pointer */
00894   struct tag  *first_tag;   /* first tag in block defined */
00895 } thead_t;
00896 
00897 /* Union containing pointers to each the small structures which are freed up.  */
00898 typedef union small_free {
00899   scope_t     *f_scope;     /* scope structure */
00900   thead_t     *f_thead;     /* tag head structure */
00901   tag_t              *f_tag;              /* tag element structure */
00902   forward_t   *f_forward;   /* forward tag reference */
00903 } small_free_t;
00904 
00905 /* String hash table entry.  */
00906 
00907 typedef struct shash {
00908   char        *string;      /* string we are hashing */
00909   symint_t     indx;        /* index within string table */
00910   EXTR        *esym_ptr;    /* global symbol pointer */
00911   localsym_t  *sym_ptr;     /* local symbol pointer */
00912   localsym_t  *end_ptr;     /* symbol pointer to end block */
00913   tag_t              *tag_ptr;     /* tag pointer */
00914   proc_t      *proc_ptr;    /* procedure descriptor pointer */
00915 } shash_t;
00916 
00917 /* Type hash table support.  The size of the hash table must fit
00918    within a page with the other extended file descriptor information.
00919    Because unique types which are hashed are fewer in number than
00920    strings, we use a smaller hash value.  */
00921 
00922 #define HASHBITS 30
00923 
00924 #ifndef THASH_SIZE
00925 #define THASH_SIZE 113
00926 #endif
00927 
00928 typedef struct thash {
00929   struct thash       *next;        /* next hash value */
00930   AUXU         type;        /* type we are hashing */
00931   symint_t     indx;        /* index within string table */
00932 } thash_t;
00933 
00934 /* Extended file descriptor that contains all of the support necessary
00935    to add things to each file separately.  */
00936 typedef struct efdr {
00937   FDR          fdr;         /* File header to be written out */
00938   FDR         *orig_fdr;    /* original file header */
00939   char        *name;        /* filename */
00940   int          fake;        /* whether this is faked .file */
00941   symint_t     void_type;   /* aux. pointer to 'void' type */
00942   symint_t     int_type;    /* aux. pointer to 'int' type */
00943   scope_t     *cur_scope;   /* current nested scopes */
00944   symint_t     file_index;  /* current file number */
00945   int          nested_scopes;      /* # nested scopes */
00946   varray_t     strings;     /* local strings */
00947   varray_t     symbols;     /* local symbols */
00948   varray_t     procs;              /* procedures */
00949   varray_t     aux_syms;    /* auxiliary symbols */
00950   struct efdr *next_file;   /* next file descriptor */
00951                             /* string/type hash tables */
00952   struct hash_control *str_hash;   /* string hash table */
00953   thash_t     *thash_head[THASH_SIZE];
00954 } efdr_t;
00955 
00956 /* Pre-initialized extended file structure.  */
00957 static const efdr_t init_file = {
00958   {                  /* FDR structure */
00959     0,               /* adr:              memory address of beginning of file */
00960     0,               /* rss:              file name (of source, if known) */
00961     0,               /* issBase:   file's string space */
00962     0,               /* cbSs:      number of bytes in the ss */
00963     0,               /* isymBase:  beginning of symbols */
00964     0,               /* csym:      count file's of symbols */
00965     0,               /* ilineBase: file's line symbols */
00966     0,               /* cline:     count of file's line symbols */
00967     0,               /* ioptBase:  file's optimization entries */
00968     0,               /* copt:      count of file's optimization entries */
00969     0,               /* ipdFirst:  start of procedures for this file */
00970     0,               /* cpd:              count of procedures for this file */
00971     0,               /* iauxBase:  file's auxiliary entries */
00972     0,               /* caux:      count of file's auxiliary entries */
00973     0,               /* rfdBase:   index into the file indirect table */
00974     0,               /* crfd:      count file indirect entries */
00975     langC,           /* lang:      language for this file */
00976     1,               /* fMerge:    whether this file can be merged */
00977     0,               /* fReadin:   true if read in (not just created) */
00978     TARGET_BYTES_BIG_ENDIAN,  /* fBigendian:     if 1, compiled on big endian machine */
00979     GLEVEL_2,        /* glevel:    level this file was compiled with */
00980     0,               /* reserved:  reserved for future use */
00981     0,               /* cbLineOffset: byte offset from header for this file ln's */
00982     0,               /* cbLine:    size of lines for this file */
00983   },
00984 
00985   (FDR *)0,          /* orig_fdr:  original file header pointer */
00986   (char *)0,         /* name:      pointer to filename */
00987   0,                 /* fake:      whether this is a faked .file */
00988   0,                 /* void_type: ptr to aux node for void type */
00989   0,                 /* int_type:  ptr to aux node for int type */
00990   (scope_t *)0,             /* cur_scope: current scope being processed */
00991   0,                 /* file_index:       current file # */
00992   0,                 /* nested_scopes: # nested scopes */
00993   INIT_VARRAY (char),       /* strings:   local string varray */
00994   INIT_VARRAY (localsym_t), /* symbols:   local symbols varray */
00995   INIT_VARRAY (proc_t),     /* procs:     procedure varray */
00996   INIT_VARRAY (aux_t),      /* aux_syms:  auxiliary symbols varray */
00997 
00998   (struct efdr *)0,  /* next_file: next file structure */
00999 
01000   (struct hash_control *)0, /* str_hash:  string hash table */
01001   { 0 },             /* thash_head:       type hash table */
01002 };
01003 
01004 static efdr_t *first_file;                /* first file descriptor */
01005 static efdr_t **last_file_ptr = &first_file;     /* file descriptor tail */
01006 
01007 /* Line number information is kept in a list until the assembly is
01008    finished.  */
01009 typedef struct lineno_list {
01010   struct lineno_list *next; /* next element in list */
01011   efdr_t *file;                    /* file this line is in */
01012   proc_t *proc;                    /* procedure this line is in */
01013   fragS *frag;                     /* fragment this line number is in */
01014   unsigned long paddr;             /* offset within fragment */
01015   long lineno;                     /* actual line number */
01016 } lineno_list_t;
01017 
01018 static lineno_list_t *first_lineno;
01019 static lineno_list_t *last_lineno;
01020 static lineno_list_t **last_lineno_ptr = &first_lineno;
01021 
01022 /* Sometimes there will be some .loc statements before a .ent.  We
01023    keep them in this list so that we can fill in the procedure pointer
01024    after we see the .ent.  */
01025 static lineno_list_t *noproc_lineno;
01026 
01027 /* Union of various things that are held in pages.  */
01028 typedef union page {
01029   char        byte   [ PAGE_SIZE ];
01030   unsigned char      ubyte  [ PAGE_SIZE ];
01031   efdr_t      file   [ PAGE_SIZE / sizeof (efdr_t)           ];
01032   FDR         ofile  [ PAGE_SIZE / sizeof (FDR)       ];
01033   proc_t      proc   [ PAGE_SIZE / sizeof (proc_t)           ];
01034   localsym_t  sym    [ PAGE_SIZE / sizeof (localsym_t)    ];
01035   aux_t              aux    [ PAGE_SIZE / sizeof (aux_t)            ];
01036   DNR         dense  [ PAGE_SIZE / sizeof (DNR)       ];
01037   scope_t     scope  [ PAGE_SIZE / sizeof (scope_t)          ];
01038   vlinks_t    vlinks [ PAGE_SIZE / sizeof (vlinks_t)         ];
01039   shash_t     shash  [ PAGE_SIZE / sizeof (shash_t)          ];
01040   thash_t     thash  [ PAGE_SIZE / sizeof (thash_t)          ];
01041   tag_t              tag    [ PAGE_SIZE / sizeof (tag_t)            ];
01042   forward_t   forward       [ PAGE_SIZE / sizeof (forward_t)     ];
01043   thead_t     thead  [ PAGE_SIZE / sizeof (thead_t)          ];
01044   lineno_list_t      lineno [ PAGE_SIZE / sizeof (lineno_list_t) ];
01045 } page_type;
01046 
01047 /* Structure holding allocation information for small sized structures.  */
01048 typedef struct alloc_info {
01049   char        *alloc_name;  /* name of this allocation type (must be first) */
01050   page_type   *cur_page;    /* current page being allocated from */
01051   small_free_t        free_list;   /* current free list if any */
01052   int          unallocated; /* number of elements unallocated on page */
01053   int          total_alloc; /* total number of allocations */
01054   int          total_free;  /* total number of frees */
01055   int          total_pages; /* total number of pages allocated */
01056 } alloc_info_t;
01057 
01058 /* Type information collected together.  */
01059 typedef struct type_info {
01060   bt_t       basic_type;           /* basic type */
01061   int        orig_type;            /* original COFF-based type */
01062   int        num_tq;               /* # type qualifiers */
01063   int        num_dims;                    /* # dimensions */
01064   int        num_sizes;            /* # sizes */
01065   int        extra_sizes;          /* # extra sizes not tied with dims */
01066   tag_t *     tag_ptr;                    /* tag pointer */
01067   int        bitfield;                    /* symbol is a bitfield */
01068   tq_t       type_qualifiers[N_TQ];       /* type qualifiers (ptr, func, array)*/
01069   symint_t    dimensions     [N_TQ];      /* dimensions for each array */
01070   symint_t    sizes       [N_TQ+2];       /* sizes of each array slice + size of
01071                                       struct/union/enum + bitfield size */
01072 } type_info_t;
01073 
01074 /* Pre-initialized type_info struct.  */
01075 static const type_info_t type_info_init = {
01076   bt_Nil,                          /* basic type */
01077   T_NULL,                          /* original COFF-based type */
01078   0,                               /* # type qualifiers */
01079   0,                               /* # dimensions */
01080   0,                               /* # sizes */
01081   0,                               /* sizes not tied with dims */
01082   NULL,                                   /* ptr to tag */
01083   0,                               /* bitfield */
01084   {                                /* type qualifiers */
01085     tq_Nil,
01086     tq_Nil,
01087     tq_Nil,
01088     tq_Nil,
01089     tq_Nil,
01090     tq_Nil,
01091   },
01092   {                                /* dimensions */
01093     0,
01094     0,
01095     0,
01096     0,
01097     0,
01098     0
01099   },
01100   {                                /* sizes */
01101     0,
01102     0,
01103     0,
01104     0,
01105     0,
01106     0,
01107     0,
01108     0,
01109   },
01110 };
01111 
01112 /* Global hash table for the tags table and global table for file
01113    descriptors.  */
01114 
01115 static varray_t file_desc = INIT_VARRAY (efdr_t);
01116 
01117 static struct hash_control *tag_hash;
01118 
01119 /* Static types for int and void.  Also, remember the last function's
01120    type (which is set up when we encounter the declaration for the
01121    function, and used when the end block for the function is emitted.  */
01122 
01123 static type_info_t int_type_info;
01124 static type_info_t void_type_info;
01125 static type_info_t last_func_type_info;
01126 static symbolS *last_func_sym_value;
01127 
01128 /* Convert COFF basic type to ECOFF basic type.  The T_NULL type
01129    really should use bt_Void, but this causes the current ecoff GDB to
01130    issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
01131    2.0) doesn't understand it, even though the compiler generates it.
01132    Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
01133    suite, but for now go with what works.
01134 
01135    It would make sense for the .type and .scl directives to use the
01136    ECOFF numbers directly, rather than using the COFF numbers and
01137    mapping them.  Unfortunately, this is historically what mips-tfile
01138    expects, and changing gcc now would be a considerable pain (the
01139    native compiler generates debugging information internally, rather
01140    than via the assembler, so it will never use .type or .scl).  */
01141 
01142 static const bt_t map_coff_types[] = {
01143   bt_Nil,                   /* T_NULL */
01144   bt_Nil,                   /* T_ARG */
01145   bt_Char,                  /* T_CHAR */
01146   bt_Short,                 /* T_SHORT */
01147   bt_Int,                   /* T_INT */
01148   bt_Long,                  /* T_LONG */
01149   bt_Float,                 /* T_FLOAT */
01150   bt_Double,                /* T_DOUBLE */
01151   bt_Struct,                /* T_STRUCT */
01152   bt_Union,                 /* T_UNION */
01153   bt_Enum,                  /* T_ENUM */
01154   bt_Enum,                  /* T_MOE */
01155   bt_UChar,                 /* T_UCHAR */
01156   bt_UShort,                /* T_USHORT */
01157   bt_UInt,                  /* T_UINT */
01158   bt_ULong                  /* T_ULONG */
01159 };
01160 
01161 /* Convert COFF storage class to ECOFF storage class.  */
01162 static const sc_t map_coff_storage[] = {
01163   sc_Nil,                   /*   0: C_NULL */
01164   sc_Abs,                   /*   1: C_AUTO         auto var */
01165   sc_Undefined,                    /*   2: C_EXT   external */
01166   sc_Data,                  /*   3: C_STAT         static */
01167   sc_Register,                     /*   4: C_REG   register */
01168   sc_Undefined,                    /*   5: C_EXTDEF  ??? */
01169   sc_Text,                  /*   6: C_LABEL        label */
01170   sc_Text,                  /*   7: C_ULABEL  user label */
01171   sc_Info,                  /*   8: C_MOS   member of struct */
01172   sc_Abs,                   /*   9: C_ARG   argument */
01173   sc_Info,                  /*  10: C_STRTAG  struct tag */
01174   sc_Info,                  /*  11: C_MOU   member of union */
01175   sc_Info,                  /*  12: C_UNTAG   union tag */
01176   sc_Info,                  /*  13: C_TPDEF        typedef */
01177   sc_Data,                  /*  14: C_USTATIC ??? */
01178   sc_Info,                  /*  15: C_ENTAG        enum tag */
01179   sc_Info,                  /*  16: C_MOE   member of enum */
01180   sc_Register,                     /*  17: C_REGPARM register parameter */
01181   sc_Bits,                  /*  18; C_FIELD        bitfield */
01182   sc_Nil,                   /*  19 */
01183   sc_Nil,                   /*  20 */
01184   sc_Nil,                   /*  21 */
01185   sc_Nil,                   /*  22 */
01186   sc_Nil,                   /*  23 */
01187   sc_Nil,                   /*  24 */
01188   sc_Nil,                   /*  25 */
01189   sc_Nil,                   /*  26 */
01190   sc_Nil,                   /*  27 */
01191   sc_Nil,                   /*  28 */
01192   sc_Nil,                   /*  29 */
01193   sc_Nil,                   /*  30 */
01194   sc_Nil,                   /*  31 */
01195   sc_Nil,                   /*  32 */
01196   sc_Nil,                   /*  33 */
01197   sc_Nil,                   /*  34 */
01198   sc_Nil,                   /*  35 */
01199   sc_Nil,                   /*  36 */
01200   sc_Nil,                   /*  37 */
01201   sc_Nil,                   /*  38 */
01202   sc_Nil,                   /*  39 */
01203   sc_Nil,                   /*  40 */
01204   sc_Nil,                   /*  41 */
01205   sc_Nil,                   /*  42 */
01206   sc_Nil,                   /*  43 */
01207   sc_Nil,                   /*  44 */
01208   sc_Nil,                   /*  45 */
01209   sc_Nil,                   /*  46 */
01210   sc_Nil,                   /*  47 */
01211   sc_Nil,                   /*  48 */
01212   sc_Nil,                   /*  49 */
01213   sc_Nil,                   /*  50 */
01214   sc_Nil,                   /*  51 */
01215   sc_Nil,                   /*  52 */
01216   sc_Nil,                   /*  53 */
01217   sc_Nil,                   /*  54 */
01218   sc_Nil,                   /*  55 */
01219   sc_Nil,                   /*  56 */
01220   sc_Nil,                   /*  57 */
01221   sc_Nil,                   /*  58 */
01222   sc_Nil,                   /*  59 */
01223   sc_Nil,                   /*  60 */
01224   sc_Nil,                   /*  61 */
01225   sc_Nil,                   /*  62 */
01226   sc_Nil,                   /*  63 */
01227   sc_Nil,                   /*  64 */
01228   sc_Nil,                   /*  65 */
01229   sc_Nil,                   /*  66 */
01230   sc_Nil,                   /*  67 */
01231   sc_Nil,                   /*  68 */
01232   sc_Nil,                   /*  69 */
01233   sc_Nil,                   /*  70 */
01234   sc_Nil,                   /*  71 */
01235   sc_Nil,                   /*  72 */
01236   sc_Nil,                   /*  73 */
01237   sc_Nil,                   /*  74 */
01238   sc_Nil,                   /*  75 */
01239   sc_Nil,                   /*  76 */
01240   sc_Nil,                   /*  77 */
01241   sc_Nil,                   /*  78 */
01242   sc_Nil,                   /*  79 */
01243   sc_Nil,                   /*  80 */
01244   sc_Nil,                   /*  81 */
01245   sc_Nil,                   /*  82 */
01246   sc_Nil,                   /*  83 */
01247   sc_Nil,                   /*  84 */
01248   sc_Nil,                   /*  85 */
01249   sc_Nil,                   /*  86 */
01250   sc_Nil,                   /*  87 */
01251   sc_Nil,                   /*  88 */
01252   sc_Nil,                   /*  89 */
01253   sc_Nil,                   /*  90 */
01254   sc_Nil,                   /*  91 */
01255   sc_Nil,                   /*  92 */
01256   sc_Nil,                   /*  93 */
01257   sc_Nil,                   /*  94 */
01258   sc_Nil,                   /*  95 */
01259   sc_Nil,                   /*  96 */
01260   sc_Nil,                   /*  97 */
01261   sc_Nil,                   /*  98 */
01262   sc_Nil,                   /*  99 */
01263   sc_Text,                  /* 100: C_BLOCK  block start/end */
01264   sc_Text,                  /* 101: C_FCN  function start/end */
01265   sc_Info,                  /* 102: C_EOS  end of struct/union/enum */
01266   sc_Nil,                   /* 103: C_FILE        file start */
01267   sc_Nil,                   /* 104: C_LINE        line number */
01268   sc_Nil,                   /* 105: C_ALIAS       combined type info */
01269   sc_Nil,                   /* 106: C_HIDDEN ??? */
01270 };
01271 
01272 /* Convert COFF storage class to ECOFF symbol type.  */
01273 static const st_t map_coff_sym_type[] = {
01274   st_Nil,                   /*   0: C_NULL */
01275   st_Local,                 /*   1: C_AUTO         auto var */
01276   st_Global,                /*   2: C_EXT   external */
01277   st_Static,                /*   3: C_STAT         static */
01278   st_Local,                 /*   4: C_REG   register */
01279   st_Global,                /*   5: C_EXTDEF  ??? */
01280   st_Label,                 /*   6: C_LABEL        label */
01281   st_Label,                 /*   7: C_ULABEL  user label */
01282   st_Member,                /*   8: C_MOS   member of struct */
01283   st_Param,                 /*   9: C_ARG   argument */
01284   st_Block,                 /*  10: C_STRTAG  struct tag */
01285   st_Member,                /*  11: C_MOU   member of union */
01286   st_Block,                 /*  12: C_UNTAG   union tag */
01287   st_Typedef,               /*  13: C_TPDEF        typedef */
01288   st_Static,                /*  14: C_USTATIC ??? */
01289   st_Block,                 /*  15: C_ENTAG        enum tag */
01290   st_Member,                /*  16: C_MOE   member of enum */
01291   st_Param,                 /*  17: C_REGPARM register parameter */
01292   st_Member,                /*  18; C_FIELD        bitfield */
01293   st_Nil,                   /*  19 */
01294   st_Nil,                   /*  20 */
01295   st_Nil,                   /*  21 */
01296   st_Nil,                   /*  22 */
01297   st_Nil,                   /*  23 */
01298   st_Nil,                   /*  24 */
01299   st_Nil,                   /*  25 */
01300   st_Nil,                   /*  26 */
01301   st_Nil,                   /*  27 */
01302   st_Nil,                   /*  28 */
01303   st_Nil,                   /*  29 */
01304   st_Nil,                   /*  30 */
01305   st_Nil,                   /*  31 */
01306   st_Nil,                   /*  32 */
01307   st_Nil,                   /*  33 */
01308   st_Nil,                   /*  34 */
01309   st_Nil,                   /*  35 */
01310   st_Nil,                   /*  36 */
01311   st_Nil,                   /*  37 */
01312   st_Nil,                   /*  38 */
01313   st_Nil,                   /*  39 */
01314   st_Nil,                   /*  40 */
01315   st_Nil,                   /*  41 */
01316   st_Nil,                   /*  42 */
01317   st_Nil,                   /*  43 */
01318   st_Nil,                   /*  44 */
01319   st_Nil,                   /*  45 */
01320   st_Nil,                   /*  46 */
01321   st_Nil,                   /*  47 */
01322   st_Nil,                   /*  48 */
01323   st_Nil,                   /*  49 */
01324   st_Nil,                   /*  50 */
01325   st_Nil,                   /*  51 */
01326   st_Nil,                   /*  52 */
01327   st_Nil,                   /*  53 */
01328   st_Nil,                   /*  54 */
01329   st_Nil,                   /*  55 */
01330   st_Nil,                   /*  56 */
01331   st_Nil,                   /*  57 */
01332   st_Nil,                   /*  58 */
01333   st_Nil,                   /*  59 */
01334   st_Nil,                   /*  60 */
01335   st_Nil,                   /*  61 */
01336   st_Nil,                   /*  62 */
01337   st_Nil,                   /*  63 */
01338   st_Nil,                   /*  64 */
01339   st_Nil,                   /*  65 */
01340   st_Nil,                   /*  66 */
01341   st_Nil,                   /*  67 */
01342   st_Nil,                   /*  68 */
01343   st_Nil,                   /*  69 */
01344   st_Nil,                   /*  70 */
01345   st_Nil,                   /*  71 */
01346   st_Nil,                   /*  72 */
01347   st_Nil,                   /*  73 */
01348   st_Nil,                   /*  74 */
01349   st_Nil,                   /*  75 */
01350   st_Nil,                   /*  76 */
01351   st_Nil,                   /*  77 */
01352   st_Nil,                   /*  78 */
01353   st_Nil,                   /*  79 */
01354   st_Nil,                   /*  80 */
01355   st_Nil,                   /*  81 */
01356   st_Nil,                   /*  82 */
01357   st_Nil,                   /*  83 */
01358   st_Nil,                   /*  84 */
01359   st_Nil,                   /*  85 */
01360   st_Nil,                   /*  86 */
01361   st_Nil,                   /*  87 */
01362   st_Nil,                   /*  88 */
01363   st_Nil,                   /*  89 */
01364   st_Nil,                   /*  90 */
01365   st_Nil,                   /*  91 */
01366   st_Nil,                   /*  92 */
01367   st_Nil,                   /*  93 */
01368   st_Nil,                   /*  94 */
01369   st_Nil,                   /*  95 */
01370   st_Nil,                   /*  96 */
01371   st_Nil,                   /*  97 */
01372   st_Nil,                   /*  98 */
01373   st_Nil,                   /*  99 */
01374   st_Block,                 /* 100: C_BLOCK  block start/end */
01375   st_Proc,                  /* 101: C_FCN  function start/end */
01376   st_End,                   /* 102: C_EOS  end of struct/union/enum */
01377   st_File,                  /* 103: C_FILE        file start */
01378   st_Nil,                   /* 104: C_LINE        line number */
01379   st_Nil,                   /* 105: C_ALIAS       combined type info */
01380   st_Nil,                   /* 106: C_HIDDEN ??? */
01381 };
01382 
01383 /* Keep track of different sized allocation requests.  */
01384 static alloc_info_t alloc_counts[(int) alloc_type_last];
01385 
01386 /* Record whether we have seen any debugging information.  */
01387 int ecoff_debugging_seen = 0;
01388 
01389 /* Various statics.  */
01390 static efdr_t  *cur_file_ptr       = (efdr_t *) 0;      /* current file desc. header */
01391 static proc_t  *cur_proc_ptr       = (proc_t *) 0;      /* current procedure header */
01392 static proc_t  *first_proc_ptr  = (proc_t *) 0; /* first procedure header */
01393 static thead_t *top_tag_head       = (thead_t *) 0; /* top level tag head */
01394 static thead_t *cur_tag_head       = (thead_t *) 0; /* current tag head */
01395 #ifdef ECOFF_DEBUG
01396 static int    debug         = 0;          /* trace functions */
01397 #endif
01398 static int    stabs_seen    = 0;          /* != 0 if stabs have been seen */
01399 
01400 static int current_file_idx;
01401 static const char *current_stabs_filename;
01402 
01403 /* Pseudo symbol to use when putting stabs into the symbol table.  */
01404 #ifndef STABS_SYMBOL
01405 #define STABS_SYMBOL "@stabs"
01406 #endif
01407 
01408 static char stabs_symbol[] = STABS_SYMBOL;
01409 
01410 /* Prototypes for functions defined in this file.  */
01411 
01412 static void add_varray_page (varray_t *vp);
01413 static symint_t add_string (varray_t *vp,
01414                          struct hash_control *hash_tbl,
01415                          const char *str,
01416                          shash_t **ret_hash);
01417 static localsym_t *add_ecoff_symbol (const char *str, st_t type,
01418                                  sc_t storage, symbolS *sym,
01419                                  bfd_vma addend, symint_t value,
01420                                  symint_t indx);
01421 static symint_t add_aux_sym_symint (symint_t aux_word);
01422 static symint_t add_aux_sym_rndx (int file_index, symint_t sym_index);
01423 static symint_t add_aux_sym_tir (type_info_t *t,
01424                              hash_state_t state,
01425                              thash_t **hash_tbl);
01426 static tag_t *get_tag (const char *tag, localsym_t *sym, bt_t basic_type);
01427 static void add_unknown_tag (tag_t *ptag);
01428 static void add_procedure (char *func);
01429 static void add_file (const char *file_name, int indx, int fake);
01430 #ifdef ECOFF_DEBUG
01431 static char *sc_to_string (sc_t storage_class);
01432 static char *st_to_string (st_t symbol_type);
01433 #endif
01434 static void mark_stabs (int);
01435 static char *ecoff_add_bytes (char **buf, char **bufend,
01436                            char *bufptr, unsigned long need);
01437 static unsigned long ecoff_padding_adjust
01438   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
01439    unsigned long offset, char **bufptrptr);
01440 static unsigned long ecoff_build_lineno
01441   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
01442    unsigned long offset, long *linecntptr);
01443 static unsigned long ecoff_build_symbols
01444   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
01445    unsigned long offset);
01446 static unsigned long ecoff_build_procs
01447   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
01448    unsigned long offset);
01449 static unsigned long ecoff_build_aux
01450   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
01451    unsigned long offset);
01452 static unsigned long ecoff_build_strings (char **buf, char **bufend,
01453                                      unsigned long offset,
01454                                      varray_t *vp);
01455 static unsigned long ecoff_build_ss
01456   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
01457    unsigned long offset);
01458 static unsigned long ecoff_build_fdr
01459   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
01460    unsigned long offset);
01461 static void ecoff_setup_ext (void);
01462 static page_type *allocate_cluster (unsigned long npages);
01463 static page_type *allocate_page (void);
01464 static scope_t *allocate_scope (void);
01465 static void free_scope (scope_t *ptr);
01466 static vlinks_t *allocate_vlinks (void);
01467 static shash_t *allocate_shash (void);
01468 static thash_t *allocate_thash (void);
01469 static tag_t *allocate_tag (void);
01470 static void free_tag (tag_t *ptr);
01471 static forward_t *allocate_forward (void);
01472 static thead_t *allocate_thead (void);
01473 static void free_thead (thead_t *ptr);
01474 static lineno_list_t *allocate_lineno_list (void);
01475 
01476 /* This function should be called when the assembler starts up.  */
01477 
01478 void
01479 ecoff_read_begin_hook (void)
01480 {
01481   tag_hash = hash_new ();
01482   top_tag_head = allocate_thead ();
01483   top_tag_head->first_tag = (tag_t *) NULL;
01484   top_tag_head->free = (thead_t *) NULL;
01485   top_tag_head->prev = cur_tag_head;
01486   cur_tag_head = top_tag_head;
01487 }
01488 
01489 /* This function should be called when a symbol is created.  */
01490 
01491 void
01492 ecoff_symbol_new_hook (symbolS *symbolP)
01493 {
01494   OBJ_SYMFIELD_TYPE *obj;
01495 
01496   /* Make sure that we have a file pointer, but only if we have seen a
01497      file.  If we haven't seen a file, then this is a probably special
01498      symbol created by md_begin which may required special handling at
01499      some point.  Creating a dummy file with a dummy name is certainly
01500      wrong.  */
01501   if (cur_file_ptr == (efdr_t *) NULL
01502       && seen_at_least_1_file ())
01503     add_file ((const char *) NULL, 0, 1);
01504   obj = symbol_get_obj (symbolP);
01505   obj->ecoff_file = cur_file_ptr;
01506   obj->ecoff_symbol = NULL;
01507   obj->ecoff_extern_size = 0;
01508 }
01509 
01510 /* Add a page to a varray object.  */
01511 
01512 static void
01513 add_varray_page (varray_t *vp /* varray to add page to */)
01514 {
01515   vlinks_t *new_links = allocate_vlinks ();
01516 
01517 #ifdef MALLOC_CHECK
01518   if (vp->object_size > 1)
01519     new_links->datum = (page_type *) xcalloc (1, vp->object_size);
01520   else
01521 #endif
01522     new_links->datum = allocate_page ();
01523 
01524   alloc_counts[(int) alloc_type_varray].total_alloc++;
01525   alloc_counts[(int) alloc_type_varray].total_pages++;
01526 
01527   new_links->start_index = vp->num_allocated;
01528   vp->objects_last_page = 0;
01529 
01530   if (vp->first == (vlinks_t *) NULL)            /* first allocation? */
01531     vp->first = vp->last = new_links;
01532   else
01533     {                                     /* 2nd or greater allocation */
01534       new_links->prev = vp->last;
01535       vp->last->next = new_links;
01536       vp->last = new_links;
01537     }
01538 }
01539 
01540 /* Add a string (and null pad) to one of the string tables.  */
01541 
01542 static symint_t
01543 add_string (varray_t *vp,                 /* string obstack */
01544            struct hash_control *hash_tbl, /* ptr to hash table */
01545            const char *str,               /* string */
01546            shash_t **ret_hash                    /* return hash pointer */)
01547 {
01548   register unsigned long len = strlen (str);
01549   register shash_t *hash_ptr;
01550 
01551   if (len >= PAGE_USIZE)
01552     as_fatal (_("string too big (%lu bytes)"), len);
01553 
01554   hash_ptr = (shash_t *) hash_find (hash_tbl, str);
01555   if (hash_ptr == (shash_t *) NULL)
01556     {
01557       register const char *err;
01558 
01559       if (vp->objects_last_page + len >= PAGE_USIZE)
01560        {
01561          vp->num_allocated =
01562            ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
01563          add_varray_page (vp);
01564        }
01565 
01566       hash_ptr = allocate_shash ();
01567       hash_ptr->indx = vp->num_allocated;
01568 
01569       hash_ptr->string = &vp->last->datum->byte[vp->objects_last_page];
01570 
01571       vp->objects_last_page += len + 1;
01572       vp->num_allocated += len + 1;
01573 
01574       strcpy (hash_ptr->string, str);
01575 
01576       err = hash_insert (hash_tbl, str, (char *) hash_ptr);
01577       if (err)
01578        as_fatal (_("inserting \"%s\" into string hash table: %s"),
01579                 str, err);
01580     }
01581 
01582   if (ret_hash != (shash_t **) NULL)
01583     *ret_hash = hash_ptr;
01584 
01585   return hash_ptr->indx;
01586 }
01587 
01588 /* Add debugging information for a symbol.  */
01589 
01590 static localsym_t *
01591 add_ecoff_symbol (const char *str, /* symbol name */
01592                 st_t type,         /* symbol type */
01593                 sc_t storage,             /* storage class */
01594                 symbolS *sym_value,       /* associated symbol.  */
01595                 bfd_vma addend,    /* addend to sym_value.  */
01596                 symint_t value,    /* value of symbol */
01597                 symint_t indx             /* index to local/aux. syms */)
01598 {
01599   localsym_t *psym;
01600   register scope_t *pscope;
01601   register thead_t *ptag_head;
01602   register tag_t *ptag;
01603   register tag_t *ptag_next;
01604   register varray_t *vp;
01605   register int scope_delta = 0;
01606   shash_t *hash_ptr = (shash_t *) NULL;
01607 
01608   if (cur_file_ptr == (efdr_t *) NULL)
01609     as_fatal (_("no current file pointer"));
01610 
01611   vp = &cur_file_ptr->symbols;
01612 
01613   if (vp->objects_last_page == vp->objects_per_page)
01614     add_varray_page (vp);
01615 
01616   psym = &vp->last->datum->sym[vp->objects_last_page++];
01617 
01618   if (str == (const char *) NULL && sym_value != (symbolS *) NULL)
01619     psym->name = S_GET_NAME (sym_value);
01620   else
01621     psym->name = str;
01622   psym->as_sym = sym_value;
01623   if (sym_value != (symbolS *) NULL)
01624     symbol_get_obj (sym_value)->ecoff_symbol = psym;
01625   psym->addend = addend;
01626   psym->file_ptr = cur_file_ptr;
01627   psym->proc_ptr = cur_proc_ptr;
01628   psym->begin_ptr = (localsym_t *) NULL;
01629   psym->index_ptr = (aux_t *) NULL;
01630   psym->forward_ref = (forward_t *) NULL;
01631   psym->sym_index = -1;
01632   memset (&psym->ecoff_sym, 0, sizeof (EXTR));
01633   psym->ecoff_sym.asym.value = value;
01634   psym->ecoff_sym.asym.st = (unsigned) type;
01635   psym->ecoff_sym.asym.sc = (unsigned) storage;
01636   psym->ecoff_sym.asym.index = indx;
01637 
01638   /* If there is an associated symbol, we wait until the end of the
01639      assembly before deciding where to put the name (it may be just an
01640      external symbol).  Otherwise, this is just a debugging symbol and
01641      the name should go with the current file.  */
01642   if (sym_value == (symbolS *) NULL)
01643     psym->ecoff_sym.asym.iss = ((str == (const char *) NULL)
01644                             ? 0
01645                             : add_string (&cur_file_ptr->strings,
01646                                          cur_file_ptr->str_hash,
01647                                          str,
01648                                          &hash_ptr));
01649 
01650   ++vp->num_allocated;
01651 
01652   if (ECOFF_IS_STAB (&psym->ecoff_sym.asym))
01653     return psym;
01654 
01655   /* Save the symbol within the hash table if this is a static
01656      item, and it has a name.  */
01657   if (hash_ptr != (shash_t *) NULL
01658       && (type == st_Global || type == st_Static || type == st_Label
01659          || type == st_Proc || type == st_StaticProc))
01660     hash_ptr->sym_ptr = psym;
01661 
01662   /* push or pop a scope if appropriate.  */
01663   switch (type)
01664     {
01665     default:
01666       break;
01667 
01668     case st_File:                  /* beginning of file */
01669     case st_Proc:                  /* procedure */
01670     case st_StaticProc:                   /* static procedure */
01671     case st_Block:                 /* begin scope */
01672       pscope = allocate_scope ();
01673       pscope->prev = cur_file_ptr->cur_scope;
01674       pscope->lsym = psym;
01675       pscope->type = type;
01676       cur_file_ptr->cur_scope = pscope;
01677 
01678       if (type != st_File)
01679        scope_delta = 1;
01680 
01681       /* For every block type except file, struct, union, or
01682          enumeration blocks, push a level on the tag stack.  We omit
01683          file types, so that tags can span file boundaries.  */
01684       if (type != st_File && storage != sc_Info)
01685        {
01686          ptag_head = allocate_thead ();
01687          ptag_head->first_tag = 0;
01688          ptag_head->prev = cur_tag_head;
01689          cur_tag_head = ptag_head;
01690        }
01691       break;
01692 
01693     case st_End:
01694       pscope = cur_file_ptr->cur_scope;
01695       if (pscope == (scope_t *) NULL)
01696        as_fatal (_("too many st_End's"));
01697       else
01698        {
01699          st_t begin_type = (st_t) pscope->lsym->ecoff_sym.asym.st;
01700 
01701          psym->begin_ptr = pscope->lsym;
01702 
01703          if (begin_type != st_File)
01704            scope_delta = -1;
01705 
01706          /* Except for file, structure, union, or enumeration end
01707             blocks remove all tags created within this scope.  */
01708          if (begin_type != st_File && storage != sc_Info)
01709            {
01710              ptag_head = cur_tag_head;
01711              cur_tag_head = ptag_head->prev;
01712 
01713              for (ptag = ptag_head->first_tag;
01714                  ptag != (tag_t *) NULL;
01715                  ptag = ptag_next)
01716               {
01717                 if (ptag->forward_ref != (forward_t *) NULL)
01718                   add_unknown_tag (ptag);
01719 
01720                 ptag_next = ptag->same_block;
01721                 ptag->hash_ptr->tag_ptr = ptag->same_name;
01722                 free_tag (ptag);
01723               }
01724 
01725              free_thead (ptag_head);
01726            }
01727 
01728          cur_file_ptr->cur_scope = pscope->prev;
01729 
01730          /* block begin gets next sym #.  This is set when we know
01731             the symbol index value.  */
01732 
01733          /* Functions push two or more aux words as follows:
01734             1st word: index+1 of the end symbol (filled in later).
01735             2nd word: type of the function (plus any aux words needed).
01736             Also, tie the external pointer back to the function begin symbol.  */
01737          if (begin_type != st_File && begin_type != st_Block)
01738            {
01739              symint_t ty;
01740              varray_t *svp = &cur_file_ptr->aux_syms;
01741 
01742              pscope->lsym->ecoff_sym.asym.index = add_aux_sym_symint (0);
01743              pscope->lsym->index_ptr =
01744               &svp->last->datum->aux[svp->objects_last_page - 1];
01745              ty = add_aux_sym_tir (&last_func_type_info,
01746                                 hash_no,
01747                                 &cur_file_ptr->thash_head[0]);
01748 
01749 /* This seems to be unnecessary.  I'm not even sure what it is
01750  * intended to do.  It's from mips-tfile.
01751  *           if (last_func_sym_value != (symbolS *) NULL)
01752  *            {
01753  *              last_func_sym_value->ifd = cur_file_ptr->file_index;
01754  *              last_func_sym_value->index = ty;
01755  *            }
01756  */
01757            }
01758 
01759          free_scope (pscope);
01760        }
01761     }
01762 
01763   cur_file_ptr->nested_scopes += scope_delta;
01764 
01765 #ifdef ECOFF_DEBUG
01766   if (debug && type != st_File
01767       && (debug > 2 || type == st_Block || type == st_End
01768          || type == st_Proc || type == st_StaticProc))
01769     {
01770       char *sc_str = sc_to_string (storage);
01771       char *st_str = st_to_string (type);
01772       int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
01773 
01774       fprintf (stderr,
01775               "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
01776               value, depth, sc_str);
01777 
01778       if (str_start && str_end_p1 - str_start > 0)
01779        fprintf (stderr, " st= %-11s name= %.*s\n",
01780                st_str, str_end_p1 - str_start, str_start);
01781       else
01782        {
01783          unsigned long len = strlen (st_str);
01784          fprintf (stderr, " st= %.*s\n", len - 1, st_str);
01785        }
01786     }
01787 #endif
01788 
01789   return psym;
01790 }
01791 
01792 /* Add an auxiliary symbol (passing a symint).  This is actually used
01793    for integral aux types, not just symints.  */
01794 
01795 static symint_t
01796 add_aux_sym_symint (symint_t aux_word /* auxiliary information word */)
01797 {
01798   register varray_t *vp;
01799   register aux_t *aux_ptr;
01800 
01801   if (cur_file_ptr == (efdr_t *) NULL)
01802     as_fatal (_("no current file pointer"));
01803 
01804   vp = &cur_file_ptr->aux_syms;
01805 
01806   if (vp->objects_last_page == vp->objects_per_page)
01807     add_varray_page (vp);
01808 
01809   aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
01810   aux_ptr->type = aux_isym;
01811   aux_ptr->data.isym = aux_word;
01812 
01813   return vp->num_allocated++;
01814 }
01815 
01816 /* Add an auxiliary symbol (passing a file/symbol index combo).  */
01817 
01818 static symint_t
01819 add_aux_sym_rndx (int file_index, symint_t sym_index)
01820 {
01821   register varray_t *vp;
01822   register aux_t *aux_ptr;
01823 
01824   if (cur_file_ptr == (efdr_t *) NULL)
01825     as_fatal (_("no current file pointer"));
01826 
01827   vp = &cur_file_ptr->aux_syms;
01828 
01829   if (vp->objects_last_page == vp->objects_per_page)
01830     add_varray_page (vp);
01831 
01832   aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
01833   aux_ptr->type = aux_rndx;
01834   aux_ptr->data.rndx.rfd   = file_index;
01835   aux_ptr->data.rndx.index = sym_index;
01836 
01837   return vp->num_allocated++;
01838 }
01839 
01840 /* Add an auxiliary symbol (passing the basic type and possibly
01841    type qualifiers).  */
01842 
01843 static symint_t
01844 add_aux_sym_tir (type_info_t *t,   /* current type information */
01845                hash_state_t state, /* whether to hash type or not */
01846                thash_t **hash_tbl  /* pointer to hash table to use */)
01847 {
01848   register varray_t *vp;
01849   register aux_t *aux_ptr;
01850   static AUXU init_aux;
01851   symint_t ret;
01852   int i;
01853   AUXU aux;
01854 
01855   if (cur_file_ptr == (efdr_t *) NULL)
01856     as_fatal (_("no current file pointer"));
01857 
01858   vp = &cur_file_ptr->aux_syms;
01859 
01860   aux = init_aux;
01861   aux.ti.bt = (int) t->basic_type;
01862   aux.ti.continued = 0;
01863   aux.ti.fBitfield = t->bitfield;
01864 
01865   aux.ti.tq0 = (int) t->type_qualifiers[0];
01866   aux.ti.tq1 = (int) t->type_qualifiers[1];
01867   aux.ti.tq2 = (int) t->type_qualifiers[2];
01868   aux.ti.tq3 = (int) t->type_qualifiers[3];
01869   aux.ti.tq4 = (int) t->type_qualifiers[4];
01870   aux.ti.tq5 = (int) t->type_qualifiers[5];
01871 
01872   /* For anything that adds additional information, we must not hash,
01873      so check here, and reset our state.  */
01874 
01875   if (state != hash_no
01876       && (t->type_qualifiers[0] == tq_Array
01877          || t->type_qualifiers[1] == tq_Array
01878          || t->type_qualifiers[2] == tq_Array
01879          || t->type_qualifiers[3] == tq_Array
01880          || t->type_qualifiers[4] == tq_Array
01881          || t->type_qualifiers[5] == tq_Array
01882          || t->basic_type == bt_Struct
01883          || t->basic_type == bt_Union
01884          || t->basic_type == bt_Enum
01885          || t->bitfield
01886          || t->num_dims > 0))
01887     state = hash_no;
01888 
01889   /* See if we can hash this type, and save some space, but some types
01890      can't be hashed (because they contain arrays or continuations),
01891      and others can be put into the hash list, but cannot use existing
01892      types because other aux entries precede this one.  */
01893 
01894   if (state != hash_no)
01895     {
01896       register thash_t *hash_ptr;
01897       register symint_t hi;
01898 
01899       hi = aux.isym & ((1 << HASHBITS) - 1);
01900       hi %= THASH_SIZE;
01901 
01902       for (hash_ptr = hash_tbl[hi];
01903           hash_ptr != (thash_t *)0;
01904           hash_ptr = hash_ptr->next)
01905        {
01906          if (aux.isym == hash_ptr->type.isym)
01907            break;
01908        }
01909 
01910       if (hash_ptr != (thash_t *) NULL && state == hash_yes)
01911        return hash_ptr->indx;
01912 
01913       if (hash_ptr == (thash_t *) NULL)
01914        {
01915          hash_ptr = allocate_thash ();
01916          hash_ptr->next = hash_tbl[hi];
01917          hash_ptr->type = aux;
01918          hash_ptr->indx = vp->num_allocated;
01919          hash_tbl[hi] = hash_ptr;
01920        }
01921     }
01922 
01923   /* Everything is set up, add the aux symbol.  */
01924   if (vp->objects_last_page == vp->objects_per_page)
01925     add_varray_page (vp);
01926 
01927   aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
01928   aux_ptr->type = aux_tir;
01929   aux_ptr->data = aux;
01930 
01931   ret = vp->num_allocated++;
01932 
01933   /* Add bitfield length if it exists.
01934 
01935      NOTE:  Mips documentation claims bitfield goes at the end of the
01936      AUX record, but the DECstation compiler emits it here.
01937      (This would only make a difference for enum bitfields.)
01938 
01939      Also note:  We use the last size given since gcc may emit 2
01940      for an enum bitfield.  */
01941 
01942   if (t->bitfield)
01943     (void) add_aux_sym_symint ((symint_t) t->sizes[t->num_sizes - 1]);
01944 
01945   /* Add tag information if needed.  Structure, union, and enum
01946      references add 2 aux symbols: a [file index, symbol index]
01947      pointer to the structure type, and the current file index.  */
01948 
01949   if (t->basic_type == bt_Struct
01950       || t->basic_type == bt_Union
01951       || t->basic_type == bt_Enum)
01952     {
01953       register symint_t file_index = t->tag_ptr->ifd;
01954       register localsym_t *sym = t->tag_ptr->sym;
01955       register forward_t *forward_ref = allocate_forward ();
01956 
01957       if (sym != (localsym_t *) NULL)
01958        {
01959          forward_ref->next = sym->forward_ref;
01960          sym->forward_ref = forward_ref;
01961        }
01962       else
01963        {
01964          forward_ref->next = t->tag_ptr->forward_ref;
01965          t->tag_ptr->forward_ref = forward_ref;
01966        }
01967 
01968       (void) add_aux_sym_rndx (ST_RFDESCAPE, indexNil);
01969       forward_ref->index_ptr
01970        = &vp->last->datum->aux[vp->objects_last_page - 1];
01971 
01972       (void) add_aux_sym_symint (file_index);
01973       forward_ref->ifd_ptr
01974        = &vp->last->datum->aux[vp->objects_last_page - 1];
01975     }
01976 
01977   /* Add information about array bounds if they exist.  */
01978   for (i = 0; i < t->num_dims; i++)
01979     {
01980       (void) add_aux_sym_rndx (ST_RFDESCAPE,
01981                             cur_file_ptr->int_type);
01982 
01983       (void) add_aux_sym_symint (cur_file_ptr->file_index);    /* file index*/
01984       (void) add_aux_sym_symint ((symint_t) 0);                /* low bound */
01985       (void) add_aux_sym_symint (t->dimensions[i] - 1);        /* high bound*/
01986       (void) add_aux_sym_symint ((t->dimensions[i] == 0)       /* stride */
01987                              ? 0
01988                              : (t->sizes[i] * 8) / t->dimensions[i]);
01989     };
01990 
01991   /* NOTE:  Mips documentation claims that the bitfield width goes here.
01992      But it needs to be emitted earlier.  */
01993 
01994   return ret;
01995 }
01996 
01997 /* Add a tag to the tag table (unless it already exists).  */
01998 
01999 static tag_t *
02000 get_tag (const char *tag,   /* tag name */
02001         localsym_t *sym,    /* tag start block */
02002         bt_t basic_type     /* bt_Struct, bt_Union, or bt_Enum */)
02003 {
02004   shash_t *hash_ptr;
02005   const char *err;
02006   tag_t *tag_ptr;
02007 
02008   if (cur_file_ptr == (efdr_t *) NULL)
02009     as_fatal (_("no current file pointer"));
02010 
02011   hash_ptr = (shash_t *) hash_find (tag_hash, tag);
02012 
02013   if (hash_ptr != (shash_t *) NULL
02014       && hash_ptr->tag_ptr != (tag_t *) NULL)
02015     {
02016       tag_ptr = hash_ptr->tag_ptr;
02017       if (sym != (localsym_t *) NULL)
02018        {
02019          tag_ptr->basic_type = basic_type;
02020          tag_ptr->ifd        = cur_file_ptr->file_index;
02021          tag_ptr->sym        = sym;
02022        }
02023       return tag_ptr;
02024     }
02025 
02026   if (hash_ptr == (shash_t *) NULL)
02027     {
02028       char *perm;
02029 
02030       perm = xstrdup (tag);
02031       hash_ptr = allocate_shash ();
02032       err = hash_insert (tag_hash, perm, (char *) hash_ptr);
02033       if (err)
02034        as_fatal (_("inserting \"%s\" into tag hash table: %s"),
02035                 tag, err);
02036       hash_ptr->string = perm;
02037     }
02038 
02039   tag_ptr = allocate_tag ();
02040   tag_ptr->forward_ref      = (forward_t *) NULL;
02041   tag_ptr->hash_ptr  = hash_ptr;
02042   tag_ptr->same_name = hash_ptr->tag_ptr;
02043   tag_ptr->basic_type       = basic_type;
02044   tag_ptr->sym              = sym;
02045   tag_ptr->ifd              = ((sym == (localsym_t *) NULL)
02046                         ? (symint_t) -1
02047                         : cur_file_ptr->file_index);
02048   tag_ptr->same_block       = cur_tag_head->first_tag;
02049 
02050   cur_tag_head->first_tag = tag_ptr;
02051   hash_ptr->tag_ptr    = tag_ptr;
02052 
02053   return tag_ptr;
02054 }
02055 
02056 /* Add an unknown {struct, union, enum} tag.  */
02057 
02058 static void
02059 add_unknown_tag (tag_t *ptag /* pointer to tag information */)
02060 {
02061   shash_t *hash_ptr  = ptag->hash_ptr;
02062   char *name         = hash_ptr->string;
02063   localsym_t *sym;
02064   forward_t **pf;
02065 
02066 #ifdef ECOFF_DEBUG
02067   if (debug > 1)
02068     {
02069       char *agg_type = "{unknown aggregate type}";
02070       switch (ptag->basic_type)
02071        {
02072        case bt_Struct:      agg_type = "struct"; break;
02073        case bt_Union:       agg_type = "union";  break;
02074        case bt_Enum: agg_type = "enum";   break;
02075        default:                           break;
02076        }
02077 
02078       fprintf (stderr, "unknown %s %.*s found\n", agg_type,
02079               hash_ptr->len, name_start);
02080     }
02081 #endif
02082 
02083   sym = add_ecoff_symbol (name,
02084                        st_Block,
02085                        sc_Info,
02086                        (symbolS *) NULL,
02087                        (bfd_vma) 0,
02088                        (symint_t) 0,
02089                        (symint_t) 0);
02090 
02091   (void) add_ecoff_symbol (name,
02092                         st_End,
02093                         sc_Info,
02094                         (symbolS *) NULL,
02095                         (bfd_vma) 0,
02096                         (symint_t) 0,
02097                         (symint_t) 0);
02098 
02099   for (pf = &sym->forward_ref; *pf != (forward_t *) NULL; pf = &(*pf)->next)
02100     ;
02101   *pf = ptag->forward_ref;
02102 }
02103 
02104 /* Add a procedure to the current file's list of procedures, and record
02105    this is the current procedure.  */
02106 
02107 static void
02108 add_procedure (char *func /* func name */)
02109 {
02110   register varray_t *vp;
02111   register proc_t *new_proc_ptr;
02112   symbolS *sym;
02113 
02114 #ifdef ECOFF_DEBUG
02115   if (debug)
02116     fputc ('\n', stderr);
02117 #endif
02118 
02119   if (cur_file_ptr == (efdr_t *) NULL)
02120     as_fatal (_("no current file pointer"));
02121 
02122   vp = &cur_file_ptr->procs;
02123 
02124   if (vp->objects_last_page == vp->objects_per_page)
02125     add_varray_page (vp);
02126 
02127   cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[vp->objects_last_page++];
02128 
02129   if (first_proc_ptr == (proc_t *) NULL)
02130     first_proc_ptr = new_proc_ptr;
02131 
02132   vp->num_allocated++;
02133 
02134   new_proc_ptr->pdr.isym = -1;
02135   new_proc_ptr->pdr.iline = -1;
02136   new_proc_ptr->pdr.lnLow = -1;
02137   new_proc_ptr->pdr.lnHigh = -1;
02138 
02139   /* Set the BSF_FUNCTION flag for the symbol.  */
02140   sym = symbol_find_or_make (func);
02141   symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
02142 
02143   /* Push the start of the function.  */
02144   new_proc_ptr->sym = add_ecoff_symbol ((const char *) NULL, st_Proc, sc_Text,
02145                                    sym, (bfd_vma) 0, (symint_t) 0,
02146                                    (symint_t) 0);
02147 
02148   ++proc_cnt;
02149 
02150   /* Fill in the linenos preceding the .ent, if any.  */
02151   if (noproc_lineno != (lineno_list_t *) NULL)
02152     {
02153       lineno_list_t *l;
02154 
02155       for (l = noproc_lineno; l != (lineno_list_t *) NULL; l = l->next)
02156        l->proc = new_proc_ptr;
02157       *last_lineno_ptr = noproc_lineno;
02158       while (*last_lineno_ptr != NULL)
02159        {
02160          last_lineno = *last_lineno_ptr;
02161          last_lineno_ptr = &last_lineno->next;
02162        }
02163       noproc_lineno = (lineno_list_t *) NULL;
02164     }
02165 }
02166 
02167 symbolS *
02168 ecoff_get_cur_proc_sym (void)
02169 {
02170   return (cur_proc_ptr ? cur_proc_ptr->sym->as_sym : NULL);
02171 }
02172 
02173 /* Add a new filename, and set up all of the file relative
02174    virtual arrays (strings, symbols, aux syms, etc.).  Record
02175    where the current file structure lives.  */
02176 
02177 static void
02178 add_file (const char *file_name, int indx ATTRIBUTE_UNUSED, int fake)
02179 {
02180   register int first_ch;
02181   register efdr_t *fil_ptr;
02182 
02183 #ifdef ECOFF_DEBUG
02184   if (debug)
02185     fprintf (stderr, "\tfile\t%.*s\n", len, file_start);
02186 #endif
02187 
02188   /* If the file name is NULL, then no .file symbol appeared, and we
02189      want to use the actual file name.  */
02190   if (file_name == (const char *) NULL)
02191     {
02192       char *file;
02193 
02194       if (first_file != (efdr_t *) NULL)
02195        as_fatal (_("fake .file after real one"));
02196       as_where (&file, (unsigned int *) NULL);
02197       file_name = (const char *) file;
02198 
02199       /* Automatically generate ECOFF debugging information, since I
02200          think that's what other ECOFF assemblers do.  We don't do
02201          this if we see a .file directive with a string, since that
02202          implies that some sort of debugging information is being
02203          provided.  */
02204       if (! symbol_table_frozen && debug_type == DEBUG_UNSPECIFIED)
02205        debug_type = DEBUG_ECOFF;
02206     }
02207   else if (debug_type == DEBUG_UNSPECIFIED)
02208     debug_type = DEBUG_NONE;
02209 
02210 #ifndef NO_LISTING
02211   if (listing)
02212     listing_source_file (file_name);
02213 #endif
02214 
02215   current_stabs_filename = file_name;
02216 
02217   /* If we're creating stabs, then we don't actually make a new FDR.
02218      Instead, we just create a stabs symbol.  */
02219   if (stabs_seen)
02220     {
02221       (void) add_ecoff_symbol (file_name, st_Nil, sc_Nil,
02222                             symbol_new ("L0\001", now_seg,
02223                                       (valueT) frag_now_fix (),
02224                                       frag_now),
02225                             (bfd_vma) 0, 0, ECOFF_MARK_STAB (N_SOL));
02226       return;
02227     }
02228 
02229   first_ch = *file_name;
02230 
02231   /* FIXME: We can't safely merge files which have line number
02232      information (fMerge will be zero in this case).  Otherwise, we
02233      get incorrect line number debugging info.  See for instance
02234      ecoff_build_lineno, which will end up setting all file->fdr.*
02235      fields multiple times, resulting in incorrect debug info.  In
02236      order to make this work right, all line number and symbol info
02237      for the same source file has to be adjacent in the object file,
02238      so that a single file descriptor can be used to point to them.
02239      This would require maintaining file specific lists of line
02240      numbers and symbols for each file, so that they can be merged
02241      together (or output together) when two .file pseudo-ops are
02242      merged into one file descriptor.  */
02243 
02244   /* See if the file has already been created.  */
02245   for (fil_ptr = first_file;
02246        fil_ptr != (efdr_t *) NULL;
02247        fil_ptr = fil_ptr->next_file)
02248     {
02249       if (first_ch == fil_ptr->name[0]
02250          && strcmp (file_name, fil_ptr->name) == 0
02251          && fil_ptr->fdr.fMerge)
02252        {
02253          cur_file_ptr = fil_ptr;
02254          if (! fake)
02255            cur_file_ptr->fake = 0;
02256          break;
02257        }
02258     }
02259 
02260   /* If this is a new file, create it.  */
02261   if (fil_ptr == (efdr_t *) NULL)
02262     {
02263       if (file_desc.objects_last_page == file_desc.objects_per_page)
02264        add_varray_page (&file_desc);
02265 
02266       fil_ptr = cur_file_ptr =
02267        &file_desc.last->datum->file[file_desc.objects_last_page++];
02268       *fil_ptr = init_file;
02269 
02270       fil_ptr->file_index = current_file_idx++;
02271       ++file_desc.num_allocated;
02272 
02273       fil_ptr->fake = fake;
02274 
02275       /* Allocate the string hash table.  */
02276       fil_ptr->str_hash = hash_new ();
02277 
02278       /* Make sure 0 byte in string table is null  */
02279       add_string (&fil_ptr->strings,
02280                 fil_ptr->str_hash,
02281                 "",
02282                 (shash_t **)0);
02283 
02284       if (strlen (file_name) > PAGE_USIZE - 2)
02285        as_fatal (_("filename goes over one page boundary"));
02286 
02287       /* Push the start of the filename. We assume that the filename
02288          will be stored at string offset 1.  */
02289       (void) add_ecoff_symbol (file_name, st_File, sc_Text,
02290                             (symbolS *) NULL, (bfd_vma) 0,
02291                             (symint_t) 0, (symint_t) 0);
02292       fil_ptr->fdr.rss = 1;
02293       fil_ptr->name = &fil_ptr->strings.last->datum->byte[1];
02294 
02295       /* Update the linked list of file descriptors.  */
02296       *last_file_ptr = fil_ptr;
02297       last_file_ptr = &fil_ptr->next_file;
02298 
02299       /* Add void & int types to the file (void should be first to catch
02300          errant 0's within the index fields).  */
02301       fil_ptr->void_type = add_aux_sym_tir (&void_type_info,
02302                                        hash_yes,
02303                                        &cur_file_ptr->thash_head[0]);
02304 
02305       fil_ptr->int_type = add_aux_sym_tir (&int_type_info,
02306                                       hash_yes,
02307                                       &cur_file_ptr->thash_head[0]);
02308     }
02309 }
02310 
02311 /* This function is called when the assembler notices a preprocessor
02312    directive switching to a new file.  This will not happen in
02313    compiler output, only in hand coded assembler.  */
02314 
02315 void
02316 ecoff_new_file (const char *name, int appfile ATTRIBUTE_UNUSED)
02317 {
02318   if (cur_file_ptr != NULL && strcmp (cur_file_ptr->name, name) == 0)
02319     return;
02320   add_file (name, 0, 0);
02321 
02322   /* This is a hand coded assembler file, so automatically turn on
02323      debugging information.  */
02324   if (debug_type == DEBUG_UNSPECIFIED)
02325     debug_type = DEBUG_ECOFF;
02326 }
02327 
02328 #ifdef ECOFF_DEBUG
02329 
02330 /* Convert storage class to string.  */
02331 
02332 static char *
02333 sc_to_string (storage_class)
02334      sc_t storage_class;
02335 {
02336   switch (storage_class)
02337     {
02338     case sc_Nil:      return "Nil,";
02339     case sc_Text:     return "Text,";
02340     case sc_Data:     return "Data,";
02341     case sc_Bss:      return "Bss,";
02342     case sc_Register:        return "Register,";
02343     case sc_Abs:      return "Abs,";
02344     case sc_Undefined:       return "Undefined,";
02345     case sc_CdbLocal:        return "CdbLocal,";
02346     case sc_Bits:     return "Bits,";
02347     case sc_CdbSystem:       return "CdbSystem,";
02348     case sc_RegImage:        return "RegImage,";
02349     case sc_Info:     return "Info,";
02350     case sc_UserStruct:      return "UserStruct,";
02351     case sc_SData:    return "SData,";
02352     case sc_SBss:     return "SBss,";
02353     case sc_RData:    return "RData,";
02354     case sc_Var:      return "Var,";
02355     case sc_Common:   return "Common,";
02356     case sc_SCommon:  return "SCommon,";
02357     case sc_VarRegister: return "VarRegister,";
02358     case sc_Variant:  return "Variant,";
02359     case sc_SUndefined:      return "SUndefined,";
02360     case sc_Init:     return "Init,";
02361     case sc_Max:      return "Max,";
02362     }
02363 
02364   return "???,";
02365 }
02366 
02367 #endif /* DEBUG */
02368 
02369 #ifdef ECOFF_DEBUG
02370 
02371 /* Convert symbol type to string.  */
02372 
02373 static char *
02374 st_to_string (symbol_type)
02375      st_t symbol_type;
02376 {
02377   switch (symbol_type)
02378     {
02379     case st_Nil:     return "Nil,";
02380     case st_Global:  return "Global,";
02381     case st_Static:  return "Static,";
02382     case st_Param:   return "Param,";
02383     case st_Local:   return "Local,";
02384     case st_Label:   return "Label,";
02385     case st_Proc:    return "Proc,";
02386     case st_Block:   return "Block,";
02387     case st_End:     return "End,";
02388     case st_Member:  return "Member,";
02389     case st_Typedef: return "Typedef,";
02390     case st_File:    return "File,";
02391     case st_RegReloc:       return "RegReloc,";
02392     case st_Forward: return "Forward,";
02393     case st_StaticProc:     return "StaticProc,";
02394     case st_Constant:       return "Constant,";
02395     case st_Str:     return "String,";
02396     case st_Number:  return "Number,";
02397     case st_Expr:    return "Expr,";
02398     case st_Type:    return "Type,";
02399     case st_Max:     return "Max,";
02400     }
02401 
02402   return "???,";
02403 }
02404 
02405 #endif /* DEBUG */
02406 
02407 /* Parse .begin directives which have a label as the first argument
02408    which gives the location of the start of the block.  */
02409 
02410 void
02411 ecoff_directive_begin (int ignore ATTRIBUTE_UNUSED)
02412 {
02413   char *name;
02414   char name_end;
02415 
02416   if (cur_file_ptr == (efdr_t *) NULL)
02417     {
02418       as_warn (_(".begin directive without a preceding .file directive"));
02419       demand_empty_rest_of_line ();
02420       return;
02421     }
02422 
02423   if (cur_proc_ptr == (proc_t *) NULL)
02424     {
02425       as_warn (_(".begin directive without a preceding .ent directive"));
02426       demand_empty_rest_of_line ();
02427       return;
02428     }
02429 
02430   name = input_line_pointer;
02431   name_end = get_symbol_end ();
02432 
02433   (void) add_ecoff_symbol ((const char *) NULL, st_Block, sc_Text,
02434                         symbol_find_or_make (name),
02435                         (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
02436 
02437   *input_line_pointer = name_end;
02438 
02439   /* The line number follows, but we don't use it.  */
02440   (void) get_absolute_expression ();
02441   demand_empty_rest_of_line ();
02442 }
02443 
02444 /* Parse .bend directives which have a label as the first argument
02445    which gives the location of the end of the block.  */
02446 
02447 void
02448 ecoff_directive_bend (int ignore ATTRIBUTE_UNUSED)
02449 {
02450   char *name;
02451   char name_end;
02452   symbolS *endsym;
02453 
02454   if (cur_file_ptr == (efdr_t *) NULL)
02455     {
02456       as_warn (_(".bend directive without a preceding .file directive"));
02457       demand_empty_rest_of_line ();
02458       return;
02459     }
02460 
02461   if (cur_proc_ptr == (proc_t *) NULL)
02462     {
02463       as_warn (_(".bend directive without a preceding .ent directive"));
02464       demand_empty_rest_of_line ();
02465       return;
02466     }
02467 
02468   name = input_line_pointer;
02469   name_end = get_symbol_end ();
02470 
02471   /* The value is the distance between the .bend directive and the
02472      corresponding symbol.  We fill in the offset when we write out
02473      the symbol.  */
02474   endsym = symbol_find (name);
02475   if (endsym == (symbolS *) NULL)
02476     as_warn (_(".bend directive names unknown symbol"));
02477   else
02478     (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym,
02479                           (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
02480 
02481   *input_line_pointer = name_end;
02482 
02483   /* The line number follows, but we don't use it.  */
02484   (void) get_absolute_expression ();
02485   demand_empty_rest_of_line ();
02486 }
02487 
02488 /* COFF debugging information is provided as a series of directives
02489    (.def, .scl, etc.).  We build up information as we read the
02490    directives in the following static variables, and file it away when
02491    we reach the .endef directive.  */
02492 static char *coff_sym_name;
02493 static type_info_t coff_type;
02494 static sc_t coff_storage_class;
02495 static st_t coff_symbol_typ;
02496 static int coff_is_function;
02497 static char *coff_tag;
02498 static valueT coff_value;
02499 static symbolS *coff_sym_value;
02500 static bfd_vma coff_sym_addend;
02501 static int coff_inside_enumeration;
02502 
02503 /* Handle a .def directive: start defining a symbol.  */
02504 
02505 void
02506 ecoff_directive_def (int ignore ATTRIBUTE_UNUSED)
02507 {
02508   char *name;
02509   char name_end;
02510 
02511   ecoff_debugging_seen = 1;
02512 
02513   SKIP_WHITESPACE ();
02514 
02515   name = input_line_pointer;
02516   name_end = get_symbol_end ();
02517 
02518   if (coff_sym_name != (char *) NULL)
02519     as_warn (_(".def pseudo-op used inside of .def/.endef; ignored"));
02520   else if (*name == '\0')
02521     as_warn (_("empty symbol name in .def; ignored"));
02522   else
02523     {
02524       if (coff_sym_name != (char *) NULL)
02525        free (coff_sym_name);
02526       if (coff_tag != (char *) NULL)
02527        free (coff_tag);
02528       
02529       coff_sym_name = xstrdup (name);
02530       coff_type = type_info_init;
02531       coff_storage_class = sc_Nil;
02532       coff_symbol_typ = st_Nil;
02533       coff_is_function = 0;
02534       coff_tag = (char *) NULL;
02535       coff_value = 0;
02536       coff_sym_value = (symbolS *) NULL;
02537       coff_sym_addend = 0;
02538     }
02539 
02540   *input_line_pointer = name_end;
02541 
02542   demand_empty_rest_of_line ();
02543 }
02544 
02545 /* Handle a .dim directive, used to give dimensions for an array.  The
02546    arguments are comma separated numbers.  mips-tfile assumes that
02547    there will not be more than 6 dimensions, and gdb won't read any
02548    more than that anyhow, so I will also make that assumption.  */
02549 
02550 void
02551 ecoff_directive_dim (int ignore ATTRIBUTE_UNUSED)
02552 {
02553   int dimens[N_TQ];
02554   int i;
02555 
02556   if (coff_sym_name == (char *) NULL)
02557     {
02558       as_warn (_(".dim pseudo-op used outside of .def/.endef; ignored"));
02559       demand_empty_rest_of_line ();
02560       return;
02561     }
02562 
02563   for (i = 0; i < N_TQ; i++)
02564     {
02565       SKIP_WHITESPACE ();
02566       dimens[i] = get_absolute_expression ();
02567       if (*input_line_pointer == ',')
02568        ++input_line_pointer;
02569       else
02570        {
02571          if (*input_line_pointer != '\n'
02572              && *input_line_pointer != ';')
02573            as_warn (_("badly formed .dim directive"));
02574          break;
02575        }
02576     }
02577 
02578   if (i == N_TQ)
02579     --i;
02580 
02581   /* The dimensions are stored away in reverse order.  */
02582   for (; i >= 0; i--)
02583     {
02584       if (coff_type.num_dims >= N_TQ)
02585        {
02586          as_warn (_("too many .dim entries"));
02587          break;
02588        }
02589       coff_type.dimensions[coff_type.num_dims] = dimens[i];
02590       ++coff_type.num_dims;
02591     }
02592 
02593   demand_empty_rest_of_line ();
02594 }
02595 
02596 /* Handle a .scl directive, which sets the COFF storage class of the
02597    symbol.  */
02598 
02599 void
02600 ecoff_directive_scl (int ignore ATTRIBUTE_UNUSED)
02601 {
02602   long val;
02603 
02604   if (coff_sym_name == (char *) NULL)
02605     {
02606       as_warn (_(".scl pseudo-op used outside of .def/.endef; ignored"));
02607       demand_empty_rest_of_line ();
02608       return;
02609     }
02610 
02611   val = get_absolute_expression ();
02612 
02613   coff_symbol_typ = map_coff_sym_type[val];
02614   coff_storage_class = map_coff_storage[val];
02615 
02616   demand_empty_rest_of_line ();
02617 }
02618 
02619 /* Handle a .size directive.  For some reason mips-tfile.c thinks that
02620    .size can have multiple arguments.  We humor it, although gcc will
02621    never generate more than one argument.  */
02622 
02623 void
02624 ecoff_directive_size (int ignore ATTRIBUTE_UNUSED)
02625 {
02626   int sizes[N_TQ];
02627   int i;
02628 
02629   if (coff_sym_name == (char *) NULL)
02630     {
02631       as_warn (_(".size pseudo-op used outside of .def/.endef; ignored"));
02632       demand_empty_rest_of_line ();
02633       return;
02634     }
02635 
02636   for (i = 0; i < N_TQ; i++)
02637     {
02638       SKIP_WHITESPACE ();
02639       sizes[i] = get_absolute_expression ();
02640       if (*input_line_pointer == ',')
02641        ++input_line_pointer;
02642       else
02643        {
02644          if (*input_line_pointer != '\n'
02645              && *input_line_pointer != ';')
02646            as_warn (_("badly formed .size directive"));
02647          break;
02648        }
02649     }
02650 
02651   if (i == N_TQ)
02652     --i;
02653 
02654   /* The sizes are stored away in reverse order.  */
02655   for (; i >= 0; i--)
02656     {
02657       if (coff_type.num_sizes >= N_TQ)
02658        {
02659          as_warn (_("too many .size entries"));
02660          break;
02661        }
02662       coff_type.sizes[coff_type.num_sizes] = sizes[i];
02663       ++coff_type.num_sizes;
02664     }
02665 
02666   demand_empty_rest_of_line ();
02667 }
02668 
02669 /* Handle the .type directive, which gives the COFF type of the
02670    symbol.  */
02671 
02672 void
02673 ecoff_directive_type (int ignore ATTRIBUTE_UNUSED)
02674 {
02675   long val;
02676   tq_t *tq_ptr;
02677   tq_t *tq_shft;
02678 
02679   if (coff_sym_name == (char *) NULL)
02680     {
02681       as_warn (_(".type pseudo-op used outside of .def/.endef; ignored"));
02682       demand_empty_rest_of_line ();
02683       return;
02684     }
02685 
02686   val = get_absolute_expression ();
02687 
02688   coff_type.orig_type = BTYPE (val);
02689   coff_type.basic_type = map_coff_types[coff_type.orig_type];
02690 
02691   tq_ptr = &coff_type.type_qualifiers[N_TQ];
02692   while (val & ~N_BTMASK)
02693     {
02694       if (tq_ptr == &coff_type.type_qualifiers[0])
02695        {
02696          /* FIXME: We could handle this by setting the continued bit.
02697             There would still be a limit: the .type argument can not
02698             be infinite.  */
02699          as_warn (_("the type of %s is too complex; it will be simplified"),
02700                  coff_sym_name);
02701          break;
02702        }
02703       if (ISPTR (val))
02704        *--tq_ptr = tq_Ptr;
02705       else if (ISFCN (val))
02706        *--tq_ptr = tq_Proc;
02707       else if (ISARY (val))
02708        *--tq_ptr = tq_Array;
02709       else
02710        as_fatal (_("Unrecognized .type argument"));
02711 
02712       val = DECREF (val);
02713     }
02714 
02715   tq_shft = &coff_type.type_qualifiers[0];
02716   while (tq_ptr != &coff_type.type_qualifiers[N_TQ])
02717     *tq_shft++ = *tq_ptr++;
02718 
02719   if (tq_shft != &coff_type.type_qualifiers[0] && tq_shft[-1] == tq_Proc)
02720     {
02721       /* If this is a function, ignore it, so that we don't get two
02722          entries (one from the .ent, and one for the .def that
02723          precedes it).  Save the type information so that the end
02724          block can properly add it after the begin block index.  For
02725          MIPS knows what reason, we must strip off the function type
02726          at this point.  */
02727       coff_is_function = 1;
02728       tq_shft[-1] = tq_Nil;
02729     }
02730 
02731   while (tq_shft != &coff_type.type_qualifiers[N_TQ])
02732     *tq_shft++ = tq_Nil;
02733 
02734   demand_empty_rest_of_line ();
02735 }
02736 
02737 /* Handle the .tag directive, which gives the name of a structure,
02738    union or enum.  */
02739 
02740 void
02741 ecoff_directive_tag (int ignore ATTRIBUTE_UNUSED)
02742 {
02743   char *name;
02744   char name_end;
02745 
02746   if (coff_sym_name == (char *) NULL)
02747     {
02748       as_warn (_(".tag pseudo-op used outside of .def/.endef; ignored"));
02749       demand_empty_rest_of_line ();
02750       return;
02751     }
02752 
02753   name = input_line_pointer;
02754   name_end = get_symbol_end ();
02755 
02756   coff_tag = xstrdup (name);
02757 
02758   *input_line_pointer = name_end;
02759 
02760   demand_empty_rest_of_line ();
02761 }
02762 
02763 /* Handle the .val directive, which gives the value of the symbol.  It
02764    may be the name of a static or global symbol.  */
02765 
02766 void
02767 ecoff_directive_val (int ignore ATTRIBUTE_UNUSED)
02768 {
02769   expressionS exp;
02770 
02771   if (coff_sym_name == (char *) NULL)
02772     {
02773       as_warn (_(".val pseudo-op used outside of .def/.endef; ignored"));
02774       demand_empty_rest_of_line ();
02775       return;
02776     }
02777 
02778   expression (&exp);
02779   if (exp.X_op != O_constant && exp.X_op != O_symbol)
02780     {
02781       as_bad (_(".val expression is too complex"));
02782       demand_empty_rest_of_line ();
02783       return;
02784     }
02785 
02786   if (exp.X_op == O_constant)
02787     coff_value = exp.X_add_number;
02788   else
02789     {
02790       coff_sym_value = exp.X_add_symbol;
02791       coff_sym_addend = exp.X_add_number;
02792     }
02793 
02794   demand_empty_rest_of_line ();
02795 }
02796 
02797 /* Handle the .endef directive, which terminates processing of COFF
02798    debugging information for a symbol.  */
02799 
02800 void
02801 ecoff_directive_endef (int ignore ATTRIBUTE_UNUSED)
02802 {
02803   char *name;
02804   symint_t indx;
02805   localsym_t *sym;
02806 
02807   demand_empty_rest_of_line ();
02808 
02809   if (coff_sym_name == (char *) NULL)
02810     {
02811       as_warn (_(".endef pseudo-op used before .def; ignored"));
02812       return;
02813     }
02814 
02815   name = coff_sym_name;
02816   coff_sym_name = (char *) NULL;
02817 
02818   /* If the symbol is a static or external, we have already gotten the
02819      appropriate type and class, so make sure we don't override those
02820      values.  This is needed because there are some type and classes
02821      that are not in COFF, such as short data, etc.  */
02822   if (coff_sym_value != (symbolS *) NULL)
02823     {
02824       coff_symbol_typ = st_Nil;
02825       coff_storage_class = sc_Nil;
02826     }
02827 
02828   coff_type.extra_sizes = coff_tag != (char *) NULL;
02829   if (coff_type.num_dims > 0)
02830     {
02831       int diff = coff_type.num_dims - coff_type.num_sizes;
02832       int i = coff_type.num_dims - 1;
02833       int j;
02834 
02835       if (coff_type.num_sizes != 1 || diff < 0)
02836        {
02837          as_warn (_("bad COFF debugging information"));
02838          return;
02839        }
02840 
02841       /* If this is an array, make sure the same number of dimensions
02842          and sizes were passed, creating extra sizes for multiply
02843          dimensioned arrays if not passed.  */
02844       coff_type.extra_sizes = 0;
02845       if (diff)
02846        {
02847          j = (sizeof (coff_type.sizes) / sizeof (coff_type.sizes[0])) - 1;
02848          while (j >= 0)
02849            {
02850              coff_type.sizes[j] = (((j - diff) >= 0)
02851                                 ? coff_type.sizes[j - diff]
02852                                 : 0);
02853              j--;
02854            }
02855 
02856          coff_type.num_sizes = i + 1;
02857          for (i--; i >= 0; i--)
02858            coff_type.sizes[i] = (coff_type.dimensions[i + 1] == 0
02859                               ? 0
02860                               : (coff_type.sizes[i + 1]
02861                                  / coff_type.dimensions[i + 1]));
02862        }
02863     }
02864   else if (coff_symbol_typ == st_Member
02865           && coff_type.num_sizes - coff_type.extra_sizes == 1)
02866     {
02867       /* Is this a bitfield?  This is indicated by a structure member
02868          having a size field that isn't an array.  */
02869       coff_type.bitfield = 1;
02870     }
02871 
02872   /* Except for enumeration members & begin/ending of scopes, put the
02873      type word in the aux. symbol table.  */
02874   if (coff_symbol_typ == st_Block || coff_symbol_typ == st_End)
02875     indx = 0;
02876   else if (coff_inside_enumeration)
02877     indx = cur_file_ptr->void_type;
02878   else
02879     {
02880       if (coff_type.basic_type == bt_Struct
02881          || coff_type.basic_type == bt_Union
02882          || coff_type.basic_type == bt_Enum)
02883        {
02884          if (coff_tag == (char *) NULL)
02885            {
02886              as_warn (_("no tag specified for %s"), name);
02887              return;
02888            }
02889 
02890          coff_type.tag_ptr = get_tag (coff_tag, (localsym_t *) NULL,
02891                                    coff_type.basic_type);
02892        }
02893 
02894       if (coff_is_function)
02895        {
02896          last_func_type_info = coff_type;
02897          last_func_sym_value = coff_sym_value;
02898          return;
02899        }
02900 
02901       indx = add_aux_sym_tir (&coff_type,
02902                            hash_yes,
02903                            &cur_file_ptr->thash_head[0]);
02904     }
02905 
02906   /* Do any last minute adjustments that are necessary.  */
02907   switch (coff_symbol_typ)
02908     {
02909     default:
02910       break;
02911 
02912       /* For the beginning of structs, unions, and enumerations, the
02913          size info needs to be passed in the value field.  */
02914     case st_Block:
02915       if (coff_type.num_sizes - coff_type.num_dims - coff_type.extra_sizes
02916          != 1)
02917        {
02918          as_warn (_("bad COFF debugging information"));
02919          return;
02920        }
02921       else
02922        coff_value = coff_type.sizes[0];
02923 
02924       coff_inside_enumeration = (coff_type.orig_type == T_ENUM);
02925       break;
02926 
02927       /* For the end of structs, unions, and enumerations, omit the
02928          name which is always ".eos".  This needs to be done last, so
02929          that any error reporting above gives the correct name.  */
02930     case st_End:
02931       free (name);
02932       name = (char *) NULL;
02933       coff_value = 0;
02934       coff_inside_enumeration = 0;
02935       break;
02936 
02937       /* Members of structures and unions that aren't bitfields, need
02938          to adjust the value from a byte offset to a bit offset.
02939          Members of enumerations do not have the value adjusted, and
02940          can be distinguished by indx == indexNil.  For enumerations,
02941          update the maximum enumeration value.  */
02942     case st_Member:
02943       if (! coff_type.bitfield && ! coff_inside_enumeration)
02944        coff_value *= 8;
02945 
02946       break;
02947     }
02948 
02949   /* Add the symbol.  */
02950   sym = add_ecoff_symbol (name,
02951                        coff_symbol_typ,
02952                        coff_storage_class,
02953                        coff_sym_value,
02954                        coff_sym_addend,
02955                        (symint_t) coff_value,
02956                        indx);
02957 
02958   /* deal with struct, union, and enum tags.  */
02959   if (coff_symbol_typ == st_Block)
02960     {
02961       /* Create or update the tag information.  */
02962       tag_t *tag_ptr = get_tag (name,
02963                             sym,
02964                             coff_type.basic_type);
02965       forward_t **pf;
02966 
02967       /* Remember any forward references.  */
02968       for (pf = &sym->forward_ref;
02969           *pf != (forward_t *) NULL;
02970           pf = &(*pf)->next)
02971        ;
02972       *pf = tag_ptr->forward_ref;
02973       tag_ptr->forward_ref = (forward_t *) NULL;
02974     }
02975 }
02976 
02977 /* Parse .end directives.  */
02978 
02979 void
02980 ecoff_directive_end (int ignore ATTRIBUTE_UNUSED)
02981 {
02982   char *name;
02983   char name_end;
02984   symbolS *ent;
02985 
02986   if (cur_file_ptr == (efdr_t *) NULL)
02987     {
02988       as_warn (_(".end directive without a preceding .file directive"));
02989       demand_empty_rest_of_line ();
02990       return;
02991     }
02992 
02993   if (cur_proc_ptr == (proc_t *) NULL)
02994     {
02995       as_warn (_(".end directive without a preceding .ent directive"));
02996       demand_empty_rest_of_line ();
02997       return;
02998     }
02999 
03000   name = input_line_pointer;
03001   name_end = get_symbol_end ();
03002 
03003   if (name == input_line_pointer)
03004     {
03005       as_warn (_(".end directive has no name"));
03006       *input_line_pointer = name_end;
03007       demand_empty_rest_of_line ();
03008       return;
03009     }
03010 
03011   /* The value is the distance between the .end directive and the
03012      corresponding symbol.  We create a fake symbol to hold the
03013      current location, and put in the offset when we write out the
03014      symbol.  */
03015   ent = symbol_find (name);
03016   if (ent == (symbolS *) NULL)
03017     as_warn (_(".end directive names unknown symbol"));
03018   else
03019     (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text,
03020                           symbol_new ("L0\001", now_seg,
03021                                     (valueT) frag_now_fix (),
03022                                     frag_now),
03023                           (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
03024 
03025   cur_proc_ptr = (proc_t *) NULL;
03026 
03027   *input_line_pointer = name_end;
03028   demand_empty_rest_of_line ();
03029 }
03030 
03031 /* Parse .ent directives.  */
03032 
03033 void
03034 ecoff_directive_ent (int ignore ATTRIBUTE_UNUSED)
03035 {
03036   char *name;
03037   char name_end;
03038 
03039   if (cur_file_ptr == (efdr_t *) NULL)
03040     add_file ((const char *) NULL, 0, 1);
03041 
03042   if (cur_proc_ptr != (proc_t *) NULL)
03043     {
03044       as_warn (_("second .ent directive found before .end directive"));
03045       demand_empty_rest_of_line ();
03046       return;
03047     }
03048 
03049   name = input_line_pointer;
03050   name_end = get_symbol_end ();
03051 
03052   if (name == input_line_pointer)
03053     {
03054       as_warn (_(".ent directive has no name"));
03055       *input_line_pointer = name_end;
03056       demand_empty_rest_of_line ();
03057       return;
03058     }
03059 
03060   add_procedure (name);
03061 
03062   *input_line_pointer = name_end;
03063 
03064   /* The .ent directive is sometimes followed by a number.  I'm not
03065      really sure what the number means.  I don't see any way to store
03066      the information in the PDR.  The Irix 4 assembler seems to ignore
03067      the information.  */
03068   SKIP_WHITESPACE ();
03069   if (*input_line_pointer == ',')
03070     {
03071       ++input_line_pointer;
03072       SKIP_WHITESPACE ();
03073     }
03074   if (ISDIGIT (*input_line_pointer)
03075       || *input_line_pointer == '-')
03076     (void) get_absolute_expression ();
03077 
03078   demand_empty_rest_of_line ();
03079 }
03080 
03081 /* Parse .extern directives.  */
03082 
03083 void
03084 ecoff_directive_extern (int ignore ATTRIBUTE_UNUSED)
03085 {
03086   char *name;
03087   int c;
03088   symbolS *symbolp;
03089   valueT size;
03090 
03091   name = input_line_pointer;
03092   c = get_symbol_end ();
03093   symbolp = symbol_find_or_make (name);
03094   *input_line_pointer = c;
03095 
03096   S_SET_EXTERNAL (symbolp);
03097 
03098   if (*input_line_pointer == ',')
03099     ++input_line_pointer;
03100   size = get_absolute_expression ();
03101 
03102   symbol_get_obj (symbolp)->ecoff_extern_size = size;
03103 }
03104 
03105 /* Parse .file directives.  */
03106 
03107 void
03108 ecoff_directive_file (int ignore ATTRIBUTE_UNUSED)
03109 {
03110   int indx;
03111   char *name;
03112   int len;
03113 
03114   if (cur_proc_ptr != (proc_t *) NULL)
03115     {
03116       as_warn (_("no way to handle .file within .ent/.end section"));
03117       demand_empty_rest_of_line ();
03118       return;
03119     }
03120 
03121   indx = (int) get_absolute_expression ();
03122 
03123   /* FIXME: we don't have to save the name here.  */
03124   name = demand_copy_C_string (&len);
03125 
03126   add_file (name, indx - 1, 0);
03127 
03128   demand_empty_rest_of_line ();
03129 }
03130 
03131 /* Parse .fmask directives.  */
03132 
03133 void
03134 ecoff_directive_fmask (int ignore ATTRIBUTE_UNUSED)
03135 {
03136   long val;
03137 
03138   if (cur_proc_ptr == (proc_t *) NULL)
03139     {
03140       as_warn (_(".fmask outside of .ent"));
03141       demand_empty_rest_of_line ();
03142       return;
03143     }
03144 
03145   if (get_absolute_expression_and_terminator (&val) != ',')
03146     {
03147       as_warn (_("bad .fmask directive"));
03148       --input_line_pointer;
03149       demand_empty_rest_of_line ();
03150       return;
03151     }
03152 
03153   cur_proc_ptr->pdr.fregmask = val;
03154   cur_proc_ptr->pdr.fregoffset = get_absolute_expression ();
03155 
03156   demand_empty_rest_of_line ();
03157 }
03158 
03159 /* Parse .frame directives.  */
03160 
03161 void
03162 ecoff_directive_frame (int ignore ATTRIBUTE_UNUSED)
03163 {
03164   long val;
03165 
03166   if (cur_proc_ptr == (proc_t *) NULL)
03167     {
03168       as_warn (_(".frame outside of .ent"));
03169       demand_empty_rest_of_line ();
03170       return;
03171     }
03172 
03173   cur_proc_ptr->pdr.framereg = tc_get_register (1);
03174 
03175   SKIP_WHITESPACE ();
03176   if (*input_line_pointer++ != ','
03177       || get_absolute_expression_and_terminator (&val) != ',')
03178     {
03179       as_warn (_("bad .frame directive"));
03180       --input_line_pointer;
03181       demand_empty_rest_of_line ();
03182       return;
03183     }
03184 
03185   cur_proc_ptr->pdr.frameoffset = val;
03186 
03187   cur_proc_ptr->pdr.pcreg = tc_get_register (0);
03188 
03189   /* Alpha-OSF1 adds "the offset of saved $a0 from $sp", according to
03190      Sandro.  I don't yet know where this value should be stored, if
03191      anywhere.  Don't call demand_empty_rest_of_line ().  */
03192   s_ignore (42);
03193 }
03194 
03195 /* Parse .mask directives.  */
03196 
03197 void
03198 ecoff_directive_mask (int ignore ATTRIBUTE_UNUSED)
03199 {
03200   long val;
03201 
03202   if (cur_proc_ptr == (proc_t *) NULL)
03203     {
03204       as_warn (_(".mask outside of .ent"));
03205       demand_empty_rest_of_line ();
03206       return;
03207     }
03208 
03209   if (get_absolute_expression_and_terminator (&val) != ',')
03210     {
03211       as_warn (_("bad .mask directive"));
03212       --input_line_pointer;
03213       demand_empty_rest_of_line ();
03214       return;
03215     }
03216 
03217   cur_proc_ptr->pdr.regmask = val;
03218   cur_proc_ptr->pdr.regoffset = get_absolute_expression ();
03219 
03220   demand_empty_rest_of_line ();
03221 }
03222 
03223 /* Parse .loc directives.  */
03224 
03225 void
03226 ecoff_directive_loc (int ignore ATTRIBUTE_UNUSED)
03227 {
03228   lineno_list_t *list;
03229   symint_t lineno;
03230 
03231   if (cur_file_ptr == (efdr_t *) NULL)
03232     {
03233       as_warn (_(".loc before .file"));
03234       demand_empty_rest_of_line ();
03235       return;
03236     }
03237 
03238   if (now_seg != text_section)
03239     {
03240       as_warn (_(".loc outside of .text"));
03241       demand_empty_rest_of_line ();
03242       return;
03243     }
03244 
03245   /* Skip the file number.  */
03246   SKIP_WHITESPACE ();
03247   get_absolute_expression ();
03248   SKIP_WHITESPACE ();
03249 
03250   lineno = get_absolute_expression ();
03251 
03252 #ifndef NO_LISTING
03253   if (listing)
03254     listing_source_line (lineno);
03255 #endif
03256 
03257   /* If we're building stabs, then output a special label rather than
03258      ECOFF line number info.  */
03259   if (stabs_seen)
03260     {
03261       (void) add_ecoff_symbol ((char *) NULL, st_Label, sc_Text,
03262                             symbol_new ("L0\001", now_seg,
03263                                       (valueT) frag_now_fix (),
03264                                       frag_now),
03265                             (bfd_vma) 0, 0, lineno);
03266       return;
03267     }
03268 
03269   list = allocate_lineno_list ();
03270 
03271   list->next = (lineno_list_t *) NULL;
03272   list->file = cur_file_ptr;
03273   list->proc = cur_proc_ptr;
03274   list->frag = frag_now;
03275   list->paddr = frag_now_fix ();
03276   list->lineno = lineno;
03277 
03278   /* We don't want to merge files which have line numbers.  */
03279   cur_file_ptr->fdr.fMerge = 0;
03280 
03281   /* A .loc directive will sometimes appear before a .ent directive,
03282      which means that cur_proc_ptr will be NULL here.  Arrange to
03283      patch this up.  */
03284   if (cur_proc_ptr == (proc_t *) NULL)
03285     {
03286       lineno_list_t **pl;
03287 
03288       pl = &noproc_lineno;
03289       while (*pl != (lineno_list_t *) NULL)
03290        pl = &(*pl)->next;
03291       *pl = list;
03292     }
03293   else
03294     {
03295       last_lineno = list;
03296       *last_lineno_ptr = list;
03297       last_lineno_ptr = &list->next;
03298     }
03299 }
03300 
03301 /* The MIPS assembler sometimes inserts nop instructions in the
03302    instruction stream.  When this happens, we must patch up the .loc
03303    information so that it points to the instruction after the nop.  */
03304 
03305 void
03306 ecoff_fix_loc (fragS *old_frag, unsigned long old_frag_offset)
03307 {
03308   if (last_lineno != NULL
03309       && last_lineno->frag == old_frag
03310       && last_lineno->paddr == old_frag_offset)
03311     {
03312       last_lineno->frag = frag_now;
03313       last_lineno->paddr = frag_now_fix ();
03314     }
03315 }
03316 
03317 /* Make sure the @stabs symbol is emitted.  */
03318 
03319 static void
03320 mark_stabs (int ignore ATTRIBUTE_UNUSED)
03321 {
03322   if (! stabs_seen)
03323     {
03324       /* Add a dummy @stabs dymbol.  */
03325       stabs_seen = 1;
03326       (void) add_ecoff_symbol (stabs_symbol, stNil, scInfo,
03327                             (symbolS *) NULL,
03328                             (bfd_vma) 0, (symint_t) -1,
03329                             ECOFF_MARK_STAB (0));
03330     }
03331 }
03332 
03333 /* Parse .weakext directives.  */
03334 #ifndef TC_MIPS
03335 /* For TC_MIPS use the version in tc-mips.c.  */
03336 void
03337 ecoff_directive_weakext (int ignore ATTRIBUTE_UNUSED)
03338 {
03339   char *name;
03340   int c;
03341   symbolS *symbolP;
03342   expressionS exp;
03343 
03344   name = input_line_pointer;
03345   c = get_symbol_end ();
03346   symbolP = symbol_find_or_make (name);
03347   *input_line_pointer = c;
03348 
03349   SKIP_WHITESPACE ();
03350 
03351   if (*input_line_pointer == ',')
03352     {
03353       if (S_IS_DEFINED (symbolP))
03354        {
03355          as_bad (_("symbol `%s' is already defined"),
03356                 S_GET_NAME (symbolP));
03357          ignore_rest_of_line ();
03358          return;
03359        }
03360 
03361       ++input_line_pointer;
03362       SKIP_WHITESPACE ();
03363       if (! is_end_of_line[(unsigned char) *input_line_pointer])
03364        {
03365          expression (&exp);
03366          if (exp.X_op != O_symbol)
03367            {
03368              as_bad (_("bad .weakext directive"));
03369              ignore_rest_of_line ();
03370              return;
03371            }
03372          symbol_set_value_expression (symbolP, &exp);
03373        }
03374     }
03375 
03376   S_SET_WEAK (symbolP);
03377 
03378   demand_empty_rest_of_line ();
03379 }
03380 #endif /* not TC_MIPS */
03381 
03382 /* Handle .stabs directives.  The actual parsing routine is done by a
03383    generic routine.  This routine is called via OBJ_PROCESS_STAB.
03384    When this is called, input_line_pointer will be pointing at the
03385    value field of the stab.
03386 
03387    .stabs directives have five fields:
03388        "string"      a string, encoding the type information.
03389        code          a numeric code, defined in <stab.h>
03390        0             a zero
03391        desc          a zero or line number
03392        value         a numeric value or an address.
03393 
03394     If the value is relocatable, we transform this into:
03395        iss           points as an index into string space
03396        value         value from lookup of the name
03397        st            st from lookup of the name
03398        sc            sc from lookup of the name
03399        index         code|CODE_MASK
03400 
03401     If the value is not relocatable, we transform this into:
03402        iss           points as an index into string space
03403        value         value
03404        st            st_Nil
03405        sc            sc_Nil
03406        index         code|CODE_MASK
03407 
03408     .stabn directives have four fields (string is null):
03409        code          a numeric code, defined in <stab.h>
03410        0             a zero
03411        desc          a zero or a line number
03412        value         a numeric value or an address.  */
03413 
03414 void
03415 ecoff_stab (segT sec ATTRIBUTE_UNUSED,
03416            int what,
03417            const char *string,
03418            int type,
03419            int other,
03420            int desc)
03421 {
03422   efdr_t *save_file_ptr = cur_file_ptr;
03423   symbolS *sym;
03424   symint_t value;
03425   bfd_vma addend;
03426   st_t st;
03427   sc_t sc;
03428   symint_t indx;
03429   localsym_t *hold = NULL;
03430 
03431   ecoff_debugging_seen = 1;
03432 
03433   /* We don't handle .stabd.  */
03434   if (what != 's' && what != 'n')
03435     {
03436       as_bad (_(".stab%c is not supported"), what);
03437       return;
03438     }
03439 
03440   /* A .stabn uses a null name, not an empty string.  */
03441   if (what == 'n')
03442     string = NULL;
03443 
03444   /* We ignore the other field.  */
03445   if (other != 0)
03446     as_warn (_(".stab%c: ignoring non-zero other field"), what);
03447 
03448   /* Make sure we have a current file.  */
03449   if (cur_file_ptr == (efdr_t *) NULL)
03450     {
03451       add_file ((const char *) NULL, 0, 1);
03452       save_file_ptr = cur_file_ptr;
03453     }
03454 
03455   /* For stabs in ECOFF, the first symbol must be @stabs.  This is a
03456      signal to gdb.  */
03457   if (stabs_seen == 0)
03458     mark_stabs (0);
03459 
03460   /* Line number stabs are handled differently, since they have two
03461      values, the line number and the address of the label.  We use the
03462      index field (aka desc) to hold the line number, and the value
03463      field to hold the address.  The symbol type is st_Label, which
03464      should be different from the other stabs, so that gdb can
03465      recognize it.  */
03466   if (type == N_SLINE)
03467     {
03468       SYMR dummy_symr;
03469       char *name;
03470       char name_end;
03471 
03472 #ifndef NO_LISTING
03473       if (listing)
03474        listing_source_line ((unsigned int) desc);
03475 #endif
03476 
03477       dummy_symr.index = desc;
03478       if (dummy_symr.index != desc)
03479        {
03480          as_warn (_("line number (%d) for .stab%c directive cannot fit in index field (20 bits)"),
03481                  desc, what);
03482          return;
03483        }
03484 
03485       name = input_line_pointer;
03486       name_end = get_symbol_end ();
03487 
03488       sym = symbol_find_or_make (name);
03489       *input_line_pointer = name_end;
03490 
03491       value = 0;
03492       addend = 0;
03493       st = st_Label;
03494       sc = sc_Text;
03495       indx = desc;
03496     }
03497   else
03498     {
03499 #ifndef NO_LISTING
03500       if (listing && (type == N_SO || type == N_SOL))
03501        listing_source_file (string);
03502 #endif
03503 
03504       if (ISDIGIT (*input_line_pointer)
03505          || *input_line_pointer == '-'
03506          || *input_line_pointer == '+')
03507        {
03508          st = st_Nil;
03509          sc = sc_Nil;
03510          sym = (symbolS *) NULL;
03511          value = get_absolute_expression ();
03512          addend = 0;
03513        }
03514       else if (! is_name_beginner ((unsigned char) *input_line_pointer))
03515        {
03516          as_warn (_("illegal .stab%c directive, bad character"), what);
03517          return;
03518        }
03519       else
03520        {
03521          expressionS exp;
03522 
03523          sc = sc_Nil;
03524          st = st_Nil;
03525 
03526          expression (&exp);
03527          if (exp.X_op == O_constant)
03528            {
03529              sym = NULL;
03530              value = exp.X_add_number;
03531              addend = 0;
03532            }
03533          else if (exp.X_op == O_symbol)
03534            {
03535              sym = exp.X_add_symbol;
03536              value = 0;
03537              addend = exp.X_add_number;
03538            }
03539          else
03540            {
03541              sym = make_expr_symbol (&exp);
03542              value = 0;
03543              addend = 0;
03544            }
03545        }
03546 
03547       indx = ECOFF_MARK_STAB (type);
03548     }
03549 
03550   /* Don't store the stabs symbol we are creating as the type of the
03551      ECOFF symbol.  We want to compute the type of the ECOFF symbol
03552      independently.  */
03553   if (sym != (symbolS *) NULL)
03554     hold = symbol_get_obj (sym)->ecoff_symbol;
03555 
03556   (void) add_ecoff_symbol (string, st, sc, sym, addend, value, indx);
03557 
03558   if (sym != (symbolS *) NULL)
03559     symbol_get_obj (sym)->ecoff_symbol = hold;
03560 
03561   /* Restore normal file type.  */
03562   cur_file_ptr = save_file_ptr;
03563 }
03564 
03565 /* Frob an ECOFF symbol.  Small common symbols go into a special
03566    .scommon section rather than bfd_com_section.  */
03567 
03568 void
03569 ecoff_frob_symbol (symbolS *sym)
03570 {
03571   if (S_IS_COMMON (sym)
03572       && S_GET_VALUE (sym) > 0
03573       && S_GET_VALUE (sym) <= bfd_get_gp_size (stdoutput))
03574     {
03575       static asection scom_section;
03576       static asymbol scom_symbol;
03577 
03578       /* We must construct a fake section similar to bfd_com_section
03579          but with the name .scommon.  */
03580       if (scom_section.name == NULL)
03581        {
03582          scom_section = bfd_com_section;
03583          scom_section.name = ".scommon";
03584          scom_section.output_section = &scom_section;
03585          scom_section.symbol = &scom_symbol;
03586          scom_section.symbol_ptr_ptr = &scom_section.symbol;
03587          scom_symbol = *bfd_com_section.symbol;
03588          scom_symbol.name = ".scommon";
03589          scom_symbol.section = &scom_section;
03590        }
03591       S_SET_SEGMENT (sym, &scom_section);
03592     }
03593 
03594   /* Double check weak symbols.  */
03595   if (S_IS_WEAK (sym))
03596     {
03597       if (S_IS_COMMON (sym))
03598        as_bad (_("symbol `%s' can not be both weak and common"),
03599               S_GET_NAME (sym));
03600     }
03601 }
03602 
03603 /* Add bytes to the symbolic information buffer.  */
03604 
03605 static char *
03606 ecoff_add_bytes (char **buf,
03607                char **bufend,
03608                char *bufptr,
03609                unsigned long need)
03610 {
03611   unsigned long at;
03612   unsigned long want;
03613 
03614   at = bufptr - *buf;
03615   need -= *bufend - bufptr;
03616   if (need < PAGE_SIZE)
03617     need = PAGE_SIZE;
03618   want = (*bufend - *buf) + need;
03619   *buf = xrealloc (*buf, want);
03620   *bufend = *buf + want;
03621   return *buf + at;
03622 }
03623 
03624 /* Adjust the symbolic information buffer to the alignment required
03625    for the ECOFF target debugging information.  */
03626 
03627 static unsigned long
03628 ecoff_padding_adjust (const struct ecoff_debug_swap *backend,
03629                     char **buf,
03630                     char **bufend,
03631                     unsigned long offset,
03632                     char **bufptrptr)
03633 {
03634   bfd_size_type align;
03635 
03636   align = backend->debug_align;
03637   if ((offset & (align - 1)) != 0)
03638     {
03639       unsigned long add;
03640 
03641       add = align - (offset & (align - 1));
03642       if ((unsigned long) (*bufend - (*buf + offset)) < add)
03643        (void) ecoff_add_bytes (buf, bufend, *buf + offset, add);
03644       memset (*buf + offset, 0, add);
03645       offset += add;
03646       if (bufptrptr != (char **) NULL)
03647        *bufptrptr = *buf + offset;
03648     }
03649 
03650   return offset;
03651 }
03652 
03653 /* Build the line number information.  */
03654 
03655 static unsigned long
03656 ecoff_build_lineno (const struct ecoff_debug_swap *backend,
03657                   char **buf,
03658                   char **bufend,
03659                   unsigned long offset,
03660                   long *linecntptr)
03661 {
03662   char *bufptr;
03663   register lineno_list_t *l;
03664   lineno_list_t *last;
03665   efdr_t *file;
03666   proc_t *proc;
03667   unsigned long c;
03668   long iline;
03669   long totcount;
03670   lineno_list_t first;
03671   lineno_list_t *local_first_lineno = first_lineno;
03672 
03673   if (linecntptr != (long *) NULL)
03674     *linecntptr = 0;
03675 
03676   bufptr = *buf + offset;
03677 
03678   file = (efdr_t *) NULL;
03679   proc = (proc_t *) NULL;
03680   last = (lineno_list_t *) NULL;
03681   c = offset;
03682   iline = 0;
03683   totcount = 0;
03684 
03685   /* FIXME?  Now that MIPS embedded-PIC is gone, it may be safe to
03686      remove this code.  */
03687   /* For some reason the address of the first procedure is ignored
03688      when reading line numbers.  This doesn't matter if the address of
03689      the first procedure is 0, but when gcc is generating MIPS
03690      embedded PIC code, it will put strings in the .text section
03691      before the first procedure.  We cope by inserting a dummy line if
03692      the address of the first procedure is not 0.  Hopefully this
03693      won't screw things up too badly.
03694 
03695      Don't do this for ECOFF assembly source line numbers.  They work
03696      without this extra attention.  */
03697   if (debug_type != DEBUG_ECOFF
03698       && first_proc_ptr != (proc_t *) NULL
03699       && local_first_lineno != (lineno_list_t *) NULL
03700       && ((S_GET_VALUE (first_proc_ptr->sym->as_sym)
03701           + bfd_get_section_vma (stdoutput,
03702                               S_GET_SEGMENT (first_proc_ptr->sym->as_sym)))
03703          != 0))
03704     {
03705       first.file = local_first_lineno->file;
03706       first.proc = local_first_lineno->proc;
03707       first.frag = &zero_address_frag;
03708       first.paddr = 0;
03709       first.lineno = 0;
03710 
03711       first.next = local_first_lineno;
03712       local_first_lineno = &first;
03713     }
03714 
03715   for (l = local_first_lineno; l != (lineno_list_t *) NULL; l = l->next)
03716     {
03717       long count;
03718       long delta;
03719 
03720       /* Get the offset to the memory address of the next line number
03721          (in words).  Do this first, so that we can skip ahead to the
03722          next useful line number entry.  */
03723       if (l->next == (lineno_list_t *) NULL)
03724        {
03725          /* We want a count of zero, but it will be decremented
03726             before it is used.  */
03727          count = 1;
03728        }
03729       else if (l->next->frag->fr_address + l->next->paddr
03730               > l->frag->fr_address + l->paddr)
03731        {
03732          count = ((l->next->frag->fr_address + l->next->paddr
03733                   - (l->frag->fr_address + l->paddr))
03734                  >> 2);
03735        }
03736       else
03737        {
03738          /* Don't change last, so we still get the right delta.  */
03739          continue;
03740        }
03741 
03742       if (l->file != file || l->proc != proc)
03743        {
03744          if (l->proc != proc && proc != (proc_t *) NULL)
03745            proc->pdr.lnHigh = last->lineno;
03746          if (l->file != file && file != (efdr_t *) NULL)
03747            {
03748              file->fdr.cbLine = c - file->fdr.cbLineOffset;
03749              file->fdr.cline = totcount + count;
03750              if (linecntptr != (long *) NULL)
03751               *linecntptr += totcount + count;
03752              totcount = 0;
03753            }
03754 
03755          if (l->file != file)
03756            {
03757              efdr_t *last_file = file;
03758 
03759              file = l->file;
03760              if (last_file != (efdr_t *) NULL)
03761               file->fdr.ilineBase
03762                 = last_file->fdr.ilineBase + last_file->fdr.cline;
03763              else
03764               file->fdr.ilineBase = 0;
03765              file->fdr.cbLineOffset = c;
03766            }
03767          if (l->proc != proc)
03768            {
03769              proc = l->proc;
03770              if (proc != (proc_t *) NULL)
03771               {
03772                 proc->pdr.lnLow = l->lineno;
03773                 proc->pdr.cbLineOffset = c - file->fdr.cbLineOffset;
03774                 proc->pdr.iline = totcount;
03775               }
03776            }
03777 
03778          last = (lineno_list_t *) NULL;
03779        }
03780 
03781       totcount += count;
03782 
03783       /* Get the offset to this line number.  */
03784       if (last == (lineno_list_t *) NULL)
03785        delta = 0;
03786       else
03787        delta = l->lineno - last->lineno;
03788 
03789       /* Put in the offset to this line number.  */
03790       while (delta != 0)
03791        {
03792          int setcount;
03793 
03794          /* 1 is added to each count read.  */
03795          --count;
03796          /* We can only adjust the word count by up to 15 words at a
03797             time.  */
03798          if (count <= 0x0f)
03799            {
03800              setcount = count;
03801              count = 0;
03802            }
03803          else
03804            {
03805              setcount = 0x0f;
03806              count -= 0x0f;
03807            }
03808          if (delta >= -7 && delta <= 7)
03809            {
03810              if (bufptr >= *bufend)
03811               bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
03812              *bufptr++ = setcount + (delta << 4);
03813              delta = 0;
03814              ++c;
03815            }
03816          else
03817            {
03818              int set;
03819 
03820              if (*bufend - bufptr < 3)
03821               bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 3);
03822              *bufptr++ = setcount + (8 << 4);
03823              if (delta < -0x8000)
03824               {
03825                 set = -0x8000;
03826                 delta += 0x8000;
03827               }
03828              else if (delta > 0x7fff)
03829               {
03830                 set = 0x7fff;
03831                 delta -= 0x7fff;
03832               }
03833              else
03834               {
03835                 set = delta;
03836                 delta = 0;
03837               }
03838              *bufptr++ = set >> 8;
03839              *bufptr++ = set & 0xffff;
03840              c += 3;
03841            }
03842        }
03843 
03844       /* Finish adjusting the count.  */
03845       while (count > 0)
03846        {
03847          if (bufptr >= *bufend)
03848            bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
03849          /* 1 is added to each count read.  */
03850          --count;
03851          if (count > 0x0f)
03852            {
03853              *bufptr++ = 0x0f;
03854              count -= 0x0f;
03855            }
03856          else
03857            {
03858              *bufptr++ = count;
03859              count = 0;
03860            }
03861          ++c;
03862        }
03863 
03864       ++iline;
03865       last = l;
03866     }
03867 
03868   if (proc != (proc_t *) NULL)
03869     proc->pdr.lnHigh = last->lineno;
03870   if (file != (efdr_t *) NULL)
03871     {
03872       file->fdr.cbLine = c - file->fdr.cbLineOffset;
03873       file->fdr.cline = totcount;
03874     }
03875 
03876   if (linecntptr != (long *) NULL)
03877     *linecntptr += totcount;
03878 
03879   c = ecoff_padding_adjust (backend, buf, bufend, c, &bufptr);
03880 
03881   return c;
03882 }
03883 
03884 /* Build and swap out the symbols.  */
03885 
03886 static unsigned long
03887 ecoff_build_symbols (const struct ecoff_debug_swap *backend,
03888                    char **buf,
03889                    char **bufend,
03890                    unsigned long offset)
03891 {
03892   const bfd_size_type external_sym_size = backend->external_sym_size;
03893   void (* const swap_sym_out) (bfd *, const SYMR *, PTR)
03894     = backend->swap_sym_out;
03895   char *sym_out;
03896   long isym;
03897   vlinks_t *file_link;
03898 
03899   sym_out = *buf + offset;
03900 
03901   isym = 0;
03902 
03903   /* The symbols are stored by file.  */
03904   for (file_link = file_desc.first;
03905        file_link != (vlinks_t *) NULL;
03906        file_link = file_link->next)
03907     {
03908       int ifilesym;
03909       int fil_cnt;
03910       efdr_t *fil_ptr;
03911       efdr_t *fil_end;
03912 
03913       if (file_link->next == (vlinks_t *) NULL)
03914        fil_cnt = file_desc.objects_last_page;
03915       else
03916        fil_cnt = file_desc.objects_per_page;
03917       fil_ptr = file_link->datum->file;
03918       fil_end = fil_ptr + fil_cnt;
03919       for (; fil_ptr < fil_end; fil_ptr++)
03920        {
03921          vlinks_t *sym_link;
03922 
03923          fil_ptr->fdr.isymBase = isym;
03924          ifilesym = isym;
03925          for (sym_link = fil_ptr->symbols.first;
03926               sym_link != (vlinks_t *) NULL;
03927               sym_link = sym_link->next)
03928            {
03929              int sym_cnt;
03930              localsym_t *sym_ptr;
03931              localsym_t *sym_end;
03932 
03933              if (sym_link->next == (vlinks_t *) NULL)
03934               sym_cnt = fil_ptr->symbols.objects_last_page;
03935              else
03936               sym_cnt = fil_ptr->symbols.objects_per_page;
03937              sym_ptr = sym_link->datum->sym;
03938              sym_end = sym_ptr + sym_cnt;
03939              for (; sym_ptr < sym_end; sym_ptr++)
03940               {
03941                 int local;
03942                 symbolS *as_sym;
03943                 forward_t *f;
03944 
03945                 know (sym_ptr->file_ptr == fil_ptr);
03946 
03947                 /* If there is no associated gas symbol, then this
03948                    is a pure debugging symbol.  We have already
03949                    added the name (if any) to fil_ptr->strings.
03950                    Otherwise we must decide whether this is an
03951                    external or a local symbol (actually, it may be
03952                    both if the local provides additional debugging
03953                    information for the external).  */
03954                 local = 1;
03955                 as_sym = sym_ptr->as_sym;
03956                 if (as_sym != (symbolS *) NULL)
03957                   {
03958                     symint_t indx;
03959 
03960                     /* The value of a block start symbol is the
03961                        offset from the start of the procedure.  For
03962                        other symbols we just use the gas value (but
03963                        we must offset it by the vma of the section,
03964                        just as BFD does, because BFD will not see
03965                        this value).  */
03966                     if (sym_ptr->ecoff_sym.asym.st == (int) st_Block
03967                        && sym_ptr->ecoff_sym.asym.sc == (int) sc_Text)
03968                      {
03969                        symbolS *begin_sym;
03970 
03971                        know (sym_ptr->proc_ptr != (proc_t *) NULL);
03972                        begin_sym = sym_ptr->proc_ptr->sym->as_sym;
03973                        if (S_GET_SEGMENT (as_sym)
03974                            != S_GET_SEGMENT (begin_sym))
03975                          as_warn (_(".begin/.bend in different segments"));
03976                        sym_ptr->ecoff_sym.asym.value =
03977                          S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
03978                      }
03979                     else
03980                      sym_ptr->ecoff_sym.asym.value =
03981                        (S_GET_VALUE (as_sym)
03982                         + bfd_get_section_vma (stdoutput,
03983                                             S_GET_SEGMENT (as_sym))
03984                         + sym_ptr->addend);
03985 
03986                     sym_ptr->ecoff_sym.weakext = S_IS_WEAK (as_sym);
03987 
03988                     /* Set st_Proc to st_StaticProc for local
03989                       functions.  */
03990                     if (sym_ptr->ecoff_sym.asym.st == st_Proc
03991                        && S_IS_DEFINED (as_sym)
03992                        && ! S_IS_EXTERNAL (as_sym)
03993                        && ! S_IS_WEAK (as_sym))
03994                      sym_ptr->ecoff_sym.asym.st = st_StaticProc;
03995 
03996                     /* Get the type and storage class based on where
03997                        the symbol actually wound up.  Traditionally,
03998                        N_LBRAC and N_RBRAC are *not* relocated.  */
03999                     indx = sym_ptr->ecoff_sym.asym.index;
04000                     if (sym_ptr->ecoff_sym.asym.st == st_Nil
04001                        && sym_ptr->ecoff_sym.asym.sc == sc_Nil
04002                        && (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
04003                            || ((ECOFF_UNMARK_STAB (indx) != N_LBRAC)
04004                               && (ECOFF_UNMARK_STAB (indx) != N_RBRAC))))
04005                      {
04006                        segT seg;
04007                        const char *segname;
04008                        st_t st;
04009                        sc_t sc;
04010 
04011                        seg = S_GET_SEGMENT (as_sym);
04012                        segname = segment_name (seg);
04013 
04014                        if (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
04015                            && (S_IS_EXTERNAL (as_sym)
04016                               || S_IS_WEAK (as_sym)
04017                               || ! S_IS_DEFINED (as_sym)))
04018                          {
04019                            if ((symbol_get_bfdsym (as_sym)->flags
04020                                & BSF_FUNCTION) != 0)
04021                             st = st_Proc;
04022                            else
04023                             st = st_Global;
04024                          }
04025                        else if (seg == text_section)
04026                          st = st_Label;
04027                        else
04028                          st = st_Static;
04029 
04030                        if (! S_IS_DEFINED (as_sym))
04031                          {
04032                            valueT s;
04033 
04034                            s = symbol_get_obj (as_sym)->ecoff_extern_size;
04035                            if (s == 0
04036                               || s > bfd_get_gp_size (stdoutput))
04037                             sc = sc_Undefined;
04038                            else
04039                             {
04040                               sc = sc_SUndefined;
04041                               sym_ptr->ecoff_sym.asym.value = s;
04042                             }
04043 #ifdef S_SET_SIZE
04044                            S_SET_SIZE (as_sym, s);
04045 #endif
04046                          }
04047                        else if (S_IS_COMMON (as_sym))
04048                          {
04049                            if (S_GET_VALUE (as_sym) > 0
04050                               && (S_GET_VALUE (as_sym)
04051                                   <= bfd_get_gp_size (stdoutput)))
04052                             sc = sc_SCommon;
04053                            else
04054                             sc = sc_Common;
04055                          }
04056                        else if (seg == text_section)
04057                          sc = sc_Text;
04058                        else if (seg == data_section)
04059                          sc = sc_Data;
04060                        else if (strcmp (segname, ".rdata") == 0
04061                                || strcmp (segname, ".rodata") == 0)
04062                          sc = sc_RData;
04063                        else if (strcmp (segname, ".sdata") == 0)
04064                          sc = sc_SData;
04065                        else if (seg == bss_section)
04066                          sc = sc_Bss;
04067                        else if (strcmp (segname, ".sbss") == 0)
04068                          sc = sc_SBss;
04069                        else if (seg == &bfd_abs_section)
04070                          sc = sc_Abs;
04071                        else
04072                          {
04073                            /* This must be a user named section.
04074                               This is not possible in ECOFF, but it
04075                               is in ELF.  */
04076                            sc = sc_Data;
04077                          }
04078 
04079                        sym_ptr->ecoff_sym.asym.st = (int) st;
04080                        sym_ptr->ecoff_sym.asym.sc = (int) sc;
04081                      }
04082 
04083                     /* This is just an external symbol if it is
04084                        outside a procedure and it has a type.
04085                        FIXME: g++ will generate symbols which have
04086                        different names in the debugging information
04087                        than the actual symbol.  Should we handle
04088                        them here?  */
04089                     if ((S_IS_EXTERNAL (as_sym)
04090                         || S_IS_WEAK (as_sym)
04091                         || ! S_IS_DEFINED (as_sym))
04092                        && sym_ptr->proc_ptr == (proc_t *) NULL
04093                        && sym_ptr->ecoff_sym.asym.st != (int) st_Nil
04094                        && ! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym))
04095                      local = 0;
04096 
04097                     /* This is just an external symbol if it is a
04098                        common symbol.  */
04099                     if (S_IS_COMMON (as_sym))
04100                      local = 0;
04101 
04102                     /* If an st_end symbol has an associated gas
04103                        symbol, then it is a local label created for
04104                        a .bend or .end directive.  Stabs line
04105                        numbers will have \001 in the names.  */
04106                     if (local
04107                        && sym_ptr->ecoff_sym.asym.st != st_End
04108                        && strchr (sym_ptr->name, '\001') == 0)
04109                      sym_ptr->ecoff_sym.asym.iss =
04110                        add_string (&fil_ptr->strings,
04111                                   fil_ptr->str_hash,
04112                                   sym_ptr->name,
04113                                   (shash_t **) NULL);
04114                   }
04115 
04116                 /* We now know the index of this symbol; fill in
04117                    locations that have been waiting for that
04118                    information.  */
04119                 if (sym_ptr->begin_ptr != (localsym_t *) NULL)
04120                   {
04121                     localsym_t *begin_ptr;
04122                     st_t begin_type;
04123 
04124                     know (local);
04125                     begin_ptr = sym_ptr->begin_ptr;
04126                     know (begin_ptr->sym_index != -1);
04127                     sym_ptr->ecoff_sym.asym.index = begin_ptr->sym_index;
04128                     if (sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
04129                      sym_ptr->ecoff_sym.asym.iss =
04130                        begin_ptr->ecoff_sym.asym.iss;
04131 
04132                     begin_type = begin_ptr->ecoff_sym.asym.st;
04133                     if (begin_type == st_File
04134                        || begin_type == st_Block)
04135                      {
04136                        begin_ptr->ecoff_sym.asym.index =
04137                          isym - ifilesym + 1;
04138                        (*swap_sym_out) (stdoutput,
04139                                       &begin_ptr->ecoff_sym.asym,
04140                                       (*buf
04141                                        + offset
04142                                        + (begin_ptr->sym_index
04143                                           * external_sym_size)));
04144                      }
04145                     else
04146                      {
04147                        know (begin_ptr->index_ptr != (aux_t *) NULL);
04148                        begin_ptr->index_ptr->data.isym =
04149                          isym - ifilesym + 1;
04150                      }
04151 
04152                     /* The value of the symbol marking the end of a
04153                        procedure is the size of the procedure.  The
04154                        value of the symbol marking the end of a
04155                        block is the offset from the start of the
04156                        procedure to the block.  */
04157                     if (begin_type == st_Proc
04158                        || begin_type == st_StaticProc)
04159                      {
04160                        know (as_sym != (symbolS *) NULL);
04161                        know (begin_ptr->as_sym != (symbolS *) NULL);
04162                        if (S_GET_SEGMENT (as_sym)
04163                            != S_GET_SEGMENT (begin_ptr->as_sym))
04164                          as_warn (_(".begin/.bend in different segments"));
04165                        sym_ptr->ecoff_sym.asym.value =
04166                          (S_GET_VALUE (as_sym)
04167                           - S_GET_VALUE (begin_ptr->as_sym));
04168 
04169                        /* If the size is odd, this is probably a
04170                           mips16 function; force it to be even.  */
04171                        if ((sym_ptr->ecoff_sym.asym.value & 1) != 0)
04172                          ++sym_ptr->ecoff_sym.asym.value;
04173 
04174 #ifdef S_SET_SIZE
04175                        S_SET_SIZE (begin_ptr->as_sym,
04176                                   sym_ptr->ecoff_sym.asym.value);
04177 #endif
04178                      }
04179                     else if (begin_type == st_Block
04180                             && sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
04181                      {
04182                        symbolS *begin_sym;
04183 
04184                        know (as_sym != (symbolS *) NULL);
04185                        know (sym_ptr->proc_ptr != (proc_t *) NULL);
04186                        begin_sym = sym_ptr->proc_ptr->sym->as_sym;
04187                        if (S_GET_SEGMENT (as_sym)
04188                            != S_GET_SEGMENT (begin_sym))
04189                          as_warn (_(".begin/.bend in different segments"));
04190                        sym_ptr->ecoff_sym.asym.value =
04191                          S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
04192                      }
04193                   }
04194 
04195                 for (f = sym_ptr->forward_ref;
04196                      f != (forward_t *) NULL;
04197                      f = f->next)
04198                   {
04199                     know (local);
04200                     f->ifd_ptr->data.isym = fil_ptr->file_index;
04201                     f->index_ptr->data.rndx.index = isym - ifilesym;
04202                   }
04203 
04204                 if (local)
04205                   {
04206                     if ((bfd_size_type)(*bufend - sym_out) < external_sym_size)
04207                      sym_out = ecoff_add_bytes (buf, bufend,
04208                                              sym_out,
04209                                              external_sym_size);
04210                     (*swap_sym_out) (stdoutput, &sym_ptr->ecoff_sym.asym,
04211                                    sym_out);
04212                     sym_out += external_sym_size;
04213 
04214                     sym_ptr->sym_index = isym;
04215 
04216                     if (sym_ptr->proc_ptr != (proc_t *) NULL
04217                        && sym_ptr->proc_ptr->sym == sym_ptr)
04218                      sym_ptr->proc_ptr->pdr.isym = isym - ifilesym;
04219 
04220                     ++isym;
04221                   }
04222 
04223                 /* Record the local symbol index and file number in
04224                    case this is an external symbol.  Note that this
04225                    destroys the asym.index field.  */
04226                 if (as_sym != (symbolS *) NULL
04227                     && symbol_get_obj (as_sym)->ecoff_symbol == sym_ptr)
04228                   {
04229                     if ((sym_ptr->ecoff_sym.asym.st == st_Proc
04230                         || sym_ptr->ecoff_sym.asym.st == st_StaticProc)
04231                        && local)
04232                      sym_ptr->ecoff_sym.asym.index = isym - ifilesym - 1;
04233                     sym_ptr->ecoff_sym.ifd = fil_ptr->file_index;
04234 
04235                     /* Don't try to merge an FDR which has an
04236                        external symbol attached to it.  */
04237                     if (S_IS_EXTERNAL (as_sym) || S_IS_WEAK (as_sym))
04238                      fil_ptr->fdr.fMerge = 0;
04239                   }
04240               }
04241            }
04242          fil_ptr->fdr.csym = isym - fil_ptr->fdr.isymBase;
04243        }
04244     }
04245 
04246   return offset + isym * external_sym_size;
04247 }
04248 
04249 /* Swap out the procedure information.  */
04250 
04251 static unsigned long
04252 ecoff_build_procs (const struct ecoff_debug_swap *backend,
04253                  char **buf,
04254                  char **bufend,
04255                  unsigned long offset)
04256 {
04257   const bfd_size_type external_pdr_size = backend->external_pdr_size;
04258   void (* const swap_pdr_out) (bfd *, const PDR *, PTR)
04259     = backend->swap_pdr_out;
04260   char *pdr_out;
04261   long iproc;
04262   vlinks_t *file_link;
04263 
04264   pdr_out = *buf + offset;
04265 
04266   iproc = 0;
04267 
04268   /* The procedures are stored by file.  */
04269   for (file_link = file_desc.first;
04270        file_link != (vlinks_t *) NULL;
04271        file_link = file_link->next)
04272     {
04273       int fil_cnt;
04274       efdr_t *fil_ptr;
04275       efdr_t *fil_end;
04276 
04277       if (file_link->next == (vlinks_t *) NULL)
04278        fil_cnt = file_desc.objects_last_page;
04279       else
04280        fil_cnt = file_desc.objects_per_page;
04281       fil_ptr = file_link->datum->file;
04282       fil_end = fil_ptr + fil_cnt;
04283       for (; fil_ptr < fil_end; fil_ptr++)
04284        {
04285          vlinks_t *proc_link;
04286          int first;
04287 
04288          fil_ptr->fdr.ipdFirst = iproc;
04289          first = 1;
04290          for (proc_link = fil_ptr->procs.first;
04291               proc_link != (vlinks_t *) NULL;
04292               proc_link = proc_link->next)
04293            {
04294              int prc_cnt;
04295              proc_t *proc_ptr;
04296              proc_t *proc_end;
04297 
04298              if (proc_link->next == (vlinks_t *) NULL)
04299               prc_cnt = fil_ptr->procs.objects_last_page;
04300              else
04301               prc_cnt = fil_ptr->procs.objects_per_page;
04302              proc_ptr = proc_link->datum->proc;
04303              proc_end = proc_ptr + prc_cnt;
04304              for (; proc_ptr < proc_end; proc_ptr++)
04305               {
04306                 symbolS *adr_sym;
04307                 unsigned long adr;
04308 
04309                 adr_sym = proc_ptr->sym->as_sym;
04310                 adr = (S_GET_VALUE (adr_sym)
04311                       + bfd_get_section_vma (stdoutput,
04312                                           S_GET_SEGMENT (adr_sym)));
04313                 if (first)
04314                   {
04315                     /* This code used to force the adr of the very
04316                        first fdr to be 0.  However, the native tools
04317                        don't do that, and I can't remember why it
04318                        used to work that way, so I took it out.  */
04319                     fil_ptr->fdr.adr = adr;
04320                     first = 0;
04321                   }
04322                 proc_ptr->pdr.adr = adr - fil_ptr->fdr.adr;
04323                 if ((bfd_size_type)(*bufend - pdr_out) < external_pdr_size)
04324                   pdr_out = ecoff_add_bytes (buf, bufend,
04325                                           pdr_out,
04326                                           external_pdr_size);
04327                 (*swap_pdr_out) (stdoutput, &proc_ptr->pdr, pdr_out);
04328                 pdr_out += external_pdr_size;
04329                 ++iproc;
04330               }
04331            }
04332          fil_ptr->fdr.cpd = iproc - fil_ptr->fdr.ipdFirst;
04333        }
04334     }
04335 
04336   return offset + iproc * external_pdr_size;
04337 }
04338 
04339 /* Swap out the aux information.  */
04340 
04341 static unsigned long
04342 ecoff_build_aux (const struct ecoff_debug_swap *backend,
04343                char **buf,
04344                char **bufend,
04345                unsigned long offset)
04346 {
04347   int bigendian;
04348   union aux_ext *aux_out;
04349   long iaux;
04350   vlinks_t *file_link;
04351 
04352   bigendian = bfd_big_endian (stdoutput);
04353 
04354   aux_out = (union aux_ext *) (*buf + offset);
04355 
04356   iaux = 0;
04357 
04358   /* The aux entries are stored by file.  */
04359   for (file_link = file_desc.first;
04360        file_link != (vlinks_t *) NULL;
04361        file_link = file_link->next)
04362     {
04363       int fil_cnt;
04364       efdr_t *fil_ptr;
04365       efdr_t *fil_end;
04366 
04367       if (file_link->next == (vlinks_t *) NULL)
04368        fil_cnt = file_desc.objects_last_page;
04369       else
04370        fil_cnt = file_desc.objects_per_page;
04371       fil_ptr = file_link->datum->file;
04372       fil_end = fil_ptr + fil_cnt;
04373       for (; fil_ptr < fil_end; fil_ptr++)
04374        {
04375          vlinks_t *aux_link;
04376 
04377          fil_ptr->fdr.fBigendian = bigendian;
04378          fil_ptr->fdr.iauxBase = iaux;
04379          for (aux_link = fil_ptr->aux_syms.first;
04380               aux_link != (vlinks_t *) NULL;
04381               aux_link = aux_link->next)
04382            {
04383              int aux_cnt;
04384              aux_t *aux_ptr;
04385              aux_t *aux_end;
04386 
04387              if (aux_link->next == (vlinks_t *) NULL)
04388               aux_cnt = fil_ptr->aux_syms.objects_last_page;
04389              else
04390               aux_cnt = fil_ptr->aux_syms.objects_per_page;
04391              aux_ptr = aux_link->datum->aux;
04392              aux_end = aux_ptr + aux_cnt;
04393              for (; aux_ptr < aux_end; aux_ptr++)
04394               {
04395                 if ((unsigned long) (*bufend - (char *) aux_out)
04396                     < sizeof (union aux_ext))
04397                   aux_out = ((union aux_ext *)
04398                             ecoff_add_bytes (buf, bufend,
04399                                           (char *) aux_out,
04400                                           sizeof (union aux_ext)));
04401                 switch (aux_ptr->type)
04402                   {
04403                   case aux_tir:
04404                     (*backend->swap_tir_out) (bigendian,
04405                                           &aux_ptr->data.ti,
04406                                           &aux_out->a_ti);
04407                     break;
04408                   case aux_rndx:
04409                     (*backend->swap_rndx_out) (bigendian,
04410                                            &aux_ptr->data.rndx,
04411                                            &aux_out->a_rndx);
04412                     break;
04413                   case aux_dnLow:
04414                     AUX_PUT_DNLOW (bigendian, aux_ptr->data.dnLow,
04415                                  aux_out);
04416                     break;
04417                   case aux_dnHigh:
04418                     AUX_PUT_DNHIGH (bigendian, aux_ptr->data.dnHigh,
04419                                   aux_out);
04420                     break;
04421                   case aux_isym:
04422                     AUX_PUT_ISYM (bigendian, aux_ptr->data.isym,
04423                                 aux_out);
04424                     break;
04425                   case aux_iss:
04426                     AUX_PUT_ISS (bigendian, aux_ptr->data.iss,
04427                                aux_out);
04428                     break;
04429                   case aux_width:
04430                     AUX_PUT_WIDTH (bigendian, aux_ptr->data.width,
04431                                  aux_out);
04432                     break;
04433                   case aux_count:
04434                     AUX_PUT_COUNT (bigendian, aux_ptr->data.count,
04435                                  aux_out);
04436                     break;
04437                   }
04438 
04439                 ++aux_out;
04440                 ++iaux;
04441               }
04442            }
04443          fil_ptr->fdr.caux = iaux - fil_ptr->fdr.iauxBase;
04444        }
04445     }
04446 
04447   return ecoff_padding_adjust (backend, buf, bufend,
04448                             offset + iaux * sizeof (union aux_ext),
04449                             (char **) NULL);
04450 }
04451 
04452 /* Copy out the strings from a varray_t.  This returns the number of
04453    bytes copied, rather than the new offset.  */
04454 
04455 static unsigned long
04456 ecoff_build_strings (char **buf,
04457                    char **bufend,
04458                    unsigned long offset,
04459                    varray_t *vp)
04460 {
04461   unsigned long istr;
04462   char *str_out;
04463   vlinks_t *str_link;
04464 
04465   str_out = *buf + offset;
04466 
04467   istr = 0;
04468 
04469   for (str_link = vp->first;
04470        str_link != (vlinks_t *) NULL;
04471        str_link = str_link->next)
04472     {
04473       unsigned long str_cnt;
04474 
04475       if (str_link->next == (vlinks_t *) NULL)
04476        str_cnt = vp->objects_last_page;
04477       else
04478        str_cnt = vp->objects_per_page;
04479 
04480       if ((unsigned long)(*bufend - str_out) < str_cnt)
04481        str_out = ecoff_add_bytes (buf, bufend, str_out, str_cnt);
04482 
04483       memcpy (str_out, str_link->datum->byte, str_cnt);
04484       str_out += str_cnt;
04485       istr += str_cnt;
04486     }
04487 
04488   return istr;
04489 }
04490 
04491 /* Dump out the local strings.  */
04492 
04493 static unsigned long
04494 ecoff_build_ss (const struct ecoff_debug_swap *backend,
04495               char **buf,
04496               char **bufend,
04497               unsigned long offset)
04498 {
04499   long iss;
04500   vlinks_t *file_link;
04501 
04502   iss = 0;
04503 
04504   for (file_link = file_desc.first;
04505        file_link != (vlinks_t *) NULL;
04506        file_link = file_link->next)
04507     {
04508       int fil_cnt;
04509       efdr_t *fil_ptr;
04510       efdr_t *fil_end;
04511 
04512       if (file_link->next == (vlinks_t *) NULL)
04513        fil_cnt = file_desc.objects_last_page;
04514       else
04515        fil_cnt = file_desc.objects_per_page;
04516       fil_ptr = file_link->datum->file;
04517       fil_end = fil_ptr + fil_cnt;
04518       for (; fil_ptr < fil_end; fil_ptr++)
04519        {
04520          long ss_cnt;
04521 
04522          fil_ptr->fdr.issBase = iss;
04523          ss_cnt = ecoff_build_strings (buf, bufend, offset + iss,
04524                                    &fil_ptr->strings);
04525          fil_ptr->fdr.cbSs = ss_cnt;
04526          iss += ss_cnt;
04527        }
04528     }
04529 
04530   return ecoff_padding_adjust (backend, buf, bufend, offset + iss,
04531                             (char **) NULL);
04532 }
04533 
04534 /* Swap out the file descriptors.  */
04535 
04536 static unsigned long
04537 ecoff_build_fdr (const struct ecoff_debug_swap *backend,
04538                char **buf,
04539                char **bufend,
04540                unsigned long offset)
04541 {
04542   const bfd_size_type external_fdr_size = backend->external_fdr_size;
04543   void (* const swap_fdr_out) (bfd *, const FDR *, PTR)
04544     = backend->swap_fdr_out;
04545   long ifile;
04546   char *fdr_out;
04547   vlinks_t *file_link;
04548 
04549   ifile = 0;
04550 
04551   fdr_out = *buf + offset;
04552 
04553   for (file_link = file_desc.first;
04554        file_link != (vlinks_t *) NULL;
04555        file_link = file_link->next)
04556     {
04557       int fil_cnt;
04558       efdr_t *fil_ptr;
04559       efdr_t *fil_end;
04560 
04561       if (file_link->next == (vlinks_t *) NULL)
04562        fil_cnt = file_desc.objects_last_page;
04563       else
04564        fil_cnt = file_desc.objects_per_page;
04565       fil_ptr = file_link->datum->file;
04566       fil_end = fil_ptr + fil_cnt;
04567       for (; fil_ptr < fil_end; fil_ptr++)
04568        {
04569          if ((bfd_size_type)(*bufend - fdr_out) < external_fdr_size)
04570            fdr_out = ecoff_add_bytes (buf, bufend, fdr_out,
04571                                    external_fdr_size);
04572          (*swap_fdr_out) (stdoutput, &fil_ptr->fdr, fdr_out);
04573          fdr_out += external_fdr_size;
04574          ++ifile;
04575        }
04576     }
04577 
04578   return offset + ifile * external_fdr_size;
04579 }
04580 
04581 /* Set up the external symbols.  These are supposed to be handled by
04582    the backend.  This routine just gets the right information and
04583    calls a backend function to deal with it.  */
04584 
04585 static void
04586 ecoff_setup_ext (void)
04587 {
04588   register symbolS *sym;
04589 
04590   for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
04591     {
04592       if (symbol_get_obj (sym)->ecoff_symbol == NULL)
04593        continue;
04594 
04595       /* If this is a local symbol, then force the fields to zero.  */
04596       if (! S_IS_EXTERNAL (sym)
04597          && ! S_IS_WEAK (sym)
04598          && S_IS_DEFINED (sym))
04599        {
04600          struct localsym *lsym;
04601 
04602          lsym = symbol_get_obj (sym)->ecoff_symbol;
04603          lsym->ecoff_sym.asym.value = 0;
04604          lsym->ecoff_sym.asym.st = (int) st_Nil;
04605          lsym->ecoff_sym.asym.sc = (int) sc_Nil;
04606          lsym->ecoff_sym.asym.index = indexNil;
04607        }
04608 
04609       obj_ecoff_set_ext (sym, &symbol_get_obj (sym)->ecoff_symbol->ecoff_sym);
04610     }
04611 }
04612 
04613 /* Build the ECOFF debugging information.  */
04614 
04615 unsigned long
04616 ecoff_build_debug (HDRR *hdr,
04617                  char **bufp,
04618                  const struct ecoff_debug_swap *backend)
04619 {
04620   const bfd_size_type external_pdr_size = backend->external_pdr_size;
04621   tag_t *ptag;
04622   tag_t *ptag_next;
04623   efdr_t *fil_ptr;
04624   int end_warning;
04625   efdr_t *hold_file_ptr;
04626   proc_t *hold_proc_ptr;
04627   symbolS *sym;
04628   char *buf;
04629   char *bufend;
04630   unsigned long offset;
04631 
04632   /* Make sure we have a file.  */
04633   if (first_file == (efdr_t *) NULL)
04634     add_file ((const char *) NULL, 0, 1);
04635 
04636   /* Handle any top level tags.  */
04637   for (ptag = top_tag_head->first_tag;
04638        ptag != (tag_t *) NULL;
04639        ptag = ptag_next)
04640     {
04641       if (ptag->forward_ref != (forward_t *) NULL)
04642        add_unknown_tag (ptag);
04643 
04644       ptag_next = ptag->same_block;
04645       ptag->hash_ptr->tag_ptr = ptag->same_name;
04646       free_tag (ptag);
04647     }
04648 
04649   free_thead (top_tag_head);
04650 
04651   /* Look through the symbols.  Add debugging information for each
04652      symbol that has not already received it.  */
04653   hold_file_ptr = cur_file_ptr;
04654   hold_proc_ptr = cur_proc_ptr;
04655   cur_proc_ptr = (proc_t *) NULL;
04656   for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
04657     {
04658       if (symbol_get_obj (sym)->ecoff_symbol != NULL
04659          || symbol_get_obj (sym)->ecoff_file == (efdr_t *) NULL
04660          || (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) != 0)
04661        continue;
04662 
04663       cur_file_ptr = symbol_get_obj (sym)->ecoff_file;
04664       add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym,
04665                      (bfd_vma) 0, S_GET_VALUE (sym), indexNil);
04666     }
04667   cur_proc_ptr = hold_proc_ptr;
04668   cur_file_ptr = hold_file_ptr;
04669 
04670   /* Output an ending symbol for all the files.  We have to do this
04671      here for the last file, so we may as well do it for all of the
04672      files.  */
04673   end_warning = 0;
04674   for (fil_ptr = first_file;
04675        fil_ptr != (efdr_t *) NULL;
04676        fil_ptr = fil_ptr->next_file)
04677     {
04678       cur_file_ptr = fil_ptr;
04679       while (cur_file_ptr->cur_scope != (scope_t *) NULL
04680             && cur_file_ptr->cur_scope->prev != (scope_t *) NULL)
04681        {
04682          cur_file_ptr->cur_scope = cur_file_ptr->cur_scope->prev;
04683          if (! end_warning && ! cur_file_ptr->fake)
04684            {
04685              as_warn (_("missing .end or .bend at end of file"));
04686              end_warning = 1;
04687            }
04688        }
04689       if (cur_file_ptr->cur_scope != (scope_t *) NULL)
04690        (void) add_ecoff_symbol ((const char *) NULL,
04691                              st_End, sc_Text,
04692                              (symbolS *) NULL,
04693                              (bfd_vma) 0,
04694                              (symint_t) 0,
04695                              (symint_t) 0);
04696     }
04697 
04698   /* Build the symbolic information.  */
04699   offset = 0;
04700   buf = xmalloc (PAGE_SIZE);
04701   bufend = buf + PAGE_SIZE;
04702 
04703   /* Build the line number information.  */
04704   hdr->cbLineOffset = offset;
04705   offset = ecoff_build_lineno (backend, &buf, &bufend, offset,
04706                             &hdr->ilineMax);
04707   hdr->cbLine = offset - hdr->cbLineOffset;
04708 
04709   /* We don't use dense numbers at all.  */
04710   hdr->idnMax = 0;
04711   hdr->cbDnOffset = 0;
04712 
04713   /* We can't build the PDR table until we have built the symbols,
04714      because a PDR contains a symbol index.  However, we set aside
04715      space at this point.  */
04716   hdr->ipdMax = proc_cnt;
04717   hdr->cbPdOffset = offset;
04718   if ((bfd_size_type)(bufend - (buf + offset)) < proc_cnt * external_pdr_size)
04719     (void) ecoff_add_bytes (&buf, &bufend, buf + offset,
04720                          proc_cnt * external_pdr_size);
04721   offset += proc_cnt * external_pdr_size;
04722 
04723   /* Build the local symbols.  */
04724   hdr->cbSymOffset = offset;
04725   offset = ecoff_build_symbols (backend, &buf, &bufend, offset);
04726   hdr->isymMax = (offset - hdr->cbSymOffset) / backend->external_sym_size;
04727 
04728   /* Building the symbols initializes the symbol index in the PDR's.
04729      Now we can swap out the PDR's.  */
04730   (void) ecoff_build_procs (backend, &buf, &bufend, hdr->cbPdOffset);
04731 
04732   /* We don't use optimization symbols.  */
04733   hdr->ioptMax = 0;
04734   hdr->cbOptOffset = 0;
04735 
04736   /* Swap out the auxiliary type information.  */
04737   hdr->cbAuxOffset = offset;
04738   offset = ecoff_build_aux (backend, &buf, &bufend, offset);
04739   hdr->iauxMax = (offset - hdr->cbAuxOffset) / sizeof (union aux_ext);
04740 
04741   /* Copy out the local strings.  */
04742   hdr->cbSsOffset = offset;
04743   offset = ecoff_build_ss (backend, &buf, &bufend, offset);
04744   hdr->issMax = offset - hdr->cbSsOffset;
04745 
04746   /* We don't use relative file descriptors.  */
04747   hdr->crfd = 0;
04748   hdr->cbRfdOffset = 0;
04749 
04750   /* Swap out the file descriptors.  */
04751   hdr->cbFdOffset = offset;
04752   offset = ecoff_build_fdr (backend, &buf, &bufend, offset);
04753   hdr->ifdMax = (offset - hdr->cbFdOffset) / backend->external_fdr_size;
04754 
04755   /* Set up the external symbols, which are handled by the BFD back
04756      end.  */
04757   hdr->issExtMax = 0;
04758   hdr->cbSsExtOffset = 0;
04759   hdr->iextMax = 0;
04760   hdr->cbExtOffset = 0;
04761   ecoff_setup_ext ();
04762 
04763   know ((offset & (backend->debug_align - 1)) == 0);
04764 
04765   /* FIXME: This value should be determined from the .verstamp directive,
04766      with reasonable defaults in config files.  */
04767 #ifdef TC_ALPHA
04768   hdr->vstamp = 0x030b;
04769 #else
04770   hdr->vstamp = 0x020b;
04771 #endif
04772 
04773   *bufp = buf;
04774   return offset;
04775 }
04776 
04777 /* Allocate a cluster of pages.  */
04778 
04779 #ifndef MALLOC_CHECK
04780 
04781 static page_type *
04782 allocate_cluster (unsigned long npages)
04783 {
04784   register page_type *value = (page_type *) xmalloc (npages * PAGE_USIZE);
04785 
04786 #ifdef ECOFF_DEBUG
04787   if (debug > 3)
04788     fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
04789 #endif
04790 
04791   memset (value, 0, npages * PAGE_USIZE);
04792 
04793   return value;
04794 }
04795 
04796 static page_type *cluster_ptr = NULL;
04797 static unsigned long pages_left = 0;
04798 
04799 #endif /* MALLOC_CHECK */
04800 
04801 /* Allocate one page (which is initialized to 0).  */
04802 
04803 static page_type *
04804 allocate_page (void)
04805 {
04806 #ifndef MALLOC_CHECK
04807 
04808   if (pages_left == 0)
04809     {
04810       pages_left = MAX_CLUSTER_PAGES;
04811       cluster_ptr = allocate_cluster (pages_left);
04812     }
04813 
04814   pages_left--;
04815   return cluster_ptr++;
04816 
04817 #else /* MALLOC_CHECK */
04818 
04819   page_type *ptr;
04820 
04821   ptr = xmalloc (PAGE_USIZE);
04822   memset (ptr, 0, PAGE_USIZE);
04823   return ptr;
04824 
04825 #endif /* MALLOC_CHECK */
04826 }
04827 
04828 /* Allocate scoping information.  */
04829 
04830 static scope_t *
04831 allocate_scope (void)
04832 {
04833   register scope_t *ptr;
04834   static scope_t initial_scope;
04835 
04836 #ifndef MALLOC_CHECK
04837 
04838   ptr = alloc_counts[(int) alloc_type_scope].free_list.f_scope;
04839   if (ptr != (scope_t *) NULL)
04840     alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr->free;
04841   else
04842     {
04843       register int unallocated     = alloc_counts[(int) alloc_type_scope].unallocated;
04844       register page_type *cur_page = alloc_counts[(int) alloc_type_scope].cur_page;
04845 
04846       if (unallocated == 0)
04847        {
04848          unallocated = PAGE_SIZE / sizeof (scope_t);
04849          alloc_counts[(int) alloc_type_scope].cur_page = cur_page = allocate_page ();
04850          alloc_counts[(int) alloc_type_scope].total_pages++;
04851        }
04852 
04853       ptr = &cur_page->scope[--unallocated];
04854       alloc_counts[(int) alloc_type_scope].unallocated = unallocated;
04855     }
04856 
04857 #else
04858 
04859   ptr = (scope_t *) xmalloc (sizeof (scope_t));
04860 
04861 #endif
04862 
04863   alloc_counts[(int) alloc_type_scope].total_alloc++;
04864   *ptr = initial_scope;
04865   return ptr;
04866 }
04867 
04868 /* Free scoping information.  */
04869 
04870 static void
04871 free_scope (scope_t *ptr)
04872 {
04873   alloc_counts[(int) alloc_type_scope].total_free++;
04874 
04875 #ifndef MALLOC_CHECK
04876   ptr->free = alloc_counts[(int) alloc_type_scope].free_list.f_scope;
04877   alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr;
04878 #else
04879   free ((PTR) ptr);
04880 #endif
04881 }
04882 
04883 /* Allocate links for pages in a virtual array.  */
04884 
04885 static vlinks_t *
04886 allocate_vlinks (void)
04887 {
04888   register vlinks_t *ptr;
04889   static vlinks_t initial_vlinks;
04890 
04891 #ifndef MALLOC_CHECK
04892 
04893   register int unallocated = alloc_counts[(int) alloc_type_vlinks].unallocated;
04894   register page_type *cur_page = alloc_counts[(int) alloc_type_vlinks].cur_page;
04895 
04896   if (unallocated == 0)
04897     {
04898       unallocated = PAGE_SIZE / sizeof (vlinks_t);
04899       alloc_counts[(int) alloc_type_vlinks].cur_page = cur_page = allocate_page ();
04900       alloc_counts[(int) alloc_type_vlinks].total_pages++;
04901     }
04902 
04903   ptr = &cur_page->vlinks[--unallocated];
04904   alloc_counts[(int) alloc_type_vlinks].unallocated = unallocated;
04905 
04906 #else
04907 
04908   ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
04909 
04910 #endif
04911 
04912   alloc_counts[(int) alloc_type_vlinks].total_alloc++;
04913   *ptr = initial_vlinks;
04914   return ptr;
04915 }
04916 
04917 /* Allocate string hash buckets.  */
04918 
04919 static shash_t *
04920 allocate_shash (void)
04921 {
04922   register shash_t *ptr;
04923   static shash_t initial_shash;
04924 
04925 #ifndef MALLOC_CHECK
04926 
04927   register int unallocated = alloc_counts[(int) alloc_type_shash].unallocated;
04928   register page_type *cur_page = alloc_counts[(int) alloc_type_shash].cur_page;
04929 
04930   if (unallocated == 0)
04931     {
04932       unallocated = PAGE_SIZE / sizeof (shash_t);
04933       alloc_counts[(int) alloc_type_shash].cur_page = cur_page = allocate_page ();
04934       alloc_counts[(int) alloc_type_shash].total_pages++;
04935     }
04936 
04937   ptr = &cur_page->shash[--unallocated];
04938   alloc_counts[(int) alloc_type_shash].unallocated = unallocated;
04939 
04940 #else
04941 
04942   ptr = (shash_t *) xmalloc (sizeof (shash_t));
04943 
04944 #endif
04945 
04946   alloc_counts[(int) alloc_type_shash].total_alloc++;
04947   *ptr = initial_shash;
04948   return ptr;
04949 }
04950 
04951 /* Allocate type hash buckets.  */
04952 
04953 static thash_t *
04954 allocate_thash (void)
04955 {
04956   register thash_t *ptr;
04957   static thash_t initial_thash;
04958 
04959 #ifndef MALLOC_CHECK
04960 
04961   register int unallocated = alloc_counts[(int) alloc_type_thash].unallocated;
04962   register page_type *cur_page = alloc_counts[(int) alloc_type_thash].cur_page;
04963 
04964   if (unallocated == 0)
04965     {
04966       unallocated = PAGE_SIZE / sizeof (thash_t);
04967       alloc_counts[(int) alloc_type_thash].cur_page = cur_page = allocate_page ();
04968       alloc_counts[(int) alloc_type_thash].total_pages++;
04969     }
04970 
04971   ptr = &cur_page->thash[--unallocated];
04972   alloc_counts[(int) alloc_type_thash].unallocated = unallocated;
04973 
04974 #else
04975 
04976   ptr = (thash_t *) xmalloc (sizeof (thash_t));
04977 
04978 #endif
04979 
04980   alloc_counts[(int) alloc_type_thash].total_alloc++;
04981   *ptr = initial_thash;
04982   return ptr;
04983 }
04984 
04985 /* Allocate structure, union, or enum tag information.  */
04986 
04987 static tag_t *
04988 allocate_tag (void)
04989 {
04990   register tag_t *ptr;
04991   static tag_t initial_tag;
04992 
04993 #ifndef MALLOC_CHECK
04994 
04995   ptr = alloc_counts[(int) alloc_type_tag].free_list.f_tag;
04996   if (ptr != (tag_t *) NULL)
04997     alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr->free;
04998   else
04999     {
05000       register int unallocated = alloc_counts[(int) alloc_type_tag].unallocated;
05001       register page_type *cur_page = alloc_counts[(int) alloc_type_tag].cur_page;
05002 
05003       if (unallocated == 0)
05004        {
05005          unallocated = PAGE_SIZE / sizeof (tag_t);
05006          alloc_counts[(int) alloc_type_tag].cur_page = cur_page = allocate_page ();
05007          alloc_counts[(int) alloc_type_tag].total_pages++;
05008        }
05009 
05010       ptr = &cur_page->tag[--unallocated];
05011       alloc_counts[(int) alloc_type_tag].unallocated = unallocated;
05012     }
05013 
05014 #else
05015 
05016   ptr = (tag_t *) xmalloc (sizeof (tag_t));
05017 
05018 #endif
05019 
05020   alloc_counts[(int) alloc_type_tag].total_alloc++;
05021   *ptr = initial_tag;
05022   return ptr;
05023 }
05024 
05025 /* Free scoping information.  */
05026 
05027 static void
05028 free_tag (tag_t *ptr)
05029 {
05030   alloc_counts[(int) alloc_type_tag].total_free++;
05031 
05032 #ifndef MALLOC_CHECK
05033   ptr->free = alloc_counts[(int) alloc_type_tag].free_list.f_tag;
05034   alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr;
05035 #else
05036   free ((PTR_T) ptr);
05037 #endif
05038 }
05039 
05040 /* Allocate forward reference to a yet unknown tag.  */
05041 
05042 static forward_t *
05043 allocate_forward (void)
05044 {
05045   register forward_t *ptr;
05046   static forward_t initial_forward;
05047 
05048 #ifndef MALLOC_CHECK
05049 
05050   register int unallocated = alloc_counts[(int) alloc_type_forward].unallocated;
05051   register page_type *cur_page = alloc_counts[(int) alloc_type_forward].cur_page;
05052 
05053   if (unallocated == 0)
05054     {
05055       unallocated = PAGE_SIZE / sizeof (forward_t);
05056       alloc_counts[(int) alloc_type_forward].cur_page = cur_page = allocate_page ();
05057       alloc_counts[(int) alloc_type_forward].total_pages++;
05058     }
05059 
05060   ptr = &cur_page->forward[--unallocated];
05061   alloc_counts[(int) alloc_type_forward].unallocated = unallocated;
05062 
05063 #else
05064 
05065   ptr = (forward_t *) xmalloc (sizeof (forward_t));
05066 
05067 #endif
05068 
05069   alloc_counts[(int) alloc_type_forward].total_alloc++;
05070   *ptr = initial_forward;
05071   return ptr;
05072 }
05073 
05074 /* Allocate head of type hash list.  */
05075 
05076 static thead_t *
05077 allocate_thead (void)
05078 {
05079   register thead_t *ptr;
05080   static thead_t initial_thead;
05081 
05082 #ifndef MALLOC_CHECK
05083 
05084   ptr = alloc_counts[(int) alloc_type_thead].free_list.f_thead;
05085   if (ptr != (thead_t *) NULL)
05086     alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr->free;
05087   else
05088     {
05089       register int unallocated = alloc_counts[(int) alloc_type_thead].unallocated;
05090       register page_type *cur_page = alloc_counts[(int) alloc_type_thead].cur_page;
05091 
05092       if (unallocated == 0)
05093        {
05094          unallocated = PAGE_SIZE / sizeof (thead_t);
05095          alloc_counts[(int) alloc_type_thead].cur_page = cur_page = allocate_page ();
05096          alloc_counts[(int) alloc_type_thead].total_pages++;
05097        }
05098 
05099       ptr = &cur_page->thead[--unallocated];
05100       alloc_counts[(int) alloc_type_thead].unallocated = unallocated;
05101     }
05102 
05103 #else
05104 
05105   ptr = (thead_t *) xmalloc (sizeof (thead_t));
05106 
05107 #endif
05108 
05109   alloc_counts[(int) alloc_type_thead].total_alloc++;
05110   *ptr = initial_thead;
05111   return ptr;
05112 }
05113 
05114 /* Free scoping information.  */
05115 
05116 static void
05117 free_thead (thead_t *ptr)
05118 {
05119   alloc_counts[(int) alloc_type_thead].total_free++;
05120 
05121 #ifndef MALLOC_CHECK
05122   ptr->free = (thead_t *) alloc_counts[(int) alloc_type_thead].free_list.f_thead;
05123   alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr;
05124 #else
05125   free ((PTR_T) ptr);
05126 #endif
05127 }
05128 
05129 static lineno_list_t *
05130 allocate_lineno_list (void)
05131 {
05132   register lineno_list_t *ptr;
05133   static lineno_list_t initial_lineno_list;
05134 
05135 #ifndef MALLOC_CHECK
05136 
05137   register int unallocated = alloc_counts[(int) alloc_type_lineno].unallocated;
05138   register page_type *cur_page = alloc_counts[(int) alloc_type_lineno].cur_page;
05139 
05140   if (unallocated == 0)
05141     {
05142       unallocated = PAGE_SIZE / sizeof (lineno_list_t);
05143       alloc_counts[(int) alloc_type_lineno].cur_page = cur_page = allocate_page ();
05144       alloc_counts[(int) alloc_type_lineno].total_pages++;
05145     }
05146 
05147   ptr = &cur_page->lineno[--unallocated];
05148   alloc_counts[(int) alloc_type_lineno].unallocated = unallocated;
05149 
05150 #else
05151 
05152   ptr = (lineno_list_t *) xmalloc (sizeof (lineno_list_t));
05153 
05154 #endif
05155 
05156   alloc_counts[(int) alloc_type_lineno].total_alloc++;
05157   *ptr = initial_lineno_list;
05158   return ptr;
05159 }
05160 
05161 void
05162 ecoff_set_gp_prolog_size (int sz)
05163 {
05164   if (cur_proc_ptr == 0)
05165     return;
05166 
05167   cur_proc_ptr->pdr.gp_prologue = sz;
05168   if (cur_proc_ptr->pdr.gp_prologue != sz)
05169     {
05170       as_warn (_("GP prologue size exceeds field size, using 0 instead"));
05171       cur_proc_ptr->pdr.gp_prologue = 0;
05172     }
05173 
05174   cur_proc_ptr->pdr.gp_used = 1;
05175 }
05176 
05177 int
05178 ecoff_no_current_file (void)
05179 {
05180   return cur_file_ptr == (efdr_t *) NULL;
05181 }
05182 
05183 void
05184 ecoff_generate_asm_lineno (void)
05185 {
05186   unsigned int lineno;
05187   char *filename;
05188   lineno_list_t *list;
05189 
05190   as_where (&filename, &lineno);
05191 
05192   if (current_stabs_filename == (char *) NULL
05193       || strcmp (current_stabs_filename, filename))
05194     add_file (filename, 0, 1);
05195 
05196   list = allocate_lineno_list ();
05197 
05198   list->next = (lineno_list_t *) NULL;
05199   list->file = cur_file_ptr;
05200   list->proc = cur_proc_ptr;
05201   list->frag = frag_now;
05202   list->paddr = frag_now_fix ();
05203   list->lineno = lineno;
05204 
05205   /* We don't want to merge files which have line numbers.  */
05206   cur_file_ptr->fdr.fMerge = 0;
05207 
05208   /* A .loc directive will sometimes appear before a .ent directive,
05209      which means that cur_proc_ptr will be NULL here.  Arrange to
05210      patch this up.  */
05211   if (cur_proc_ptr == (proc_t *) NULL)
05212     {
05213       lineno_list_t **pl;
05214 
05215       pl = &noproc_lineno;
05216       while (*pl != (lineno_list_t *) NULL)
05217        pl = &(*pl)->next;
05218       *pl = list;
05219     }
05220   else
05221     {
05222       last_lineno = list;
05223       *last_lineno_ptr = list;
05224       last_lineno_ptr = &list->next;
05225     }
05226 }
05227 
05228 #else
05229 
05230 void
05231 ecoff_generate_asm_lineno (void)
05232 {
05233 }
05234 
05235 #endif /* ECOFF_DEBUGGING */