12159047fSniklas /* ECOFF debugging support.
2c074d1c9Sdrahn Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3b55d4692Sfgsch Free Software Foundation, Inc.
42159047fSniklas Contributed by Cygnus Support.
52159047fSniklas This file was put together by Ian Lance Taylor <ian@cygnus.com>. A
62159047fSniklas good deal of it comes directly from mips-tfile.c, by Michael
72159047fSniklas Meissner <meissner@osf.org>.
82159047fSniklas
92159047fSniklas This file is part of GAS.
102159047fSniklas
112159047fSniklas GAS is free software; you can redistribute it and/or modify
122159047fSniklas it under the terms of the GNU General Public License as published by
132159047fSniklas the Free Software Foundation; either version 2, or (at your option)
142159047fSniklas any later version.
152159047fSniklas
162159047fSniklas GAS is distributed in the hope that it will be useful,
172159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
182159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
192159047fSniklas GNU General Public License for more details.
202159047fSniklas
212159047fSniklas You should have received a copy of the GNU General Public License
22191aa565Sniklas along with GAS; see the file COPYING. If not, write to the Free
23191aa565Sniklas Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24191aa565Sniklas 02111-1307, USA. */
252159047fSniklas
262159047fSniklas #include "as.h"
272159047fSniklas
282159047fSniklas /* This file is compiled conditionally for those targets which use
292159047fSniklas ECOFF debugging information (e.g., MIPS ECOFF, MIPS ELF, Alpha
302159047fSniklas ECOFF). */
312159047fSniklas
32b305b0f1Sespie #include "ecoff.h"
33b305b0f1Sespie
342159047fSniklas #ifdef ECOFF_DEBUGGING
352159047fSniklas
362159047fSniklas #include "coff/internal.h"
372159047fSniklas #include "coff/symconst.h"
382159047fSniklas #include "aout/stab_gnu.h"
392159047fSniklas
40c074d1c9Sdrahn #include "safe-ctype.h"
412159047fSniklas
422159047fSniklas /* Why isn't this in coff/sym.h? */
432159047fSniklas #define ST_RFDESCAPE 0xfff
442159047fSniklas
452159047fSniklas /* This file constructs the information used by the ECOFF debugging
462159047fSniklas format. It just builds a large block of data.
472159047fSniklas
482159047fSniklas We support both ECOFF style debugging and stabs debugging (the
492159047fSniklas stabs symbols are encapsulated in ECOFF symbols). This should let
502159047fSniklas us handle anything the compiler might throw at us. */
512159047fSniklas
522159047fSniklas /* Here is a brief description of the MIPS ECOFF symbol table, by
532159047fSniklas Michael Meissner. The MIPS symbol table has the following pieces:
542159047fSniklas
552159047fSniklas Symbolic Header
562159047fSniklas |
572159047fSniklas +-- Auxiliary Symbols
582159047fSniklas |
592159047fSniklas +-- Dense number table
602159047fSniklas |
612159047fSniklas +-- Optimizer Symbols
622159047fSniklas |
632159047fSniklas +-- External Strings
642159047fSniklas |
652159047fSniklas +-- External Symbols
662159047fSniklas |
672159047fSniklas +-- Relative file descriptors
682159047fSniklas |
692159047fSniklas +-- File table
702159047fSniklas |
712159047fSniklas +-- Procedure table
722159047fSniklas |
732159047fSniklas +-- Line number table
742159047fSniklas |
752159047fSniklas +-- Local Strings
762159047fSniklas |
772159047fSniklas +-- Local Symbols
782159047fSniklas
792159047fSniklas The symbolic header points to each of the other tables, and also
802159047fSniklas contains the number of entries. It also contains a magic number
812159047fSniklas and MIPS compiler version number, such as 2.0.
822159047fSniklas
832159047fSniklas The auxiliary table is a series of 32 bit integers, that are
842159047fSniklas referenced as needed from the local symbol table. Unlike standard
852159047fSniklas COFF, the aux. information does not follow the symbol that uses
862159047fSniklas it, but rather is a separate table. In theory, this would allow
872159047fSniklas the MIPS compilers to collapse duplicate aux. entries, but I've not
882159047fSniklas noticed this happening with the 1.31 compiler suite. The different
892159047fSniklas types of aux. entries are:
902159047fSniklas
912159047fSniklas 1) dnLow: Low bound on array dimension.
922159047fSniklas
932159047fSniklas 2) dnHigh: High bound on array dimension.
942159047fSniklas
952159047fSniklas 3) isym: Index to the local symbol which is the start of the
962159047fSniklas function for the end of function first aux. entry.
972159047fSniklas
982159047fSniklas 4) width: Width of structures and bitfields.
992159047fSniklas
1002159047fSniklas 5) count: Count of ranges for variant part.
1012159047fSniklas
1022159047fSniklas 6) rndx: A relative index into the symbol table. The relative
1032159047fSniklas index field has two parts: rfd which is a pointer into the
1042159047fSniklas relative file index table or ST_RFDESCAPE which says the next
1052159047fSniklas aux. entry is the file number, and index: which is the pointer
1062159047fSniklas into the local symbol within a given file table. This is for
1072159047fSniklas things like references to types defined in another file.
1082159047fSniklas
1092159047fSniklas 7) Type information: This is like the COFF type bits, except it
1102159047fSniklas is 32 bits instead of 16; they still have room to add new
1112159047fSniklas basic types; and they can handle more than 6 levels of array,
1122159047fSniklas pointer, function, etc. Each type information field contains
1132159047fSniklas the following structure members:
1142159047fSniklas
1152159047fSniklas a) fBitfield: a bit that says this is a bitfield, and the
1162159047fSniklas size in bits follows as the next aux. entry.
1172159047fSniklas
1182159047fSniklas b) continued: a bit that says the next aux. entry is a
1192159047fSniklas continuation of the current type information (in case
1202159047fSniklas there are more than 6 levels of array/ptr/function).
1212159047fSniklas
1222159047fSniklas c) bt: an integer containing the base type before adding
1232159047fSniklas array, pointer, function, etc. qualifiers. The
1242159047fSniklas current base types that I have documentation for are:
1252159047fSniklas
1262159047fSniklas btNil -- undefined
1272159047fSniklas btAdr -- address - integer same size as ptr
1282159047fSniklas btChar -- character
1292159047fSniklas btUChar -- unsigned character
1302159047fSniklas btShort -- short
1312159047fSniklas btUShort -- unsigned short
1322159047fSniklas btInt -- int
1332159047fSniklas btUInt -- unsigned int
1342159047fSniklas btLong -- long
1352159047fSniklas btULong -- unsigned long
1362159047fSniklas btFloat -- float (real)
1372159047fSniklas btDouble -- Double (real)
1382159047fSniklas btStruct -- Structure (Record)
1392159047fSniklas btUnion -- Union (variant)
1402159047fSniklas btEnum -- Enumerated
1412159047fSniklas btTypedef -- defined via a typedef isymRef
1422159047fSniklas btRange -- subrange of int
1432159047fSniklas btSet -- pascal sets
1442159047fSniklas btComplex -- fortran complex
1452159047fSniklas btDComplex -- fortran double complex
1462159047fSniklas btIndirect -- forward or unnamed typedef
1472159047fSniklas btFixedDec -- Fixed Decimal
1482159047fSniklas btFloatDec -- Float Decimal
1492159047fSniklas btString -- Varying Length Character String
1502159047fSniklas btBit -- Aligned Bit String
1512159047fSniklas btPicture -- Picture
1522159047fSniklas btVoid -- Void (MIPS cc revision >= 2.00)
1532159047fSniklas
1542159047fSniklas d) tq0 - tq5: type qualifier fields as needed. The
1552159047fSniklas current type qualifier fields I have documentation for
1562159047fSniklas are:
1572159047fSniklas
1582159047fSniklas tqNil -- no more qualifiers
1592159047fSniklas tqPtr -- pointer
1602159047fSniklas tqProc -- procedure
1612159047fSniklas tqArray -- array
1622159047fSniklas tqFar -- 8086 far pointers
1632159047fSniklas tqVol -- volatile
1642159047fSniklas
1652159047fSniklas The dense number table is used in the front ends, and disappears by
1662159047fSniklas the time the .o is created.
1672159047fSniklas
1682159047fSniklas With the 1.31 compiler suite, the optimization symbols don't seem
1692159047fSniklas to be used as far as I can tell.
1702159047fSniklas
1712159047fSniklas The linker is the first entity that creates the relative file
1722159047fSniklas descriptor table, and I believe it is used so that the individual
1732159047fSniklas file table pointers don't have to be rewritten when the objects are
1742159047fSniklas merged together into the program file.
1752159047fSniklas
1762159047fSniklas Unlike COFF, the basic symbol & string tables are split into
1772159047fSniklas external and local symbols/strings. The relocation information
1782159047fSniklas only goes off of the external symbol table, and the debug
1792159047fSniklas information only goes off of the internal symbol table. The
1802159047fSniklas external symbols can have links to an appropriate file index and
1812159047fSniklas symbol within the file to give it the appropriate type information.
1822159047fSniklas Because of this, the external symbols are actually larger than the
1832159047fSniklas internal symbols (to contain the link information), and contain the
1842159047fSniklas local symbol structure as a member, though this member is not the
1852159047fSniklas first member of the external symbol structure (!). I suspect this
1862159047fSniklas split is to make strip easier to deal with.
1872159047fSniklas
1882159047fSniklas Each file table has offsets for where the line numbers, local
1892159047fSniklas strings, local symbols, and procedure table starts from within the
1902159047fSniklas global tables, and the indexs are reset to 0 for each of those
1912159047fSniklas tables for the file.
1922159047fSniklas
1932159047fSniklas The procedure table contains the binary equivalents of the .ent
1942159047fSniklas (start of the function address), .frame (what register is the
1952159047fSniklas virtual frame pointer, constant offset from the register to obtain
1962159047fSniklas the VFP, and what register holds the return address), .mask/.fmask
1972159047fSniklas (bitmask of saved registers, and where the first register is stored
1982159047fSniklas relative to the VFP) assembler directives. It also contains the
1992159047fSniklas low and high bounds of the line numbers if debugging is turned on.
2002159047fSniklas
2012159047fSniklas The line number table is a compressed form of the normal COFF line
2022159047fSniklas table. Each line number entry is either 1 or 3 bytes long, and
2032159047fSniklas contains a signed delta from the previous line, and an unsigned
2042159047fSniklas count of the number of instructions this statement takes.
2052159047fSniklas
2062159047fSniklas The local symbol table contains the following fields:
2072159047fSniklas
2082159047fSniklas 1) iss: index to the local string table giving the name of the
2092159047fSniklas symbol.
2102159047fSniklas
2112159047fSniklas 2) value: value of the symbol (address, register number, etc.).
2122159047fSniklas
2132159047fSniklas 3) st: symbol type. The current symbol types are:
2142159047fSniklas
2152159047fSniklas stNil -- Nuthin' special
2162159047fSniklas stGlobal -- external symbol
2172159047fSniklas stStatic -- static
2182159047fSniklas stParam -- procedure argument
2192159047fSniklas stLocal -- local variable
2202159047fSniklas stLabel -- label
2212159047fSniklas stProc -- External Procedure
2222159047fSniklas stBlock -- beginning of block
2232159047fSniklas stEnd -- end (of anything)
2242159047fSniklas stMember -- member (of anything)
2252159047fSniklas stTypedef -- type definition
2262159047fSniklas stFile -- file name
2272159047fSniklas stRegReloc -- register relocation
2282159047fSniklas stForward -- forwarding address
2292159047fSniklas stStaticProc -- Static procedure
2302159047fSniklas stConstant -- const
2312159047fSniklas
2322159047fSniklas 4) sc: storage class. The current storage classes are:
2332159047fSniklas
2342159047fSniklas scText -- text symbol
2352159047fSniklas scData -- initialized data symbol
2362159047fSniklas scBss -- un-initialized data symbol
2372159047fSniklas scRegister -- value of symbol is register number
2382159047fSniklas scAbs -- value of symbol is absolute
2392159047fSniklas scUndefined -- who knows?
2402159047fSniklas scCdbLocal -- variable's value is IN se->va.??
2412159047fSniklas scBits -- this is a bit field
2422159047fSniklas scCdbSystem -- value is IN debugger's address space
2432159047fSniklas scRegImage -- register value saved on stack
2442159047fSniklas scInfo -- symbol contains debugger information
2452159047fSniklas scUserStruct -- addr in struct user for current process
2462159047fSniklas scSData -- load time only small data
2472159047fSniklas scSBss -- load time only small common
2482159047fSniklas scRData -- load time only read only data
2492159047fSniklas scVar -- Var parameter (fortranpascal)
2502159047fSniklas scCommon -- common variable
2512159047fSniklas scSCommon -- small common
2522159047fSniklas scVarRegister -- Var parameter in a register
2532159047fSniklas scVariant -- Variant record
2542159047fSniklas scSUndefined -- small undefined(external) data
2552159047fSniklas scInit -- .init section symbol
2562159047fSniklas
2572159047fSniklas 5) index: pointer to a local symbol or aux. entry.
2582159047fSniklas
2592159047fSniklas For the following program:
2602159047fSniklas
2612159047fSniklas #include <stdio.h>
2622159047fSniklas
2632159047fSniklas main(){
2642159047fSniklas printf("Hello World!\n");
2652159047fSniklas return 0;
2662159047fSniklas }
2672159047fSniklas
2682159047fSniklas Mips-tdump produces the following information:
2692159047fSniklas
2702159047fSniklas Global file header:
2712159047fSniklas magic number 0x162
2722159047fSniklas # sections 2
2732159047fSniklas timestamp 645311799, Wed Jun 13 17:16:39 1990
2742159047fSniklas symbolic header offset 284
2752159047fSniklas symbolic header size 96
2762159047fSniklas optional header 56
2772159047fSniklas flags 0x0
2782159047fSniklas
2792159047fSniklas Symbolic header, magic number = 0x7009, vstamp = 1.31:
2802159047fSniklas
2812159047fSniklas Info Offset Number Bytes
2822159047fSniklas ==== ====== ====== =====
2832159047fSniklas
2842159047fSniklas Line numbers 380 4 4 [13]
2852159047fSniklas Dense numbers 0 0 0
2862159047fSniklas Procedures Tables 384 1 52
2872159047fSniklas Local Symbols 436 16 192
2882159047fSniklas Optimization Symbols 0 0 0
2892159047fSniklas Auxiliary Symbols 628 39 156
2902159047fSniklas Local Strings 784 80 80
2912159047fSniklas External Strings 864 144 144
2922159047fSniklas File Tables 1008 2 144
2932159047fSniklas Relative Files 0 0 0
2942159047fSniklas External Symbols 1152 20 320
2952159047fSniklas
2962159047fSniklas File #0, "hello2.c"
2972159047fSniklas
2982159047fSniklas Name index = 1 Readin = No
2992159047fSniklas Merge = No Endian = LITTLE
3002159047fSniklas Debug level = G2 Language = C
3012159047fSniklas Adr = 0x00000000
3022159047fSniklas
3032159047fSniklas Info Start Number Size Offset
3042159047fSniklas ==== ===== ====== ==== ======
3052159047fSniklas Local strings 0 15 15 784
3062159047fSniklas Local symbols 0 6 72 436
3072159047fSniklas Line numbers 0 13 13 380
3082159047fSniklas Optimization symbols 0 0 0 0
3092159047fSniklas Procedures 0 1 52 384
3102159047fSniklas Auxiliary symbols 0 14 56 628
3112159047fSniklas Relative Files 0 0 0 0
3122159047fSniklas
3132159047fSniklas There are 6 local symbols, starting at 436
3142159047fSniklas
3152159047fSniklas Symbol# 0: "hello2.c"
3162159047fSniklas End+1 symbol = 6
3172159047fSniklas String index = 1
3182159047fSniklas Storage class = Text Index = 6
3192159047fSniklas Symbol type = File Value = 0
3202159047fSniklas
3212159047fSniklas Symbol# 1: "main"
3222159047fSniklas End+1 symbol = 5
3232159047fSniklas Type = int
3242159047fSniklas String index = 10
3252159047fSniklas Storage class = Text Index = 12
3262159047fSniklas Symbol type = Proc Value = 0
3272159047fSniklas
3282159047fSniklas Symbol# 2: ""
3292159047fSniklas End+1 symbol = 4
3302159047fSniklas String index = 0
3312159047fSniklas Storage class = Text Index = 4
3322159047fSniklas Symbol type = Block Value = 8
3332159047fSniklas
3342159047fSniklas Symbol# 3: ""
3352159047fSniklas First symbol = 2
3362159047fSniklas String index = 0
3372159047fSniklas Storage class = Text Index = 2
3382159047fSniklas Symbol type = End Value = 28
3392159047fSniklas
3402159047fSniklas Symbol# 4: "main"
3412159047fSniklas First symbol = 1
3422159047fSniklas String index = 10
3432159047fSniklas Storage class = Text Index = 1
3442159047fSniklas Symbol type = End Value = 52
3452159047fSniklas
3462159047fSniklas Symbol# 5: "hello2.c"
3472159047fSniklas First symbol = 0
3482159047fSniklas String index = 1
3492159047fSniklas Storage class = Text Index = 0
3502159047fSniklas Symbol type = End Value = 0
3512159047fSniklas
3522159047fSniklas There are 14 auxiliary table entries, starting at 628.
3532159047fSniklas
3542159047fSniklas * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
3552159047fSniklas * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
3562159047fSniklas * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0]
3572159047fSniklas * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0]
3582159047fSniklas * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
3592159047fSniklas * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0]
3602159047fSniklas * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0]
3612159047fSniklas * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0]
3622159047fSniklas * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0]
3632159047fSniklas * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0]
3642159047fSniklas * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0]
3652159047fSniklas * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0]
3662159047fSniklas #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0]
3672159047fSniklas #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
3682159047fSniklas
3692159047fSniklas There are 1 procedure descriptor entries, starting at 0.
3702159047fSniklas
3712159047fSniklas Procedure descriptor 0:
3722159047fSniklas Name index = 10 Name = "main"
3732159047fSniklas .mask 0x80000000,-4 .fmask 0x00000000,0
3742159047fSniklas .frame $29,24,$31
3752159047fSniklas Opt. start = -1 Symbols start = 1
3762159047fSniklas First line # = 3 Last line # = 6
3772159047fSniklas Line Offset = 0 Address = 0x00000000
3782159047fSniklas
3792159047fSniklas There are 4 bytes holding line numbers, starting at 380.
3802159047fSniklas Line 3, delta 0, count 2
3812159047fSniklas Line 4, delta 1, count 3
3822159047fSniklas Line 5, delta 1, count 2
3832159047fSniklas Line 6, delta 1, count 6
3842159047fSniklas
3852159047fSniklas File #1, "/usr/include/stdio.h"
3862159047fSniklas
3872159047fSniklas Name index = 1 Readin = No
3882159047fSniklas Merge = Yes Endian = LITTLE
3892159047fSniklas Debug level = G2 Language = C
3902159047fSniklas Adr = 0x00000000
3912159047fSniklas
3922159047fSniklas Info Start Number Size Offset
3932159047fSniklas ==== ===== ====== ==== ======
3942159047fSniklas Local strings 15 65 65 799
3952159047fSniklas Local symbols 6 10 120 508
3962159047fSniklas Line numbers 0 0 0 380
3972159047fSniklas Optimization symbols 0 0 0 0
3982159047fSniklas Procedures 1 0 0 436
3992159047fSniklas Auxiliary symbols 14 25 100 684
4002159047fSniklas Relative Files 0 0 0 0
4012159047fSniklas
4022159047fSniklas There are 10 local symbols, starting at 442
4032159047fSniklas
4042159047fSniklas Symbol# 0: "/usr/include/stdio.h"
4052159047fSniklas End+1 symbol = 10
4062159047fSniklas String index = 1
4072159047fSniklas Storage class = Text Index = 10
4082159047fSniklas Symbol type = File Value = 0
4092159047fSniklas
4102159047fSniklas Symbol# 1: "_iobuf"
4112159047fSniklas End+1 symbol = 9
4122159047fSniklas String index = 22
4132159047fSniklas Storage class = Info Index = 9
4142159047fSniklas Symbol type = Block Value = 20
4152159047fSniklas
4162159047fSniklas Symbol# 2: "_cnt"
4172159047fSniklas Type = int
4182159047fSniklas String index = 29
4192159047fSniklas Storage class = Info Index = 4
4202159047fSniklas Symbol type = Member Value = 0
4212159047fSniklas
4222159047fSniklas Symbol# 3: "_ptr"
4232159047fSniklas Type = ptr to char
4242159047fSniklas String index = 34
4252159047fSniklas Storage class = Info Index = 15
4262159047fSniklas Symbol type = Member Value = 32
4272159047fSniklas
4282159047fSniklas Symbol# 4: "_base"
4292159047fSniklas Type = ptr to char
4302159047fSniklas String index = 39
4312159047fSniklas Storage class = Info Index = 16
4322159047fSniklas Symbol type = Member Value = 64
4332159047fSniklas
4342159047fSniklas Symbol# 5: "_bufsiz"
4352159047fSniklas Type = int
4362159047fSniklas String index = 45
4372159047fSniklas Storage class = Info Index = 4
4382159047fSniklas Symbol type = Member Value = 96
4392159047fSniklas
4402159047fSniklas Symbol# 6: "_flag"
4412159047fSniklas Type = short
4422159047fSniklas String index = 53
4432159047fSniklas Storage class = Info Index = 3
4442159047fSniklas Symbol type = Member Value = 128
4452159047fSniklas
4462159047fSniklas Symbol# 7: "_file"
4472159047fSniklas Type = char
4482159047fSniklas String index = 59
4492159047fSniklas Storage class = Info Index = 2
4502159047fSniklas Symbol type = Member Value = 144
4512159047fSniklas
4522159047fSniklas Symbol# 8: ""
4532159047fSniklas First symbol = 1
4542159047fSniklas String index = 0
4552159047fSniklas Storage class = Info Index = 1
4562159047fSniklas Symbol type = End Value = 0
4572159047fSniklas
4582159047fSniklas Symbol# 9: "/usr/include/stdio.h"
4592159047fSniklas First symbol = 0
4602159047fSniklas String index = 1
4612159047fSniklas Storage class = Text Index = 0
4622159047fSniklas Symbol type = End Value = 0
4632159047fSniklas
4642159047fSniklas There are 25 auxiliary table entries, starting at 642.
4652159047fSniklas
4662159047fSniklas * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
4672159047fSniklas #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
4682159047fSniklas #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
4692159047fSniklas * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0]
4702159047fSniklas * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1]
4712159047fSniklas * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
4722159047fSniklas * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4]
4732159047fSniklas * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
4742159047fSniklas * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4752159047fSniklas * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0]
4762159047fSniklas * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0]
4772159047fSniklas * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4782159047fSniklas * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4792159047fSniklas * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4802159047fSniklas * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4812159047fSniklas * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4822159047fSniklas * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4832159047fSniklas * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4842159047fSniklas * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4852159047fSniklas * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4862159047fSniklas * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4872159047fSniklas * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4882159047fSniklas * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4892159047fSniklas * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4902159047fSniklas * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
4912159047fSniklas
4922159047fSniklas There are 0 procedure descriptor entries, starting at 1.
4932159047fSniklas
4942159047fSniklas There are 20 external symbols, starting at 1152
4952159047fSniklas
4962159047fSniklas Symbol# 0: "_iob"
4972159047fSniklas Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
4982159047fSniklas String index = 0 Ifd = 1
4992159047fSniklas Storage class = Nil Index = 17
5002159047fSniklas Symbol type = Global Value = 60
5012159047fSniklas
5022159047fSniklas Symbol# 1: "fopen"
5032159047fSniklas String index = 5 Ifd = 1
5042159047fSniklas Storage class = Nil Index = 1048575
5052159047fSniklas Symbol type = Proc Value = 0
5062159047fSniklas
5072159047fSniklas Symbol# 2: "fdopen"
5082159047fSniklas String index = 11 Ifd = 1
5092159047fSniklas Storage class = Nil Index = 1048575
5102159047fSniklas Symbol type = Proc Value = 0
5112159047fSniklas
5122159047fSniklas Symbol# 3: "freopen"
5132159047fSniklas String index = 18 Ifd = 1
5142159047fSniklas Storage class = Nil Index = 1048575
5152159047fSniklas Symbol type = Proc Value = 0
5162159047fSniklas
5172159047fSniklas Symbol# 4: "popen"
5182159047fSniklas String index = 26 Ifd = 1
5192159047fSniklas Storage class = Nil Index = 1048575
5202159047fSniklas Symbol type = Proc Value = 0
5212159047fSniklas
5222159047fSniklas Symbol# 5: "tmpfile"
5232159047fSniklas String index = 32 Ifd = 1
5242159047fSniklas Storage class = Nil Index = 1048575
5252159047fSniklas Symbol type = Proc Value = 0
5262159047fSniklas
5272159047fSniklas Symbol# 6: "ftell"
5282159047fSniklas String index = 40 Ifd = 1
5292159047fSniklas Storage class = Nil Index = 1048575
5302159047fSniklas Symbol type = Proc Value = 0
5312159047fSniklas
5322159047fSniklas Symbol# 7: "rewind"
5332159047fSniklas String index = 46 Ifd = 1
5342159047fSniklas Storage class = Nil Index = 1048575
5352159047fSniklas Symbol type = Proc Value = 0
5362159047fSniklas
5372159047fSniklas Symbol# 8: "setbuf"
5382159047fSniklas String index = 53 Ifd = 1
5392159047fSniklas Storage class = Nil Index = 1048575
5402159047fSniklas Symbol type = Proc Value = 0
5412159047fSniklas
5422159047fSniklas Symbol# 9: "setbuffer"
5432159047fSniklas String index = 60 Ifd = 1
5442159047fSniklas Storage class = Nil Index = 1048575
5452159047fSniklas Symbol type = Proc Value = 0
5462159047fSniklas
5472159047fSniklas Symbol# 10: "setlinebuf"
5482159047fSniklas String index = 70 Ifd = 1
5492159047fSniklas Storage class = Nil Index = 1048575
5502159047fSniklas Symbol type = Proc Value = 0
5512159047fSniklas
5522159047fSniklas Symbol# 11: "fgets"
5532159047fSniklas String index = 81 Ifd = 1
5542159047fSniklas Storage class = Nil Index = 1048575
5552159047fSniklas Symbol type = Proc Value = 0
5562159047fSniklas
5572159047fSniklas Symbol# 12: "gets"
5582159047fSniklas String index = 87 Ifd = 1
5592159047fSniklas Storage class = Nil Index = 1048575
5602159047fSniklas Symbol type = Proc Value = 0
5612159047fSniklas
5622159047fSniklas Symbol# 13: "ctermid"
5632159047fSniklas String index = 92 Ifd = 1
5642159047fSniklas Storage class = Nil Index = 1048575
5652159047fSniklas Symbol type = Proc Value = 0
5662159047fSniklas
5672159047fSniklas Symbol# 14: "cuserid"
5682159047fSniklas String index = 100 Ifd = 1
5692159047fSniklas Storage class = Nil Index = 1048575
5702159047fSniklas Symbol type = Proc Value = 0
5712159047fSniklas
5722159047fSniklas Symbol# 15: "tempnam"
5732159047fSniklas String index = 108 Ifd = 1
5742159047fSniklas Storage class = Nil Index = 1048575
5752159047fSniklas Symbol type = Proc Value = 0
5762159047fSniklas
5772159047fSniklas Symbol# 16: "tmpnam"
5782159047fSniklas String index = 116 Ifd = 1
5792159047fSniklas Storage class = Nil Index = 1048575
5802159047fSniklas Symbol type = Proc Value = 0
5812159047fSniklas
5822159047fSniklas Symbol# 17: "sprintf"
5832159047fSniklas String index = 123 Ifd = 1
5842159047fSniklas Storage class = Nil Index = 1048575
5852159047fSniklas Symbol type = Proc Value = 0
5862159047fSniklas
5872159047fSniklas Symbol# 18: "main"
5882159047fSniklas Type = int
5892159047fSniklas String index = 131 Ifd = 0
5902159047fSniklas Storage class = Text Index = 1
5912159047fSniklas Symbol type = Proc Value = 0
5922159047fSniklas
5932159047fSniklas Symbol# 19: "printf"
5942159047fSniklas String index = 136 Ifd = 0
5952159047fSniklas Storage class = Undefined Index = 1048575
5962159047fSniklas Symbol type = Proc Value = 0
5972159047fSniklas
5982159047fSniklas The following auxiliary table entries were unused:
5992159047fSniklas
6002159047fSniklas #0 0 0x00000000 void
6012159047fSniklas #2 8 0x00000008 char
6022159047fSniklas #3 16 0x00000010 short
6032159047fSniklas #4 24 0x00000018 int
6042159047fSniklas #5 32 0x00000020 long
6052159047fSniklas #6 40 0x00000028 float
6062159047fSniklas #7 44 0x0000002c double
6072159047fSniklas #8 12 0x0000000c unsigned char
6082159047fSniklas #9 20 0x00000014 unsigned short
6092159047fSniklas #10 28 0x0000001c unsigned int
6102159047fSniklas #11 36 0x00000024 unsigned long
6112159047fSniklas #14 0 0x00000000 void
6122159047fSniklas #15 24 0x00000018 int
6132159047fSniklas #19 32 0x00000020 long
6142159047fSniklas #20 40 0x00000028 float
6152159047fSniklas #21 44 0x0000002c double
6162159047fSniklas #22 12 0x0000000c unsigned char
6172159047fSniklas #23 20 0x00000014 unsigned short
6182159047fSniklas #24 28 0x0000001c unsigned int
6192159047fSniklas #25 36 0x00000024 unsigned long
6202159047fSniklas #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 }
6212159047fSniklas */
6222159047fSniklas
6232159047fSniklas /* Redefinition of of storage classes as an enumeration for better
6242159047fSniklas debugging. */
6252159047fSniklas
6262159047fSniklas typedef enum sc {
6272159047fSniklas sc_Nil = scNil, /* no storage class */
6282159047fSniklas sc_Text = scText, /* text symbol */
6292159047fSniklas sc_Data = scData, /* initialized data symbol */
6302159047fSniklas sc_Bss = scBss, /* un-initialized data symbol */
6312159047fSniklas sc_Register = scRegister, /* value of symbol is register number */
6322159047fSniklas sc_Abs = scAbs, /* value of symbol is absolute */
6332159047fSniklas sc_Undefined = scUndefined, /* who knows? */
6342159047fSniklas sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
6352159047fSniklas sc_Bits = scBits, /* this is a bit field */
6362159047fSniklas sc_CdbSystem = scCdbSystem, /* value is IN CDB's address space */
6372159047fSniklas sc_RegImage = scRegImage, /* register value saved on stack */
6382159047fSniklas sc_Info = scInfo, /* symbol contains debugger information */
6392159047fSniklas sc_UserStruct = scUserStruct, /* addr in struct user for current process */
6402159047fSniklas sc_SData = scSData, /* load time only small data */
6412159047fSniklas sc_SBss = scSBss, /* load time only small common */
6422159047fSniklas sc_RData = scRData, /* load time only read only data */
6432159047fSniklas sc_Var = scVar, /* Var parameter (fortran,pascal) */
6442159047fSniklas sc_Common = scCommon, /* common variable */
6452159047fSniklas sc_SCommon = scSCommon, /* small common */
6462159047fSniklas sc_VarRegister = scVarRegister, /* Var parameter in a register */
6472159047fSniklas sc_Variant = scVariant, /* Variant record */
6482159047fSniklas sc_SUndefined = scSUndefined, /* small undefined(external) data */
6492159047fSniklas sc_Init = scInit, /* .init section symbol */
6502159047fSniklas sc_Max = scMax /* Max storage class+1 */
6512159047fSniklas } sc_t;
6522159047fSniklas
6532159047fSniklas /* Redefinition of symbol type. */
6542159047fSniklas
6552159047fSniklas typedef enum st {
6562159047fSniklas st_Nil = stNil, /* Nuthin' special */
6572159047fSniklas st_Global = stGlobal, /* external symbol */
6582159047fSniklas st_Static = stStatic, /* static */
6592159047fSniklas st_Param = stParam, /* procedure argument */
6602159047fSniklas st_Local = stLocal, /* local variable */
6612159047fSniklas st_Label = stLabel, /* label */
6622159047fSniklas st_Proc = stProc, /* " " Procedure */
6632159047fSniklas st_Block = stBlock, /* beginning of block */
6642159047fSniklas st_End = stEnd, /* end (of anything) */
6652159047fSniklas st_Member = stMember, /* member (of anything - struct/union/enum */
6662159047fSniklas st_Typedef = stTypedef, /* type definition */
6672159047fSniklas st_File = stFile, /* file name */
6682159047fSniklas st_RegReloc = stRegReloc, /* register relocation */
6692159047fSniklas st_Forward = stForward, /* forwarding address */
6702159047fSniklas st_StaticProc = stStaticProc, /* load time only static procs */
6712159047fSniklas st_Constant = stConstant, /* const */
6722159047fSniklas st_Str = stStr, /* string */
6732159047fSniklas st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
6742159047fSniklas st_Expr = stExpr, /* 2+2 vs. 4 */
6752159047fSniklas st_Type = stType, /* post-coercion SER */
6762159047fSniklas st_Max = stMax /* max type+1 */
6772159047fSniklas } st_t;
6782159047fSniklas
6792159047fSniklas /* Redefinition of type qualifiers. */
6802159047fSniklas
6812159047fSniklas typedef enum tq {
6822159047fSniklas tq_Nil = tqNil, /* bt is what you see */
6832159047fSniklas tq_Ptr = tqPtr, /* pointer */
6842159047fSniklas tq_Proc = tqProc, /* procedure */
6852159047fSniklas tq_Array = tqArray, /* duh */
6862159047fSniklas tq_Far = tqFar, /* longer addressing - 8086/8 land */
6872159047fSniklas tq_Vol = tqVol, /* volatile */
6882159047fSniklas tq_Max = tqMax /* Max type qualifier+1 */
6892159047fSniklas } tq_t;
6902159047fSniklas
6912159047fSniklas /* Redefinition of basic types. */
6922159047fSniklas
6932159047fSniklas typedef enum bt {
6942159047fSniklas bt_Nil = btNil, /* undefined */
6952159047fSniklas bt_Adr = btAdr, /* address - integer same size as pointer */
6962159047fSniklas bt_Char = btChar, /* character */
6972159047fSniklas bt_UChar = btUChar, /* unsigned character */
6982159047fSniklas bt_Short = btShort, /* short */
6992159047fSniklas bt_UShort = btUShort, /* unsigned short */
7002159047fSniklas bt_Int = btInt, /* int */
7012159047fSniklas bt_UInt = btUInt, /* unsigned int */
7022159047fSniklas bt_Long = btLong, /* long */
7032159047fSniklas bt_ULong = btULong, /* unsigned long */
7042159047fSniklas bt_Float = btFloat, /* float (real) */
7052159047fSniklas bt_Double = btDouble, /* Double (real) */
7062159047fSniklas bt_Struct = btStruct, /* Structure (Record) */
7072159047fSniklas bt_Union = btUnion, /* Union (variant) */
7082159047fSniklas bt_Enum = btEnum, /* Enumerated */
7092159047fSniklas bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
7102159047fSniklas bt_Range = btRange, /* subrange of int */
7112159047fSniklas bt_Set = btSet, /* pascal sets */
7122159047fSniklas bt_Complex = btComplex, /* fortran complex */
7132159047fSniklas bt_DComplex = btDComplex, /* fortran double complex */
7142159047fSniklas bt_Indirect = btIndirect, /* forward or unnamed typedef */
7152159047fSniklas bt_FixedDec = btFixedDec, /* Fixed Decimal */
7162159047fSniklas bt_FloatDec = btFloatDec, /* Float Decimal */
7172159047fSniklas bt_String = btString, /* Varying Length Character String */
7182159047fSniklas bt_Bit = btBit, /* Aligned Bit String */
7192159047fSniklas bt_Picture = btPicture, /* Picture */
7202159047fSniklas bt_Void = btVoid, /* Void */
7212159047fSniklas bt_Max = btMax /* Max basic type+1 */
7222159047fSniklas } bt_t;
7232159047fSniklas
7242159047fSniklas #define N_TQ itqMax
7252159047fSniklas
7262159047fSniklas /* States for whether to hash type or not. */
7272159047fSniklas typedef enum hash_state {
728b55d4692Sfgsch hash_no = 0, /* Don't hash type */
729b55d4692Sfgsch hash_yes = 1, /* OK to hash type, or use previous hash */
730b55d4692Sfgsch hash_record = 2 /* OK to record hash, but don't use prev. */
7312159047fSniklas } hash_state_t;
7322159047fSniklas
7332159047fSniklas /* Types of different sized allocation requests. */
7342159047fSniklas enum alloc_type {
7352159047fSniklas alloc_type_none, /* dummy value */
7362159047fSniklas alloc_type_scope, /* nested scopes linked list */
7372159047fSniklas alloc_type_vlinks, /* glue linking pages in varray */
7382159047fSniklas alloc_type_shash, /* string hash element */
7392159047fSniklas alloc_type_thash, /* type hash element */
7402159047fSniklas alloc_type_tag, /* struct/union/tag element */
7412159047fSniklas alloc_type_forward, /* element to hold unknown tag */
7422159047fSniklas alloc_type_thead, /* head of type hash list */
7432159047fSniklas alloc_type_varray, /* general varray allocation */
7442159047fSniklas alloc_type_lineno, /* line number list */
7452159047fSniklas alloc_type_last /* last+1 element for array bounds */
7462159047fSniklas };
7472159047fSniklas
7482159047fSniklas /* Types of auxiliary type information. */
7492159047fSniklas enum aux_type {
7502159047fSniklas aux_tir, /* TIR type information */
7512159047fSniklas aux_rndx, /* relative index into symbol table */
7522159047fSniklas aux_dnLow, /* low dimension */
7532159047fSniklas aux_dnHigh, /* high dimension */
7542159047fSniklas aux_isym, /* symbol table index (end of proc) */
7552159047fSniklas aux_iss, /* index into string space (not used) */
7562159047fSniklas aux_width, /* width for non-default sized struc fields */
7572159047fSniklas aux_count /* count of ranges for variant arm */
7582159047fSniklas };
7592159047fSniklas
7602159047fSniklas /* Structures to provide n-number of virtual arrays, each of which can
7612159047fSniklas grow linearly, and which are written in the object file as
7622159047fSniklas sequential pages. On systems with a BSD malloc, the
7632159047fSniklas MAX_CLUSTER_PAGES should be 1 less than a power of two, since
7642159047fSniklas malloc adds it's overhead, and rounds up to the next power of 2.
7652159047fSniklas Pages are linked together via a linked list.
7662159047fSniklas
7672159047fSniklas If PAGE_SIZE is > 4096, the string length in the shash_t structure
7682159047fSniklas can't be represented (assuming there are strings > 4096 bytes). */
7692159047fSniklas
770b305b0f1Sespie /* FIXME: Yes, there can be such strings while emitting C++ class debug
771b305b0f1Sespie info. Templates are the offender here, the test case in question
772b305b0f1Sespie having a mangled class name of
773b305b0f1Sespie
774b305b0f1Sespie t7rb_tree4Z4xkeyZt4pair2ZC4xkeyZt7xsocket1Z4UserZt9select1st2Zt4pair\
775b305b0f1Sespie 2ZC4xkeyZt7xsocket1Z4UserZ4xkeyZt4less1Z4xkey
776b305b0f1Sespie
777b305b0f1Sespie Repeat that a couple dozen times while listing the class members and
778b305b0f1Sespie you've got strings over 4k. Hack around this for now by increasing
779b305b0f1Sespie the page size. A proper solution would abandon this structure scheme
780b305b0f1Sespie certainly for very large strings, and possibly entirely. */
781b305b0f1Sespie
7822159047fSniklas #ifndef PAGE_SIZE
783b305b0f1Sespie #define PAGE_SIZE (8*1024) /* size of varray pages */
7842159047fSniklas #endif
7852159047fSniklas
7862159047fSniklas #define PAGE_USIZE ((unsigned long) PAGE_SIZE)
7872159047fSniklas
7882159047fSniklas #ifndef MAX_CLUSTER_PAGES /* # pages to get from system */
7892159047fSniklas #define MAX_CLUSTER_PAGES 63
7902159047fSniklas #endif
7912159047fSniklas
7922159047fSniklas /* Linked list connecting separate page allocations. */
7932159047fSniklas typedef struct vlinks {
7942159047fSniklas struct vlinks *prev; /* previous set of pages */
7952159047fSniklas struct vlinks *next; /* next set of pages */
7962159047fSniklas union page *datum; /* start of page */
7972159047fSniklas unsigned long start_index; /* starting index # of page */
7982159047fSniklas } vlinks_t;
7992159047fSniklas
8002159047fSniklas /* Virtual array header. */
8012159047fSniklas typedef struct varray {
8022159047fSniklas vlinks_t *first; /* first page link */
8032159047fSniklas vlinks_t *last; /* last page link */
8042159047fSniklas unsigned long num_allocated; /* # objects allocated */
8052159047fSniklas unsigned short object_size; /* size in bytes of each object */
8062159047fSniklas unsigned short objects_per_page; /* # objects that can fit on a page */
8072159047fSniklas unsigned short objects_last_page; /* # objects allocated on last page */
8082159047fSniklas } varray_t;
8092159047fSniklas
8102159047fSniklas #ifndef MALLOC_CHECK
8112159047fSniklas #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
8122159047fSniklas #else
8132159047fSniklas #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
8142159047fSniklas #endif
8152159047fSniklas
8162159047fSniklas #define INIT_VARRAY(type) { /* macro to initialize a varray */ \
8172159047fSniklas (vlinks_t *)0, /* first */ \
8182159047fSniklas (vlinks_t *)0, /* last */ \
8192159047fSniklas 0, /* num_allocated */ \
8202159047fSniklas sizeof (type), /* object_size */ \
8212159047fSniklas OBJECTS_PER_PAGE (type), /* objects_per_page */ \
8222159047fSniklas OBJECTS_PER_PAGE (type), /* objects_last_page */ \
8232159047fSniklas }
8242159047fSniklas
8252159047fSniklas /* Master type for indexes within the symbol table. */
8262159047fSniklas typedef unsigned long symint_t;
8272159047fSniklas
8282159047fSniklas /* Linked list support for nested scopes (file, block, structure, etc.). */
8292159047fSniklas typedef struct scope {
8302159047fSniklas struct scope *prev; /* previous scope level */
8312159047fSniklas struct scope *free; /* free list pointer */
8322159047fSniklas struct localsym *lsym; /* pointer to local symbol node */
8332159047fSniklas st_t type; /* type of the node */
8342159047fSniklas } scope_t;
8352159047fSniklas
8362159047fSniklas /* For a local symbol we store a gas symbol as well as the debugging
8372159047fSniklas information we generate. The gas symbol will be NULL if this is
8382159047fSniklas only a debugging symbol. */
8392159047fSniklas typedef struct localsym {
8402159047fSniklas const char *name; /* symbol name */
8412159047fSniklas symbolS *as_sym; /* symbol as seen by gas */
842191aa565Sniklas bfd_vma addend; /* addend to as_sym value */
8432159047fSniklas struct efdr *file_ptr; /* file pointer */
8442159047fSniklas struct ecoff_proc *proc_ptr; /* proc pointer */
8452159047fSniklas struct localsym *begin_ptr; /* symbol at start of block */
8462159047fSniklas struct ecoff_aux *index_ptr; /* index value to be filled in */
8472159047fSniklas struct forward *forward_ref; /* forward references to this symbol */
8482159047fSniklas long sym_index; /* final symbol index */
8492159047fSniklas EXTR ecoff_sym; /* ECOFF debugging symbol */
8502159047fSniklas } localsym_t;
8512159047fSniklas
8522159047fSniklas /* For aux information we keep the type and the data. */
8532159047fSniklas typedef struct ecoff_aux {
8542159047fSniklas enum aux_type type; /* aux type */
8552159047fSniklas AUXU data; /* aux data */
8562159047fSniklas } aux_t;
8572159047fSniklas
8582159047fSniklas /* For a procedure we store the gas symbol as well as the PDR
8592159047fSniklas debugging information. */
8602159047fSniklas typedef struct ecoff_proc {
8612159047fSniklas localsym_t *sym; /* associated symbol */
8622159047fSniklas PDR pdr; /* ECOFF debugging info */
8632159047fSniklas } proc_t;
8642159047fSniklas
8652159047fSniklas /* Number of proc_t structures allocated. */
8662159047fSniklas static unsigned long proc_cnt;
8672159047fSniklas
8682159047fSniklas /* Forward reference list for tags referenced, but not yet defined. */
8692159047fSniklas typedef struct forward {
8702159047fSniklas struct forward *next; /* next forward reference */
8712159047fSniklas struct forward *free; /* free list pointer */
8722159047fSniklas aux_t *ifd_ptr; /* pointer to store file index */
8732159047fSniklas aux_t *index_ptr; /* pointer to store symbol index */
8742159047fSniklas } forward_t;
8752159047fSniklas
8762159047fSniklas /* Linked list support for tags. The first tag in the list is always
8772159047fSniklas the current tag for that block. */
8782159047fSniklas typedef struct tag {
8792159047fSniklas struct tag *free; /* free list pointer */
8802159047fSniklas struct shash *hash_ptr; /* pointer to the hash table head */
8812159047fSniklas struct tag *same_name; /* tag with same name in outer scope */
8822159047fSniklas struct tag *same_block; /* next tag defined in the same block. */
8832159047fSniklas struct forward *forward_ref; /* list of forward references */
8842159047fSniklas bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
8852159047fSniklas symint_t ifd; /* file # tag defined in */
8862159047fSniklas localsym_t *sym; /* file's local symbols */
8872159047fSniklas } tag_t;
8882159047fSniklas
8892159047fSniklas /* Head of a block's linked list of tags. */
8902159047fSniklas typedef struct thead {
8912159047fSniklas struct thead *prev; /* previous block */
8922159047fSniklas struct thead *free; /* free list pointer */
8932159047fSniklas struct tag *first_tag; /* first tag in block defined */
8942159047fSniklas } thead_t;
8952159047fSniklas
8962159047fSniklas /* Union containing pointers to each the small structures which are freed up. */
8972159047fSniklas typedef union small_free {
8982159047fSniklas scope_t *f_scope; /* scope structure */
8992159047fSniklas thead_t *f_thead; /* tag head structure */
9002159047fSniklas tag_t *f_tag; /* tag element structure */
9012159047fSniklas forward_t *f_forward; /* forward tag reference */
9022159047fSniklas } small_free_t;
9032159047fSniklas
9042159047fSniklas /* String hash table entry. */
9052159047fSniklas
9062159047fSniklas typedef struct shash {
9072159047fSniklas char *string; /* string we are hashing */
9082159047fSniklas symint_t indx; /* index within string table */
9092159047fSniklas EXTR *esym_ptr; /* global symbol pointer */
9102159047fSniklas localsym_t *sym_ptr; /* local symbol pointer */
9112159047fSniklas localsym_t *end_ptr; /* symbol pointer to end block */
9122159047fSniklas tag_t *tag_ptr; /* tag pointer */
9132159047fSniklas proc_t *proc_ptr; /* procedure descriptor pointer */
9142159047fSniklas } shash_t;
9152159047fSniklas
9162159047fSniklas /* Type hash table support. The size of the hash table must fit
9172159047fSniklas within a page with the other extended file descriptor information.
9182159047fSniklas Because unique types which are hashed are fewer in number than
9192159047fSniklas strings, we use a smaller hash value. */
9202159047fSniklas
9212159047fSniklas #define HASHBITS 30
9222159047fSniklas
9232159047fSniklas #ifndef THASH_SIZE
9242159047fSniklas #define THASH_SIZE 113
9252159047fSniklas #endif
9262159047fSniklas
9272159047fSniklas typedef struct thash {
9282159047fSniklas struct thash *next; /* next hash value */
9292159047fSniklas AUXU type; /* type we are hashing */
9302159047fSniklas symint_t indx; /* index within string table */
9312159047fSniklas } thash_t;
9322159047fSniklas
9332159047fSniklas /* Extended file descriptor that contains all of the support necessary
9342159047fSniklas to add things to each file separately. */
9352159047fSniklas typedef struct efdr {
9362159047fSniklas FDR fdr; /* File header to be written out */
9372159047fSniklas FDR *orig_fdr; /* original file header */
9382159047fSniklas char *name; /* filename */
9392159047fSniklas int fake; /* whether this is faked .file */
9402159047fSniklas symint_t void_type; /* aux. pointer to 'void' type */
9412159047fSniklas symint_t int_type; /* aux. pointer to 'int' type */
9422159047fSniklas scope_t *cur_scope; /* current nested scopes */
9432159047fSniklas symint_t file_index; /* current file number */
9442159047fSniklas int nested_scopes; /* # nested scopes */
9452159047fSniklas varray_t strings; /* local strings */
9462159047fSniklas varray_t symbols; /* local symbols */
9472159047fSniklas varray_t procs; /* procedures */
9482159047fSniklas varray_t aux_syms; /* auxiliary symbols */
9492159047fSniklas struct efdr *next_file; /* next file descriptor */
9502159047fSniklas /* string/type hash tables */
9512159047fSniklas struct hash_control *str_hash; /* string hash table */
9522159047fSniklas thash_t *thash_head[THASH_SIZE];
9532159047fSniklas } efdr_t;
9542159047fSniklas
9552159047fSniklas /* Pre-initialized extended file structure. */
956b55d4692Sfgsch static const efdr_t init_file = {
9572159047fSniklas { /* FDR structure */
9582159047fSniklas 0, /* adr: memory address of beginning of file */
9592159047fSniklas 0, /* rss: file name (of source, if known) */
9602159047fSniklas 0, /* issBase: file's string space */
9612159047fSniklas 0, /* cbSs: number of bytes in the ss */
9622159047fSniklas 0, /* isymBase: beginning of symbols */
9632159047fSniklas 0, /* csym: count file's of symbols */
9642159047fSniklas 0, /* ilineBase: file's line symbols */
9652159047fSniklas 0, /* cline: count of file's line symbols */
9662159047fSniklas 0, /* ioptBase: file's optimization entries */
9672159047fSniklas 0, /* copt: count of file's optimization entries */
9682159047fSniklas 0, /* ipdFirst: start of procedures for this file */
9692159047fSniklas 0, /* cpd: count of procedures for this file */
9702159047fSniklas 0, /* iauxBase: file's auxiliary entries */
9712159047fSniklas 0, /* caux: count of file's auxiliary entries */
9722159047fSniklas 0, /* rfdBase: index into the file indirect table */
9732159047fSniklas 0, /* crfd: count file indirect entries */
9742159047fSniklas langC, /* lang: language for this file */
9750c6d0228Sniklas 1, /* fMerge: whether this file can be merged */
9762159047fSniklas 0, /* fReadin: true if read in (not just created) */
9776a4c786fSespie TARGET_BYTES_BIG_ENDIAN, /* fBigendian: if 1, compiled on big endian machine */
9782159047fSniklas GLEVEL_2, /* glevel: level this file was compiled with */
9792159047fSniklas 0, /* reserved: reserved for future use */
9802159047fSniklas 0, /* cbLineOffset: byte offset from header for this file ln's */
9812159047fSniklas 0, /* cbLine: size of lines for this file */
9822159047fSniklas },
9832159047fSniklas
9842159047fSniklas (FDR *)0, /* orig_fdr: original file header pointer */
9852159047fSniklas (char *)0, /* name: pointer to filename */
9862159047fSniklas 0, /* fake: whether this is a faked .file */
9872159047fSniklas 0, /* void_type: ptr to aux node for void type */
9882159047fSniklas 0, /* int_type: ptr to aux node for int type */
9892159047fSniklas (scope_t *)0, /* cur_scope: current scope being processed */
9902159047fSniklas 0, /* file_index: current file # */
9912159047fSniklas 0, /* nested_scopes: # nested scopes */
9922159047fSniklas INIT_VARRAY (char), /* strings: local string varray */
9932159047fSniklas INIT_VARRAY (localsym_t), /* symbols: local symbols varray */
9942159047fSniklas INIT_VARRAY (proc_t), /* procs: procedure varray */
9952159047fSniklas INIT_VARRAY (aux_t), /* aux_syms: auxiliary symbols varray */
9962159047fSniklas
9972159047fSniklas (struct efdr *)0, /* next_file: next file structure */
9982159047fSniklas
9992159047fSniklas (struct hash_control *)0, /* str_hash: string hash table */
10002159047fSniklas { 0 }, /* thash_head: type hash table */
10012159047fSniklas };
10022159047fSniklas
10032159047fSniklas static efdr_t *first_file; /* first file descriptor */
10042159047fSniklas static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */
10052159047fSniklas
10062159047fSniklas /* Line number information is kept in a list until the assembly is
10072159047fSniklas finished. */
10082159047fSniklas typedef struct lineno_list {
10092159047fSniklas struct lineno_list *next; /* next element in list */
10102159047fSniklas efdr_t *file; /* file this line is in */
10112159047fSniklas proc_t *proc; /* procedure this line is in */
10122159047fSniklas fragS *frag; /* fragment this line number is in */
10132159047fSniklas unsigned long paddr; /* offset within fragment */
10142159047fSniklas long lineno; /* actual line number */
10152159047fSniklas } lineno_list_t;
10162159047fSniklas
10172159047fSniklas static lineno_list_t *first_lineno;
10180c6d0228Sniklas static lineno_list_t *last_lineno;
10192159047fSniklas static lineno_list_t **last_lineno_ptr = &first_lineno;
10202159047fSniklas
10212159047fSniklas /* Sometimes there will be some .loc statements before a .ent. We
10222159047fSniklas keep them in this list so that we can fill in the procedure pointer
10232159047fSniklas after we see the .ent. */
10242159047fSniklas static lineno_list_t *noproc_lineno;
10252159047fSniklas
10262159047fSniklas /* Union of various things that are held in pages. */
10272159047fSniklas typedef union page {
10282159047fSniklas char byte [ PAGE_SIZE ];
10292159047fSniklas unsigned char ubyte [ PAGE_SIZE ];
10302159047fSniklas efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
10312159047fSniklas FDR ofile [ PAGE_SIZE / sizeof (FDR) ];
10322159047fSniklas proc_t proc [ PAGE_SIZE / sizeof (proc_t) ];
10332159047fSniklas localsym_t sym [ PAGE_SIZE / sizeof (localsym_t) ];
10342159047fSniklas aux_t aux [ PAGE_SIZE / sizeof (aux_t) ];
10352159047fSniklas DNR dense [ PAGE_SIZE / sizeof (DNR) ];
10362159047fSniklas scope_t scope [ PAGE_SIZE / sizeof (scope_t) ];
10372159047fSniklas vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ];
10382159047fSniklas shash_t shash [ PAGE_SIZE / sizeof (shash_t) ];
10392159047fSniklas thash_t thash [ PAGE_SIZE / sizeof (thash_t) ];
10402159047fSniklas tag_t tag [ PAGE_SIZE / sizeof (tag_t) ];
10412159047fSniklas forward_t forward [ PAGE_SIZE / sizeof (forward_t) ];
10422159047fSniklas thead_t thead [ PAGE_SIZE / sizeof (thead_t) ];
10432159047fSniklas lineno_list_t lineno [ PAGE_SIZE / sizeof (lineno_list_t) ];
1044b305b0f1Sespie } page_type;
10452159047fSniklas
10462159047fSniklas /* Structure holding allocation information for small sized structures. */
10472159047fSniklas typedef struct alloc_info {
10482159047fSniklas char *alloc_name; /* name of this allocation type (must be first) */
1049b305b0f1Sespie page_type *cur_page; /* current page being allocated from */
10502159047fSniklas small_free_t free_list; /* current free list if any */
10512159047fSniklas int unallocated; /* number of elements unallocated on page */
10522159047fSniklas int total_alloc; /* total number of allocations */
10532159047fSniklas int total_free; /* total number of frees */
10542159047fSniklas int total_pages; /* total number of pages allocated */
10552159047fSniklas } alloc_info_t;
10562159047fSniklas
10572159047fSniklas /* Type information collected together. */
10582159047fSniklas typedef struct type_info {
10592159047fSniklas bt_t basic_type; /* basic type */
10602159047fSniklas int orig_type; /* original COFF-based type */
10612159047fSniklas int num_tq; /* # type qualifiers */
10622159047fSniklas int num_dims; /* # dimensions */
10632159047fSniklas int num_sizes; /* # sizes */
10642159047fSniklas int extra_sizes; /* # extra sizes not tied with dims */
10652159047fSniklas tag_t * tag_ptr; /* tag pointer */
10662159047fSniklas int bitfield; /* symbol is a bitfield */
10672159047fSniklas tq_t type_qualifiers[N_TQ]; /* type qualifiers (ptr, func, array)*/
10682159047fSniklas symint_t dimensions [N_TQ]; /* dimensions for each array */
10692159047fSniklas symint_t sizes [N_TQ+2]; /* sizes of each array slice + size of
10702159047fSniklas struct/union/enum + bitfield size */
10712159047fSniklas } type_info_t;
10722159047fSniklas
10732159047fSniklas /* Pre-initialized type_info struct. */
10742159047fSniklas static const type_info_t type_info_init = {
10752159047fSniklas bt_Nil, /* basic type */
10762159047fSniklas T_NULL, /* original COFF-based type */
10772159047fSniklas 0, /* # type qualifiers */
10782159047fSniklas 0, /* # dimensions */
10792159047fSniklas 0, /* # sizes */
10802159047fSniklas 0, /* sizes not tied with dims */
10812159047fSniklas NULL, /* ptr to tag */
10822159047fSniklas 0, /* bitfield */
10832159047fSniklas { /* type qualifiers */
10842159047fSniklas tq_Nil,
10852159047fSniklas tq_Nil,
10862159047fSniklas tq_Nil,
10872159047fSniklas tq_Nil,
10882159047fSniklas tq_Nil,
10892159047fSniklas tq_Nil,
10902159047fSniklas },
10912159047fSniklas { /* dimensions */
10922159047fSniklas 0,
10932159047fSniklas 0,
10942159047fSniklas 0,
10952159047fSniklas 0,
10962159047fSniklas 0,
10972159047fSniklas 0
10982159047fSniklas },
10992159047fSniklas { /* sizes */
11002159047fSniklas 0,
11012159047fSniklas 0,
11022159047fSniklas 0,
11032159047fSniklas 0,
11042159047fSniklas 0,
11052159047fSniklas 0,
11062159047fSniklas 0,
11072159047fSniklas 0,
11082159047fSniklas },
11092159047fSniklas };
11102159047fSniklas
11112159047fSniklas /* Global hash table for the tags table and global table for file
11122159047fSniklas descriptors. */
11132159047fSniklas
11142159047fSniklas static varray_t file_desc = INIT_VARRAY (efdr_t);
11152159047fSniklas
11162159047fSniklas static struct hash_control *tag_hash;
11172159047fSniklas
11182159047fSniklas /* Static types for int and void. Also, remember the last function's
11192159047fSniklas type (which is set up when we encounter the declaration for the
11202159047fSniklas function, and used when the end block for the function is emitted. */
11212159047fSniklas
11222159047fSniklas static type_info_t int_type_info;
11232159047fSniklas static type_info_t void_type_info;
11242159047fSniklas static type_info_t last_func_type_info;
11252159047fSniklas static symbolS *last_func_sym_value;
11262159047fSniklas
11272159047fSniklas /* Convert COFF basic type to ECOFF basic type. The T_NULL type
11282159047fSniklas really should use bt_Void, but this causes the current ecoff GDB to
11292159047fSniklas issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
11302159047fSniklas 2.0) doesn't understand it, even though the compiler generates it.
11312159047fSniklas Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
11322159047fSniklas suite, but for now go with what works.
11332159047fSniklas
11342159047fSniklas It would make sense for the .type and .scl directives to use the
11352159047fSniklas ECOFF numbers directly, rather than using the COFF numbers and
11362159047fSniklas mapping them. Unfortunately, this is historically what mips-tfile
11372159047fSniklas expects, and changing gcc now would be a considerable pain (the
11382159047fSniklas native compiler generates debugging information internally, rather
11392159047fSniklas than via the assembler, so it will never use .type or .scl). */
11402159047fSniklas
11412159047fSniklas static const bt_t map_coff_types[] = {
11422159047fSniklas bt_Nil, /* T_NULL */
11432159047fSniklas bt_Nil, /* T_ARG */
11442159047fSniklas bt_Char, /* T_CHAR */
11452159047fSniklas bt_Short, /* T_SHORT */
11462159047fSniklas bt_Int, /* T_INT */
11472159047fSniklas bt_Long, /* T_LONG */
11482159047fSniklas bt_Float, /* T_FLOAT */
11492159047fSniklas bt_Double, /* T_DOUBLE */
11502159047fSniklas bt_Struct, /* T_STRUCT */
11512159047fSniklas bt_Union, /* T_UNION */
11522159047fSniklas bt_Enum, /* T_ENUM */
11532159047fSniklas bt_Enum, /* T_MOE */
11542159047fSniklas bt_UChar, /* T_UCHAR */
11552159047fSniklas bt_UShort, /* T_USHORT */
11562159047fSniklas bt_UInt, /* T_UINT */
11572159047fSniklas bt_ULong /* T_ULONG */
11582159047fSniklas };
11592159047fSniklas
11602159047fSniklas /* Convert COFF storage class to ECOFF storage class. */
11612159047fSniklas static const sc_t map_coff_storage[] = {
11622159047fSniklas sc_Nil, /* 0: C_NULL */
11632159047fSniklas sc_Abs, /* 1: C_AUTO auto var */
11642159047fSniklas sc_Undefined, /* 2: C_EXT external */
11652159047fSniklas sc_Data, /* 3: C_STAT static */
11662159047fSniklas sc_Register, /* 4: C_REG register */
11672159047fSniklas sc_Undefined, /* 5: C_EXTDEF ??? */
11682159047fSniklas sc_Text, /* 6: C_LABEL label */
11692159047fSniklas sc_Text, /* 7: C_ULABEL user label */
11702159047fSniklas sc_Info, /* 8: C_MOS member of struct */
11712159047fSniklas sc_Abs, /* 9: C_ARG argument */
11722159047fSniklas sc_Info, /* 10: C_STRTAG struct tag */
11732159047fSniklas sc_Info, /* 11: C_MOU member of union */
11742159047fSniklas sc_Info, /* 12: C_UNTAG union tag */
11752159047fSniklas sc_Info, /* 13: C_TPDEF typedef */
11762159047fSniklas sc_Data, /* 14: C_USTATIC ??? */
11772159047fSniklas sc_Info, /* 15: C_ENTAG enum tag */
11782159047fSniklas sc_Info, /* 16: C_MOE member of enum */
11792159047fSniklas sc_Register, /* 17: C_REGPARM register parameter */
11802159047fSniklas sc_Bits, /* 18; C_FIELD bitfield */
11812159047fSniklas sc_Nil, /* 19 */
11822159047fSniklas sc_Nil, /* 20 */
11832159047fSniklas sc_Nil, /* 21 */
11842159047fSniklas sc_Nil, /* 22 */
11852159047fSniklas sc_Nil, /* 23 */
11862159047fSniklas sc_Nil, /* 24 */
11872159047fSniklas sc_Nil, /* 25 */
11882159047fSniklas sc_Nil, /* 26 */
11892159047fSniklas sc_Nil, /* 27 */
11902159047fSniklas sc_Nil, /* 28 */
11912159047fSniklas sc_Nil, /* 29 */
11922159047fSniklas sc_Nil, /* 30 */
11932159047fSniklas sc_Nil, /* 31 */
11942159047fSniklas sc_Nil, /* 32 */
11952159047fSniklas sc_Nil, /* 33 */
11962159047fSniklas sc_Nil, /* 34 */
11972159047fSniklas sc_Nil, /* 35 */
11982159047fSniklas sc_Nil, /* 36 */
11992159047fSniklas sc_Nil, /* 37 */
12002159047fSniklas sc_Nil, /* 38 */
12012159047fSniklas sc_Nil, /* 39 */
12022159047fSniklas sc_Nil, /* 40 */
12032159047fSniklas sc_Nil, /* 41 */
12042159047fSniklas sc_Nil, /* 42 */
12052159047fSniklas sc_Nil, /* 43 */
12062159047fSniklas sc_Nil, /* 44 */
12072159047fSniklas sc_Nil, /* 45 */
12082159047fSniklas sc_Nil, /* 46 */
12092159047fSniklas sc_Nil, /* 47 */
12102159047fSniklas sc_Nil, /* 48 */
12112159047fSniklas sc_Nil, /* 49 */
12122159047fSniklas sc_Nil, /* 50 */
12132159047fSniklas sc_Nil, /* 51 */
12142159047fSniklas sc_Nil, /* 52 */
12152159047fSniklas sc_Nil, /* 53 */
12162159047fSniklas sc_Nil, /* 54 */
12172159047fSniklas sc_Nil, /* 55 */
12182159047fSniklas sc_Nil, /* 56 */
12192159047fSniklas sc_Nil, /* 57 */
12202159047fSniklas sc_Nil, /* 58 */
12212159047fSniklas sc_Nil, /* 59 */
12222159047fSniklas sc_Nil, /* 60 */
12232159047fSniklas sc_Nil, /* 61 */
12242159047fSniklas sc_Nil, /* 62 */
12252159047fSniklas sc_Nil, /* 63 */
12262159047fSniklas sc_Nil, /* 64 */
12272159047fSniklas sc_Nil, /* 65 */
12282159047fSniklas sc_Nil, /* 66 */
12292159047fSniklas sc_Nil, /* 67 */
12302159047fSniklas sc_Nil, /* 68 */
12312159047fSniklas sc_Nil, /* 69 */
12322159047fSniklas sc_Nil, /* 70 */
12332159047fSniklas sc_Nil, /* 71 */
12342159047fSniklas sc_Nil, /* 72 */
12352159047fSniklas sc_Nil, /* 73 */
12362159047fSniklas sc_Nil, /* 74 */
12372159047fSniklas sc_Nil, /* 75 */
12382159047fSniklas sc_Nil, /* 76 */
12392159047fSniklas sc_Nil, /* 77 */
12402159047fSniklas sc_Nil, /* 78 */
12412159047fSniklas sc_Nil, /* 79 */
12422159047fSniklas sc_Nil, /* 80 */
12432159047fSniklas sc_Nil, /* 81 */
12442159047fSniklas sc_Nil, /* 82 */
12452159047fSniklas sc_Nil, /* 83 */
12462159047fSniklas sc_Nil, /* 84 */
12472159047fSniklas sc_Nil, /* 85 */
12482159047fSniklas sc_Nil, /* 86 */
12492159047fSniklas sc_Nil, /* 87 */
12502159047fSniklas sc_Nil, /* 88 */
12512159047fSniklas sc_Nil, /* 89 */
12522159047fSniklas sc_Nil, /* 90 */
12532159047fSniklas sc_Nil, /* 91 */
12542159047fSniklas sc_Nil, /* 92 */
12552159047fSniklas sc_Nil, /* 93 */
12562159047fSniklas sc_Nil, /* 94 */
12572159047fSniklas sc_Nil, /* 95 */
12582159047fSniklas sc_Nil, /* 96 */
12592159047fSniklas sc_Nil, /* 97 */
12602159047fSniklas sc_Nil, /* 98 */
12612159047fSniklas sc_Nil, /* 99 */
12622159047fSniklas sc_Text, /* 100: C_BLOCK block start/end */
12632159047fSniklas sc_Text, /* 101: C_FCN function start/end */
12642159047fSniklas sc_Info, /* 102: C_EOS end of struct/union/enum */
12652159047fSniklas sc_Nil, /* 103: C_FILE file start */
12662159047fSniklas sc_Nil, /* 104: C_LINE line number */
12672159047fSniklas sc_Nil, /* 105: C_ALIAS combined type info */
12682159047fSniklas sc_Nil, /* 106: C_HIDDEN ??? */
12692159047fSniklas };
12702159047fSniklas
12712159047fSniklas /* Convert COFF storage class to ECOFF symbol type. */
12722159047fSniklas static const st_t map_coff_sym_type[] = {
12732159047fSniklas st_Nil, /* 0: C_NULL */
12742159047fSniklas st_Local, /* 1: C_AUTO auto var */
12752159047fSniklas st_Global, /* 2: C_EXT external */
12762159047fSniklas st_Static, /* 3: C_STAT static */
12772159047fSniklas st_Local, /* 4: C_REG register */
12782159047fSniklas st_Global, /* 5: C_EXTDEF ??? */
12792159047fSniklas st_Label, /* 6: C_LABEL label */
12802159047fSniklas st_Label, /* 7: C_ULABEL user label */
12812159047fSniklas st_Member, /* 8: C_MOS member of struct */
12822159047fSniklas st_Param, /* 9: C_ARG argument */
12832159047fSniklas st_Block, /* 10: C_STRTAG struct tag */
12842159047fSniklas st_Member, /* 11: C_MOU member of union */
12852159047fSniklas st_Block, /* 12: C_UNTAG union tag */
12862159047fSniklas st_Typedef, /* 13: C_TPDEF typedef */
12872159047fSniklas st_Static, /* 14: C_USTATIC ??? */
12882159047fSniklas st_Block, /* 15: C_ENTAG enum tag */
12892159047fSniklas st_Member, /* 16: C_MOE member of enum */
12902159047fSniklas st_Param, /* 17: C_REGPARM register parameter */
12912159047fSniklas st_Member, /* 18; C_FIELD bitfield */
12922159047fSniklas st_Nil, /* 19 */
12932159047fSniklas st_Nil, /* 20 */
12942159047fSniklas st_Nil, /* 21 */
12952159047fSniklas st_Nil, /* 22 */
12962159047fSniklas st_Nil, /* 23 */
12972159047fSniklas st_Nil, /* 24 */
12982159047fSniklas st_Nil, /* 25 */
12992159047fSniklas st_Nil, /* 26 */
13002159047fSniklas st_Nil, /* 27 */
13012159047fSniklas st_Nil, /* 28 */
13022159047fSniklas st_Nil, /* 29 */
13032159047fSniklas st_Nil, /* 30 */
13042159047fSniklas st_Nil, /* 31 */
13052159047fSniklas st_Nil, /* 32 */
13062159047fSniklas st_Nil, /* 33 */
13072159047fSniklas st_Nil, /* 34 */
13082159047fSniklas st_Nil, /* 35 */
13092159047fSniklas st_Nil, /* 36 */
13102159047fSniklas st_Nil, /* 37 */
13112159047fSniklas st_Nil, /* 38 */
13122159047fSniklas st_Nil, /* 39 */
13132159047fSniklas st_Nil, /* 40 */
13142159047fSniklas st_Nil, /* 41 */
13152159047fSniklas st_Nil, /* 42 */
13162159047fSniklas st_Nil, /* 43 */
13172159047fSniklas st_Nil, /* 44 */
13182159047fSniklas st_Nil, /* 45 */
13192159047fSniklas st_Nil, /* 46 */
13202159047fSniklas st_Nil, /* 47 */
13212159047fSniklas st_Nil, /* 48 */
13222159047fSniklas st_Nil, /* 49 */
13232159047fSniklas st_Nil, /* 50 */
13242159047fSniklas st_Nil, /* 51 */
13252159047fSniklas st_Nil, /* 52 */
13262159047fSniklas st_Nil, /* 53 */
13272159047fSniklas st_Nil, /* 54 */
13282159047fSniklas st_Nil, /* 55 */
13292159047fSniklas st_Nil, /* 56 */
13302159047fSniklas st_Nil, /* 57 */
13312159047fSniklas st_Nil, /* 58 */
13322159047fSniklas st_Nil, /* 59 */
13332159047fSniklas st_Nil, /* 60 */
13342159047fSniklas st_Nil, /* 61 */
13352159047fSniklas st_Nil, /* 62 */
13362159047fSniklas st_Nil, /* 63 */
13372159047fSniklas st_Nil, /* 64 */
13382159047fSniklas st_Nil, /* 65 */
13392159047fSniklas st_Nil, /* 66 */
13402159047fSniklas st_Nil, /* 67 */
13412159047fSniklas st_Nil, /* 68 */
13422159047fSniklas st_Nil, /* 69 */
13432159047fSniklas st_Nil, /* 70 */
13442159047fSniklas st_Nil, /* 71 */
13452159047fSniklas st_Nil, /* 72 */
13462159047fSniklas st_Nil, /* 73 */
13472159047fSniklas st_Nil, /* 74 */
13482159047fSniklas st_Nil, /* 75 */
13492159047fSniklas st_Nil, /* 76 */
13502159047fSniklas st_Nil, /* 77 */
13512159047fSniklas st_Nil, /* 78 */
13522159047fSniklas st_Nil, /* 79 */
13532159047fSniklas st_Nil, /* 80 */
13542159047fSniklas st_Nil, /* 81 */
13552159047fSniklas st_Nil, /* 82 */
13562159047fSniklas st_Nil, /* 83 */
13572159047fSniklas st_Nil, /* 84 */
13582159047fSniklas st_Nil, /* 85 */
13592159047fSniklas st_Nil, /* 86 */
13602159047fSniklas st_Nil, /* 87 */
13612159047fSniklas st_Nil, /* 88 */
13622159047fSniklas st_Nil, /* 89 */
13632159047fSniklas st_Nil, /* 90 */
13642159047fSniklas st_Nil, /* 91 */
13652159047fSniklas st_Nil, /* 92 */
13662159047fSniklas st_Nil, /* 93 */
13672159047fSniklas st_Nil, /* 94 */
13682159047fSniklas st_Nil, /* 95 */
13692159047fSniklas st_Nil, /* 96 */
13702159047fSniklas st_Nil, /* 97 */
13712159047fSniklas st_Nil, /* 98 */
13722159047fSniklas st_Nil, /* 99 */
13732159047fSniklas st_Block, /* 100: C_BLOCK block start/end */
13742159047fSniklas st_Proc, /* 101: C_FCN function start/end */
13752159047fSniklas st_End, /* 102: C_EOS end of struct/union/enum */
13762159047fSniklas st_File, /* 103: C_FILE file start */
13772159047fSniklas st_Nil, /* 104: C_LINE line number */
13782159047fSniklas st_Nil, /* 105: C_ALIAS combined type info */
13792159047fSniklas st_Nil, /* 106: C_HIDDEN ??? */
13802159047fSniklas };
13812159047fSniklas
13822159047fSniklas /* Keep track of different sized allocation requests. */
13832159047fSniklas static alloc_info_t alloc_counts[(int) alloc_type_last];
13842159047fSniklas
13852159047fSniklas /* Record whether we have seen any debugging information. */
13862159047fSniklas int ecoff_debugging_seen = 0;
13872159047fSniklas
13882159047fSniklas /* Various statics. */
13892159047fSniklas static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */
13902159047fSniklas static proc_t *cur_proc_ptr = (proc_t *) 0; /* current procedure header */
13912159047fSniklas static proc_t *first_proc_ptr = (proc_t *) 0; /* first procedure header */
13922159047fSniklas static thead_t *top_tag_head = (thead_t *) 0; /* top level tag head */
13932159047fSniklas static thead_t *cur_tag_head = (thead_t *) 0; /* current tag head */
13942159047fSniklas #ifdef ECOFF_DEBUG
13952159047fSniklas static int debug = 0; /* trace functions */
13962159047fSniklas #endif
13972159047fSniklas static int stabs_seen = 0; /* != 0 if stabs have been seen */
13982159047fSniklas
13992159047fSniklas static int current_file_idx;
14002159047fSniklas static const char *current_stabs_filename;
14012159047fSniklas
14022159047fSniklas /* Pseudo symbol to use when putting stabs into the symbol table. */
14032159047fSniklas #ifndef STABS_SYMBOL
14042159047fSniklas #define STABS_SYMBOL "@stabs"
14052159047fSniklas #endif
14062159047fSniklas
14072159047fSniklas static char stabs_symbol[] = STABS_SYMBOL;
14082159047fSniklas
14092159047fSniklas /* Prototypes for functions defined in this file. */
14102159047fSniklas
1411*007c2a45Smiod static void add_varray_page (varray_t *vp);
1412*007c2a45Smiod static symint_t add_string (varray_t *vp,
14132159047fSniklas struct hash_control *hash_tbl,
14142159047fSniklas const char *str,
1415*007c2a45Smiod shash_t **ret_hash);
1416*007c2a45Smiod static localsym_t *add_ecoff_symbol (const char *str, st_t type,
14172159047fSniklas sc_t storage, symbolS *sym,
1418191aa565Sniklas bfd_vma addend, symint_t value,
1419*007c2a45Smiod symint_t indx);
1420*007c2a45Smiod static symint_t add_aux_sym_symint (symint_t aux_word);
1421*007c2a45Smiod static symint_t add_aux_sym_rndx (int file_index, symint_t sym_index);
1422*007c2a45Smiod static symint_t add_aux_sym_tir (type_info_t *t,
14232159047fSniklas hash_state_t state,
1424*007c2a45Smiod thash_t **hash_tbl);
1425*007c2a45Smiod static tag_t *get_tag (const char *tag, localsym_t *sym, bt_t basic_type);
1426*007c2a45Smiod static void add_unknown_tag (tag_t *ptag);
1427*007c2a45Smiod static void add_procedure (char *func);
1428*007c2a45Smiod static void add_file (const char *file_name, int indx, int fake);
14292159047fSniklas #ifdef ECOFF_DEBUG
1430*007c2a45Smiod static char *sc_to_string (sc_t storage_class);
1431*007c2a45Smiod static char *st_to_string (st_t symbol_type);
14322159047fSniklas #endif
1433*007c2a45Smiod static void mark_stabs (int);
1434*007c2a45Smiod static char *ecoff_add_bytes (char **buf, char **bufend,
1435*007c2a45Smiod char *bufptr, unsigned long need);
14362159047fSniklas static unsigned long ecoff_padding_adjust
1437*007c2a45Smiod (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1438*007c2a45Smiod unsigned long offset, char **bufptrptr);
14392159047fSniklas static unsigned long ecoff_build_lineno
1440*007c2a45Smiod (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1441*007c2a45Smiod unsigned long offset, long *linecntptr);
14422159047fSniklas static unsigned long ecoff_build_symbols
1443*007c2a45Smiod (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1444*007c2a45Smiod unsigned long offset);
14452159047fSniklas static unsigned long ecoff_build_procs
1446*007c2a45Smiod (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1447*007c2a45Smiod unsigned long offset);
14482159047fSniklas static unsigned long ecoff_build_aux
1449*007c2a45Smiod (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1450*007c2a45Smiod unsigned long offset);
1451*007c2a45Smiod static unsigned long ecoff_build_strings (char **buf, char **bufend,
14522159047fSniklas unsigned long offset,
1453*007c2a45Smiod varray_t *vp);
14542159047fSniklas static unsigned long ecoff_build_ss
1455*007c2a45Smiod (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1456*007c2a45Smiod unsigned long offset);
14572159047fSniklas static unsigned long ecoff_build_fdr
1458*007c2a45Smiod (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1459*007c2a45Smiod unsigned long offset);
1460*007c2a45Smiod static void ecoff_setup_ext (void);
1461*007c2a45Smiod static page_type *allocate_cluster (unsigned long npages);
1462*007c2a45Smiod static page_type *allocate_page (void);
1463*007c2a45Smiod static scope_t *allocate_scope (void);
1464*007c2a45Smiod static void free_scope (scope_t *ptr);
1465*007c2a45Smiod static vlinks_t *allocate_vlinks (void);
1466*007c2a45Smiod static shash_t *allocate_shash (void);
1467*007c2a45Smiod static thash_t *allocate_thash (void);
1468*007c2a45Smiod static tag_t *allocate_tag (void);
1469*007c2a45Smiod static void free_tag (tag_t *ptr);
1470*007c2a45Smiod static forward_t *allocate_forward (void);
1471*007c2a45Smiod static thead_t *allocate_thead (void);
1472*007c2a45Smiod static void free_thead (thead_t *ptr);
1473*007c2a45Smiod static lineno_list_t *allocate_lineno_list (void);
14742159047fSniklas
14752159047fSniklas /* This function should be called when the assembler starts up. */
14762159047fSniklas
14772159047fSniklas void
ecoff_read_begin_hook(void)1478*007c2a45Smiod ecoff_read_begin_hook (void)
14792159047fSniklas {
14802159047fSniklas tag_hash = hash_new ();
14812159047fSniklas top_tag_head = allocate_thead ();
14822159047fSniklas top_tag_head->first_tag = (tag_t *) NULL;
14832159047fSniklas top_tag_head->free = (thead_t *) NULL;
14842159047fSniklas top_tag_head->prev = cur_tag_head;
14852159047fSniklas cur_tag_head = top_tag_head;
14862159047fSniklas }
14872159047fSniklas
14882159047fSniklas /* This function should be called when a symbol is created. */
14892159047fSniklas
14902159047fSniklas void
ecoff_symbol_new_hook(symbolS * symbolP)1491*007c2a45Smiod ecoff_symbol_new_hook (symbolS *symbolP)
14922159047fSniklas {
1493b305b0f1Sespie OBJ_SYMFIELD_TYPE *obj;
1494b305b0f1Sespie
14952159047fSniklas /* Make sure that we have a file pointer, but only if we have seen a
14962159047fSniklas file. If we haven't seen a file, then this is a probably special
14972159047fSniklas symbol created by md_begin which may required special handling at
14982159047fSniklas some point. Creating a dummy file with a dummy name is certainly
14992159047fSniklas wrong. */
15002159047fSniklas if (cur_file_ptr == (efdr_t *) NULL
15012159047fSniklas && seen_at_least_1_file ())
15022159047fSniklas add_file ((const char *) NULL, 0, 1);
1503b305b0f1Sespie obj = symbol_get_obj (symbolP);
1504b305b0f1Sespie obj->ecoff_file = cur_file_ptr;
1505b305b0f1Sespie obj->ecoff_symbol = NULL;
1506b305b0f1Sespie obj->ecoff_extern_size = 0;
15072159047fSniklas }
15082159047fSniklas
15092159047fSniklas /* Add a page to a varray object. */
15102159047fSniklas
15112159047fSniklas static void
add_varray_page(varray_t * vp)1512*007c2a45Smiod add_varray_page (varray_t *vp /* varray to add page to */)
15132159047fSniklas {
15142159047fSniklas vlinks_t *new_links = allocate_vlinks ();
15152159047fSniklas
15162159047fSniklas #ifdef MALLOC_CHECK
15172159047fSniklas if (vp->object_size > 1)
1518b305b0f1Sespie new_links->datum = (page_type *) xcalloc (1, vp->object_size);
15192159047fSniklas else
15202159047fSniklas #endif
15212159047fSniklas new_links->datum = allocate_page ();
15222159047fSniklas
15232159047fSniklas alloc_counts[(int) alloc_type_varray].total_alloc++;
15242159047fSniklas alloc_counts[(int) alloc_type_varray].total_pages++;
15252159047fSniklas
15262159047fSniklas new_links->start_index = vp->num_allocated;
15272159047fSniklas vp->objects_last_page = 0;
15282159047fSniklas
15292159047fSniklas if (vp->first == (vlinks_t *) NULL) /* first allocation? */
15302159047fSniklas vp->first = vp->last = new_links;
15312159047fSniklas else
15322159047fSniklas { /* 2nd or greater allocation */
15332159047fSniklas new_links->prev = vp->last;
15342159047fSniklas vp->last->next = new_links;
15352159047fSniklas vp->last = new_links;
15362159047fSniklas }
15372159047fSniklas }
15382159047fSniklas
15392159047fSniklas /* Add a string (and null pad) to one of the string tables. */
15402159047fSniklas
15412159047fSniklas static symint_t
add_string(varray_t * vp,struct hash_control * hash_tbl,const char * str,shash_t ** ret_hash)1542*007c2a45Smiod add_string (varray_t *vp, /* string obstack */
1543*007c2a45Smiod struct hash_control *hash_tbl, /* ptr to hash table */
1544*007c2a45Smiod const char *str, /* string */
1545*007c2a45Smiod shash_t **ret_hash /* return hash pointer */)
15462159047fSniklas {
15472159047fSniklas register unsigned long len = strlen (str);
15482159047fSniklas register shash_t *hash_ptr;
15492159047fSniklas
15502159047fSniklas if (len >= PAGE_USIZE)
1551c074d1c9Sdrahn as_fatal (_("string too big (%lu bytes)"), len);
15522159047fSniklas
15532159047fSniklas hash_ptr = (shash_t *) hash_find (hash_tbl, str);
15542159047fSniklas if (hash_ptr == (shash_t *) NULL)
15552159047fSniklas {
15562159047fSniklas register const char *err;
15572159047fSniklas
15582159047fSniklas if (vp->objects_last_page + len >= PAGE_USIZE)
15592159047fSniklas {
15602159047fSniklas vp->num_allocated =
15612159047fSniklas ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
15622159047fSniklas add_varray_page (vp);
15632159047fSniklas }
15642159047fSniklas
15652159047fSniklas hash_ptr = allocate_shash ();
15662159047fSniklas hash_ptr->indx = vp->num_allocated;
15672159047fSniklas
15682159047fSniklas hash_ptr->string = &vp->last->datum->byte[vp->objects_last_page];
15692159047fSniklas
15702159047fSniklas vp->objects_last_page += len + 1;
15712159047fSniklas vp->num_allocated += len + 1;
15722159047fSniklas
15732159047fSniklas strcpy (hash_ptr->string, str);
15742159047fSniklas
15752159047fSniklas err = hash_insert (hash_tbl, str, (char *) hash_ptr);
15762159047fSniklas if (err)
1577c074d1c9Sdrahn as_fatal (_("inserting \"%s\" into string hash table: %s"),
15782159047fSniklas str, err);
15792159047fSniklas }
15802159047fSniklas
15812159047fSniklas if (ret_hash != (shash_t **) NULL)
15822159047fSniklas *ret_hash = hash_ptr;
15832159047fSniklas
15842159047fSniklas return hash_ptr->indx;
15852159047fSniklas }
15862159047fSniklas
15872159047fSniklas /* Add debugging information for a symbol. */
15882159047fSniklas
15892159047fSniklas static localsym_t *
add_ecoff_symbol(const char * str,st_t type,sc_t storage,symbolS * sym_value,bfd_vma addend,symint_t value,symint_t indx)1590*007c2a45Smiod add_ecoff_symbol (const char *str, /* symbol name */
1591*007c2a45Smiod st_t type, /* symbol type */
1592*007c2a45Smiod sc_t storage, /* storage class */
1593*007c2a45Smiod symbolS *sym_value, /* associated symbol. */
1594*007c2a45Smiod bfd_vma addend, /* addend to sym_value. */
1595*007c2a45Smiod symint_t value, /* value of symbol */
1596*007c2a45Smiod symint_t indx /* index to local/aux. syms */)
15972159047fSniklas {
15982159047fSniklas localsym_t *psym;
15992159047fSniklas register scope_t *pscope;
16002159047fSniklas register thead_t *ptag_head;
16012159047fSniklas register tag_t *ptag;
16022159047fSniklas register tag_t *ptag_next;
16032159047fSniklas register varray_t *vp;
16042159047fSniklas register int scope_delta = 0;
16052159047fSniklas shash_t *hash_ptr = (shash_t *) NULL;
16062159047fSniklas
16072159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
1608b305b0f1Sespie as_fatal (_("no current file pointer"));
16092159047fSniklas
16102159047fSniklas vp = &cur_file_ptr->symbols;
16112159047fSniklas
16122159047fSniklas if (vp->objects_last_page == vp->objects_per_page)
16132159047fSniklas add_varray_page (vp);
16142159047fSniklas
16152159047fSniklas psym = &vp->last->datum->sym[vp->objects_last_page++];
16162159047fSniklas
16172159047fSniklas if (str == (const char *) NULL && sym_value != (symbolS *) NULL)
16182159047fSniklas psym->name = S_GET_NAME (sym_value);
16192159047fSniklas else
16202159047fSniklas psym->name = str;
16212159047fSniklas psym->as_sym = sym_value;
16222159047fSniklas if (sym_value != (symbolS *) NULL)
1623b305b0f1Sespie symbol_get_obj (sym_value)->ecoff_symbol = psym;
1624191aa565Sniklas psym->addend = addend;
16252159047fSniklas psym->file_ptr = cur_file_ptr;
16262159047fSniklas psym->proc_ptr = cur_proc_ptr;
16272159047fSniklas psym->begin_ptr = (localsym_t *) NULL;
16282159047fSniklas psym->index_ptr = (aux_t *) NULL;
16292159047fSniklas psym->forward_ref = (forward_t *) NULL;
16302159047fSniklas psym->sym_index = -1;
16312159047fSniklas memset (&psym->ecoff_sym, 0, sizeof (EXTR));
16322159047fSniklas psym->ecoff_sym.asym.value = value;
16332159047fSniklas psym->ecoff_sym.asym.st = (unsigned) type;
16342159047fSniklas psym->ecoff_sym.asym.sc = (unsigned) storage;
16352159047fSniklas psym->ecoff_sym.asym.index = indx;
16362159047fSniklas
16372159047fSniklas /* If there is an associated symbol, we wait until the end of the
16382159047fSniklas assembly before deciding where to put the name (it may be just an
16392159047fSniklas external symbol). Otherwise, this is just a debugging symbol and
16402159047fSniklas the name should go with the current file. */
16412159047fSniklas if (sym_value == (symbolS *) NULL)
16422159047fSniklas psym->ecoff_sym.asym.iss = ((str == (const char *) NULL)
16432159047fSniklas ? 0
16442159047fSniklas : add_string (&cur_file_ptr->strings,
16452159047fSniklas cur_file_ptr->str_hash,
16462159047fSniklas str,
16472159047fSniklas &hash_ptr));
16482159047fSniklas
16492159047fSniklas ++vp->num_allocated;
16502159047fSniklas
16512159047fSniklas if (ECOFF_IS_STAB (&psym->ecoff_sym.asym))
16522159047fSniklas return psym;
16532159047fSniklas
16542159047fSniklas /* Save the symbol within the hash table if this is a static
16552159047fSniklas item, and it has a name. */
16562159047fSniklas if (hash_ptr != (shash_t *) NULL
16572159047fSniklas && (type == st_Global || type == st_Static || type == st_Label
16582159047fSniklas || type == st_Proc || type == st_StaticProc))
16592159047fSniklas hash_ptr->sym_ptr = psym;
16602159047fSniklas
16612159047fSniklas /* push or pop a scope if appropriate. */
16622159047fSniklas switch (type)
16632159047fSniklas {
16642159047fSniklas default:
16652159047fSniklas break;
16662159047fSniklas
16672159047fSniklas case st_File: /* beginning of file */
16682159047fSniklas case st_Proc: /* procedure */
16692159047fSniklas case st_StaticProc: /* static procedure */
16702159047fSniklas case st_Block: /* begin scope */
16712159047fSniklas pscope = allocate_scope ();
16722159047fSniklas pscope->prev = cur_file_ptr->cur_scope;
16732159047fSniklas pscope->lsym = psym;
16742159047fSniklas pscope->type = type;
16752159047fSniklas cur_file_ptr->cur_scope = pscope;
16762159047fSniklas
16772159047fSniklas if (type != st_File)
16782159047fSniklas scope_delta = 1;
16792159047fSniklas
16802159047fSniklas /* For every block type except file, struct, union, or
16812159047fSniklas enumeration blocks, push a level on the tag stack. We omit
16822159047fSniklas file types, so that tags can span file boundaries. */
16832159047fSniklas if (type != st_File && storage != sc_Info)
16842159047fSniklas {
16852159047fSniklas ptag_head = allocate_thead ();
16862159047fSniklas ptag_head->first_tag = 0;
16872159047fSniklas ptag_head->prev = cur_tag_head;
16882159047fSniklas cur_tag_head = ptag_head;
16892159047fSniklas }
16902159047fSniklas break;
16912159047fSniklas
16922159047fSniklas case st_End:
16932159047fSniklas pscope = cur_file_ptr->cur_scope;
16942159047fSniklas if (pscope == (scope_t *) NULL)
1695b305b0f1Sespie as_fatal (_("too many st_End's"));
16962159047fSniklas else
16972159047fSniklas {
16982159047fSniklas st_t begin_type = (st_t) pscope->lsym->ecoff_sym.asym.st;
16992159047fSniklas
17002159047fSniklas psym->begin_ptr = pscope->lsym;
17012159047fSniklas
17022159047fSniklas if (begin_type != st_File)
17032159047fSniklas scope_delta = -1;
17042159047fSniklas
17052159047fSniklas /* Except for file, structure, union, or enumeration end
17062159047fSniklas blocks remove all tags created within this scope. */
17072159047fSniklas if (begin_type != st_File && storage != sc_Info)
17082159047fSniklas {
17092159047fSniklas ptag_head = cur_tag_head;
17102159047fSniklas cur_tag_head = ptag_head->prev;
17112159047fSniklas
17122159047fSniklas for (ptag = ptag_head->first_tag;
17132159047fSniklas ptag != (tag_t *) NULL;
17142159047fSniklas ptag = ptag_next)
17152159047fSniklas {
17162159047fSniklas if (ptag->forward_ref != (forward_t *) NULL)
17172159047fSniklas add_unknown_tag (ptag);
17182159047fSniklas
17192159047fSniklas ptag_next = ptag->same_block;
17202159047fSniklas ptag->hash_ptr->tag_ptr = ptag->same_name;
17212159047fSniklas free_tag (ptag);
17222159047fSniklas }
17232159047fSniklas
17242159047fSniklas free_thead (ptag_head);
17252159047fSniklas }
17262159047fSniklas
17272159047fSniklas cur_file_ptr->cur_scope = pscope->prev;
17282159047fSniklas
17292159047fSniklas /* block begin gets next sym #. This is set when we know
17302159047fSniklas the symbol index value. */
17312159047fSniklas
17322159047fSniklas /* Functions push two or more aux words as follows:
17332159047fSniklas 1st word: index+1 of the end symbol (filled in later).
17342159047fSniklas 2nd word: type of the function (plus any aux words needed).
17352159047fSniklas Also, tie the external pointer back to the function begin symbol. */
17362159047fSniklas if (begin_type != st_File && begin_type != st_Block)
17372159047fSniklas {
17382159047fSniklas symint_t ty;
17392159047fSniklas varray_t *svp = &cur_file_ptr->aux_syms;
17402159047fSniklas
17412159047fSniklas pscope->lsym->ecoff_sym.asym.index = add_aux_sym_symint (0);
17422159047fSniklas pscope->lsym->index_ptr =
17432159047fSniklas &svp->last->datum->aux[svp->objects_last_page - 1];
17442159047fSniklas ty = add_aux_sym_tir (&last_func_type_info,
17452159047fSniklas hash_no,
17462159047fSniklas &cur_file_ptr->thash_head[0]);
17472159047fSniklas
17482159047fSniklas /* This seems to be unnecessary. I'm not even sure what it is
17492159047fSniklas * intended to do. It's from mips-tfile.
17502159047fSniklas * if (last_func_sym_value != (symbolS *) NULL)
17512159047fSniklas * {
17522159047fSniklas * last_func_sym_value->ifd = cur_file_ptr->file_index;
17532159047fSniklas * last_func_sym_value->index = ty;
17542159047fSniklas * }
17552159047fSniklas */
17562159047fSniklas }
17572159047fSniklas
17582159047fSniklas free_scope (pscope);
17592159047fSniklas }
17602159047fSniklas }
17612159047fSniklas
17622159047fSniklas cur_file_ptr->nested_scopes += scope_delta;
17632159047fSniklas
17642159047fSniklas #ifdef ECOFF_DEBUG
17652159047fSniklas if (debug && type != st_File
17662159047fSniklas && (debug > 2 || type == st_Block || type == st_End
17672159047fSniklas || type == st_Proc || type == st_StaticProc))
17682159047fSniklas {
17692159047fSniklas char *sc_str = sc_to_string (storage);
17702159047fSniklas char *st_str = st_to_string (type);
17712159047fSniklas int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
17722159047fSniklas
17732159047fSniklas fprintf (stderr,
17742159047fSniklas "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
17752159047fSniklas value, depth, sc_str);
17762159047fSniklas
17772159047fSniklas if (str_start && str_end_p1 - str_start > 0)
1778b55d4692Sfgsch fprintf (stderr, " st= %-11s name= %.*s\n",
1779b55d4692Sfgsch st_str, str_end_p1 - str_start, str_start);
17802159047fSniklas else
17812159047fSniklas {
17822159047fSniklas unsigned long len = strlen (st_str);
17832159047fSniklas fprintf (stderr, " st= %.*s\n", len - 1, st_str);
17842159047fSniklas }
17852159047fSniklas }
17862159047fSniklas #endif
17872159047fSniklas
17882159047fSniklas return psym;
17892159047fSniklas }
17902159047fSniklas
17912159047fSniklas /* Add an auxiliary symbol (passing a symint). This is actually used
17922159047fSniklas for integral aux types, not just symints. */
17932159047fSniklas
17942159047fSniklas static symint_t
add_aux_sym_symint(symint_t aux_word)1795*007c2a45Smiod add_aux_sym_symint (symint_t aux_word /* auxiliary information word */)
17962159047fSniklas {
17972159047fSniklas register varray_t *vp;
17982159047fSniklas register aux_t *aux_ptr;
17992159047fSniklas
18002159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
1801b305b0f1Sespie as_fatal (_("no current file pointer"));
18022159047fSniklas
18032159047fSniklas vp = &cur_file_ptr->aux_syms;
18042159047fSniklas
18052159047fSniklas if (vp->objects_last_page == vp->objects_per_page)
18062159047fSniklas add_varray_page (vp);
18072159047fSniklas
18082159047fSniklas aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
18092159047fSniklas aux_ptr->type = aux_isym;
18102159047fSniklas aux_ptr->data.isym = aux_word;
18112159047fSniklas
18122159047fSniklas return vp->num_allocated++;
18132159047fSniklas }
18142159047fSniklas
18152159047fSniklas /* Add an auxiliary symbol (passing a file/symbol index combo). */
18162159047fSniklas
18172159047fSniklas static symint_t
add_aux_sym_rndx(int file_index,symint_t sym_index)1818*007c2a45Smiod add_aux_sym_rndx (int file_index, symint_t sym_index)
18192159047fSniklas {
18202159047fSniklas register varray_t *vp;
18212159047fSniklas register aux_t *aux_ptr;
18222159047fSniklas
18232159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
1824b305b0f1Sespie as_fatal (_("no current file pointer"));
18252159047fSniklas
18262159047fSniklas vp = &cur_file_ptr->aux_syms;
18272159047fSniklas
18282159047fSniklas if (vp->objects_last_page == vp->objects_per_page)
18292159047fSniklas add_varray_page (vp);
18302159047fSniklas
18312159047fSniklas aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
18322159047fSniklas aux_ptr->type = aux_rndx;
18332159047fSniklas aux_ptr->data.rndx.rfd = file_index;
18342159047fSniklas aux_ptr->data.rndx.index = sym_index;
18352159047fSniklas
18362159047fSniklas return vp->num_allocated++;
18372159047fSniklas }
18382159047fSniklas
18392159047fSniklas /* Add an auxiliary symbol (passing the basic type and possibly
18402159047fSniklas type qualifiers). */
18412159047fSniklas
18422159047fSniklas static symint_t
add_aux_sym_tir(type_info_t * t,hash_state_t state,thash_t ** hash_tbl)1843*007c2a45Smiod add_aux_sym_tir (type_info_t *t, /* current type information */
1844*007c2a45Smiod hash_state_t state, /* whether to hash type or not */
1845*007c2a45Smiod thash_t **hash_tbl /* pointer to hash table to use */)
18462159047fSniklas {
18472159047fSniklas register varray_t *vp;
18482159047fSniklas register aux_t *aux_ptr;
18492159047fSniklas static AUXU init_aux;
18502159047fSniklas symint_t ret;
18512159047fSniklas int i;
18522159047fSniklas AUXU aux;
18532159047fSniklas
18542159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
1855b305b0f1Sespie as_fatal (_("no current file pointer"));
18562159047fSniklas
18572159047fSniklas vp = &cur_file_ptr->aux_syms;
18582159047fSniklas
18592159047fSniklas aux = init_aux;
18602159047fSniklas aux.ti.bt = (int) t->basic_type;
18612159047fSniklas aux.ti.continued = 0;
18622159047fSniklas aux.ti.fBitfield = t->bitfield;
18632159047fSniklas
18642159047fSniklas aux.ti.tq0 = (int) t->type_qualifiers[0];
18652159047fSniklas aux.ti.tq1 = (int) t->type_qualifiers[1];
18662159047fSniklas aux.ti.tq2 = (int) t->type_qualifiers[2];
18672159047fSniklas aux.ti.tq3 = (int) t->type_qualifiers[3];
18682159047fSniklas aux.ti.tq4 = (int) t->type_qualifiers[4];
18692159047fSniklas aux.ti.tq5 = (int) t->type_qualifiers[5];
18702159047fSniklas
18712159047fSniklas /* For anything that adds additional information, we must not hash,
18722159047fSniklas so check here, and reset our state. */
18732159047fSniklas
18742159047fSniklas if (state != hash_no
18752159047fSniklas && (t->type_qualifiers[0] == tq_Array
18762159047fSniklas || t->type_qualifiers[1] == tq_Array
18772159047fSniklas || t->type_qualifiers[2] == tq_Array
18782159047fSniklas || t->type_qualifiers[3] == tq_Array
18792159047fSniklas || t->type_qualifiers[4] == tq_Array
18802159047fSniklas || t->type_qualifiers[5] == tq_Array
18812159047fSniklas || t->basic_type == bt_Struct
18822159047fSniklas || t->basic_type == bt_Union
18832159047fSniklas || t->basic_type == bt_Enum
18842159047fSniklas || t->bitfield
18852159047fSniklas || t->num_dims > 0))
18862159047fSniklas state = hash_no;
18872159047fSniklas
18882159047fSniklas /* See if we can hash this type, and save some space, but some types
18892159047fSniklas can't be hashed (because they contain arrays or continuations),
18902159047fSniklas and others can be put into the hash list, but cannot use existing
18912159047fSniklas types because other aux entries precede this one. */
18922159047fSniklas
18932159047fSniklas if (state != hash_no)
18942159047fSniklas {
18952159047fSniklas register thash_t *hash_ptr;
18962159047fSniklas register symint_t hi;
18972159047fSniklas
18982159047fSniklas hi = aux.isym & ((1 << HASHBITS) - 1);
18992159047fSniklas hi %= THASH_SIZE;
19002159047fSniklas
19012159047fSniklas for (hash_ptr = hash_tbl[hi];
19022159047fSniklas hash_ptr != (thash_t *)0;
19032159047fSniklas hash_ptr = hash_ptr->next)
19042159047fSniklas {
19052159047fSniklas if (aux.isym == hash_ptr->type.isym)
19062159047fSniklas break;
19072159047fSniklas }
19082159047fSniklas
19092159047fSniklas if (hash_ptr != (thash_t *) NULL && state == hash_yes)
19102159047fSniklas return hash_ptr->indx;
19112159047fSniklas
19122159047fSniklas if (hash_ptr == (thash_t *) NULL)
19132159047fSniklas {
19142159047fSniklas hash_ptr = allocate_thash ();
19152159047fSniklas hash_ptr->next = hash_tbl[hi];
19162159047fSniklas hash_ptr->type = aux;
19172159047fSniklas hash_ptr->indx = vp->num_allocated;
19182159047fSniklas hash_tbl[hi] = hash_ptr;
19192159047fSniklas }
19202159047fSniklas }
19212159047fSniklas
19222159047fSniklas /* Everything is set up, add the aux symbol. */
19232159047fSniklas if (vp->objects_last_page == vp->objects_per_page)
19242159047fSniklas add_varray_page (vp);
19252159047fSniklas
19262159047fSniklas aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
19272159047fSniklas aux_ptr->type = aux_tir;
19282159047fSniklas aux_ptr->data = aux;
19292159047fSniklas
19302159047fSniklas ret = vp->num_allocated++;
19312159047fSniklas
19322159047fSniklas /* Add bitfield length if it exists.
19332159047fSniklas
19342159047fSniklas NOTE: Mips documentation claims bitfield goes at the end of the
19352159047fSniklas AUX record, but the DECstation compiler emits it here.
19362159047fSniklas (This would only make a difference for enum bitfields.)
19372159047fSniklas
19382159047fSniklas Also note: We use the last size given since gcc may emit 2
19392159047fSniklas for an enum bitfield. */
19402159047fSniklas
19412159047fSniklas if (t->bitfield)
19422159047fSniklas (void) add_aux_sym_symint ((symint_t) t->sizes[t->num_sizes - 1]);
19432159047fSniklas
19442159047fSniklas /* Add tag information if needed. Structure, union, and enum
19452159047fSniklas references add 2 aux symbols: a [file index, symbol index]
19462159047fSniklas pointer to the structure type, and the current file index. */
19472159047fSniklas
19482159047fSniklas if (t->basic_type == bt_Struct
19492159047fSniklas || t->basic_type == bt_Union
19502159047fSniklas || t->basic_type == bt_Enum)
19512159047fSniklas {
19522159047fSniklas register symint_t file_index = t->tag_ptr->ifd;
19532159047fSniklas register localsym_t *sym = t->tag_ptr->sym;
19542159047fSniklas register forward_t *forward_ref = allocate_forward ();
19552159047fSniklas
19562159047fSniklas if (sym != (localsym_t *) NULL)
19572159047fSniklas {
19582159047fSniklas forward_ref->next = sym->forward_ref;
19592159047fSniklas sym->forward_ref = forward_ref;
19602159047fSniklas }
19612159047fSniklas else
19622159047fSniklas {
19632159047fSniklas forward_ref->next = t->tag_ptr->forward_ref;
19642159047fSniklas t->tag_ptr->forward_ref = forward_ref;
19652159047fSniklas }
19662159047fSniklas
19672159047fSniklas (void) add_aux_sym_rndx (ST_RFDESCAPE, indexNil);
19682159047fSniklas forward_ref->index_ptr
19692159047fSniklas = &vp->last->datum->aux[vp->objects_last_page - 1];
19702159047fSniklas
19712159047fSniklas (void) add_aux_sym_symint (file_index);
19722159047fSniklas forward_ref->ifd_ptr
19732159047fSniklas = &vp->last->datum->aux[vp->objects_last_page - 1];
19742159047fSniklas }
19752159047fSniklas
19762159047fSniklas /* Add information about array bounds if they exist. */
19772159047fSniklas for (i = 0; i < t->num_dims; i++)
19782159047fSniklas {
19792159047fSniklas (void) add_aux_sym_rndx (ST_RFDESCAPE,
19802159047fSniklas cur_file_ptr->int_type);
19812159047fSniklas
19822159047fSniklas (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/
19832159047fSniklas (void) add_aux_sym_symint ((symint_t) 0); /* low bound */
19842159047fSniklas (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/
19852159047fSniklas (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */
19862159047fSniklas ? 0
19872159047fSniklas : (t->sizes[i] * 8) / t->dimensions[i]);
19882159047fSniklas };
19892159047fSniklas
19902159047fSniklas /* NOTE: Mips documentation claims that the bitfield width goes here.
19912159047fSniklas But it needs to be emitted earlier. */
19922159047fSniklas
19932159047fSniklas return ret;
19942159047fSniklas }
19952159047fSniklas
19962159047fSniklas /* Add a tag to the tag table (unless it already exists). */
19972159047fSniklas
19982159047fSniklas static tag_t *
get_tag(const char * tag,localsym_t * sym,bt_t basic_type)1999*007c2a45Smiod get_tag (const char *tag, /* tag name */
2000*007c2a45Smiod localsym_t *sym, /* tag start block */
2001*007c2a45Smiod bt_t basic_type /* bt_Struct, bt_Union, or bt_Enum */)
20022159047fSniklas {
20032159047fSniklas shash_t *hash_ptr;
20042159047fSniklas const char *err;
20052159047fSniklas tag_t *tag_ptr;
20062159047fSniklas
20072159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
2008b305b0f1Sespie as_fatal (_("no current file pointer"));
20092159047fSniklas
20102159047fSniklas hash_ptr = (shash_t *) hash_find (tag_hash, tag);
20112159047fSniklas
20122159047fSniklas if (hash_ptr != (shash_t *) NULL
20132159047fSniklas && hash_ptr->tag_ptr != (tag_t *) NULL)
20142159047fSniklas {
20152159047fSniklas tag_ptr = hash_ptr->tag_ptr;
20162159047fSniklas if (sym != (localsym_t *) NULL)
20172159047fSniklas {
20182159047fSniklas tag_ptr->basic_type = basic_type;
20192159047fSniklas tag_ptr->ifd = cur_file_ptr->file_index;
20202159047fSniklas tag_ptr->sym = sym;
20212159047fSniklas }
20222159047fSniklas return tag_ptr;
20232159047fSniklas }
20242159047fSniklas
20252159047fSniklas if (hash_ptr == (shash_t *) NULL)
20262159047fSniklas {
20272159047fSniklas char *perm;
20282159047fSniklas
2029c074d1c9Sdrahn perm = xstrdup (tag);
20302159047fSniklas hash_ptr = allocate_shash ();
20312159047fSniklas err = hash_insert (tag_hash, perm, (char *) hash_ptr);
20322159047fSniklas if (err)
2033c074d1c9Sdrahn as_fatal (_("inserting \"%s\" into tag hash table: %s"),
20342159047fSniklas tag, err);
20352159047fSniklas hash_ptr->string = perm;
20362159047fSniklas }
20372159047fSniklas
20382159047fSniklas tag_ptr = allocate_tag ();
20392159047fSniklas tag_ptr->forward_ref = (forward_t *) NULL;
20402159047fSniklas tag_ptr->hash_ptr = hash_ptr;
20412159047fSniklas tag_ptr->same_name = hash_ptr->tag_ptr;
20422159047fSniklas tag_ptr->basic_type = basic_type;
20432159047fSniklas tag_ptr->sym = sym;
20442159047fSniklas tag_ptr->ifd = ((sym == (localsym_t *) NULL)
20452159047fSniklas ? (symint_t) -1
20462159047fSniklas : cur_file_ptr->file_index);
20472159047fSniklas tag_ptr->same_block = cur_tag_head->first_tag;
20482159047fSniklas
20492159047fSniklas cur_tag_head->first_tag = tag_ptr;
20502159047fSniklas hash_ptr->tag_ptr = tag_ptr;
20512159047fSniklas
20522159047fSniklas return tag_ptr;
20532159047fSniklas }
20542159047fSniklas
20552159047fSniklas /* Add an unknown {struct, union, enum} tag. */
20562159047fSniklas
20572159047fSniklas static void
add_unknown_tag(tag_t * ptag)2058*007c2a45Smiod add_unknown_tag (tag_t *ptag /* pointer to tag information */)
20592159047fSniklas {
20602159047fSniklas shash_t *hash_ptr = ptag->hash_ptr;
20612159047fSniklas char *name = hash_ptr->string;
20622159047fSniklas localsym_t *sym;
20632159047fSniklas forward_t **pf;
20642159047fSniklas
20652159047fSniklas #ifdef ECOFF_DEBUG
20662159047fSniklas if (debug > 1)
20672159047fSniklas {
20682159047fSniklas char *agg_type = "{unknown aggregate type}";
20692159047fSniklas switch (ptag->basic_type)
20702159047fSniklas {
20712159047fSniklas case bt_Struct: agg_type = "struct"; break;
20722159047fSniklas case bt_Union: agg_type = "union"; break;
20732159047fSniklas case bt_Enum: agg_type = "enum"; break;
20742159047fSniklas default: break;
20752159047fSniklas }
20762159047fSniklas
20772159047fSniklas fprintf (stderr, "unknown %s %.*s found\n", agg_type,
20782159047fSniklas hash_ptr->len, name_start);
20792159047fSniklas }
20802159047fSniklas #endif
20812159047fSniklas
20822159047fSniklas sym = add_ecoff_symbol (name,
20832159047fSniklas st_Block,
20842159047fSniklas sc_Info,
20852159047fSniklas (symbolS *) NULL,
2086191aa565Sniklas (bfd_vma) 0,
20872159047fSniklas (symint_t) 0,
20882159047fSniklas (symint_t) 0);
20892159047fSniklas
20902159047fSniklas (void) add_ecoff_symbol (name,
20912159047fSniklas st_End,
20922159047fSniklas sc_Info,
20932159047fSniklas (symbolS *) NULL,
2094191aa565Sniklas (bfd_vma) 0,
20952159047fSniklas (symint_t) 0,
20962159047fSniklas (symint_t) 0);
20972159047fSniklas
20982159047fSniklas for (pf = &sym->forward_ref; *pf != (forward_t *) NULL; pf = &(*pf)->next)
20992159047fSniklas ;
21002159047fSniklas *pf = ptag->forward_ref;
21012159047fSniklas }
21022159047fSniklas
21032159047fSniklas /* Add a procedure to the current file's list of procedures, and record
21042159047fSniklas this is the current procedure. */
21052159047fSniklas
21062159047fSniklas static void
add_procedure(char * func)2107*007c2a45Smiod add_procedure (char *func /* func name */)
21082159047fSniklas {
21092159047fSniklas register varray_t *vp;
21102159047fSniklas register proc_t *new_proc_ptr;
2111191aa565Sniklas symbolS *sym;
21122159047fSniklas
21132159047fSniklas #ifdef ECOFF_DEBUG
21142159047fSniklas if (debug)
21152159047fSniklas fputc ('\n', stderr);
21162159047fSniklas #endif
21172159047fSniklas
21182159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
2119b305b0f1Sespie as_fatal (_("no current file pointer"));
21202159047fSniklas
21212159047fSniklas vp = &cur_file_ptr->procs;
21222159047fSniklas
21232159047fSniklas if (vp->objects_last_page == vp->objects_per_page)
21242159047fSniklas add_varray_page (vp);
21252159047fSniklas
21262159047fSniklas cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[vp->objects_last_page++];
21272159047fSniklas
21282159047fSniklas if (first_proc_ptr == (proc_t *) NULL)
21292159047fSniklas first_proc_ptr = new_proc_ptr;
21302159047fSniklas
21312159047fSniklas vp->num_allocated++;
21322159047fSniklas
21332159047fSniklas new_proc_ptr->pdr.isym = -1;
21342159047fSniklas new_proc_ptr->pdr.iline = -1;
21352159047fSniklas new_proc_ptr->pdr.lnLow = -1;
21362159047fSniklas new_proc_ptr->pdr.lnHigh = -1;
21372159047fSniklas
2138191aa565Sniklas /* Set the BSF_FUNCTION flag for the symbol. */
2139191aa565Sniklas sym = symbol_find_or_make (func);
2140b305b0f1Sespie symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
2141191aa565Sniklas
21422159047fSniklas /* Push the start of the function. */
21432159047fSniklas new_proc_ptr->sym = add_ecoff_symbol ((const char *) NULL, st_Proc, sc_Text,
2144191aa565Sniklas sym, (bfd_vma) 0, (symint_t) 0,
2145191aa565Sniklas (symint_t) 0);
21462159047fSniklas
21472159047fSniklas ++proc_cnt;
21482159047fSniklas
21492159047fSniklas /* Fill in the linenos preceding the .ent, if any. */
21502159047fSniklas if (noproc_lineno != (lineno_list_t *) NULL)
21512159047fSniklas {
21522159047fSniklas lineno_list_t *l;
21532159047fSniklas
21542159047fSniklas for (l = noproc_lineno; l != (lineno_list_t *) NULL; l = l->next)
21552159047fSniklas l->proc = new_proc_ptr;
21562159047fSniklas *last_lineno_ptr = noproc_lineno;
21572159047fSniklas while (*last_lineno_ptr != NULL)
21580c6d0228Sniklas {
21590c6d0228Sniklas last_lineno = *last_lineno_ptr;
21600c6d0228Sniklas last_lineno_ptr = &last_lineno->next;
21610c6d0228Sniklas }
21622159047fSniklas noproc_lineno = (lineno_list_t *) NULL;
21632159047fSniklas }
21642159047fSniklas }
2165b305b0f1Sespie
2166b305b0f1Sespie symbolS *
ecoff_get_cur_proc_sym(void)2167*007c2a45Smiod ecoff_get_cur_proc_sym (void)
2168b305b0f1Sespie {
2169b305b0f1Sespie return (cur_proc_ptr ? cur_proc_ptr->sym->as_sym : NULL);
2170b305b0f1Sespie }
21712159047fSniklas
21722159047fSniklas /* Add a new filename, and set up all of the file relative
21732159047fSniklas virtual arrays (strings, symbols, aux syms, etc.). Record
21742159047fSniklas where the current file structure lives. */
21752159047fSniklas
21762159047fSniklas static void
add_file(const char * file_name,int indx ATTRIBUTE_UNUSED,int fake)2177*007c2a45Smiod add_file (const char *file_name, int indx ATTRIBUTE_UNUSED, int fake)
21782159047fSniklas {
21792159047fSniklas register int first_ch;
21802159047fSniklas register efdr_t *fil_ptr;
21812159047fSniklas
21822159047fSniklas #ifdef ECOFF_DEBUG
21832159047fSniklas if (debug)
21842159047fSniklas fprintf (stderr, "\tfile\t%.*s\n", len, file_start);
21852159047fSniklas #endif
21862159047fSniklas
21872159047fSniklas /* If the file name is NULL, then no .file symbol appeared, and we
21882159047fSniklas want to use the actual file name. */
21892159047fSniklas if (file_name == (const char *) NULL)
21902159047fSniklas {
21912159047fSniklas char *file;
21922159047fSniklas
21932159047fSniklas if (first_file != (efdr_t *) NULL)
2194b305b0f1Sespie as_fatal (_("fake .file after real one"));
21952159047fSniklas as_where (&file, (unsigned int *) NULL);
21962159047fSniklas file_name = (const char *) file;
21972159047fSniklas
2198b305b0f1Sespie /* Automatically generate ECOFF debugging information, since I
2199b305b0f1Sespie think that's what other ECOFF assemblers do. We don't do
2200b305b0f1Sespie this if we see a .file directive with a string, since that
2201b305b0f1Sespie implies that some sort of debugging information is being
2202b305b0f1Sespie provided. */
2203b55d4692Sfgsch if (! symbol_table_frozen && debug_type == DEBUG_UNSPECIFIED)
2204b305b0f1Sespie debug_type = DEBUG_ECOFF;
22052159047fSniklas }
2206c074d1c9Sdrahn else if (debug_type == DEBUG_UNSPECIFIED)
2207b55d4692Sfgsch debug_type = DEBUG_NONE;
22082159047fSniklas
22092159047fSniklas #ifndef NO_LISTING
22102159047fSniklas if (listing)
22112159047fSniklas listing_source_file (file_name);
22122159047fSniklas #endif
22132159047fSniklas
22142159047fSniklas current_stabs_filename = file_name;
22152159047fSniklas
22162159047fSniklas /* If we're creating stabs, then we don't actually make a new FDR.
22172159047fSniklas Instead, we just create a stabs symbol. */
22182159047fSniklas if (stabs_seen)
22192159047fSniklas {
22202159047fSniklas (void) add_ecoff_symbol (file_name, st_Nil, sc_Nil,
22212159047fSniklas symbol_new ("L0\001", now_seg,
22222159047fSniklas (valueT) frag_now_fix (),
22232159047fSniklas frag_now),
2224191aa565Sniklas (bfd_vma) 0, 0, ECOFF_MARK_STAB (N_SOL));
22252159047fSniklas return;
22262159047fSniklas }
22272159047fSniklas
22282159047fSniklas first_ch = *file_name;
22292159047fSniklas
22300c6d0228Sniklas /* FIXME: We can't safely merge files which have line number
22310c6d0228Sniklas information (fMerge will be zero in this case). Otherwise, we
22320c6d0228Sniklas get incorrect line number debugging info. See for instance
22330c6d0228Sniklas ecoff_build_lineno, which will end up setting all file->fdr.*
22340c6d0228Sniklas fields multiple times, resulting in incorrect debug info. In
22350c6d0228Sniklas order to make this work right, all line number and symbol info
22360c6d0228Sniklas for the same source file has to be adjacent in the object file,
22370c6d0228Sniklas so that a single file descriptor can be used to point to them.
22380c6d0228Sniklas This would require maintaining file specific lists of line
22390c6d0228Sniklas numbers and symbols for each file, so that they can be merged
22400c6d0228Sniklas together (or output together) when two .file pseudo-ops are
22410c6d0228Sniklas merged into one file descriptor. */
22422159047fSniklas
22432159047fSniklas /* See if the file has already been created. */
22442159047fSniklas for (fil_ptr = first_file;
22452159047fSniklas fil_ptr != (efdr_t *) NULL;
22462159047fSniklas fil_ptr = fil_ptr->next_file)
22472159047fSniklas {
22482159047fSniklas if (first_ch == fil_ptr->name[0]
22490c6d0228Sniklas && strcmp (file_name, fil_ptr->name) == 0
22500c6d0228Sniklas && fil_ptr->fdr.fMerge)
22512159047fSniklas {
22522159047fSniklas cur_file_ptr = fil_ptr;
22532159047fSniklas if (! fake)
22542159047fSniklas cur_file_ptr->fake = 0;
22552159047fSniklas break;
22562159047fSniklas }
22572159047fSniklas }
22582159047fSniklas
22592159047fSniklas /* If this is a new file, create it. */
22602159047fSniklas if (fil_ptr == (efdr_t *) NULL)
22612159047fSniklas {
22622159047fSniklas if (file_desc.objects_last_page == file_desc.objects_per_page)
22632159047fSniklas add_varray_page (&file_desc);
22642159047fSniklas
22652159047fSniklas fil_ptr = cur_file_ptr =
22662159047fSniklas &file_desc.last->datum->file[file_desc.objects_last_page++];
22672159047fSniklas *fil_ptr = init_file;
22682159047fSniklas
22692159047fSniklas fil_ptr->file_index = current_file_idx++;
22702159047fSniklas ++file_desc.num_allocated;
22712159047fSniklas
22722159047fSniklas fil_ptr->fake = fake;
22732159047fSniklas
22742159047fSniklas /* Allocate the string hash table. */
22752159047fSniklas fil_ptr->str_hash = hash_new ();
22762159047fSniklas
22772159047fSniklas /* Make sure 0 byte in string table is null */
22782159047fSniklas add_string (&fil_ptr->strings,
22792159047fSniklas fil_ptr->str_hash,
22802159047fSniklas "",
22812159047fSniklas (shash_t **)0);
22822159047fSniklas
22832159047fSniklas if (strlen (file_name) > PAGE_USIZE - 2)
2284c074d1c9Sdrahn as_fatal (_("filename goes over one page boundary"));
22852159047fSniklas
22862159047fSniklas /* Push the start of the filename. We assume that the filename
22872159047fSniklas will be stored at string offset 1. */
22882159047fSniklas (void) add_ecoff_symbol (file_name, st_File, sc_Text,
2289191aa565Sniklas (symbolS *) NULL, (bfd_vma) 0,
22902159047fSniklas (symint_t) 0, (symint_t) 0);
22912159047fSniklas fil_ptr->fdr.rss = 1;
22922159047fSniklas fil_ptr->name = &fil_ptr->strings.last->datum->byte[1];
22932159047fSniklas
22942159047fSniklas /* Update the linked list of file descriptors. */
22952159047fSniklas *last_file_ptr = fil_ptr;
22962159047fSniklas last_file_ptr = &fil_ptr->next_file;
22972159047fSniklas
22982159047fSniklas /* Add void & int types to the file (void should be first to catch
22992159047fSniklas errant 0's within the index fields). */
23002159047fSniklas fil_ptr->void_type = add_aux_sym_tir (&void_type_info,
23012159047fSniklas hash_yes,
23022159047fSniklas &cur_file_ptr->thash_head[0]);
23032159047fSniklas
23042159047fSniklas fil_ptr->int_type = add_aux_sym_tir (&int_type_info,
23052159047fSniklas hash_yes,
23062159047fSniklas &cur_file_ptr->thash_head[0]);
23072159047fSniklas }
23082159047fSniklas }
2309e93f7393Sniklas
2310e93f7393Sniklas /* This function is called when the assembler notices a preprocessor
2311e93f7393Sniklas directive switching to a new file. This will not happen in
2312e93f7393Sniklas compiler output, only in hand coded assembler. */
2313e93f7393Sniklas
2314e93f7393Sniklas void
ecoff_new_file(const char * name)2315*007c2a45Smiod ecoff_new_file (const char *name)
2316e93f7393Sniklas {
2317e93f7393Sniklas if (cur_file_ptr != NULL && strcmp (cur_file_ptr->name, name) == 0)
2318e93f7393Sniklas return;
2319e93f7393Sniklas add_file (name, 0, 0);
2320b305b0f1Sespie
2321b305b0f1Sespie /* This is a hand coded assembler file, so automatically turn on
2322b305b0f1Sespie debugging information. */
2323b55d4692Sfgsch if (debug_type == DEBUG_UNSPECIFIED)
2324b305b0f1Sespie debug_type = DEBUG_ECOFF;
2325e93f7393Sniklas }
23262159047fSniklas
23272159047fSniklas #ifdef ECOFF_DEBUG
23282159047fSniklas
23292159047fSniklas /* Convert storage class to string. */
23302159047fSniklas
23312159047fSniklas static char *
sc_to_string(storage_class)23322159047fSniklas sc_to_string (storage_class)
23332159047fSniklas sc_t storage_class;
23342159047fSniklas {
23352159047fSniklas switch (storage_class)
23362159047fSniklas {
23372159047fSniklas case sc_Nil: return "Nil,";
23382159047fSniklas case sc_Text: return "Text,";
23392159047fSniklas case sc_Data: return "Data,";
23402159047fSniklas case sc_Bss: return "Bss,";
23412159047fSniklas case sc_Register: return "Register,";
23422159047fSniklas case sc_Abs: return "Abs,";
23432159047fSniklas case sc_Undefined: return "Undefined,";
23442159047fSniklas case sc_CdbLocal: return "CdbLocal,";
23452159047fSniklas case sc_Bits: return "Bits,";
23462159047fSniklas case sc_CdbSystem: return "CdbSystem,";
23472159047fSniklas case sc_RegImage: return "RegImage,";
23482159047fSniklas case sc_Info: return "Info,";
23492159047fSniklas case sc_UserStruct: return "UserStruct,";
23502159047fSniklas case sc_SData: return "SData,";
23512159047fSniklas case sc_SBss: return "SBss,";
23522159047fSniklas case sc_RData: return "RData,";
23532159047fSniklas case sc_Var: return "Var,";
23542159047fSniklas case sc_Common: return "Common,";
23552159047fSniklas case sc_SCommon: return "SCommon,";
23562159047fSniklas case sc_VarRegister: return "VarRegister,";
23572159047fSniklas case sc_Variant: return "Variant,";
23582159047fSniklas case sc_SUndefined: return "SUndefined,";
23592159047fSniklas case sc_Init: return "Init,";
23602159047fSniklas case sc_Max: return "Max,";
23612159047fSniklas }
23622159047fSniklas
23632159047fSniklas return "???,";
23642159047fSniklas }
23652159047fSniklas
23662159047fSniklas #endif /* DEBUG */
23672159047fSniklas
23682159047fSniklas #ifdef ECOFF_DEBUG
23692159047fSniklas
23702159047fSniklas /* Convert symbol type to string. */
23712159047fSniklas
23722159047fSniklas static char *
st_to_string(symbol_type)23732159047fSniklas st_to_string (symbol_type)
23742159047fSniklas st_t symbol_type;
23752159047fSniklas {
23762159047fSniklas switch (symbol_type)
23772159047fSniklas {
23782159047fSniklas case st_Nil: return "Nil,";
23792159047fSniklas case st_Global: return "Global,";
23802159047fSniklas case st_Static: return "Static,";
23812159047fSniklas case st_Param: return "Param,";
23822159047fSniklas case st_Local: return "Local,";
23832159047fSniklas case st_Label: return "Label,";
23842159047fSniklas case st_Proc: return "Proc,";
23852159047fSniklas case st_Block: return "Block,";
23862159047fSniklas case st_End: return "End,";
23872159047fSniklas case st_Member: return "Member,";
23882159047fSniklas case st_Typedef: return "Typedef,";
23892159047fSniklas case st_File: return "File,";
23902159047fSniklas case st_RegReloc: return "RegReloc,";
23912159047fSniklas case st_Forward: return "Forward,";
23922159047fSniklas case st_StaticProc: return "StaticProc,";
23932159047fSniklas case st_Constant: return "Constant,";
23942159047fSniklas case st_Str: return "String,";
23952159047fSniklas case st_Number: return "Number,";
23962159047fSniklas case st_Expr: return "Expr,";
23972159047fSniklas case st_Type: return "Type,";
23982159047fSniklas case st_Max: return "Max,";
23992159047fSniklas }
24002159047fSniklas
24012159047fSniklas return "???,";
24022159047fSniklas }
24032159047fSniklas
24042159047fSniklas #endif /* DEBUG */
24052159047fSniklas
24062159047fSniklas /* Parse .begin directives which have a label as the first argument
24072159047fSniklas which gives the location of the start of the block. */
24082159047fSniklas
24092159047fSniklas void
ecoff_directive_begin(int ignore ATTRIBUTE_UNUSED)2410*007c2a45Smiod ecoff_directive_begin (int ignore ATTRIBUTE_UNUSED)
24112159047fSniklas {
24122159047fSniklas char *name;
24132159047fSniklas char name_end;
24142159047fSniklas
24152159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
24162159047fSniklas {
2417b305b0f1Sespie as_warn (_(".begin directive without a preceding .file directive"));
24182159047fSniklas demand_empty_rest_of_line ();
24192159047fSniklas return;
24202159047fSniklas }
24212159047fSniklas
24222159047fSniklas if (cur_proc_ptr == (proc_t *) NULL)
24232159047fSniklas {
2424b305b0f1Sespie as_warn (_(".begin directive without a preceding .ent directive"));
24252159047fSniklas demand_empty_rest_of_line ();
24262159047fSniklas return;
24272159047fSniklas }
24282159047fSniklas
24292159047fSniklas name = input_line_pointer;
24302159047fSniklas name_end = get_symbol_end ();
24312159047fSniklas
24322159047fSniklas (void) add_ecoff_symbol ((const char *) NULL, st_Block, sc_Text,
24332159047fSniklas symbol_find_or_make (name),
2434191aa565Sniklas (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
24352159047fSniklas
24362159047fSniklas *input_line_pointer = name_end;
24372159047fSniklas
24382159047fSniklas /* The line number follows, but we don't use it. */
24392159047fSniklas (void) get_absolute_expression ();
24402159047fSniklas demand_empty_rest_of_line ();
24412159047fSniklas }
24422159047fSniklas
24432159047fSniklas /* Parse .bend directives which have a label as the first argument
24442159047fSniklas which gives the location of the end of the block. */
24452159047fSniklas
24462159047fSniklas void
ecoff_directive_bend(int ignore ATTRIBUTE_UNUSED)2447*007c2a45Smiod ecoff_directive_bend (int ignore ATTRIBUTE_UNUSED)
24482159047fSniklas {
24492159047fSniklas char *name;
24502159047fSniklas char name_end;
24512159047fSniklas symbolS *endsym;
24522159047fSniklas
24532159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
24542159047fSniklas {
2455b305b0f1Sespie as_warn (_(".bend directive without a preceding .file directive"));
24562159047fSniklas demand_empty_rest_of_line ();
24572159047fSniklas return;
24582159047fSniklas }
24592159047fSniklas
24602159047fSniklas if (cur_proc_ptr == (proc_t *) NULL)
24612159047fSniklas {
2462b305b0f1Sespie as_warn (_(".bend directive without a preceding .ent directive"));
24632159047fSniklas demand_empty_rest_of_line ();
24642159047fSniklas return;
24652159047fSniklas }
24662159047fSniklas
24672159047fSniklas name = input_line_pointer;
24682159047fSniklas name_end = get_symbol_end ();
24692159047fSniklas
24702159047fSniklas /* The value is the distance between the .bend directive and the
24712159047fSniklas corresponding symbol. We fill in the offset when we write out
24722159047fSniklas the symbol. */
24732159047fSniklas endsym = symbol_find (name);
24742159047fSniklas if (endsym == (symbolS *) NULL)
2475b305b0f1Sespie as_warn (_(".bend directive names unknown symbol"));
24762159047fSniklas else
24772159047fSniklas (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym,
2478191aa565Sniklas (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
24792159047fSniklas
24802159047fSniklas *input_line_pointer = name_end;
24812159047fSniklas
24822159047fSniklas /* The line number follows, but we don't use it. */
24832159047fSniklas (void) get_absolute_expression ();
24842159047fSniklas demand_empty_rest_of_line ();
24852159047fSniklas }
24862159047fSniklas
24872159047fSniklas /* COFF debugging information is provided as a series of directives
24882159047fSniklas (.def, .scl, etc.). We build up information as we read the
24892159047fSniklas directives in the following static variables, and file it away when
24902159047fSniklas we reach the .endef directive. */
24912159047fSniklas static char *coff_sym_name;
24922159047fSniklas static type_info_t coff_type;
24932159047fSniklas static sc_t coff_storage_class;
24942159047fSniklas static st_t coff_symbol_typ;
24952159047fSniklas static int coff_is_function;
24962159047fSniklas static char *coff_tag;
24972159047fSniklas static valueT coff_value;
2498191aa565Sniklas static symbolS *coff_sym_value;
2499191aa565Sniklas static bfd_vma coff_sym_addend;
25002159047fSniklas static int coff_inside_enumeration;
25012159047fSniklas
25022159047fSniklas /* Handle a .def directive: start defining a symbol. */
25032159047fSniklas
25042159047fSniklas void
ecoff_directive_def(int ignore ATTRIBUTE_UNUSED)2505*007c2a45Smiod ecoff_directive_def (int ignore ATTRIBUTE_UNUSED)
25062159047fSniklas {
25072159047fSniklas char *name;
25082159047fSniklas char name_end;
25092159047fSniklas
25102159047fSniklas ecoff_debugging_seen = 1;
25112159047fSniklas
25122159047fSniklas SKIP_WHITESPACE ();
25132159047fSniklas
25142159047fSniklas name = input_line_pointer;
25152159047fSniklas name_end = get_symbol_end ();
25162159047fSniklas
25172159047fSniklas if (coff_sym_name != (char *) NULL)
2518b305b0f1Sespie as_warn (_(".def pseudo-op used inside of .def/.endef; ignored"));
25192159047fSniklas else if (*name == '\0')
2520c074d1c9Sdrahn as_warn (_("empty symbol name in .def; ignored"));
25212159047fSniklas else
25222159047fSniklas {
25232159047fSniklas if (coff_sym_name != (char *) NULL)
25242159047fSniklas free (coff_sym_name);
25252159047fSniklas if (coff_tag != (char *) NULL)
25262159047fSniklas free (coff_tag);
2527c074d1c9Sdrahn
2528c074d1c9Sdrahn coff_sym_name = xstrdup (name);
25292159047fSniklas coff_type = type_info_init;
25302159047fSniklas coff_storage_class = sc_Nil;
25312159047fSniklas coff_symbol_typ = st_Nil;
25322159047fSniklas coff_is_function = 0;
25332159047fSniklas coff_tag = (char *) NULL;
25342159047fSniklas coff_value = 0;
25352159047fSniklas coff_sym_value = (symbolS *) NULL;
2536191aa565Sniklas coff_sym_addend = 0;
25372159047fSniklas }
25382159047fSniklas
25392159047fSniklas *input_line_pointer = name_end;
25402159047fSniklas
25412159047fSniklas demand_empty_rest_of_line ();
25422159047fSniklas }
25432159047fSniklas
25442159047fSniklas /* Handle a .dim directive, used to give dimensions for an array. The
25452159047fSniklas arguments are comma separated numbers. mips-tfile assumes that
25462159047fSniklas there will not be more than 6 dimensions, and gdb won't read any
25472159047fSniklas more than that anyhow, so I will also make that assumption. */
25482159047fSniklas
25492159047fSniklas void
ecoff_directive_dim(int ignore ATTRIBUTE_UNUSED)2550*007c2a45Smiod ecoff_directive_dim (int ignore ATTRIBUTE_UNUSED)
25512159047fSniklas {
25522159047fSniklas int dimens[N_TQ];
25532159047fSniklas int i;
25542159047fSniklas
25552159047fSniklas if (coff_sym_name == (char *) NULL)
25562159047fSniklas {
2557b305b0f1Sespie as_warn (_(".dim pseudo-op used outside of .def/.endef; ignored"));
25582159047fSniklas demand_empty_rest_of_line ();
25592159047fSniklas return;
25602159047fSniklas }
25612159047fSniklas
25622159047fSniklas for (i = 0; i < N_TQ; i++)
25632159047fSniklas {
25642159047fSniklas SKIP_WHITESPACE ();
25652159047fSniklas dimens[i] = get_absolute_expression ();
25662159047fSniklas if (*input_line_pointer == ',')
25672159047fSniklas ++input_line_pointer;
25682159047fSniklas else
25692159047fSniklas {
25702159047fSniklas if (*input_line_pointer != '\n'
25712159047fSniklas && *input_line_pointer != ';')
2572c074d1c9Sdrahn as_warn (_("badly formed .dim directive"));
25732159047fSniklas break;
25742159047fSniklas }
25752159047fSniklas }
25762159047fSniklas
25772159047fSniklas if (i == N_TQ)
25782159047fSniklas --i;
25792159047fSniklas
25802159047fSniklas /* The dimensions are stored away in reverse order. */
25812159047fSniklas for (; i >= 0; i--)
25822159047fSniklas {
25832159047fSniklas if (coff_type.num_dims >= N_TQ)
25842159047fSniklas {
2585c074d1c9Sdrahn as_warn (_("too many .dim entries"));
25862159047fSniklas break;
25872159047fSniklas }
25882159047fSniklas coff_type.dimensions[coff_type.num_dims] = dimens[i];
25892159047fSniklas ++coff_type.num_dims;
25902159047fSniklas }
25912159047fSniklas
25922159047fSniklas demand_empty_rest_of_line ();
25932159047fSniklas }
25942159047fSniklas
25952159047fSniklas /* Handle a .scl directive, which sets the COFF storage class of the
25962159047fSniklas symbol. */
25972159047fSniklas
25982159047fSniklas void
ecoff_directive_scl(int ignore ATTRIBUTE_UNUSED)2599*007c2a45Smiod ecoff_directive_scl (int ignore ATTRIBUTE_UNUSED)
26002159047fSniklas {
26012159047fSniklas long val;
26022159047fSniklas
26032159047fSniklas if (coff_sym_name == (char *) NULL)
26042159047fSniklas {
2605b305b0f1Sespie as_warn (_(".scl pseudo-op used outside of .def/.endef; ignored"));
26062159047fSniklas demand_empty_rest_of_line ();
26072159047fSniklas return;
26082159047fSniklas }
26092159047fSniklas
26102159047fSniklas val = get_absolute_expression ();
26112159047fSniklas
26122159047fSniklas coff_symbol_typ = map_coff_sym_type[val];
26132159047fSniklas coff_storage_class = map_coff_storage[val];
26142159047fSniklas
26152159047fSniklas demand_empty_rest_of_line ();
26162159047fSniklas }
26172159047fSniklas
26182159047fSniklas /* Handle a .size directive. For some reason mips-tfile.c thinks that
26192159047fSniklas .size can have multiple arguments. We humor it, although gcc will
26202159047fSniklas never generate more than one argument. */
26212159047fSniklas
26222159047fSniklas void
ecoff_directive_size(int ignore ATTRIBUTE_UNUSED)2623*007c2a45Smiod ecoff_directive_size (int ignore ATTRIBUTE_UNUSED)
26242159047fSniklas {
26252159047fSniklas int sizes[N_TQ];
26262159047fSniklas int i;
26272159047fSniklas
26282159047fSniklas if (coff_sym_name == (char *) NULL)
26292159047fSniklas {
2630b305b0f1Sespie as_warn (_(".size pseudo-op used outside of .def/.endef; ignored"));
26312159047fSniklas demand_empty_rest_of_line ();
26322159047fSniklas return;
26332159047fSniklas }
26342159047fSniklas
26352159047fSniklas for (i = 0; i < N_TQ; i++)
26362159047fSniklas {
26372159047fSniklas SKIP_WHITESPACE ();
26382159047fSniklas sizes[i] = get_absolute_expression ();
26392159047fSniklas if (*input_line_pointer == ',')
26402159047fSniklas ++input_line_pointer;
26412159047fSniklas else
26422159047fSniklas {
26432159047fSniklas if (*input_line_pointer != '\n'
26442159047fSniklas && *input_line_pointer != ';')
2645c074d1c9Sdrahn as_warn (_("badly formed .size directive"));
26462159047fSniklas break;
26472159047fSniklas }
26482159047fSniklas }
26492159047fSniklas
26502159047fSniklas if (i == N_TQ)
26512159047fSniklas --i;
26522159047fSniklas
26532159047fSniklas /* The sizes are stored away in reverse order. */
26542159047fSniklas for (; i >= 0; i--)
26552159047fSniklas {
26562159047fSniklas if (coff_type.num_sizes >= N_TQ)
26572159047fSniklas {
2658c074d1c9Sdrahn as_warn (_("too many .size entries"));
26592159047fSniklas break;
26602159047fSniklas }
26612159047fSniklas coff_type.sizes[coff_type.num_sizes] = sizes[i];
26622159047fSniklas ++coff_type.num_sizes;
26632159047fSniklas }
26642159047fSniklas
26652159047fSniklas demand_empty_rest_of_line ();
26662159047fSniklas }
26672159047fSniklas
26682159047fSniklas /* Handle the .type directive, which gives the COFF type of the
26692159047fSniklas symbol. */
26702159047fSniklas
26712159047fSniklas void
ecoff_directive_type(int ignore ATTRIBUTE_UNUSED)2672*007c2a45Smiod ecoff_directive_type (int ignore ATTRIBUTE_UNUSED)
26732159047fSniklas {
26742159047fSniklas long val;
26752159047fSniklas tq_t *tq_ptr;
26762159047fSniklas tq_t *tq_shft;
26772159047fSniklas
26782159047fSniklas if (coff_sym_name == (char *) NULL)
26792159047fSniklas {
2680b305b0f1Sespie as_warn (_(".type pseudo-op used outside of .def/.endef; ignored"));
26812159047fSniklas demand_empty_rest_of_line ();
26822159047fSniklas return;
26832159047fSniklas }
26842159047fSniklas
26852159047fSniklas val = get_absolute_expression ();
26862159047fSniklas
26872159047fSniklas coff_type.orig_type = BTYPE (val);
26882159047fSniklas coff_type.basic_type = map_coff_types[coff_type.orig_type];
26892159047fSniklas
26902159047fSniklas tq_ptr = &coff_type.type_qualifiers[N_TQ];
26912159047fSniklas while (val & ~N_BTMASK)
26922159047fSniklas {
26932159047fSniklas if (tq_ptr == &coff_type.type_qualifiers[0])
26942159047fSniklas {
26952159047fSniklas /* FIXME: We could handle this by setting the continued bit.
26962159047fSniklas There would still be a limit: the .type argument can not
26972159047fSniklas be infinite. */
2698c074d1c9Sdrahn as_warn (_("the type of %s is too complex; it will be simplified"),
26992159047fSniklas coff_sym_name);
27002159047fSniklas break;
27012159047fSniklas }
27022159047fSniklas if (ISPTR (val))
27032159047fSniklas *--tq_ptr = tq_Ptr;
27042159047fSniklas else if (ISFCN (val))
27052159047fSniklas *--tq_ptr = tq_Proc;
27062159047fSniklas else if (ISARY (val))
27072159047fSniklas *--tq_ptr = tq_Array;
27082159047fSniklas else
2709b305b0f1Sespie as_fatal (_("Unrecognized .type argument"));
27102159047fSniklas
27112159047fSniklas val = DECREF (val);
27122159047fSniklas }
27132159047fSniklas
27142159047fSniklas tq_shft = &coff_type.type_qualifiers[0];
27152159047fSniklas while (tq_ptr != &coff_type.type_qualifiers[N_TQ])
27162159047fSniklas *tq_shft++ = *tq_ptr++;
27172159047fSniklas
27182159047fSniklas if (tq_shft != &coff_type.type_qualifiers[0] && tq_shft[-1] == tq_Proc)
27192159047fSniklas {
27202159047fSniklas /* If this is a function, ignore it, so that we don't get two
27212159047fSniklas entries (one from the .ent, and one for the .def that
27222159047fSniklas precedes it). Save the type information so that the end
27232159047fSniklas block can properly add it after the begin block index. For
27242159047fSniklas MIPS knows what reason, we must strip off the function type
27252159047fSniklas at this point. */
27262159047fSniklas coff_is_function = 1;
27272159047fSniklas tq_shft[-1] = tq_Nil;
27282159047fSniklas }
27292159047fSniklas
27302159047fSniklas while (tq_shft != &coff_type.type_qualifiers[N_TQ])
27312159047fSniklas *tq_shft++ = tq_Nil;
27322159047fSniklas
27332159047fSniklas demand_empty_rest_of_line ();
27342159047fSniklas }
27352159047fSniklas
27362159047fSniklas /* Handle the .tag directive, which gives the name of a structure,
27372159047fSniklas union or enum. */
27382159047fSniklas
27392159047fSniklas void
ecoff_directive_tag(int ignore ATTRIBUTE_UNUSED)2740*007c2a45Smiod ecoff_directive_tag (int ignore ATTRIBUTE_UNUSED)
27412159047fSniklas {
27422159047fSniklas char *name;
27432159047fSniklas char name_end;
27442159047fSniklas
27452159047fSniklas if (coff_sym_name == (char *) NULL)
27462159047fSniklas {
2747b305b0f1Sespie as_warn (_(".tag pseudo-op used outside of .def/.endef; ignored"));
27482159047fSniklas demand_empty_rest_of_line ();
27492159047fSniklas return;
27502159047fSniklas }
27512159047fSniklas
27522159047fSniklas name = input_line_pointer;
27532159047fSniklas name_end = get_symbol_end ();
27542159047fSniklas
2755c074d1c9Sdrahn coff_tag = xstrdup (name);
27562159047fSniklas
27572159047fSniklas *input_line_pointer = name_end;
27582159047fSniklas
27592159047fSniklas demand_empty_rest_of_line ();
27602159047fSniklas }
27612159047fSniklas
27622159047fSniklas /* Handle the .val directive, which gives the value of the symbol. It
27632159047fSniklas may be the name of a static or global symbol. */
27642159047fSniklas
27652159047fSniklas void
ecoff_directive_val(int ignore ATTRIBUTE_UNUSED)2766*007c2a45Smiod ecoff_directive_val (int ignore ATTRIBUTE_UNUSED)
27672159047fSniklas {
2768191aa565Sniklas expressionS exp;
2769191aa565Sniklas
27702159047fSniklas if (coff_sym_name == (char *) NULL)
27712159047fSniklas {
2772b305b0f1Sespie as_warn (_(".val pseudo-op used outside of .def/.endef; ignored"));
27732159047fSniklas demand_empty_rest_of_line ();
27742159047fSniklas return;
27752159047fSniklas }
27762159047fSniklas
2777191aa565Sniklas expression (&exp);
2778191aa565Sniklas if (exp.X_op != O_constant && exp.X_op != O_symbol)
2779191aa565Sniklas {
2780b305b0f1Sespie as_bad (_(".val expression is too copmlex"));
2781191aa565Sniklas demand_empty_rest_of_line ();
2782191aa565Sniklas return;
2783191aa565Sniklas }
2784191aa565Sniklas
2785191aa565Sniklas if (exp.X_op == O_constant)
2786191aa565Sniklas coff_value = exp.X_add_number;
27872159047fSniklas else
27882159047fSniklas {
2789191aa565Sniklas coff_sym_value = exp.X_add_symbol;
2790191aa565Sniklas coff_sym_addend = exp.X_add_number;
27912159047fSniklas }
27922159047fSniklas
27932159047fSniklas demand_empty_rest_of_line ();
27942159047fSniklas }
27952159047fSniklas
27962159047fSniklas /* Handle the .endef directive, which terminates processing of COFF
27972159047fSniklas debugging information for a symbol. */
27982159047fSniklas
27992159047fSniklas void
ecoff_directive_endef(int ignore ATTRIBUTE_UNUSED)2800*007c2a45Smiod ecoff_directive_endef (int ignore ATTRIBUTE_UNUSED)
28012159047fSniklas {
28022159047fSniklas char *name;
28032159047fSniklas symint_t indx;
28042159047fSniklas localsym_t *sym;
28052159047fSniklas
28062159047fSniklas demand_empty_rest_of_line ();
28072159047fSniklas
28082159047fSniklas if (coff_sym_name == (char *) NULL)
28092159047fSniklas {
2810b305b0f1Sespie as_warn (_(".endef pseudo-op used before .def; ignored"));
28112159047fSniklas return;
28122159047fSniklas }
28132159047fSniklas
28142159047fSniklas name = coff_sym_name;
28152159047fSniklas coff_sym_name = (char *) NULL;
28162159047fSniklas
28172159047fSniklas /* If the symbol is a static or external, we have already gotten the
28182159047fSniklas appropriate type and class, so make sure we don't override those
28192159047fSniklas values. This is needed because there are some type and classes
28202159047fSniklas that are not in COFF, such as short data, etc. */
28212159047fSniklas if (coff_sym_value != (symbolS *) NULL)
28222159047fSniklas {
28232159047fSniklas coff_symbol_typ = st_Nil;
28242159047fSniklas coff_storage_class = sc_Nil;
28252159047fSniklas }
28262159047fSniklas
28272159047fSniklas coff_type.extra_sizes = coff_tag != (char *) NULL;
28282159047fSniklas if (coff_type.num_dims > 0)
28292159047fSniklas {
28302159047fSniklas int diff = coff_type.num_dims - coff_type.num_sizes;
28312159047fSniklas int i = coff_type.num_dims - 1;
28322159047fSniklas int j;
28332159047fSniklas
28342159047fSniklas if (coff_type.num_sizes != 1 || diff < 0)
28352159047fSniklas {
2836c074d1c9Sdrahn as_warn (_("bad COFF debugging information"));
28372159047fSniklas return;
28382159047fSniklas }
28392159047fSniklas
28402159047fSniklas /* If this is an array, make sure the same number of dimensions
28412159047fSniklas and sizes were passed, creating extra sizes for multiply
28422159047fSniklas dimensioned arrays if not passed. */
28432159047fSniklas coff_type.extra_sizes = 0;
28442159047fSniklas if (diff)
28452159047fSniklas {
28462159047fSniklas j = (sizeof (coff_type.sizes) / sizeof (coff_type.sizes[0])) - 1;
28472159047fSniklas while (j >= 0)
28482159047fSniklas {
28492159047fSniklas coff_type.sizes[j] = (((j - diff) >= 0)
28502159047fSniklas ? coff_type.sizes[j - diff]
28512159047fSniklas : 0);
28522159047fSniklas j--;
28532159047fSniklas }
28542159047fSniklas
28552159047fSniklas coff_type.num_sizes = i + 1;
28562159047fSniklas for (i--; i >= 0; i--)
28570c6d0228Sniklas coff_type.sizes[i] = (coff_type.dimensions[i + 1] == 0
28580c6d0228Sniklas ? 0
28590c6d0228Sniklas : (coff_type.sizes[i + 1]
28600c6d0228Sniklas / coff_type.dimensions[i + 1]));
28612159047fSniklas }
28622159047fSniklas }
28632159047fSniklas else if (coff_symbol_typ == st_Member
28642159047fSniklas && coff_type.num_sizes - coff_type.extra_sizes == 1)
28652159047fSniklas {
2866*007c2a45Smiod /* Is this a bitfield? This is indicated by a structure member
28672159047fSniklas having a size field that isn't an array. */
28682159047fSniklas coff_type.bitfield = 1;
28692159047fSniklas }
28702159047fSniklas
28712159047fSniklas /* Except for enumeration members & begin/ending of scopes, put the
28722159047fSniklas type word in the aux. symbol table. */
28732159047fSniklas if (coff_symbol_typ == st_Block || coff_symbol_typ == st_End)
28742159047fSniklas indx = 0;
28752159047fSniklas else if (coff_inside_enumeration)
28762159047fSniklas indx = cur_file_ptr->void_type;
28772159047fSniklas else
28782159047fSniklas {
28792159047fSniklas if (coff_type.basic_type == bt_Struct
28802159047fSniklas || coff_type.basic_type == bt_Union
28812159047fSniklas || coff_type.basic_type == bt_Enum)
28822159047fSniklas {
28832159047fSniklas if (coff_tag == (char *) NULL)
28842159047fSniklas {
2885c074d1c9Sdrahn as_warn (_("no tag specified for %s"), name);
28862159047fSniklas return;
28872159047fSniklas }
28882159047fSniklas
28892159047fSniklas coff_type.tag_ptr = get_tag (coff_tag, (localsym_t *) NULL,
28902159047fSniklas coff_type.basic_type);
28912159047fSniklas }
28922159047fSniklas
28932159047fSniklas if (coff_is_function)
28942159047fSniklas {
28952159047fSniklas last_func_type_info = coff_type;
28962159047fSniklas last_func_sym_value = coff_sym_value;
28972159047fSniklas return;
28982159047fSniklas }
28992159047fSniklas
29002159047fSniklas indx = add_aux_sym_tir (&coff_type,
29012159047fSniklas hash_yes,
29022159047fSniklas &cur_file_ptr->thash_head[0]);
29032159047fSniklas }
29042159047fSniklas
29052159047fSniklas /* Do any last minute adjustments that are necessary. */
29062159047fSniklas switch (coff_symbol_typ)
29072159047fSniklas {
29082159047fSniklas default:
29092159047fSniklas break;
29102159047fSniklas
29112159047fSniklas /* For the beginning of structs, unions, and enumerations, the
29122159047fSniklas size info needs to be passed in the value field. */
29132159047fSniklas case st_Block:
29142159047fSniklas if (coff_type.num_sizes - coff_type.num_dims - coff_type.extra_sizes
29152159047fSniklas != 1)
29162159047fSniklas {
2917c074d1c9Sdrahn as_warn (_("bad COFF debugging information"));
29182159047fSniklas return;
29192159047fSniklas }
29202159047fSniklas else
29212159047fSniklas coff_value = coff_type.sizes[0];
29222159047fSniklas
29232159047fSniklas coff_inside_enumeration = (coff_type.orig_type == T_ENUM);
29242159047fSniklas break;
29252159047fSniklas
29262159047fSniklas /* For the end of structs, unions, and enumerations, omit the
29272159047fSniklas name which is always ".eos". This needs to be done last, so
29282159047fSniklas that any error reporting above gives the correct name. */
29292159047fSniklas case st_End:
29302159047fSniklas free (name);
29312159047fSniklas name = (char *) NULL;
29322159047fSniklas coff_value = 0;
29332159047fSniklas coff_inside_enumeration = 0;
29342159047fSniklas break;
29352159047fSniklas
29362159047fSniklas /* Members of structures and unions that aren't bitfields, need
29372159047fSniklas to adjust the value from a byte offset to a bit offset.
29382159047fSniklas Members of enumerations do not have the value adjusted, and
29392159047fSniklas can be distinguished by indx == indexNil. For enumerations,
29402159047fSniklas update the maximum enumeration value. */
29412159047fSniklas case st_Member:
29422159047fSniklas if (! coff_type.bitfield && ! coff_inside_enumeration)
29432159047fSniklas coff_value *= 8;
29442159047fSniklas
29452159047fSniklas break;
29462159047fSniklas }
29472159047fSniklas
29482159047fSniklas /* Add the symbol. */
29492159047fSniklas sym = add_ecoff_symbol (name,
29502159047fSniklas coff_symbol_typ,
29512159047fSniklas coff_storage_class,
29522159047fSniklas coff_sym_value,
2953191aa565Sniklas coff_sym_addend,
29542159047fSniklas (symint_t) coff_value,
29552159047fSniklas indx);
29562159047fSniklas
29572159047fSniklas /* deal with struct, union, and enum tags. */
29582159047fSniklas if (coff_symbol_typ == st_Block)
29592159047fSniklas {
29602159047fSniklas /* Create or update the tag information. */
29612159047fSniklas tag_t *tag_ptr = get_tag (name,
29622159047fSniklas sym,
29632159047fSniklas coff_type.basic_type);
29642159047fSniklas forward_t **pf;
29652159047fSniklas
29662159047fSniklas /* Remember any forward references. */
29672159047fSniklas for (pf = &sym->forward_ref;
29682159047fSniklas *pf != (forward_t *) NULL;
29692159047fSniklas pf = &(*pf)->next)
29702159047fSniklas ;
29712159047fSniklas *pf = tag_ptr->forward_ref;
29722159047fSniklas tag_ptr->forward_ref = (forward_t *) NULL;
29732159047fSniklas }
29742159047fSniklas }
29752159047fSniklas
29762159047fSniklas /* Parse .end directives. */
29772159047fSniklas
29782159047fSniklas void
ecoff_directive_end(int ignore ATTRIBUTE_UNUSED)2979*007c2a45Smiod ecoff_directive_end (int ignore ATTRIBUTE_UNUSED)
29802159047fSniklas {
29812159047fSniklas char *name;
29822159047fSniklas char name_end;
29832159047fSniklas symbolS *ent;
29842159047fSniklas
29852159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
29862159047fSniklas {
2987b305b0f1Sespie as_warn (_(".end directive without a preceding .file directive"));
29882159047fSniklas demand_empty_rest_of_line ();
29892159047fSniklas return;
29902159047fSniklas }
29912159047fSniklas
29922159047fSniklas if (cur_proc_ptr == (proc_t *) NULL)
29932159047fSniklas {
2994b305b0f1Sespie as_warn (_(".end directive without a preceding .ent directive"));
29952159047fSniklas demand_empty_rest_of_line ();
29962159047fSniklas return;
29972159047fSniklas }
29982159047fSniklas
29992159047fSniklas name = input_line_pointer;
30002159047fSniklas name_end = get_symbol_end ();
30012159047fSniklas
3002c074d1c9Sdrahn if (name == input_line_pointer)
30032159047fSniklas {
3004b305b0f1Sespie as_warn (_(".end directive has no name"));
30052159047fSniklas *input_line_pointer = name_end;
30062159047fSniklas demand_empty_rest_of_line ();
30072159047fSniklas return;
30082159047fSniklas }
30092159047fSniklas
30102159047fSniklas /* The value is the distance between the .end directive and the
30112159047fSniklas corresponding symbol. We create a fake symbol to hold the
30122159047fSniklas current location, and put in the offset when we write out the
30132159047fSniklas symbol. */
30142159047fSniklas ent = symbol_find (name);
30152159047fSniklas if (ent == (symbolS *) NULL)
3016b305b0f1Sespie as_warn (_(".end directive names unknown symbol"));
30172159047fSniklas else
30182159047fSniklas (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text,
30192159047fSniklas symbol_new ("L0\001", now_seg,
30202159047fSniklas (valueT) frag_now_fix (),
30212159047fSniklas frag_now),
3022191aa565Sniklas (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
30232159047fSniklas
30242159047fSniklas cur_proc_ptr = (proc_t *) NULL;
30252159047fSniklas
30262159047fSniklas *input_line_pointer = name_end;
30272159047fSniklas demand_empty_rest_of_line ();
30282159047fSniklas }
30292159047fSniklas
30302159047fSniklas /* Parse .ent directives. */
30312159047fSniklas
30322159047fSniklas void
ecoff_directive_ent(int ignore ATTRIBUTE_UNUSED)3033*007c2a45Smiod ecoff_directive_ent (int ignore ATTRIBUTE_UNUSED)
30342159047fSniklas {
30352159047fSniklas char *name;
30362159047fSniklas char name_end;
30372159047fSniklas
30382159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
30392159047fSniklas add_file ((const char *) NULL, 0, 1);
30402159047fSniklas
30412159047fSniklas if (cur_proc_ptr != (proc_t *) NULL)
30422159047fSniklas {
3043b305b0f1Sespie as_warn (_("second .ent directive found before .end directive"));
30442159047fSniklas demand_empty_rest_of_line ();
30452159047fSniklas return;
30462159047fSniklas }
30472159047fSniklas
30482159047fSniklas name = input_line_pointer;
30492159047fSniklas name_end = get_symbol_end ();
30502159047fSniklas
3051c074d1c9Sdrahn if (name == input_line_pointer)
30522159047fSniklas {
3053b305b0f1Sespie as_warn (_(".ent directive has no name"));
30542159047fSniklas *input_line_pointer = name_end;
30552159047fSniklas demand_empty_rest_of_line ();
30562159047fSniklas return;
30572159047fSniklas }
30582159047fSniklas
30592159047fSniklas add_procedure (name);
30602159047fSniklas
30612159047fSniklas *input_line_pointer = name_end;
30622159047fSniklas
30632159047fSniklas /* The .ent directive is sometimes followed by a number. I'm not
30642159047fSniklas really sure what the number means. I don't see any way to store
30652159047fSniklas the information in the PDR. The Irix 4 assembler seems to ignore
30662159047fSniklas the information. */
30672159047fSniklas SKIP_WHITESPACE ();
30682159047fSniklas if (*input_line_pointer == ',')
30692159047fSniklas {
30702159047fSniklas ++input_line_pointer;
30712159047fSniklas SKIP_WHITESPACE ();
30722159047fSniklas }
3073c074d1c9Sdrahn if (ISDIGIT (*input_line_pointer)
3074b305b0f1Sespie || *input_line_pointer == '-')
30752159047fSniklas (void) get_absolute_expression ();
30762159047fSniklas
30772159047fSniklas demand_empty_rest_of_line ();
30782159047fSniklas }
30792159047fSniklas
30802159047fSniklas /* Parse .extern directives. */
30812159047fSniklas
30822159047fSniklas void
ecoff_directive_extern(int ignore ATTRIBUTE_UNUSED)3083*007c2a45Smiod ecoff_directive_extern (int ignore ATTRIBUTE_UNUSED)
30842159047fSniklas {
30852159047fSniklas char *name;
30862159047fSniklas int c;
30872159047fSniklas symbolS *symbolp;
30882159047fSniklas valueT size;
30892159047fSniklas
30902159047fSniklas name = input_line_pointer;
30912159047fSniklas c = get_symbol_end ();
30922159047fSniklas symbolp = symbol_find_or_make (name);
30932159047fSniklas *input_line_pointer = c;
30942159047fSniklas
30952159047fSniklas S_SET_EXTERNAL (symbolp);
30962159047fSniklas
30972159047fSniklas if (*input_line_pointer == ',')
30982159047fSniklas ++input_line_pointer;
30992159047fSniklas size = get_absolute_expression ();
31002159047fSniklas
3101b305b0f1Sespie symbol_get_obj (symbolp)->ecoff_extern_size = size;
31022159047fSniklas }
31032159047fSniklas
31042159047fSniklas /* Parse .file directives. */
31052159047fSniklas
31062159047fSniklas void
ecoff_directive_file(int ignore ATTRIBUTE_UNUSED)3107*007c2a45Smiod ecoff_directive_file (int ignore ATTRIBUTE_UNUSED)
31082159047fSniklas {
31092159047fSniklas int indx;
31102159047fSniklas char *name;
31112159047fSniklas int len;
31122159047fSniklas
31132159047fSniklas if (cur_proc_ptr != (proc_t *) NULL)
31142159047fSniklas {
3115c074d1c9Sdrahn as_warn (_("no way to handle .file within .ent/.end section"));
31162159047fSniklas demand_empty_rest_of_line ();
31172159047fSniklas return;
31182159047fSniklas }
31192159047fSniklas
31202159047fSniklas indx = (int) get_absolute_expression ();
31212159047fSniklas
31222159047fSniklas /* FIXME: we don't have to save the name here. */
31232159047fSniklas name = demand_copy_C_string (&len);
31242159047fSniklas
31252159047fSniklas add_file (name, indx - 1, 0);
31262159047fSniklas
31272159047fSniklas demand_empty_rest_of_line ();
31282159047fSniklas }
31292159047fSniklas
31302159047fSniklas /* Parse .fmask directives. */
31312159047fSniklas
31322159047fSniklas void
ecoff_directive_fmask(int ignore ATTRIBUTE_UNUSED)3133*007c2a45Smiod ecoff_directive_fmask (int ignore ATTRIBUTE_UNUSED)
31342159047fSniklas {
31352159047fSniklas long val;
31362159047fSniklas
31372159047fSniklas if (cur_proc_ptr == (proc_t *) NULL)
31382159047fSniklas {
3139b305b0f1Sespie as_warn (_(".fmask outside of .ent"));
31402159047fSniklas demand_empty_rest_of_line ();
31412159047fSniklas return;
31422159047fSniklas }
31432159047fSniklas
31442159047fSniklas if (get_absolute_expression_and_terminator (&val) != ',')
31452159047fSniklas {
3146c074d1c9Sdrahn as_warn (_("bad .fmask directive"));
31472159047fSniklas --input_line_pointer;
31482159047fSniklas demand_empty_rest_of_line ();
31492159047fSniklas return;
31502159047fSniklas }
31512159047fSniklas
31522159047fSniklas cur_proc_ptr->pdr.fregmask = val;
31532159047fSniklas cur_proc_ptr->pdr.fregoffset = get_absolute_expression ();
31542159047fSniklas
31552159047fSniklas demand_empty_rest_of_line ();
31562159047fSniklas }
31572159047fSniklas
31582159047fSniklas /* Parse .frame directives. */
31592159047fSniklas
31602159047fSniklas void
ecoff_directive_frame(int ignore ATTRIBUTE_UNUSED)3161*007c2a45Smiod ecoff_directive_frame (int ignore ATTRIBUTE_UNUSED)
31622159047fSniklas {
31632159047fSniklas long val;
31642159047fSniklas
31652159047fSniklas if (cur_proc_ptr == (proc_t *) NULL)
31662159047fSniklas {
3167b305b0f1Sespie as_warn (_(".frame outside of .ent"));
31682159047fSniklas demand_empty_rest_of_line ();
31692159047fSniklas return;
31702159047fSniklas }
31712159047fSniklas
31722159047fSniklas cur_proc_ptr->pdr.framereg = tc_get_register (1);
31732159047fSniklas
31742159047fSniklas SKIP_WHITESPACE ();
31752159047fSniklas if (*input_line_pointer++ != ','
31762159047fSniklas || get_absolute_expression_and_terminator (&val) != ',')
31772159047fSniklas {
3178c074d1c9Sdrahn as_warn (_("bad .frame directive"));
31792159047fSniklas --input_line_pointer;
31802159047fSniklas demand_empty_rest_of_line ();
31812159047fSniklas return;
31822159047fSniklas }
31832159047fSniklas
31842159047fSniklas cur_proc_ptr->pdr.frameoffset = val;
31852159047fSniklas
31862159047fSniklas cur_proc_ptr->pdr.pcreg = tc_get_register (0);
31872159047fSniklas
3188b55d4692Sfgsch #if 0
3189b55d4692Sfgsch /* Alpha-OSF1 adds "the offset of saved $a0 from $sp", according to
3190b55d4692Sfgsch Sandro. I don't yet know where this value should be stored, if
31912159047fSniklas anywhere. */
31922159047fSniklas demand_empty_rest_of_line ();
31932159047fSniklas #else
31942159047fSniklas s_ignore (42);
31952159047fSniklas #endif
31962159047fSniklas }
31972159047fSniklas
31982159047fSniklas /* Parse .mask directives. */
31992159047fSniklas
32002159047fSniklas void
ecoff_directive_mask(int ignore ATTRIBUTE_UNUSED)3201*007c2a45Smiod ecoff_directive_mask (int ignore ATTRIBUTE_UNUSED)
32022159047fSniklas {
32032159047fSniklas long val;
32042159047fSniklas
32052159047fSniklas if (cur_proc_ptr == (proc_t *) NULL)
32062159047fSniklas {
3207b305b0f1Sespie as_warn (_(".mask outside of .ent"));
32082159047fSniklas demand_empty_rest_of_line ();
32092159047fSniklas return;
32102159047fSniklas }
32112159047fSniklas
32122159047fSniklas if (get_absolute_expression_and_terminator (&val) != ',')
32132159047fSniklas {
3214c074d1c9Sdrahn as_warn (_("bad .mask directive"));
32152159047fSniklas --input_line_pointer;
32162159047fSniklas demand_empty_rest_of_line ();
32172159047fSniklas return;
32182159047fSniklas }
32192159047fSniklas
32202159047fSniklas cur_proc_ptr->pdr.regmask = val;
32212159047fSniklas cur_proc_ptr->pdr.regoffset = get_absolute_expression ();
32222159047fSniklas
32232159047fSniklas demand_empty_rest_of_line ();
32242159047fSniklas }
32252159047fSniklas
32262159047fSniklas /* Parse .loc directives. */
32272159047fSniklas
32282159047fSniklas void
ecoff_directive_loc(int ignore ATTRIBUTE_UNUSED)3229*007c2a45Smiod ecoff_directive_loc (int ignore ATTRIBUTE_UNUSED)
32302159047fSniklas {
32312159047fSniklas lineno_list_t *list;
32322159047fSniklas symint_t lineno;
32332159047fSniklas
32342159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
32352159047fSniklas {
3236b305b0f1Sespie as_warn (_(".loc before .file"));
32372159047fSniklas demand_empty_rest_of_line ();
32382159047fSniklas return;
32392159047fSniklas }
32402159047fSniklas
32412159047fSniklas if (now_seg != text_section)
32422159047fSniklas {
3243b305b0f1Sespie as_warn (_(".loc outside of .text"));
32442159047fSniklas demand_empty_rest_of_line ();
32452159047fSniklas return;
32462159047fSniklas }
32472159047fSniklas
32482159047fSniklas /* Skip the file number. */
32492159047fSniklas SKIP_WHITESPACE ();
32502159047fSniklas get_absolute_expression ();
32512159047fSniklas SKIP_WHITESPACE ();
32522159047fSniklas
32532159047fSniklas lineno = get_absolute_expression ();
32542159047fSniklas
32552159047fSniklas #ifndef NO_LISTING
32562159047fSniklas if (listing)
32572159047fSniklas listing_source_line (lineno);
32582159047fSniklas #endif
32592159047fSniklas
32602159047fSniklas /* If we're building stabs, then output a special label rather than
32612159047fSniklas ECOFF line number info. */
32622159047fSniklas if (stabs_seen)
32632159047fSniklas {
32642159047fSniklas (void) add_ecoff_symbol ((char *) NULL, st_Label, sc_Text,
32652159047fSniklas symbol_new ("L0\001", now_seg,
32662159047fSniklas (valueT) frag_now_fix (),
32672159047fSniklas frag_now),
3268191aa565Sniklas (bfd_vma) 0, 0, lineno);
32692159047fSniklas return;
32702159047fSniklas }
32712159047fSniklas
32722159047fSniklas list = allocate_lineno_list ();
32732159047fSniklas
32742159047fSniklas list->next = (lineno_list_t *) NULL;
32752159047fSniklas list->file = cur_file_ptr;
32762159047fSniklas list->proc = cur_proc_ptr;
32772159047fSniklas list->frag = frag_now;
32782159047fSniklas list->paddr = frag_now_fix ();
32792159047fSniklas list->lineno = lineno;
32802159047fSniklas
32810c6d0228Sniklas /* We don't want to merge files which have line numbers. */
32820c6d0228Sniklas cur_file_ptr->fdr.fMerge = 0;
32830c6d0228Sniklas
32842159047fSniklas /* A .loc directive will sometimes appear before a .ent directive,
32852159047fSniklas which means that cur_proc_ptr will be NULL here. Arrange to
32862159047fSniklas patch this up. */
32872159047fSniklas if (cur_proc_ptr == (proc_t *) NULL)
32882159047fSniklas {
32892159047fSniklas lineno_list_t **pl;
32902159047fSniklas
32912159047fSniklas pl = &noproc_lineno;
32922159047fSniklas while (*pl != (lineno_list_t *) NULL)
32932159047fSniklas pl = &(*pl)->next;
32942159047fSniklas *pl = list;
32952159047fSniklas }
32962159047fSniklas else
32972159047fSniklas {
32980c6d0228Sniklas last_lineno = list;
32992159047fSniklas *last_lineno_ptr = list;
33002159047fSniklas last_lineno_ptr = &list->next;
33012159047fSniklas }
33022159047fSniklas }
33030c6d0228Sniklas
33040c6d0228Sniklas /* The MIPS assembler sometimes inserts nop instructions in the
33050c6d0228Sniklas instruction stream. When this happens, we must patch up the .loc
33060c6d0228Sniklas information so that it points to the instruction after the nop. */
33070c6d0228Sniklas
33080c6d0228Sniklas void
ecoff_fix_loc(fragS * old_frag,unsigned long old_frag_offset)3309*007c2a45Smiod ecoff_fix_loc (fragS *old_frag, unsigned long old_frag_offset)
33100c6d0228Sniklas {
33110c6d0228Sniklas if (last_lineno != NULL
33120c6d0228Sniklas && last_lineno->frag == old_frag
33130c6d0228Sniklas && last_lineno->paddr == old_frag_offset)
33140c6d0228Sniklas {
33150c6d0228Sniklas last_lineno->frag = frag_now;
33160c6d0228Sniklas last_lineno->paddr = frag_now_fix ();
33170c6d0228Sniklas }
33180c6d0228Sniklas }
33192159047fSniklas
33202159047fSniklas /* Make sure the @stabs symbol is emitted. */
33212159047fSniklas
33222159047fSniklas static void
mark_stabs(int ignore ATTRIBUTE_UNUSED)3323*007c2a45Smiod mark_stabs (int ignore ATTRIBUTE_UNUSED)
33242159047fSniklas {
33252159047fSniklas if (! stabs_seen)
33262159047fSniklas {
33272159047fSniklas /* Add a dummy @stabs dymbol. */
33282159047fSniklas stabs_seen = 1;
33292159047fSniklas (void) add_ecoff_symbol (stabs_symbol, stNil, scInfo,
33302159047fSniklas (symbolS *) NULL,
3331191aa565Sniklas (bfd_vma) 0, (symint_t) -1,
3332191aa565Sniklas ECOFF_MARK_STAB (0));
33332159047fSniklas }
33342159047fSniklas }
33352159047fSniklas
33362159047fSniklas /* Parse .weakext directives. */
3337b305b0f1Sespie #ifndef TC_MIPS
3338b305b0f1Sespie /* For TC_MIPS use the version in tc-mips.c. */
33392159047fSniklas void
ecoff_directive_weakext(int ignore ATTRIBUTE_UNUSED)3340*007c2a45Smiod ecoff_directive_weakext (int ignore ATTRIBUTE_UNUSED)
33412159047fSniklas {
33422159047fSniklas char *name;
33432159047fSniklas int c;
33442159047fSniklas symbolS *symbolP;
33452159047fSniklas expressionS exp;
33462159047fSniklas
33472159047fSniklas name = input_line_pointer;
33482159047fSniklas c = get_symbol_end ();
33492159047fSniklas symbolP = symbol_find_or_make (name);
33502159047fSniklas *input_line_pointer = c;
33512159047fSniklas
33522159047fSniklas SKIP_WHITESPACE ();
33532159047fSniklas
3354191aa565Sniklas if (*input_line_pointer == ',')
33552159047fSniklas {
33562159047fSniklas if (S_IS_DEFINED (symbolP))
33572159047fSniklas {
3358c074d1c9Sdrahn as_bad (_("symbol `%s' is already defined"),
33592159047fSniklas S_GET_NAME (symbolP));
33602159047fSniklas ignore_rest_of_line ();
33612159047fSniklas return;
33622159047fSniklas }
33632159047fSniklas
33642159047fSniklas ++input_line_pointer;
33652159047fSniklas SKIP_WHITESPACE ();
33662159047fSniklas if (! is_end_of_line[(unsigned char) *input_line_pointer])
33672159047fSniklas {
33682159047fSniklas expression (&exp);
33692159047fSniklas if (exp.X_op != O_symbol)
33702159047fSniklas {
3371b305b0f1Sespie as_bad (_("bad .weakext directive"));
33722159047fSniklas ignore_rest_of_line ();
33732159047fSniklas return;
33742159047fSniklas }
3375b305b0f1Sespie symbol_set_value_expression (symbolP, &exp);
33762159047fSniklas }
33772159047fSniklas }
33782159047fSniklas
33792159047fSniklas S_SET_WEAK (symbolP);
33802159047fSniklas
33812159047fSniklas demand_empty_rest_of_line ();
33822159047fSniklas }
3383b305b0f1Sespie #endif /* not TC_MIPS */
33842159047fSniklas
33852159047fSniklas /* Handle .stabs directives. The actual parsing routine is done by a
33862159047fSniklas generic routine. This routine is called via OBJ_PROCESS_STAB.
33872159047fSniklas When this is called, input_line_pointer will be pointing at the
33882159047fSniklas value field of the stab.
33892159047fSniklas
33902159047fSniklas .stabs directives have five fields:
33912159047fSniklas "string" a string, encoding the type information.
33922159047fSniklas code a numeric code, defined in <stab.h>
33932159047fSniklas 0 a zero
33942159047fSniklas desc a zero or line number
33952159047fSniklas value a numeric value or an address.
33962159047fSniklas
33972159047fSniklas If the value is relocatable, we transform this into:
33982159047fSniklas iss points as an index into string space
33992159047fSniklas value value from lookup of the name
34002159047fSniklas st st from lookup of the name
34012159047fSniklas sc sc from lookup of the name
34022159047fSniklas index code|CODE_MASK
34032159047fSniklas
34042159047fSniklas If the value is not relocatable, we transform this into:
34052159047fSniklas iss points as an index into string space
34062159047fSniklas value value
34072159047fSniklas st st_Nil
34082159047fSniklas sc sc_Nil
34092159047fSniklas index code|CODE_MASK
34102159047fSniklas
34112159047fSniklas .stabn directives have four fields (string is null):
34122159047fSniklas code a numeric code, defined in <stab.h>
34132159047fSniklas 0 a zero
34142159047fSniklas desc a zero or a line number
34152159047fSniklas value a numeric value or an address. */
34162159047fSniklas
34172159047fSniklas void
ecoff_stab(segT sec ATTRIBUTE_UNUSED,int what,const char * string,int type,int other,int desc)3418*007c2a45Smiod ecoff_stab (segT sec ATTRIBUTE_UNUSED,
3419*007c2a45Smiod int what,
3420*007c2a45Smiod const char *string,
3421*007c2a45Smiod int type,
3422*007c2a45Smiod int other,
3423*007c2a45Smiod int desc)
34242159047fSniklas {
34252159047fSniklas efdr_t *save_file_ptr = cur_file_ptr;
34262159047fSniklas symbolS *sym;
34272159047fSniklas symint_t value;
3428191aa565Sniklas bfd_vma addend;
34292159047fSniklas st_t st;
34302159047fSniklas sc_t sc;
34312159047fSniklas symint_t indx;
34322159047fSniklas localsym_t *hold = NULL;
34332159047fSniklas
34342159047fSniklas ecoff_debugging_seen = 1;
34352159047fSniklas
34362159047fSniklas /* We don't handle .stabd. */
34372159047fSniklas if (what != 's' && what != 'n')
34382159047fSniklas {
3439b305b0f1Sespie as_bad (_(".stab%c is not supported"), what);
34402159047fSniklas return;
34412159047fSniklas }
34422159047fSniklas
34432159047fSniklas /* A .stabn uses a null name, not an empty string. */
34442159047fSniklas if (what == 'n')
34452159047fSniklas string = NULL;
34462159047fSniklas
34472159047fSniklas /* We ignore the other field. */
34482159047fSniklas if (other != 0)
3449b305b0f1Sespie as_warn (_(".stab%c: ignoring non-zero other field"), what);
34502159047fSniklas
34512159047fSniklas /* Make sure we have a current file. */
34522159047fSniklas if (cur_file_ptr == (efdr_t *) NULL)
34532159047fSniklas {
34542159047fSniklas add_file ((const char *) NULL, 0, 1);
34552159047fSniklas save_file_ptr = cur_file_ptr;
34562159047fSniklas }
34572159047fSniklas
34582159047fSniklas /* For stabs in ECOFF, the first symbol must be @stabs. This is a
34592159047fSniklas signal to gdb. */
34602159047fSniklas if (stabs_seen == 0)
34612159047fSniklas mark_stabs (0);
34622159047fSniklas
34632159047fSniklas /* Line number stabs are handled differently, since they have two
34642159047fSniklas values, the line number and the address of the label. We use the
34652159047fSniklas index field (aka desc) to hold the line number, and the value
34662159047fSniklas field to hold the address. The symbol type is st_Label, which
34672159047fSniklas should be different from the other stabs, so that gdb can
34682159047fSniklas recognize it. */
34692159047fSniklas if (type == N_SLINE)
34702159047fSniklas {
34712159047fSniklas SYMR dummy_symr;
34722159047fSniklas char *name;
34732159047fSniklas char name_end;
34742159047fSniklas
34752159047fSniklas #ifndef NO_LISTING
34762159047fSniklas if (listing)
34772159047fSniklas listing_source_line ((unsigned int) desc);
34782159047fSniklas #endif
34792159047fSniklas
34802159047fSniklas dummy_symr.index = desc;
34812159047fSniklas if (dummy_symr.index != desc)
34822159047fSniklas {
3483c074d1c9Sdrahn as_warn (_("line number (%d) for .stab%c directive cannot fit in index field (20 bits)"),
34842159047fSniklas desc, what);
34852159047fSniklas return;
34862159047fSniklas }
34872159047fSniklas
34882159047fSniklas name = input_line_pointer;
34892159047fSniklas name_end = get_symbol_end ();
34902159047fSniklas
34912159047fSniklas sym = symbol_find_or_make (name);
34922159047fSniklas *input_line_pointer = name_end;
34932159047fSniklas
34942159047fSniklas value = 0;
3495191aa565Sniklas addend = 0;
34962159047fSniklas st = st_Label;
34972159047fSniklas sc = sc_Text;
34982159047fSniklas indx = desc;
34992159047fSniklas }
35002159047fSniklas else
35012159047fSniklas {
35022159047fSniklas #ifndef NO_LISTING
35032159047fSniklas if (listing && (type == N_SO || type == N_SOL))
35042159047fSniklas listing_source_file (string);
35052159047fSniklas #endif
35062159047fSniklas
3507c074d1c9Sdrahn if (ISDIGIT (*input_line_pointer)
35082159047fSniklas || *input_line_pointer == '-'
35092159047fSniklas || *input_line_pointer == '+')
35102159047fSniklas {
35112159047fSniklas st = st_Nil;
35122159047fSniklas sc = sc_Nil;
35132159047fSniklas sym = (symbolS *) NULL;
35142159047fSniklas value = get_absolute_expression ();
3515191aa565Sniklas addend = 0;
35162159047fSniklas }
35172159047fSniklas else if (! is_name_beginner ((unsigned char) *input_line_pointer))
35182159047fSniklas {
3519c074d1c9Sdrahn as_warn (_("illegal .stab%c directive, bad character"), what);
35202159047fSniklas return;
35212159047fSniklas }
35222159047fSniklas else
35232159047fSniklas {
3524191aa565Sniklas expressionS exp;
35252159047fSniklas
35262159047fSniklas sc = sc_Nil;
35272159047fSniklas st = st_Nil;
35282159047fSniklas
3529191aa565Sniklas expression (&exp);
3530191aa565Sniklas if (exp.X_op == O_constant)
35312159047fSniklas {
3532191aa565Sniklas sym = NULL;
3533191aa565Sniklas value = exp.X_add_number;
3534191aa565Sniklas addend = 0;
3535191aa565Sniklas }
3536191aa565Sniklas else if (exp.X_op == O_symbol)
3537191aa565Sniklas {
3538191aa565Sniklas sym = exp.X_add_symbol;
3539191aa565Sniklas value = 0;
3540191aa565Sniklas addend = exp.X_add_number;
3541191aa565Sniklas }
3542191aa565Sniklas else
3543191aa565Sniklas {
3544e93f7393Sniklas sym = make_expr_symbol (&exp);
3545191aa565Sniklas value = 0;
3546191aa565Sniklas addend = 0;
35472159047fSniklas }
35482159047fSniklas }
35492159047fSniklas
35502159047fSniklas indx = ECOFF_MARK_STAB (type);
35512159047fSniklas }
35522159047fSniklas
35532159047fSniklas /* Don't store the stabs symbol we are creating as the type of the
35542159047fSniklas ECOFF symbol. We want to compute the type of the ECOFF symbol
35552159047fSniklas independently. */
35562159047fSniklas if (sym != (symbolS *) NULL)
3557b305b0f1Sespie hold = symbol_get_obj (sym)->ecoff_symbol;
35582159047fSniklas
3559191aa565Sniklas (void) add_ecoff_symbol (string, st, sc, sym, addend, value, indx);
35602159047fSniklas
35612159047fSniklas if (sym != (symbolS *) NULL)
3562b305b0f1Sespie symbol_get_obj (sym)->ecoff_symbol = hold;
35632159047fSniklas
35642159047fSniklas /* Restore normal file type. */
35652159047fSniklas cur_file_ptr = save_file_ptr;
35662159047fSniklas }
35672159047fSniklas
35682159047fSniklas /* Frob an ECOFF symbol. Small common symbols go into a special
35692159047fSniklas .scommon section rather than bfd_com_section. */
35702159047fSniklas
35712159047fSniklas void
ecoff_frob_symbol(symbolS * sym)3572*007c2a45Smiod ecoff_frob_symbol (symbolS *sym)
35732159047fSniklas {
35742159047fSniklas if (S_IS_COMMON (sym)
35752159047fSniklas && S_GET_VALUE (sym) > 0
3576c074d1c9Sdrahn && S_GET_VALUE (sym) <= bfd_get_gp_size (stdoutput))
35772159047fSniklas {
35782159047fSniklas static asection scom_section;
35792159047fSniklas static asymbol scom_symbol;
35802159047fSniklas
35812159047fSniklas /* We must construct a fake section similar to bfd_com_section
35822159047fSniklas but with the name .scommon. */
35832159047fSniklas if (scom_section.name == NULL)
35842159047fSniklas {
35852159047fSniklas scom_section = bfd_com_section;
35862159047fSniklas scom_section.name = ".scommon";
35872159047fSniklas scom_section.output_section = &scom_section;
35882159047fSniklas scom_section.symbol = &scom_symbol;
35892159047fSniklas scom_section.symbol_ptr_ptr = &scom_section.symbol;
35902159047fSniklas scom_symbol = *bfd_com_section.symbol;
35912159047fSniklas scom_symbol.name = ".scommon";
35922159047fSniklas scom_symbol.section = &scom_section;
35932159047fSniklas }
35942159047fSniklas S_SET_SEGMENT (sym, &scom_section);
35952159047fSniklas }
35962159047fSniklas
35972159047fSniklas /* Double check weak symbols. */
3598b305b0f1Sespie if (S_IS_WEAK (sym))
35992159047fSniklas {
36002159047fSniklas if (S_IS_COMMON (sym))
3601c074d1c9Sdrahn as_bad (_("symbol `%s' can not be both weak and common"),
36022159047fSniklas S_GET_NAME (sym));
36032159047fSniklas }
36042159047fSniklas }
36052159047fSniklas
36062159047fSniklas /* Add bytes to the symbolic information buffer. */
36072159047fSniklas
36082159047fSniklas static char *
ecoff_add_bytes(char ** buf,char ** bufend,char * bufptr,unsigned long need)3609*007c2a45Smiod ecoff_add_bytes (char **buf,
3610*007c2a45Smiod char **bufend,
3611*007c2a45Smiod char *bufptr,
3612*007c2a45Smiod unsigned long need)
36132159047fSniklas {
36142159047fSniklas unsigned long at;
36152159047fSniklas unsigned long want;
36162159047fSniklas
36172159047fSniklas at = bufptr - *buf;
36182159047fSniklas need -= *bufend - bufptr;
36192159047fSniklas if (need < PAGE_SIZE)
36202159047fSniklas need = PAGE_SIZE;
36212159047fSniklas want = (*bufend - *buf) + need;
36222159047fSniklas *buf = xrealloc (*buf, want);
36232159047fSniklas *bufend = *buf + want;
36242159047fSniklas return *buf + at;
36252159047fSniklas }
36262159047fSniklas
36272159047fSniklas /* Adjust the symbolic information buffer to the alignment required
36282159047fSniklas for the ECOFF target debugging information. */
36292159047fSniklas
36302159047fSniklas static unsigned long
ecoff_padding_adjust(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset,char ** bufptrptr)3631*007c2a45Smiod ecoff_padding_adjust (const struct ecoff_debug_swap *backend,
3632*007c2a45Smiod char **buf,
3633*007c2a45Smiod char **bufend,
3634*007c2a45Smiod unsigned long offset,
3635*007c2a45Smiod char **bufptrptr)
36362159047fSniklas {
36372159047fSniklas bfd_size_type align;
36382159047fSniklas
36392159047fSniklas align = backend->debug_align;
36402159047fSniklas if ((offset & (align - 1)) != 0)
36412159047fSniklas {
36422159047fSniklas unsigned long add;
36432159047fSniklas
36442159047fSniklas add = align - (offset & (align - 1));
3645b55d4692Sfgsch if ((unsigned long) (*bufend - (*buf + offset)) < add)
36462159047fSniklas (void) ecoff_add_bytes (buf, bufend, *buf + offset, add);
36472159047fSniklas memset (*buf + offset, 0, add);
36482159047fSniklas offset += add;
36492159047fSniklas if (bufptrptr != (char **) NULL)
36502159047fSniklas *bufptrptr = *buf + offset;
36512159047fSniklas }
36522159047fSniklas
36532159047fSniklas return offset;
36542159047fSniklas }
36552159047fSniklas
36562159047fSniklas /* Build the line number information. */
36572159047fSniklas
36582159047fSniklas static unsigned long
ecoff_build_lineno(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset,long * linecntptr)3659*007c2a45Smiod ecoff_build_lineno (const struct ecoff_debug_swap *backend,
3660*007c2a45Smiod char **buf,
3661*007c2a45Smiod char **bufend,
3662*007c2a45Smiod unsigned long offset,
3663*007c2a45Smiod long *linecntptr)
36642159047fSniklas {
36652159047fSniklas char *bufptr;
36662159047fSniklas register lineno_list_t *l;
36672159047fSniklas lineno_list_t *last;
36682159047fSniklas efdr_t *file;
36692159047fSniklas proc_t *proc;
36702159047fSniklas unsigned long c;
36712159047fSniklas long iline;
36722159047fSniklas long totcount;
36732159047fSniklas lineno_list_t first;
3674b305b0f1Sespie lineno_list_t *local_first_lineno = first_lineno;
36752159047fSniklas
36762159047fSniklas if (linecntptr != (long *) NULL)
36772159047fSniklas *linecntptr = 0;
36782159047fSniklas
36792159047fSniklas bufptr = *buf + offset;
36802159047fSniklas
36812159047fSniklas file = (efdr_t *) NULL;
36822159047fSniklas proc = (proc_t *) NULL;
36832159047fSniklas last = (lineno_list_t *) NULL;
36842159047fSniklas c = offset;
36852159047fSniklas iline = 0;
36862159047fSniklas totcount = 0;
36872159047fSniklas
36882159047fSniklas /* For some reason the address of the first procedure is ignored
36892159047fSniklas when reading line numbers. This doesn't matter if the address of
36902159047fSniklas the first procedure is 0, but when gcc is generating MIPS
36912159047fSniklas embedded PIC code, it will put strings in the .text section
36922159047fSniklas before the first procedure. We cope by inserting a dummy line if
36932159047fSniklas the address of the first procedure is not 0. Hopefully this
3694b305b0f1Sespie won't screw things up too badly.
3695b305b0f1Sespie
3696b305b0f1Sespie Don't do this for ECOFF assembly source line numbers. They work
3697b305b0f1Sespie without this extra attention. */
3698b305b0f1Sespie if (debug_type != DEBUG_ECOFF
3699b305b0f1Sespie && first_proc_ptr != (proc_t *) NULL
3700b305b0f1Sespie && local_first_lineno != (lineno_list_t *) NULL
37012159047fSniklas && ((S_GET_VALUE (first_proc_ptr->sym->as_sym)
37022159047fSniklas + bfd_get_section_vma (stdoutput,
37032159047fSniklas S_GET_SEGMENT (first_proc_ptr->sym->as_sym)))
37042159047fSniklas != 0))
37052159047fSniklas {
3706b305b0f1Sespie first.file = local_first_lineno->file;
3707b305b0f1Sespie first.proc = local_first_lineno->proc;
37082159047fSniklas first.frag = &zero_address_frag;
37092159047fSniklas first.paddr = 0;
37102159047fSniklas first.lineno = 0;
37112159047fSniklas
3712b305b0f1Sespie first.next = local_first_lineno;
3713b305b0f1Sespie local_first_lineno = &first;
37142159047fSniklas }
37152159047fSniklas
3716b305b0f1Sespie for (l = local_first_lineno; l != (lineno_list_t *) NULL; l = l->next)
37172159047fSniklas {
37182159047fSniklas long count;
37192159047fSniklas long delta;
37202159047fSniklas
37212159047fSniklas /* Get the offset to the memory address of the next line number
37222159047fSniklas (in words). Do this first, so that we can skip ahead to the
37232159047fSniklas next useful line number entry. */
37242159047fSniklas if (l->next == (lineno_list_t *) NULL)
37252159047fSniklas {
37262159047fSniklas /* We want a count of zero, but it will be decremented
37272159047fSniklas before it is used. */
37282159047fSniklas count = 1;
37292159047fSniklas }
3730191aa565Sniklas else if (l->next->frag->fr_address + l->next->paddr
3731191aa565Sniklas > l->frag->fr_address + l->paddr)
37322159047fSniklas {
37332159047fSniklas count = ((l->next->frag->fr_address + l->next->paddr
37342159047fSniklas - (l->frag->fr_address + l->paddr))
37352159047fSniklas >> 2);
3736191aa565Sniklas }
3737191aa565Sniklas else
37382159047fSniklas {
37392159047fSniklas /* Don't change last, so we still get the right delta. */
37402159047fSniklas continue;
37412159047fSniklas }
37422159047fSniklas
37432159047fSniklas if (l->file != file || l->proc != proc)
37442159047fSniklas {
37452159047fSniklas if (l->proc != proc && proc != (proc_t *) NULL)
37462159047fSniklas proc->pdr.lnHigh = last->lineno;
37472159047fSniklas if (l->file != file && file != (efdr_t *) NULL)
37482159047fSniklas {
37492159047fSniklas file->fdr.cbLine = c - file->fdr.cbLineOffset;
37502159047fSniklas file->fdr.cline = totcount + count;
37512159047fSniklas if (linecntptr != (long *) NULL)
37522159047fSniklas *linecntptr += totcount + count;
37532159047fSniklas totcount = 0;
37542159047fSniklas }
37552159047fSniklas
37562159047fSniklas if (l->file != file)
37572159047fSniklas {
37582159047fSniklas efdr_t *last_file = file;
37592159047fSniklas
37602159047fSniklas file = l->file;
37612159047fSniklas if (last_file != (efdr_t *) NULL)
37622159047fSniklas file->fdr.ilineBase
37632159047fSniklas = last_file->fdr.ilineBase + last_file->fdr.cline;
37642159047fSniklas else
37652159047fSniklas file->fdr.ilineBase = 0;
37662159047fSniklas file->fdr.cbLineOffset = c;
37672159047fSniklas }
37682159047fSniklas if (l->proc != proc)
37692159047fSniklas {
37702159047fSniklas proc = l->proc;
37712159047fSniklas if (proc != (proc_t *) NULL)
37722159047fSniklas {
37732159047fSniklas proc->pdr.lnLow = l->lineno;
37742159047fSniklas proc->pdr.cbLineOffset = c - file->fdr.cbLineOffset;
37752159047fSniklas proc->pdr.iline = totcount;
37762159047fSniklas }
37772159047fSniklas }
37782159047fSniklas
37792159047fSniklas last = (lineno_list_t *) NULL;
37802159047fSniklas }
37812159047fSniklas
37822159047fSniklas totcount += count;
37832159047fSniklas
37842159047fSniklas /* Get the offset to this line number. */
37852159047fSniklas if (last == (lineno_list_t *) NULL)
37862159047fSniklas delta = 0;
37872159047fSniklas else
37882159047fSniklas delta = l->lineno - last->lineno;
37892159047fSniklas
37902159047fSniklas /* Put in the offset to this line number. */
37912159047fSniklas while (delta != 0)
37922159047fSniklas {
37932159047fSniklas int setcount;
37942159047fSniklas
37952159047fSniklas /* 1 is added to each count read. */
37962159047fSniklas --count;
37972159047fSniklas /* We can only adjust the word count by up to 15 words at a
37982159047fSniklas time. */
37992159047fSniklas if (count <= 0x0f)
38002159047fSniklas {
38012159047fSniklas setcount = count;
38022159047fSniklas count = 0;
38032159047fSniklas }
38042159047fSniklas else
38052159047fSniklas {
38062159047fSniklas setcount = 0x0f;
38072159047fSniklas count -= 0x0f;
38082159047fSniklas }
38092159047fSniklas if (delta >= -7 && delta <= 7)
38102159047fSniklas {
38112159047fSniklas if (bufptr >= *bufend)
38122159047fSniklas bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
38132159047fSniklas *bufptr++ = setcount + (delta << 4);
38142159047fSniklas delta = 0;
38152159047fSniklas ++c;
38162159047fSniklas }
38172159047fSniklas else
38182159047fSniklas {
38192159047fSniklas int set;
38202159047fSniklas
38212159047fSniklas if (*bufend - bufptr < 3)
38222159047fSniklas bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 3);
38232159047fSniklas *bufptr++ = setcount + (8 << 4);
38242159047fSniklas if (delta < -0x8000)
38252159047fSniklas {
38262159047fSniklas set = -0x8000;
38272159047fSniklas delta += 0x8000;
38282159047fSniklas }
38292159047fSniklas else if (delta > 0x7fff)
38302159047fSniklas {
38312159047fSniklas set = 0x7fff;
38322159047fSniklas delta -= 0x7fff;
38332159047fSniklas }
38342159047fSniklas else
38352159047fSniklas {
38362159047fSniklas set = delta;
38372159047fSniklas delta = 0;
38382159047fSniklas }
38392159047fSniklas *bufptr++ = set >> 8;
38402159047fSniklas *bufptr++ = set & 0xffff;
38412159047fSniklas c += 3;
38422159047fSniklas }
38432159047fSniklas }
38442159047fSniklas
38452159047fSniklas /* Finish adjusting the count. */
38462159047fSniklas while (count > 0)
38472159047fSniklas {
38482159047fSniklas if (bufptr >= *bufend)
38492159047fSniklas bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
38502159047fSniklas /* 1 is added to each count read. */
38512159047fSniklas --count;
38522159047fSniklas if (count > 0x0f)
38532159047fSniklas {
38542159047fSniklas *bufptr++ = 0x0f;
38552159047fSniklas count -= 0x0f;
38562159047fSniklas }
38572159047fSniklas else
38582159047fSniklas {
38592159047fSniklas *bufptr++ = count;
38602159047fSniklas count = 0;
38612159047fSniklas }
38622159047fSniklas ++c;
38632159047fSniklas }
38642159047fSniklas
38652159047fSniklas ++iline;
38662159047fSniklas last = l;
38672159047fSniklas }
38682159047fSniklas
38692159047fSniklas if (proc != (proc_t *) NULL)
38702159047fSniklas proc->pdr.lnHigh = last->lineno;
38712159047fSniklas if (file != (efdr_t *) NULL)
38722159047fSniklas {
38732159047fSniklas file->fdr.cbLine = c - file->fdr.cbLineOffset;
38742159047fSniklas file->fdr.cline = totcount;
38752159047fSniklas }
38762159047fSniklas
38772159047fSniklas if (linecntptr != (long *) NULL)
38782159047fSniklas *linecntptr += totcount;
38792159047fSniklas
38802159047fSniklas c = ecoff_padding_adjust (backend, buf, bufend, c, &bufptr);
38812159047fSniklas
38822159047fSniklas return c;
38832159047fSniklas }
38842159047fSniklas
38852159047fSniklas /* Build and swap out the symbols. */
38862159047fSniklas
38872159047fSniklas static unsigned long
ecoff_build_symbols(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)3888*007c2a45Smiod ecoff_build_symbols (const struct ecoff_debug_swap *backend,
3889*007c2a45Smiod char **buf,
3890*007c2a45Smiod char **bufend,
3891*007c2a45Smiod unsigned long offset)
38922159047fSniklas {
38932159047fSniklas const bfd_size_type external_sym_size = backend->external_sym_size;
3894*007c2a45Smiod void (* const swap_sym_out) (bfd *, const SYMR *, PTR)
38952159047fSniklas = backend->swap_sym_out;
38962159047fSniklas char *sym_out;
38972159047fSniklas long isym;
38982159047fSniklas vlinks_t *file_link;
38992159047fSniklas
39002159047fSniklas sym_out = *buf + offset;
39012159047fSniklas
39022159047fSniklas isym = 0;
39032159047fSniklas
39042159047fSniklas /* The symbols are stored by file. */
39052159047fSniklas for (file_link = file_desc.first;
39062159047fSniklas file_link != (vlinks_t *) NULL;
39072159047fSniklas file_link = file_link->next)
39082159047fSniklas {
39092159047fSniklas int ifilesym;
39102159047fSniklas int fil_cnt;
39112159047fSniklas efdr_t *fil_ptr;
39122159047fSniklas efdr_t *fil_end;
39132159047fSniklas
39142159047fSniklas if (file_link->next == (vlinks_t *) NULL)
39152159047fSniklas fil_cnt = file_desc.objects_last_page;
39162159047fSniklas else
39172159047fSniklas fil_cnt = file_desc.objects_per_page;
39182159047fSniklas fil_ptr = file_link->datum->file;
39192159047fSniklas fil_end = fil_ptr + fil_cnt;
39202159047fSniklas for (; fil_ptr < fil_end; fil_ptr++)
39212159047fSniklas {
39222159047fSniklas vlinks_t *sym_link;
39232159047fSniklas
39242159047fSniklas fil_ptr->fdr.isymBase = isym;
39252159047fSniklas ifilesym = isym;
39262159047fSniklas for (sym_link = fil_ptr->symbols.first;
39272159047fSniklas sym_link != (vlinks_t *) NULL;
39282159047fSniklas sym_link = sym_link->next)
39292159047fSniklas {
39302159047fSniklas int sym_cnt;
39312159047fSniklas localsym_t *sym_ptr;
39322159047fSniklas localsym_t *sym_end;
39332159047fSniklas
39342159047fSniklas if (sym_link->next == (vlinks_t *) NULL)
39352159047fSniklas sym_cnt = fil_ptr->symbols.objects_last_page;
39362159047fSniklas else
39372159047fSniklas sym_cnt = fil_ptr->symbols.objects_per_page;
39382159047fSniklas sym_ptr = sym_link->datum->sym;
39392159047fSniklas sym_end = sym_ptr + sym_cnt;
39402159047fSniklas for (; sym_ptr < sym_end; sym_ptr++)
39412159047fSniklas {
39422159047fSniklas int local;
39432159047fSniklas symbolS *as_sym;
39442159047fSniklas forward_t *f;
39452159047fSniklas
39462159047fSniklas know (sym_ptr->file_ptr == fil_ptr);
39472159047fSniklas
39482159047fSniklas /* If there is no associated gas symbol, then this
39492159047fSniklas is a pure debugging symbol. We have already
39502159047fSniklas added the name (if any) to fil_ptr->strings.
39512159047fSniklas Otherwise we must decide whether this is an
39522159047fSniklas external or a local symbol (actually, it may be
39532159047fSniklas both if the local provides additional debugging
39542159047fSniklas information for the external). */
39552159047fSniklas local = 1;
39562159047fSniklas as_sym = sym_ptr->as_sym;
39572159047fSniklas if (as_sym != (symbolS *) NULL)
39582159047fSniklas {
39592159047fSniklas symint_t indx;
39602159047fSniklas
39612159047fSniklas /* The value of a block start symbol is the
39622159047fSniklas offset from the start of the procedure. For
39632159047fSniklas other symbols we just use the gas value (but
39642159047fSniklas we must offset it by the vma of the section,
39652159047fSniklas just as BFD does, because BFD will not see
39662159047fSniklas this value). */
39672159047fSniklas if (sym_ptr->ecoff_sym.asym.st == (int) st_Block
39682159047fSniklas && sym_ptr->ecoff_sym.asym.sc == (int) sc_Text)
39692159047fSniklas {
39702159047fSniklas symbolS *begin_sym;
39712159047fSniklas
39722159047fSniklas know (sym_ptr->proc_ptr != (proc_t *) NULL);
39732159047fSniklas begin_sym = sym_ptr->proc_ptr->sym->as_sym;
39742159047fSniklas if (S_GET_SEGMENT (as_sym)
39752159047fSniklas != S_GET_SEGMENT (begin_sym))
3976b305b0f1Sespie as_warn (_(".begin/.bend in different segments"));
39772159047fSniklas sym_ptr->ecoff_sym.asym.value =
39782159047fSniklas S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
39792159047fSniklas }
39802159047fSniklas else
39812159047fSniklas sym_ptr->ecoff_sym.asym.value =
39822159047fSniklas (S_GET_VALUE (as_sym)
39832159047fSniklas + bfd_get_section_vma (stdoutput,
3984191aa565Sniklas S_GET_SEGMENT (as_sym))
3985191aa565Sniklas + sym_ptr->addend);
39862159047fSniklas
39872159047fSniklas sym_ptr->ecoff_sym.weakext = S_IS_WEAK (as_sym);
39882159047fSniklas
39892159047fSniklas /* Set st_Proc to st_StaticProc for local
39902159047fSniklas functions. */
39912159047fSniklas if (sym_ptr->ecoff_sym.asym.st == st_Proc
39922159047fSniklas && S_IS_DEFINED (as_sym)
39932159047fSniklas && ! S_IS_EXTERNAL (as_sym)
39942159047fSniklas && ! S_IS_WEAK (as_sym))
39952159047fSniklas sym_ptr->ecoff_sym.asym.st = st_StaticProc;
39962159047fSniklas
39972159047fSniklas /* Get the type and storage class based on where
39982159047fSniklas the symbol actually wound up. Traditionally,
39992159047fSniklas N_LBRAC and N_RBRAC are *not* relocated. */
40002159047fSniklas indx = sym_ptr->ecoff_sym.asym.index;
40012159047fSniklas if (sym_ptr->ecoff_sym.asym.st == st_Nil
40022159047fSniklas && sym_ptr->ecoff_sym.asym.sc == sc_Nil
40032159047fSniklas && (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
40042159047fSniklas || ((ECOFF_UNMARK_STAB (indx) != N_LBRAC)
40052159047fSniklas && (ECOFF_UNMARK_STAB (indx) != N_RBRAC))))
40062159047fSniklas {
40072159047fSniklas segT seg;
40082159047fSniklas const char *segname;
40092159047fSniklas st_t st;
40102159047fSniklas sc_t sc;
40112159047fSniklas
40122159047fSniklas seg = S_GET_SEGMENT (as_sym);
40132159047fSniklas segname = segment_name (seg);
40142159047fSniklas
40152159047fSniklas if (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
40162159047fSniklas && (S_IS_EXTERNAL (as_sym)
40172159047fSniklas || S_IS_WEAK (as_sym)
40182159047fSniklas || ! S_IS_DEFINED (as_sym)))
40192159047fSniklas {
4020b305b0f1Sespie if ((symbol_get_bfdsym (as_sym)->flags
4021b305b0f1Sespie & BSF_FUNCTION) != 0)
40222159047fSniklas st = st_Proc;
40232159047fSniklas else
40242159047fSniklas st = st_Global;
40252159047fSniklas }
40262159047fSniklas else if (seg == text_section)
40272159047fSniklas st = st_Label;
40282159047fSniklas else
40292159047fSniklas st = st_Static;
40302159047fSniklas
40312159047fSniklas if (! S_IS_DEFINED (as_sym))
40322159047fSniklas {
4033b305b0f1Sespie valueT s;
4034b305b0f1Sespie
4035b305b0f1Sespie s = symbol_get_obj (as_sym)->ecoff_extern_size;
4036b305b0f1Sespie if (s == 0
4037c074d1c9Sdrahn || s > bfd_get_gp_size (stdoutput))
40382159047fSniklas sc = sc_Undefined;
40392159047fSniklas else
40402159047fSniklas {
40412159047fSniklas sc = sc_SUndefined;
4042b305b0f1Sespie sym_ptr->ecoff_sym.asym.value = s;
40432159047fSniklas }
4044191aa565Sniklas #ifdef S_SET_SIZE
4045b305b0f1Sespie S_SET_SIZE (as_sym, s);
4046191aa565Sniklas #endif
40472159047fSniklas }
40482159047fSniklas else if (S_IS_COMMON (as_sym))
40492159047fSniklas {
40502159047fSniklas if (S_GET_VALUE (as_sym) > 0
40512159047fSniklas && (S_GET_VALUE (as_sym)
4052c074d1c9Sdrahn <= bfd_get_gp_size (stdoutput)))
40532159047fSniklas sc = sc_SCommon;
40542159047fSniklas else
40552159047fSniklas sc = sc_Common;
40562159047fSniklas }
40572159047fSniklas else if (seg == text_section)
40582159047fSniklas sc = sc_Text;
40592159047fSniklas else if (seg == data_section)
40602159047fSniklas sc = sc_Data;
40612159047fSniklas else if (strcmp (segname, ".rdata") == 0
40622159047fSniklas || strcmp (segname, ".rodata") == 0)
40632159047fSniklas sc = sc_RData;
40642159047fSniklas else if (strcmp (segname, ".sdata") == 0)
40652159047fSniklas sc = sc_SData;
40662159047fSniklas else if (seg == bss_section)
40672159047fSniklas sc = sc_Bss;
40682159047fSniklas else if (strcmp (segname, ".sbss") == 0)
40692159047fSniklas sc = sc_SBss;
40702159047fSniklas else if (seg == &bfd_abs_section)
40712159047fSniklas sc = sc_Abs;
40722159047fSniklas else
40732159047fSniklas {
40742159047fSniklas /* This must be a user named section.
40752159047fSniklas This is not possible in ECOFF, but it
40762159047fSniklas is in ELF. */
40772159047fSniklas sc = sc_Data;
40782159047fSniklas }
40792159047fSniklas
40802159047fSniklas sym_ptr->ecoff_sym.asym.st = (int) st;
40812159047fSniklas sym_ptr->ecoff_sym.asym.sc = (int) sc;
40822159047fSniklas }
40832159047fSniklas
40842159047fSniklas /* This is just an external symbol if it is
40852159047fSniklas outside a procedure and it has a type.
40862159047fSniklas FIXME: g++ will generate symbols which have
40872159047fSniklas different names in the debugging information
40882159047fSniklas than the actual symbol. Should we handle
40892159047fSniklas them here? */
40902159047fSniklas if ((S_IS_EXTERNAL (as_sym)
40912159047fSniklas || S_IS_WEAK (as_sym)
40922159047fSniklas || ! S_IS_DEFINED (as_sym))
40932159047fSniklas && sym_ptr->proc_ptr == (proc_t *) NULL
40942159047fSniklas && sym_ptr->ecoff_sym.asym.st != (int) st_Nil
40952159047fSniklas && ! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym))
40962159047fSniklas local = 0;
40972159047fSniklas
40986a4c786fSespie /* This is just an external symbol if it is a
40996a4c786fSespie common symbol. */
41006a4c786fSespie if (S_IS_COMMON (as_sym))
41016a4c786fSespie local = 0;
41026a4c786fSespie
41032159047fSniklas /* If an st_end symbol has an associated gas
41042159047fSniklas symbol, then it is a local label created for
41052159047fSniklas a .bend or .end directive. Stabs line
41062159047fSniklas numbers will have \001 in the names. */
41072159047fSniklas if (local
41082159047fSniklas && sym_ptr->ecoff_sym.asym.st != st_End
41092159047fSniklas && strchr (sym_ptr->name, '\001') == 0)
41102159047fSniklas sym_ptr->ecoff_sym.asym.iss =
41112159047fSniklas add_string (&fil_ptr->strings,
41122159047fSniklas fil_ptr->str_hash,
41132159047fSniklas sym_ptr->name,
41142159047fSniklas (shash_t **) NULL);
41152159047fSniklas }
41162159047fSniklas
41172159047fSniklas /* We now know the index of this symbol; fill in
41182159047fSniklas locations that have been waiting for that
41192159047fSniklas information. */
41202159047fSniklas if (sym_ptr->begin_ptr != (localsym_t *) NULL)
41212159047fSniklas {
41222159047fSniklas localsym_t *begin_ptr;
41232159047fSniklas st_t begin_type;
41242159047fSniklas
41252159047fSniklas know (local);
41262159047fSniklas begin_ptr = sym_ptr->begin_ptr;
41272159047fSniklas know (begin_ptr->sym_index != -1);
41282159047fSniklas sym_ptr->ecoff_sym.asym.index = begin_ptr->sym_index;
41292159047fSniklas if (sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
41302159047fSniklas sym_ptr->ecoff_sym.asym.iss =
41312159047fSniklas begin_ptr->ecoff_sym.asym.iss;
41322159047fSniklas
41332159047fSniklas begin_type = begin_ptr->ecoff_sym.asym.st;
41342159047fSniklas if (begin_type == st_File
41352159047fSniklas || begin_type == st_Block)
41362159047fSniklas {
41372159047fSniklas begin_ptr->ecoff_sym.asym.index =
41382159047fSniklas isym - ifilesym + 1;
41392159047fSniklas (*swap_sym_out) (stdoutput,
41402159047fSniklas &begin_ptr->ecoff_sym.asym,
41412159047fSniklas (*buf
41422159047fSniklas + offset
41432159047fSniklas + (begin_ptr->sym_index
41442159047fSniklas * external_sym_size)));
41452159047fSniklas }
41462159047fSniklas else
41472159047fSniklas {
41482159047fSniklas know (begin_ptr->index_ptr != (aux_t *) NULL);
41492159047fSniklas begin_ptr->index_ptr->data.isym =
41502159047fSniklas isym - ifilesym + 1;
41512159047fSniklas }
41522159047fSniklas
41532159047fSniklas /* The value of the symbol marking the end of a
41542159047fSniklas procedure is the size of the procedure. The
41552159047fSniklas value of the symbol marking the end of a
41562159047fSniklas block is the offset from the start of the
41572159047fSniklas procedure to the block. */
41582159047fSniklas if (begin_type == st_Proc
41592159047fSniklas || begin_type == st_StaticProc)
41602159047fSniklas {
41612159047fSniklas know (as_sym != (symbolS *) NULL);
41622159047fSniklas know (begin_ptr->as_sym != (symbolS *) NULL);
41632159047fSniklas if (S_GET_SEGMENT (as_sym)
41642159047fSniklas != S_GET_SEGMENT (begin_ptr->as_sym))
4165b305b0f1Sespie as_warn (_(".begin/.bend in different segments"));
41662159047fSniklas sym_ptr->ecoff_sym.asym.value =
41672159047fSniklas (S_GET_VALUE (as_sym)
41682159047fSniklas - S_GET_VALUE (begin_ptr->as_sym));
41696a4c786fSespie
41706a4c786fSespie /* If the size is odd, this is probably a
41716a4c786fSespie mips16 function; force it to be even. */
41726a4c786fSespie if ((sym_ptr->ecoff_sym.asym.value & 1) != 0)
41736a4c786fSespie ++sym_ptr->ecoff_sym.asym.value;
41746a4c786fSespie
4175191aa565Sniklas #ifdef S_SET_SIZE
4176191aa565Sniklas S_SET_SIZE (begin_ptr->as_sym,
4177191aa565Sniklas sym_ptr->ecoff_sym.asym.value);
4178191aa565Sniklas #endif
41792159047fSniklas }
41802159047fSniklas else if (begin_type == st_Block
41812159047fSniklas && sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
41822159047fSniklas {
41832159047fSniklas symbolS *begin_sym;
41842159047fSniklas
41852159047fSniklas know (as_sym != (symbolS *) NULL);
41862159047fSniklas know (sym_ptr->proc_ptr != (proc_t *) NULL);
41872159047fSniklas begin_sym = sym_ptr->proc_ptr->sym->as_sym;
41882159047fSniklas if (S_GET_SEGMENT (as_sym)
41892159047fSniklas != S_GET_SEGMENT (begin_sym))
4190b305b0f1Sespie as_warn (_(".begin/.bend in different segments"));
41912159047fSniklas sym_ptr->ecoff_sym.asym.value =
41922159047fSniklas S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
41932159047fSniklas }
41942159047fSniklas }
41952159047fSniklas
41962159047fSniklas for (f = sym_ptr->forward_ref;
41972159047fSniklas f != (forward_t *) NULL;
41982159047fSniklas f = f->next)
41992159047fSniklas {
42002159047fSniklas know (local);
42012159047fSniklas f->ifd_ptr->data.isym = fil_ptr->file_index;
42022159047fSniklas f->index_ptr->data.rndx.index = isym - ifilesym;
42032159047fSniklas }
42042159047fSniklas
42052159047fSniklas if (local)
42062159047fSniklas {
4207b55d4692Sfgsch if ((bfd_size_type)(*bufend - sym_out) < external_sym_size)
42082159047fSniklas sym_out = ecoff_add_bytes (buf, bufend,
42092159047fSniklas sym_out,
42102159047fSniklas external_sym_size);
42112159047fSniklas (*swap_sym_out) (stdoutput, &sym_ptr->ecoff_sym.asym,
42122159047fSniklas sym_out);
42132159047fSniklas sym_out += external_sym_size;
42142159047fSniklas
42152159047fSniklas sym_ptr->sym_index = isym;
42162159047fSniklas
42172159047fSniklas if (sym_ptr->proc_ptr != (proc_t *) NULL
42182159047fSniklas && sym_ptr->proc_ptr->sym == sym_ptr)
42192159047fSniklas sym_ptr->proc_ptr->pdr.isym = isym - ifilesym;
42202159047fSniklas
42212159047fSniklas ++isym;
42222159047fSniklas }
42232159047fSniklas
42242159047fSniklas /* Record the local symbol index and file number in
42252159047fSniklas case this is an external symbol. Note that this
42262159047fSniklas destroys the asym.index field. */
42272159047fSniklas if (as_sym != (symbolS *) NULL
4228b305b0f1Sespie && symbol_get_obj (as_sym)->ecoff_symbol == sym_ptr)
42292159047fSniklas {
42302159047fSniklas if ((sym_ptr->ecoff_sym.asym.st == st_Proc
42312159047fSniklas || sym_ptr->ecoff_sym.asym.st == st_StaticProc)
42322159047fSniklas && local)
42332159047fSniklas sym_ptr->ecoff_sym.asym.index = isym - ifilesym - 1;
42342159047fSniklas sym_ptr->ecoff_sym.ifd = fil_ptr->file_index;
4235b305b0f1Sespie
4236b305b0f1Sespie /* Don't try to merge an FDR which has an
4237b305b0f1Sespie external symbol attached to it. */
4238b305b0f1Sespie if (S_IS_EXTERNAL (as_sym) || S_IS_WEAK (as_sym))
4239b305b0f1Sespie fil_ptr->fdr.fMerge = 0;
42402159047fSniklas }
42412159047fSniklas }
42422159047fSniklas }
42432159047fSniklas fil_ptr->fdr.csym = isym - fil_ptr->fdr.isymBase;
42442159047fSniklas }
42452159047fSniklas }
42462159047fSniklas
42472159047fSniklas return offset + isym * external_sym_size;
42482159047fSniklas }
42492159047fSniklas
42502159047fSniklas /* Swap out the procedure information. */
42512159047fSniklas
42522159047fSniklas static unsigned long
ecoff_build_procs(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)4253*007c2a45Smiod ecoff_build_procs (const struct ecoff_debug_swap *backend,
4254*007c2a45Smiod char **buf,
4255*007c2a45Smiod char **bufend,
4256*007c2a45Smiod unsigned long offset)
42572159047fSniklas {
42582159047fSniklas const bfd_size_type external_pdr_size = backend->external_pdr_size;
4259*007c2a45Smiod void (* const swap_pdr_out) (bfd *, const PDR *, PTR)
42602159047fSniklas = backend->swap_pdr_out;
42612159047fSniklas char *pdr_out;
42622159047fSniklas long iproc;
42632159047fSniklas vlinks_t *file_link;
42642159047fSniklas
42652159047fSniklas pdr_out = *buf + offset;
42662159047fSniklas
42672159047fSniklas iproc = 0;
42682159047fSniklas
42692159047fSniklas /* The procedures are stored by file. */
42702159047fSniklas for (file_link = file_desc.first;
42712159047fSniklas file_link != (vlinks_t *) NULL;
42722159047fSniklas file_link = file_link->next)
42732159047fSniklas {
42742159047fSniklas int fil_cnt;
42752159047fSniklas efdr_t *fil_ptr;
42762159047fSniklas efdr_t *fil_end;
42772159047fSniklas
42782159047fSniklas if (file_link->next == (vlinks_t *) NULL)
42792159047fSniklas fil_cnt = file_desc.objects_last_page;
42802159047fSniklas else
42812159047fSniklas fil_cnt = file_desc.objects_per_page;
42822159047fSniklas fil_ptr = file_link->datum->file;
42832159047fSniklas fil_end = fil_ptr + fil_cnt;
42842159047fSniklas for (; fil_ptr < fil_end; fil_ptr++)
42852159047fSniklas {
42862159047fSniklas vlinks_t *proc_link;
42872159047fSniklas int first;
42882159047fSniklas
42892159047fSniklas fil_ptr->fdr.ipdFirst = iproc;
42902159047fSniklas first = 1;
42912159047fSniklas for (proc_link = fil_ptr->procs.first;
42922159047fSniklas proc_link != (vlinks_t *) NULL;
42932159047fSniklas proc_link = proc_link->next)
42942159047fSniklas {
42952159047fSniklas int prc_cnt;
42962159047fSniklas proc_t *proc_ptr;
42972159047fSniklas proc_t *proc_end;
42982159047fSniklas
42992159047fSniklas if (proc_link->next == (vlinks_t *) NULL)
43002159047fSniklas prc_cnt = fil_ptr->procs.objects_last_page;
43012159047fSniklas else
43022159047fSniklas prc_cnt = fil_ptr->procs.objects_per_page;
43032159047fSniklas proc_ptr = proc_link->datum->proc;
43042159047fSniklas proc_end = proc_ptr + prc_cnt;
43052159047fSniklas for (; proc_ptr < proc_end; proc_ptr++)
43062159047fSniklas {
43072159047fSniklas symbolS *adr_sym;
43082159047fSniklas unsigned long adr;
43092159047fSniklas
43102159047fSniklas adr_sym = proc_ptr->sym->as_sym;
43112159047fSniklas adr = (S_GET_VALUE (adr_sym)
43122159047fSniklas + bfd_get_section_vma (stdoutput,
43132159047fSniklas S_GET_SEGMENT (adr_sym)));
43142159047fSniklas if (first)
43152159047fSniklas {
43162159047fSniklas /* This code used to force the adr of the very
43172159047fSniklas first fdr to be 0. However, the native tools
43182159047fSniklas don't do that, and I can't remember why it
43192159047fSniklas used to work that way, so I took it out. */
43202159047fSniklas fil_ptr->fdr.adr = adr;
43212159047fSniklas first = 0;
43222159047fSniklas }
43232159047fSniklas proc_ptr->pdr.adr = adr - fil_ptr->fdr.adr;
4324b55d4692Sfgsch if ((bfd_size_type)(*bufend - pdr_out) < external_pdr_size)
43252159047fSniklas pdr_out = ecoff_add_bytes (buf, bufend,
43262159047fSniklas pdr_out,
43272159047fSniklas external_pdr_size);
43282159047fSniklas (*swap_pdr_out) (stdoutput, &proc_ptr->pdr, pdr_out);
43292159047fSniklas pdr_out += external_pdr_size;
43302159047fSniklas ++iproc;
43312159047fSniklas }
43322159047fSniklas }
43332159047fSniklas fil_ptr->fdr.cpd = iproc - fil_ptr->fdr.ipdFirst;
43342159047fSniklas }
43352159047fSniklas }
43362159047fSniklas
43372159047fSniklas return offset + iproc * external_pdr_size;
43382159047fSniklas }
43392159047fSniklas
43402159047fSniklas /* Swap out the aux information. */
43412159047fSniklas
43422159047fSniklas static unsigned long
ecoff_build_aux(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)4343*007c2a45Smiod ecoff_build_aux (const struct ecoff_debug_swap *backend,
4344*007c2a45Smiod char **buf,
4345*007c2a45Smiod char **bufend,
4346*007c2a45Smiod unsigned long offset)
43472159047fSniklas {
43482159047fSniklas int bigendian;
43492159047fSniklas union aux_ext *aux_out;
43502159047fSniklas long iaux;
43512159047fSniklas vlinks_t *file_link;
43522159047fSniklas
4353191aa565Sniklas bigendian = bfd_big_endian (stdoutput);
43542159047fSniklas
43552159047fSniklas aux_out = (union aux_ext *) (*buf + offset);
43562159047fSniklas
43572159047fSniklas iaux = 0;
43582159047fSniklas
43592159047fSniklas /* The aux entries are stored by file. */
43602159047fSniklas for (file_link = file_desc.first;
43612159047fSniklas file_link != (vlinks_t *) NULL;
43622159047fSniklas file_link = file_link->next)
43632159047fSniklas {
43642159047fSniklas int fil_cnt;
43652159047fSniklas efdr_t *fil_ptr;
43662159047fSniklas efdr_t *fil_end;
43672159047fSniklas
43682159047fSniklas if (file_link->next == (vlinks_t *) NULL)
43692159047fSniklas fil_cnt = file_desc.objects_last_page;
43702159047fSniklas else
43712159047fSniklas fil_cnt = file_desc.objects_per_page;
43722159047fSniklas fil_ptr = file_link->datum->file;
43732159047fSniklas fil_end = fil_ptr + fil_cnt;
43742159047fSniklas for (; fil_ptr < fil_end; fil_ptr++)
43752159047fSniklas {
43762159047fSniklas vlinks_t *aux_link;
43772159047fSniklas
43782159047fSniklas fil_ptr->fdr.fBigendian = bigendian;
43792159047fSniklas fil_ptr->fdr.iauxBase = iaux;
43802159047fSniklas for (aux_link = fil_ptr->aux_syms.first;
43812159047fSniklas aux_link != (vlinks_t *) NULL;
43822159047fSniklas aux_link = aux_link->next)
43832159047fSniklas {
43842159047fSniklas int aux_cnt;
43852159047fSniklas aux_t *aux_ptr;
43862159047fSniklas aux_t *aux_end;
43872159047fSniklas
43882159047fSniklas if (aux_link->next == (vlinks_t *) NULL)
43892159047fSniklas aux_cnt = fil_ptr->aux_syms.objects_last_page;
43902159047fSniklas else
43912159047fSniklas aux_cnt = fil_ptr->aux_syms.objects_per_page;
43922159047fSniklas aux_ptr = aux_link->datum->aux;
43932159047fSniklas aux_end = aux_ptr + aux_cnt;
43942159047fSniklas for (; aux_ptr < aux_end; aux_ptr++)
43952159047fSniklas {
4396b55d4692Sfgsch if ((unsigned long) (*bufend - (char *) aux_out)
4397b55d4692Sfgsch < sizeof (union aux_ext))
43982159047fSniklas aux_out = ((union aux_ext *)
43992159047fSniklas ecoff_add_bytes (buf, bufend,
44002159047fSniklas (char *) aux_out,
44012159047fSniklas sizeof (union aux_ext)));
44022159047fSniklas switch (aux_ptr->type)
44032159047fSniklas {
44042159047fSniklas case aux_tir:
44052159047fSniklas (*backend->swap_tir_out) (bigendian,
44062159047fSniklas &aux_ptr->data.ti,
44072159047fSniklas &aux_out->a_ti);
44082159047fSniklas break;
44092159047fSniklas case aux_rndx:
44102159047fSniklas (*backend->swap_rndx_out) (bigendian,
44112159047fSniklas &aux_ptr->data.rndx,
44122159047fSniklas &aux_out->a_rndx);
44132159047fSniklas break;
44142159047fSniklas case aux_dnLow:
44152159047fSniklas AUX_PUT_DNLOW (bigendian, aux_ptr->data.dnLow,
44162159047fSniklas aux_out);
44172159047fSniklas break;
44182159047fSniklas case aux_dnHigh:
44192159047fSniklas AUX_PUT_DNHIGH (bigendian, aux_ptr->data.dnHigh,
44202159047fSniklas aux_out);
44212159047fSniklas break;
44222159047fSniklas case aux_isym:
44232159047fSniklas AUX_PUT_ISYM (bigendian, aux_ptr->data.isym,
44242159047fSniklas aux_out);
44252159047fSniklas break;
44262159047fSniklas case aux_iss:
44272159047fSniklas AUX_PUT_ISS (bigendian, aux_ptr->data.iss,
44282159047fSniklas aux_out);
44292159047fSniklas break;
44302159047fSniklas case aux_width:
44312159047fSniklas AUX_PUT_WIDTH (bigendian, aux_ptr->data.width,
44322159047fSniklas aux_out);
44332159047fSniklas break;
44342159047fSniklas case aux_count:
44352159047fSniklas AUX_PUT_COUNT (bigendian, aux_ptr->data.count,
44362159047fSniklas aux_out);
44372159047fSniklas break;
44382159047fSniklas }
44392159047fSniklas
44402159047fSniklas ++aux_out;
44412159047fSniklas ++iaux;
44422159047fSniklas }
44432159047fSniklas }
44442159047fSniklas fil_ptr->fdr.caux = iaux - fil_ptr->fdr.iauxBase;
44452159047fSniklas }
44462159047fSniklas }
44472159047fSniklas
44482159047fSniklas return ecoff_padding_adjust (backend, buf, bufend,
44492159047fSniklas offset + iaux * sizeof (union aux_ext),
44502159047fSniklas (char **) NULL);
44512159047fSniklas }
44522159047fSniklas
44532159047fSniklas /* Copy out the strings from a varray_t. This returns the number of
44542159047fSniklas bytes copied, rather than the new offset. */
44552159047fSniklas
44562159047fSniklas static unsigned long
ecoff_build_strings(char ** buf,char ** bufend,unsigned long offset,varray_t * vp)4457*007c2a45Smiod ecoff_build_strings (char **buf,
4458*007c2a45Smiod char **bufend,
4459*007c2a45Smiod unsigned long offset,
4460*007c2a45Smiod varray_t *vp)
44612159047fSniklas {
44622159047fSniklas unsigned long istr;
44632159047fSniklas char *str_out;
44642159047fSniklas vlinks_t *str_link;
44652159047fSniklas
44662159047fSniklas str_out = *buf + offset;
44672159047fSniklas
44682159047fSniklas istr = 0;
44692159047fSniklas
44702159047fSniklas for (str_link = vp->first;
44712159047fSniklas str_link != (vlinks_t *) NULL;
44722159047fSniklas str_link = str_link->next)
44732159047fSniklas {
44742159047fSniklas unsigned long str_cnt;
44752159047fSniklas
44762159047fSniklas if (str_link->next == (vlinks_t *) NULL)
44772159047fSniklas str_cnt = vp->objects_last_page;
44782159047fSniklas else
44792159047fSniklas str_cnt = vp->objects_per_page;
44802159047fSniklas
4481b55d4692Sfgsch if ((unsigned long)(*bufend - str_out) < str_cnt)
44822159047fSniklas str_out = ecoff_add_bytes (buf, bufend, str_out, str_cnt);
44832159047fSniklas
44842159047fSniklas memcpy (str_out, str_link->datum->byte, str_cnt);
44852159047fSniklas str_out += str_cnt;
44862159047fSniklas istr += str_cnt;
44872159047fSniklas }
44882159047fSniklas
44892159047fSniklas return istr;
44902159047fSniklas }
44912159047fSniklas
44922159047fSniklas /* Dump out the local strings. */
44932159047fSniklas
44942159047fSniklas static unsigned long
ecoff_build_ss(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)4495*007c2a45Smiod ecoff_build_ss (const struct ecoff_debug_swap *backend,
4496*007c2a45Smiod char **buf,
4497*007c2a45Smiod char **bufend,
4498*007c2a45Smiod unsigned long offset)
44992159047fSniklas {
45002159047fSniklas long iss;
45012159047fSniklas vlinks_t *file_link;
45022159047fSniklas
45032159047fSniklas iss = 0;
45042159047fSniklas
45052159047fSniklas for (file_link = file_desc.first;
45062159047fSniklas file_link != (vlinks_t *) NULL;
45072159047fSniklas file_link = file_link->next)
45082159047fSniklas {
45092159047fSniklas int fil_cnt;
45102159047fSniklas efdr_t *fil_ptr;
45112159047fSniklas efdr_t *fil_end;
45122159047fSniklas
45132159047fSniklas if (file_link->next == (vlinks_t *) NULL)
45142159047fSniklas fil_cnt = file_desc.objects_last_page;
45152159047fSniklas else
45162159047fSniklas fil_cnt = file_desc.objects_per_page;
45172159047fSniklas fil_ptr = file_link->datum->file;
45182159047fSniklas fil_end = fil_ptr + fil_cnt;
45192159047fSniklas for (; fil_ptr < fil_end; fil_ptr++)
45202159047fSniklas {
45212159047fSniklas long ss_cnt;
45222159047fSniklas
45232159047fSniklas fil_ptr->fdr.issBase = iss;
45242159047fSniklas ss_cnt = ecoff_build_strings (buf, bufend, offset + iss,
45252159047fSniklas &fil_ptr->strings);
45262159047fSniklas fil_ptr->fdr.cbSs = ss_cnt;
45272159047fSniklas iss += ss_cnt;
45282159047fSniklas }
45292159047fSniklas }
45302159047fSniklas
45312159047fSniklas return ecoff_padding_adjust (backend, buf, bufend, offset + iss,
45322159047fSniklas (char **) NULL);
45332159047fSniklas }
45342159047fSniklas
45352159047fSniklas /* Swap out the file descriptors. */
45362159047fSniklas
45372159047fSniklas static unsigned long
ecoff_build_fdr(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)4538*007c2a45Smiod ecoff_build_fdr (const struct ecoff_debug_swap *backend,
4539*007c2a45Smiod char **buf,
4540*007c2a45Smiod char **bufend,
4541*007c2a45Smiod unsigned long offset)
45422159047fSniklas {
45432159047fSniklas const bfd_size_type external_fdr_size = backend->external_fdr_size;
4544*007c2a45Smiod void (* const swap_fdr_out) (bfd *, const FDR *, PTR)
45452159047fSniklas = backend->swap_fdr_out;
45462159047fSniklas long ifile;
45472159047fSniklas char *fdr_out;
45482159047fSniklas vlinks_t *file_link;
45492159047fSniklas
45502159047fSniklas ifile = 0;
45512159047fSniklas
45522159047fSniklas fdr_out = *buf + offset;
45532159047fSniklas
45542159047fSniklas for (file_link = file_desc.first;
45552159047fSniklas file_link != (vlinks_t *) NULL;
45562159047fSniklas file_link = file_link->next)
45572159047fSniklas {
45582159047fSniklas int fil_cnt;
45592159047fSniklas efdr_t *fil_ptr;
45602159047fSniklas efdr_t *fil_end;
45612159047fSniklas
45622159047fSniklas if (file_link->next == (vlinks_t *) NULL)
45632159047fSniklas fil_cnt = file_desc.objects_last_page;
45642159047fSniklas else
45652159047fSniklas fil_cnt = file_desc.objects_per_page;
45662159047fSniklas fil_ptr = file_link->datum->file;
45672159047fSniklas fil_end = fil_ptr + fil_cnt;
45682159047fSniklas for (; fil_ptr < fil_end; fil_ptr++)
45692159047fSniklas {
4570b55d4692Sfgsch if ((bfd_size_type)(*bufend - fdr_out) < external_fdr_size)
45712159047fSniklas fdr_out = ecoff_add_bytes (buf, bufend, fdr_out,
45722159047fSniklas external_fdr_size);
45732159047fSniklas (*swap_fdr_out) (stdoutput, &fil_ptr->fdr, fdr_out);
45742159047fSniklas fdr_out += external_fdr_size;
45752159047fSniklas ++ifile;
45762159047fSniklas }
45772159047fSniklas }
45782159047fSniklas
45792159047fSniklas return offset + ifile * external_fdr_size;
45802159047fSniklas }
45812159047fSniklas
45822159047fSniklas /* Set up the external symbols. These are supposed to be handled by
45832159047fSniklas the backend. This routine just gets the right information and
45842159047fSniklas calls a backend function to deal with it. */
45852159047fSniklas
45862159047fSniklas static void
ecoff_setup_ext(void)4587*007c2a45Smiod ecoff_setup_ext (void)
45882159047fSniklas {
45892159047fSniklas register symbolS *sym;
45902159047fSniklas
45912159047fSniklas for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
45922159047fSniklas {
4593b305b0f1Sespie if (symbol_get_obj (sym)->ecoff_symbol == NULL)
45942159047fSniklas continue;
45952159047fSniklas
45962159047fSniklas /* If this is a local symbol, then force the fields to zero. */
45972159047fSniklas if (! S_IS_EXTERNAL (sym)
45982159047fSniklas && ! S_IS_WEAK (sym)
45992159047fSniklas && S_IS_DEFINED (sym))
46002159047fSniklas {
4601b305b0f1Sespie struct localsym *lsym;
4602b305b0f1Sespie
4603b305b0f1Sespie lsym = symbol_get_obj (sym)->ecoff_symbol;
4604b305b0f1Sespie lsym->ecoff_sym.asym.value = 0;
4605b305b0f1Sespie lsym->ecoff_sym.asym.st = (int) st_Nil;
4606b305b0f1Sespie lsym->ecoff_sym.asym.sc = (int) sc_Nil;
4607b305b0f1Sespie lsym->ecoff_sym.asym.index = indexNil;
46082159047fSniklas }
46092159047fSniklas
4610b305b0f1Sespie obj_ecoff_set_ext (sym, &symbol_get_obj (sym)->ecoff_symbol->ecoff_sym);
46112159047fSniklas }
46122159047fSniklas }
46132159047fSniklas
46142159047fSniklas /* Build the ECOFF debugging information. */
46152159047fSniklas
46162159047fSniklas unsigned long
ecoff_build_debug(HDRR * hdr,char ** bufp,const struct ecoff_debug_swap * backend)4617*007c2a45Smiod ecoff_build_debug (HDRR *hdr,
4618*007c2a45Smiod char **bufp,
4619*007c2a45Smiod const struct ecoff_debug_swap *backend)
46202159047fSniklas {
46212159047fSniklas const bfd_size_type external_pdr_size = backend->external_pdr_size;
46222159047fSniklas tag_t *ptag;
46232159047fSniklas tag_t *ptag_next;
46242159047fSniklas efdr_t *fil_ptr;
46252159047fSniklas int end_warning;
46262159047fSniklas efdr_t *hold_file_ptr;
46272159047fSniklas proc_t *hold_proc_ptr;
46282159047fSniklas symbolS *sym;
46292159047fSniklas char *buf;
46302159047fSniklas char *bufend;
46312159047fSniklas unsigned long offset;
46322159047fSniklas
46332159047fSniklas /* Make sure we have a file. */
46342159047fSniklas if (first_file == (efdr_t *) NULL)
46352159047fSniklas add_file ((const char *) NULL, 0, 1);
46362159047fSniklas
46372159047fSniklas /* Handle any top level tags. */
46382159047fSniklas for (ptag = top_tag_head->first_tag;
46392159047fSniklas ptag != (tag_t *) NULL;
46402159047fSniklas ptag = ptag_next)
46412159047fSniklas {
46422159047fSniklas if (ptag->forward_ref != (forward_t *) NULL)
46432159047fSniklas add_unknown_tag (ptag);
46442159047fSniklas
46452159047fSniklas ptag_next = ptag->same_block;
46462159047fSniklas ptag->hash_ptr->tag_ptr = ptag->same_name;
46472159047fSniklas free_tag (ptag);
46482159047fSniklas }
46492159047fSniklas
46502159047fSniklas free_thead (top_tag_head);
46512159047fSniklas
46522159047fSniklas /* Look through the symbols. Add debugging information for each
46532159047fSniklas symbol that has not already received it. */
46542159047fSniklas hold_file_ptr = cur_file_ptr;
46552159047fSniklas hold_proc_ptr = cur_proc_ptr;
46562159047fSniklas cur_proc_ptr = (proc_t *) NULL;
46572159047fSniklas for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
46582159047fSniklas {
4659b305b0f1Sespie if (symbol_get_obj (sym)->ecoff_symbol != NULL
4660b305b0f1Sespie || symbol_get_obj (sym)->ecoff_file == (efdr_t *) NULL
4661b305b0f1Sespie || (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) != 0)
46622159047fSniklas continue;
46632159047fSniklas
4664b305b0f1Sespie cur_file_ptr = symbol_get_obj (sym)->ecoff_file;
46652159047fSniklas add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym,
4666191aa565Sniklas (bfd_vma) 0, S_GET_VALUE (sym), indexNil);
46672159047fSniklas }
46682159047fSniklas cur_proc_ptr = hold_proc_ptr;
46692159047fSniklas cur_file_ptr = hold_file_ptr;
46702159047fSniklas
46712159047fSniklas /* Output an ending symbol for all the files. We have to do this
46722159047fSniklas here for the last file, so we may as well do it for all of the
46732159047fSniklas files. */
46742159047fSniklas end_warning = 0;
46752159047fSniklas for (fil_ptr = first_file;
46762159047fSniklas fil_ptr != (efdr_t *) NULL;
46772159047fSniklas fil_ptr = fil_ptr->next_file)
46782159047fSniklas {
46792159047fSniklas cur_file_ptr = fil_ptr;
46802159047fSniklas while (cur_file_ptr->cur_scope != (scope_t *) NULL
46812159047fSniklas && cur_file_ptr->cur_scope->prev != (scope_t *) NULL)
46822159047fSniklas {
46832159047fSniklas cur_file_ptr->cur_scope = cur_file_ptr->cur_scope->prev;
46842159047fSniklas if (! end_warning && ! cur_file_ptr->fake)
46852159047fSniklas {
4686c074d1c9Sdrahn as_warn (_("missing .end or .bend at end of file"));
46872159047fSniklas end_warning = 1;
46882159047fSniklas }
46892159047fSniklas }
46902159047fSniklas if (cur_file_ptr->cur_scope != (scope_t *) NULL)
46912159047fSniklas (void) add_ecoff_symbol ((const char *) NULL,
46922159047fSniklas st_End, sc_Text,
46932159047fSniklas (symbolS *) NULL,
4694191aa565Sniklas (bfd_vma) 0,
46952159047fSniklas (symint_t) 0,
46962159047fSniklas (symint_t) 0);
46972159047fSniklas }
46982159047fSniklas
46992159047fSniklas /* Build the symbolic information. */
47002159047fSniklas offset = 0;
47012159047fSniklas buf = xmalloc (PAGE_SIZE);
47022159047fSniklas bufend = buf + PAGE_SIZE;
47032159047fSniklas
47042159047fSniklas /* Build the line number information. */
47052159047fSniklas hdr->cbLineOffset = offset;
47062159047fSniklas offset = ecoff_build_lineno (backend, &buf, &bufend, offset,
47072159047fSniklas &hdr->ilineMax);
47082159047fSniklas hdr->cbLine = offset - hdr->cbLineOffset;
47092159047fSniklas
47102159047fSniklas /* We don't use dense numbers at all. */
47112159047fSniklas hdr->idnMax = 0;
47122159047fSniklas hdr->cbDnOffset = 0;
47132159047fSniklas
47142159047fSniklas /* We can't build the PDR table until we have built the symbols,
47152159047fSniklas because a PDR contains a symbol index. However, we set aside
47162159047fSniklas space at this point. */
47172159047fSniklas hdr->ipdMax = proc_cnt;
47182159047fSniklas hdr->cbPdOffset = offset;
4719b55d4692Sfgsch if ((bfd_size_type)(bufend - (buf + offset)) < proc_cnt * external_pdr_size)
47202159047fSniklas (void) ecoff_add_bytes (&buf, &bufend, buf + offset,
47212159047fSniklas proc_cnt * external_pdr_size);
47222159047fSniklas offset += proc_cnt * external_pdr_size;
47232159047fSniklas
47242159047fSniklas /* Build the local symbols. */
47252159047fSniklas hdr->cbSymOffset = offset;
47262159047fSniklas offset = ecoff_build_symbols (backend, &buf, &bufend, offset);
47272159047fSniklas hdr->isymMax = (offset - hdr->cbSymOffset) / backend->external_sym_size;
47282159047fSniklas
47292159047fSniklas /* Building the symbols initializes the symbol index in the PDR's.
47302159047fSniklas Now we can swap out the PDR's. */
47312159047fSniklas (void) ecoff_build_procs (backend, &buf, &bufend, hdr->cbPdOffset);
47322159047fSniklas
47332159047fSniklas /* We don't use optimization symbols. */
47342159047fSniklas hdr->ioptMax = 0;
47352159047fSniklas hdr->cbOptOffset = 0;
47362159047fSniklas
47372159047fSniklas /* Swap out the auxiliary type information. */
47382159047fSniklas hdr->cbAuxOffset = offset;
47392159047fSniklas offset = ecoff_build_aux (backend, &buf, &bufend, offset);
47402159047fSniklas hdr->iauxMax = (offset - hdr->cbAuxOffset) / sizeof (union aux_ext);
47412159047fSniklas
47422159047fSniklas /* Copy out the local strings. */
47432159047fSniklas hdr->cbSsOffset = offset;
47442159047fSniklas offset = ecoff_build_ss (backend, &buf, &bufend, offset);
47452159047fSniklas hdr->issMax = offset - hdr->cbSsOffset;
47462159047fSniklas
47472159047fSniklas /* We don't use relative file descriptors. */
47482159047fSniklas hdr->crfd = 0;
47492159047fSniklas hdr->cbRfdOffset = 0;
47502159047fSniklas
47512159047fSniklas /* Swap out the file descriptors. */
47522159047fSniklas hdr->cbFdOffset = offset;
47532159047fSniklas offset = ecoff_build_fdr (backend, &buf, &bufend, offset);
47542159047fSniklas hdr->ifdMax = (offset - hdr->cbFdOffset) / backend->external_fdr_size;
47552159047fSniklas
47562159047fSniklas /* Set up the external symbols, which are handled by the BFD back
47572159047fSniklas end. */
47582159047fSniklas hdr->issExtMax = 0;
47592159047fSniklas hdr->cbSsExtOffset = 0;
47602159047fSniklas hdr->iextMax = 0;
47612159047fSniklas hdr->cbExtOffset = 0;
47622159047fSniklas ecoff_setup_ext ();
47632159047fSniklas
47642159047fSniklas know ((offset & (backend->debug_align - 1)) == 0);
47652159047fSniklas
47662159047fSniklas /* FIXME: This value should be determined from the .verstamp directive,
47672159047fSniklas with reasonable defaults in config files. */
47682159047fSniklas #ifdef TC_ALPHA
47692159047fSniklas hdr->vstamp = 0x030b;
47702159047fSniklas #else
47712159047fSniklas hdr->vstamp = 0x020b;
47722159047fSniklas #endif
47732159047fSniklas
47742159047fSniklas *bufp = buf;
47752159047fSniklas return offset;
47762159047fSniklas }
47772159047fSniklas
47782159047fSniklas /* Allocate a cluster of pages. */
47792159047fSniklas
47802159047fSniklas #ifndef MALLOC_CHECK
47812159047fSniklas
4782b305b0f1Sespie static page_type *
allocate_cluster(unsigned long npages)4783*007c2a45Smiod allocate_cluster (unsigned long npages)
47842159047fSniklas {
4785b305b0f1Sespie register page_type *value = (page_type *) xmalloc (npages * PAGE_USIZE);
47862159047fSniklas
47872159047fSniklas #ifdef ECOFF_DEBUG
47882159047fSniklas if (debug > 3)
47892159047fSniklas fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
47902159047fSniklas #endif
47912159047fSniklas
47922159047fSniklas memset (value, 0, npages * PAGE_USIZE);
47932159047fSniklas
47942159047fSniklas return value;
47952159047fSniklas }
47962159047fSniklas
4797b305b0f1Sespie static page_type *cluster_ptr = NULL;
47982159047fSniklas static unsigned long pages_left = 0;
47992159047fSniklas
48002159047fSniklas #endif /* MALLOC_CHECK */
48012159047fSniklas
48022159047fSniklas /* Allocate one page (which is initialized to 0). */
48032159047fSniklas
4804b305b0f1Sespie static page_type *
allocate_page(void)4805*007c2a45Smiod allocate_page (void)
48062159047fSniklas {
48072159047fSniklas #ifndef MALLOC_CHECK
48082159047fSniklas
48092159047fSniklas if (pages_left == 0)
48102159047fSniklas {
48112159047fSniklas pages_left = MAX_CLUSTER_PAGES;
48122159047fSniklas cluster_ptr = allocate_cluster (pages_left);
48132159047fSniklas }
48142159047fSniklas
48152159047fSniklas pages_left--;
48162159047fSniklas return cluster_ptr++;
48172159047fSniklas
48182159047fSniklas #else /* MALLOC_CHECK */
48192159047fSniklas
4820b305b0f1Sespie page_type *ptr;
48212159047fSniklas
48222159047fSniklas ptr = xmalloc (PAGE_USIZE);
48232159047fSniklas memset (ptr, 0, PAGE_USIZE);
48242159047fSniklas return ptr;
48252159047fSniklas
48262159047fSniklas #endif /* MALLOC_CHECK */
48272159047fSniklas }
48282159047fSniklas
48292159047fSniklas /* Allocate scoping information. */
48302159047fSniklas
48312159047fSniklas static scope_t *
allocate_scope(void)4832*007c2a45Smiod allocate_scope (void)
48332159047fSniklas {
48342159047fSniklas register scope_t *ptr;
48352159047fSniklas static scope_t initial_scope;
48362159047fSniklas
48372159047fSniklas #ifndef MALLOC_CHECK
48382159047fSniklas
48392159047fSniklas ptr = alloc_counts[(int) alloc_type_scope].free_list.f_scope;
48402159047fSniklas if (ptr != (scope_t *) NULL)
48412159047fSniklas alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr->free;
48422159047fSniklas else
48432159047fSniklas {
48442159047fSniklas register int unallocated = alloc_counts[(int) alloc_type_scope].unallocated;
4845b305b0f1Sespie register page_type *cur_page = alloc_counts[(int) alloc_type_scope].cur_page;
48462159047fSniklas
48472159047fSniklas if (unallocated == 0)
48482159047fSniklas {
48492159047fSniklas unallocated = PAGE_SIZE / sizeof (scope_t);
48502159047fSniklas alloc_counts[(int) alloc_type_scope].cur_page = cur_page = allocate_page ();
48512159047fSniklas alloc_counts[(int) alloc_type_scope].total_pages++;
48522159047fSniklas }
48532159047fSniklas
48542159047fSniklas ptr = &cur_page->scope[--unallocated];
48552159047fSniklas alloc_counts[(int) alloc_type_scope].unallocated = unallocated;
48562159047fSniklas }
48572159047fSniklas
48582159047fSniklas #else
48592159047fSniklas
48602159047fSniklas ptr = (scope_t *) xmalloc (sizeof (scope_t));
48612159047fSniklas
48622159047fSniklas #endif
48632159047fSniklas
48642159047fSniklas alloc_counts[(int) alloc_type_scope].total_alloc++;
48652159047fSniklas *ptr = initial_scope;
48662159047fSniklas return ptr;
48672159047fSniklas }
48682159047fSniklas
48692159047fSniklas /* Free scoping information. */
48702159047fSniklas
48712159047fSniklas static void
free_scope(scope_t * ptr)4872*007c2a45Smiod free_scope (scope_t *ptr)
48732159047fSniklas {
48742159047fSniklas alloc_counts[(int) alloc_type_scope].total_free++;
48752159047fSniklas
48762159047fSniklas #ifndef MALLOC_CHECK
48772159047fSniklas ptr->free = alloc_counts[(int) alloc_type_scope].free_list.f_scope;
48782159047fSniklas alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr;
48792159047fSniklas #else
48802159047fSniklas free ((PTR) ptr);
48812159047fSniklas #endif
48822159047fSniklas }
48832159047fSniklas
48842159047fSniklas /* Allocate links for pages in a virtual array. */
48852159047fSniklas
48862159047fSniklas static vlinks_t *
allocate_vlinks(void)4887*007c2a45Smiod allocate_vlinks (void)
48882159047fSniklas {
48892159047fSniklas register vlinks_t *ptr;
48902159047fSniklas static vlinks_t initial_vlinks;
48912159047fSniklas
48922159047fSniklas #ifndef MALLOC_CHECK
48932159047fSniklas
48942159047fSniklas register int unallocated = alloc_counts[(int) alloc_type_vlinks].unallocated;
4895b305b0f1Sespie register page_type *cur_page = alloc_counts[(int) alloc_type_vlinks].cur_page;
48962159047fSniklas
48972159047fSniklas if (unallocated == 0)
48982159047fSniklas {
48992159047fSniklas unallocated = PAGE_SIZE / sizeof (vlinks_t);
49002159047fSniklas alloc_counts[(int) alloc_type_vlinks].cur_page = cur_page = allocate_page ();
49012159047fSniklas alloc_counts[(int) alloc_type_vlinks].total_pages++;
49022159047fSniklas }
49032159047fSniklas
49042159047fSniklas ptr = &cur_page->vlinks[--unallocated];
49052159047fSniklas alloc_counts[(int) alloc_type_vlinks].unallocated = unallocated;
49062159047fSniklas
49072159047fSniklas #else
49082159047fSniklas
49092159047fSniklas ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
49102159047fSniklas
49112159047fSniklas #endif
49122159047fSniklas
49132159047fSniklas alloc_counts[(int) alloc_type_vlinks].total_alloc++;
49142159047fSniklas *ptr = initial_vlinks;
49152159047fSniklas return ptr;
49162159047fSniklas }
49172159047fSniklas
49182159047fSniklas /* Allocate string hash buckets. */
49192159047fSniklas
49202159047fSniklas static shash_t *
allocate_shash(void)4921*007c2a45Smiod allocate_shash (void)
49222159047fSniklas {
49232159047fSniklas register shash_t *ptr;
49242159047fSniklas static shash_t initial_shash;
49252159047fSniklas
49262159047fSniklas #ifndef MALLOC_CHECK
49272159047fSniklas
49282159047fSniklas register int unallocated = alloc_counts[(int) alloc_type_shash].unallocated;
4929b305b0f1Sespie register page_type *cur_page = alloc_counts[(int) alloc_type_shash].cur_page;
49302159047fSniklas
49312159047fSniklas if (unallocated == 0)
49322159047fSniklas {
49332159047fSniklas unallocated = PAGE_SIZE / sizeof (shash_t);
49342159047fSniklas alloc_counts[(int) alloc_type_shash].cur_page = cur_page = allocate_page ();
49352159047fSniklas alloc_counts[(int) alloc_type_shash].total_pages++;
49362159047fSniklas }
49372159047fSniklas
49382159047fSniklas ptr = &cur_page->shash[--unallocated];
49392159047fSniklas alloc_counts[(int) alloc_type_shash].unallocated = unallocated;
49402159047fSniklas
49412159047fSniklas #else
49422159047fSniklas
49432159047fSniklas ptr = (shash_t *) xmalloc (sizeof (shash_t));
49442159047fSniklas
49452159047fSniklas #endif
49462159047fSniklas
49472159047fSniklas alloc_counts[(int) alloc_type_shash].total_alloc++;
49482159047fSniklas *ptr = initial_shash;
49492159047fSniklas return ptr;
49502159047fSniklas }
49512159047fSniklas
49522159047fSniklas /* Allocate type hash buckets. */
49532159047fSniklas
49542159047fSniklas static thash_t *
allocate_thash(void)4955*007c2a45Smiod allocate_thash (void)
49562159047fSniklas {
49572159047fSniklas register thash_t *ptr;
49582159047fSniklas static thash_t initial_thash;
49592159047fSniklas
49602159047fSniklas #ifndef MALLOC_CHECK
49612159047fSniklas
49622159047fSniklas register int unallocated = alloc_counts[(int) alloc_type_thash].unallocated;
4963b305b0f1Sespie register page_type *cur_page = alloc_counts[(int) alloc_type_thash].cur_page;
49642159047fSniklas
49652159047fSniklas if (unallocated == 0)
49662159047fSniklas {
49672159047fSniklas unallocated = PAGE_SIZE / sizeof (thash_t);
49682159047fSniklas alloc_counts[(int) alloc_type_thash].cur_page = cur_page = allocate_page ();
49692159047fSniklas alloc_counts[(int) alloc_type_thash].total_pages++;
49702159047fSniklas }
49712159047fSniklas
49722159047fSniklas ptr = &cur_page->thash[--unallocated];
49732159047fSniklas alloc_counts[(int) alloc_type_thash].unallocated = unallocated;
49742159047fSniklas
49752159047fSniklas #else
49762159047fSniklas
49772159047fSniklas ptr = (thash_t *) xmalloc (sizeof (thash_t));
49782159047fSniklas
49792159047fSniklas #endif
49802159047fSniklas
49812159047fSniklas alloc_counts[(int) alloc_type_thash].total_alloc++;
49822159047fSniklas *ptr = initial_thash;
49832159047fSniklas return ptr;
49842159047fSniklas }
49852159047fSniklas
49862159047fSniklas /* Allocate structure, union, or enum tag information. */
49872159047fSniklas
49882159047fSniklas static tag_t *
allocate_tag(void)4989*007c2a45Smiod allocate_tag (void)
49902159047fSniklas {
49912159047fSniklas register tag_t *ptr;
49922159047fSniklas static tag_t initial_tag;
49932159047fSniklas
49942159047fSniklas #ifndef MALLOC_CHECK
49952159047fSniklas
49962159047fSniklas ptr = alloc_counts[(int) alloc_type_tag].free_list.f_tag;
49972159047fSniklas if (ptr != (tag_t *) NULL)
49982159047fSniklas alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr->free;
49992159047fSniklas else
50002159047fSniklas {
50012159047fSniklas register int unallocated = alloc_counts[(int) alloc_type_tag].unallocated;
5002b305b0f1Sespie register page_type *cur_page = alloc_counts[(int) alloc_type_tag].cur_page;
50032159047fSniklas
50042159047fSniklas if (unallocated == 0)
50052159047fSniklas {
50062159047fSniklas unallocated = PAGE_SIZE / sizeof (tag_t);
50072159047fSniklas alloc_counts[(int) alloc_type_tag].cur_page = cur_page = allocate_page ();
50082159047fSniklas alloc_counts[(int) alloc_type_tag].total_pages++;
50092159047fSniklas }
50102159047fSniklas
50112159047fSniklas ptr = &cur_page->tag[--unallocated];
50122159047fSniklas alloc_counts[(int) alloc_type_tag].unallocated = unallocated;
50132159047fSniklas }
50142159047fSniklas
50152159047fSniklas #else
50162159047fSniklas
50172159047fSniklas ptr = (tag_t *) xmalloc (sizeof (tag_t));
50182159047fSniklas
50192159047fSniklas #endif
50202159047fSniklas
50212159047fSniklas alloc_counts[(int) alloc_type_tag].total_alloc++;
50222159047fSniklas *ptr = initial_tag;
50232159047fSniklas return ptr;
50242159047fSniklas }
50252159047fSniklas
50262159047fSniklas /* Free scoping information. */
50272159047fSniklas
50282159047fSniklas static void
free_tag(tag_t * ptr)5029*007c2a45Smiod free_tag (tag_t *ptr)
50302159047fSniklas {
50312159047fSniklas alloc_counts[(int) alloc_type_tag].total_free++;
50322159047fSniklas
50332159047fSniklas #ifndef MALLOC_CHECK
50342159047fSniklas ptr->free = alloc_counts[(int) alloc_type_tag].free_list.f_tag;
50352159047fSniklas alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr;
50362159047fSniklas #else
50372159047fSniklas free ((PTR_T) ptr);
50382159047fSniklas #endif
50392159047fSniklas }
50402159047fSniklas
50412159047fSniklas /* Allocate forward reference to a yet unknown tag. */
50422159047fSniklas
50432159047fSniklas static forward_t *
allocate_forward(void)5044*007c2a45Smiod allocate_forward (void)
50452159047fSniklas {
50462159047fSniklas register forward_t *ptr;
50472159047fSniklas static forward_t initial_forward;
50482159047fSniklas
50492159047fSniklas #ifndef MALLOC_CHECK
50502159047fSniklas
50512159047fSniklas register int unallocated = alloc_counts[(int) alloc_type_forward].unallocated;
5052b305b0f1Sespie register page_type *cur_page = alloc_counts[(int) alloc_type_forward].cur_page;
50532159047fSniklas
50542159047fSniklas if (unallocated == 0)
50552159047fSniklas {
50562159047fSniklas unallocated = PAGE_SIZE / sizeof (forward_t);
50572159047fSniklas alloc_counts[(int) alloc_type_forward].cur_page = cur_page = allocate_page ();
50582159047fSniklas alloc_counts[(int) alloc_type_forward].total_pages++;
50592159047fSniklas }
50602159047fSniklas
50612159047fSniklas ptr = &cur_page->forward[--unallocated];
50622159047fSniklas alloc_counts[(int) alloc_type_forward].unallocated = unallocated;
50632159047fSniklas
50642159047fSniklas #else
50652159047fSniklas
50662159047fSniklas ptr = (forward_t *) xmalloc (sizeof (forward_t));
50672159047fSniklas
50682159047fSniklas #endif
50692159047fSniklas
50702159047fSniklas alloc_counts[(int) alloc_type_forward].total_alloc++;
50712159047fSniklas *ptr = initial_forward;
50722159047fSniklas return ptr;
50732159047fSniklas }
50742159047fSniklas
50752159047fSniklas /* Allocate head of type hash list. */
50762159047fSniklas
50772159047fSniklas static thead_t *
allocate_thead(void)5078*007c2a45Smiod allocate_thead (void)
50792159047fSniklas {
50802159047fSniklas register thead_t *ptr;
50812159047fSniklas static thead_t initial_thead;
50822159047fSniklas
50832159047fSniklas #ifndef MALLOC_CHECK
50842159047fSniklas
50852159047fSniklas ptr = alloc_counts[(int) alloc_type_thead].free_list.f_thead;
50862159047fSniklas if (ptr != (thead_t *) NULL)
50872159047fSniklas alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr->free;
50882159047fSniklas else
50892159047fSniklas {
50902159047fSniklas register int unallocated = alloc_counts[(int) alloc_type_thead].unallocated;
5091b305b0f1Sespie register page_type *cur_page = alloc_counts[(int) alloc_type_thead].cur_page;
50922159047fSniklas
50932159047fSniklas if (unallocated == 0)
50942159047fSniklas {
50952159047fSniklas unallocated = PAGE_SIZE / sizeof (thead_t);
50962159047fSniklas alloc_counts[(int) alloc_type_thead].cur_page = cur_page = allocate_page ();
50972159047fSniklas alloc_counts[(int) alloc_type_thead].total_pages++;
50982159047fSniklas }
50992159047fSniklas
51002159047fSniklas ptr = &cur_page->thead[--unallocated];
51012159047fSniklas alloc_counts[(int) alloc_type_thead].unallocated = unallocated;
51022159047fSniklas }
51032159047fSniklas
51042159047fSniklas #else
51052159047fSniklas
51062159047fSniklas ptr = (thead_t *) xmalloc (sizeof (thead_t));
51072159047fSniklas
51082159047fSniklas #endif
51092159047fSniklas
51102159047fSniklas alloc_counts[(int) alloc_type_thead].total_alloc++;
51112159047fSniklas *ptr = initial_thead;
51122159047fSniklas return ptr;
51132159047fSniklas }
51142159047fSniklas
51152159047fSniklas /* Free scoping information. */
51162159047fSniklas
51172159047fSniklas static void
free_thead(thead_t * ptr)5118*007c2a45Smiod free_thead (thead_t *ptr)
51192159047fSniklas {
51202159047fSniklas alloc_counts[(int) alloc_type_thead].total_free++;
51212159047fSniklas
51222159047fSniklas #ifndef MALLOC_CHECK
51232159047fSniklas ptr->free = (thead_t *) alloc_counts[(int) alloc_type_thead].free_list.f_thead;
51242159047fSniklas alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr;
51252159047fSniklas #else
51262159047fSniklas free ((PTR_T) ptr);
51272159047fSniklas #endif
51282159047fSniklas }
51292159047fSniklas
51302159047fSniklas static lineno_list_t *
allocate_lineno_list(void)5131*007c2a45Smiod allocate_lineno_list (void)
51322159047fSniklas {
51332159047fSniklas register lineno_list_t *ptr;
51342159047fSniklas static lineno_list_t initial_lineno_list;
51352159047fSniklas
51362159047fSniklas #ifndef MALLOC_CHECK
51372159047fSniklas
51382159047fSniklas register int unallocated = alloc_counts[(int) alloc_type_lineno].unallocated;
5139b305b0f1Sespie register page_type *cur_page = alloc_counts[(int) alloc_type_lineno].cur_page;
51402159047fSniklas
51412159047fSniklas if (unallocated == 0)
51422159047fSniklas {
51432159047fSniklas unallocated = PAGE_SIZE / sizeof (lineno_list_t);
51442159047fSniklas alloc_counts[(int) alloc_type_lineno].cur_page = cur_page = allocate_page ();
51452159047fSniklas alloc_counts[(int) alloc_type_lineno].total_pages++;
51462159047fSniklas }
51472159047fSniklas
51482159047fSniklas ptr = &cur_page->lineno[--unallocated];
51492159047fSniklas alloc_counts[(int) alloc_type_lineno].unallocated = unallocated;
51502159047fSniklas
51512159047fSniklas #else
51522159047fSniklas
51532159047fSniklas ptr = (lineno_list_t *) xmalloc (sizeof (lineno_list_t));
51542159047fSniklas
51552159047fSniklas #endif
51562159047fSniklas
51572159047fSniklas alloc_counts[(int) alloc_type_lineno].total_alloc++;
51582159047fSniklas *ptr = initial_lineno_list;
51592159047fSniklas return ptr;
51602159047fSniklas }
51612159047fSniklas
51622159047fSniklas void
ecoff_set_gp_prolog_size(int sz)5163*007c2a45Smiod ecoff_set_gp_prolog_size (int sz)
51642159047fSniklas {
51652159047fSniklas if (cur_proc_ptr == 0)
51662159047fSniklas return;
51672159047fSniklas
51682159047fSniklas cur_proc_ptr->pdr.gp_prologue = sz;
51692159047fSniklas if (cur_proc_ptr->pdr.gp_prologue != sz)
51702159047fSniklas {
5171b305b0f1Sespie as_warn (_("GP prologue size exceeds field size, using 0 instead"));
51722159047fSniklas cur_proc_ptr->pdr.gp_prologue = 0;
51732159047fSniklas }
51742159047fSniklas
51752159047fSniklas cur_proc_ptr->pdr.gp_used = 1;
51762159047fSniklas }
51772159047fSniklas
51782159047fSniklas int
ecoff_no_current_file(void)5179*007c2a45Smiod ecoff_no_current_file (void)
51802159047fSniklas {
51812159047fSniklas return cur_file_ptr == (efdr_t *) NULL;
51822159047fSniklas }
51832159047fSniklas
51842159047fSniklas void
ecoff_generate_asm_lineno(void)5185*007c2a45Smiod ecoff_generate_asm_lineno (void)
51862159047fSniklas {
5187b305b0f1Sespie unsigned int lineno;
5188b305b0f1Sespie char *filename;
51892159047fSniklas lineno_list_t *list;
51902159047fSniklas
5191b305b0f1Sespie as_where (&filename, &lineno);
51922159047fSniklas
5193b305b0f1Sespie if (current_stabs_filename == (char *) NULL
5194b305b0f1Sespie || strcmp (current_stabs_filename, filename))
51952159047fSniklas add_file (filename, 0, 1);
51962159047fSniklas
51972159047fSniklas list = allocate_lineno_list ();
51982159047fSniklas
51992159047fSniklas list->next = (lineno_list_t *) NULL;
52002159047fSniklas list->file = cur_file_ptr;
52012159047fSniklas list->proc = cur_proc_ptr;
52022159047fSniklas list->frag = frag_now;
52032159047fSniklas list->paddr = frag_now_fix ();
52042159047fSniklas list->lineno = lineno;
52052159047fSniklas
52060c6d0228Sniklas /* We don't want to merge files which have line numbers. */
52070c6d0228Sniklas cur_file_ptr->fdr.fMerge = 0;
52080c6d0228Sniklas
52092159047fSniklas /* A .loc directive will sometimes appear before a .ent directive,
52102159047fSniklas which means that cur_proc_ptr will be NULL here. Arrange to
52112159047fSniklas patch this up. */
52122159047fSniklas if (cur_proc_ptr == (proc_t *) NULL)
52132159047fSniklas {
52142159047fSniklas lineno_list_t **pl;
52152159047fSniklas
52162159047fSniklas pl = &noproc_lineno;
52172159047fSniklas while (*pl != (lineno_list_t *) NULL)
52182159047fSniklas pl = &(*pl)->next;
52192159047fSniklas *pl = list;
52202159047fSniklas }
52212159047fSniklas else
52222159047fSniklas {
52230c6d0228Sniklas last_lineno = list;
52242159047fSniklas *last_lineno_ptr = list;
52252159047fSniklas last_lineno_ptr = &list->next;
52262159047fSniklas }
52272159047fSniklas }
52282159047fSniklas
5229b305b0f1Sespie #else
5230b305b0f1Sespie
52312159047fSniklas void
ecoff_generate_asm_lineno(void)5232*007c2a45Smiod ecoff_generate_asm_lineno (void)
52332159047fSniklas {
52342159047fSniklas }
52352159047fSniklas
52362159047fSniklas #endif /* ECOFF_DEBUGGING */
5237