xref: /dragonfly/contrib/binutils-2.27/gas/ecoff.c (revision a9fa9459)
1*a9fa9459Szrj /* ECOFF debugging support.
2*a9fa9459Szrj    Copyright (C) 1993-2016 Free Software Foundation, Inc.
3*a9fa9459Szrj    Contributed by Cygnus Support.
4*a9fa9459Szrj    This file was put together by Ian Lance Taylor <ian@cygnus.com>.  A
5*a9fa9459Szrj    good deal of it comes directly from mips-tfile.c, by Michael
6*a9fa9459Szrj    Meissner <meissner@osf.org>.
7*a9fa9459Szrj 
8*a9fa9459Szrj    This file is part of GAS.
9*a9fa9459Szrj 
10*a9fa9459Szrj    GAS is free software; you can redistribute it and/or modify
11*a9fa9459Szrj    it under the terms of the GNU General Public License as published by
12*a9fa9459Szrj    the Free Software Foundation; either version 3, or (at your option)
13*a9fa9459Szrj    any later version.
14*a9fa9459Szrj 
15*a9fa9459Szrj    GAS is distributed in the hope that it will be useful,
16*a9fa9459Szrj    but WITHOUT ANY WARRANTY; without even the implied warranty of
17*a9fa9459Szrj    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*a9fa9459Szrj    GNU General Public License for more details.
19*a9fa9459Szrj 
20*a9fa9459Szrj    You should have received a copy of the GNU General Public License
21*a9fa9459Szrj    along with GAS; see the file COPYING.  If not, write to the Free
22*a9fa9459Szrj    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23*a9fa9459Szrj    02110-1301, USA.  */
24*a9fa9459Szrj 
25*a9fa9459Szrj #include "as.h"
26*a9fa9459Szrj 
27*a9fa9459Szrj /* This file is compiled conditionally for those targets which use
28*a9fa9459Szrj    ECOFF debugging information (e.g., MIPS ELF, Alpha ECOFF).  */
29*a9fa9459Szrj 
30*a9fa9459Szrj #include "ecoff.h"
31*a9fa9459Szrj 
32*a9fa9459Szrj #ifdef ECOFF_DEBUGGING
33*a9fa9459Szrj 
34*a9fa9459Szrj #include "coff/internal.h"
35*a9fa9459Szrj #include "coff/symconst.h"
36*a9fa9459Szrj #include "aout/stab_gnu.h"
37*a9fa9459Szrj #include "filenames.h"
38*a9fa9459Szrj #include "safe-ctype.h"
39*a9fa9459Szrj 
40*a9fa9459Szrj /* Why isn't this in coff/sym.h?  */
41*a9fa9459Szrj #define ST_RFDESCAPE 0xfff
42*a9fa9459Szrj 
43*a9fa9459Szrj /* This file constructs the information used by the ECOFF debugging
44*a9fa9459Szrj    format.  It just builds a large block of data.
45*a9fa9459Szrj 
46*a9fa9459Szrj    We support both ECOFF style debugging and stabs debugging (the
47*a9fa9459Szrj    stabs symbols are encapsulated in ECOFF symbols).  This should let
48*a9fa9459Szrj    us handle anything the compiler might throw at us.  */
49*a9fa9459Szrj 
50*a9fa9459Szrj /* Here is a brief description of the MIPS ECOFF symbol table, by
51*a9fa9459Szrj    Michael Meissner.  The MIPS symbol table has the following pieces:
52*a9fa9459Szrj 
53*a9fa9459Szrj 	Symbolic Header
54*a9fa9459Szrj 	    |
55*a9fa9459Szrj 	    +--	Auxiliary Symbols
56*a9fa9459Szrj 	    |
57*a9fa9459Szrj 	    +--	Dense number table
58*a9fa9459Szrj 	    |
59*a9fa9459Szrj 	    +--	Optimizer Symbols
60*a9fa9459Szrj 	    |
61*a9fa9459Szrj 	    +--	External Strings
62*a9fa9459Szrj 	    |
63*a9fa9459Szrj 	    +--	External Symbols
64*a9fa9459Szrj 	    |
65*a9fa9459Szrj 	    +--	Relative file descriptors
66*a9fa9459Szrj 	    |
67*a9fa9459Szrj 	    +--	File table
68*a9fa9459Szrj 		    |
69*a9fa9459Szrj 		    +--	Procedure table
70*a9fa9459Szrj 		    |
71*a9fa9459Szrj 		    +--	Line number table
72*a9fa9459Szrj 		    |
73*a9fa9459Szrj 		    +--	Local Strings
74*a9fa9459Szrj 		    |
75*a9fa9459Szrj 		    +--	Local Symbols
76*a9fa9459Szrj 
77*a9fa9459Szrj    The symbolic header points to each of the other tables, and also
78*a9fa9459Szrj    contains the number of entries.  It also contains a magic number
79*a9fa9459Szrj    and MIPS compiler version number, such as 2.0.
80*a9fa9459Szrj 
81*a9fa9459Szrj    The auxiliary table is a series of 32 bit integers, that are
82*a9fa9459Szrj    referenced as needed from the local symbol table.  Unlike standard
83*a9fa9459Szrj    COFF, the aux.  information does not follow the symbol that uses
84*a9fa9459Szrj    it, but rather is a separate table.  In theory, this would allow
85*a9fa9459Szrj    the MIPS compilers to collapse duplicate aux. entries, but I've not
86*a9fa9459Szrj    noticed this happening with the 1.31 compiler suite.  The different
87*a9fa9459Szrj    types of aux. entries are:
88*a9fa9459Szrj 
89*a9fa9459Szrj     1)	dnLow: Low bound on array dimension.
90*a9fa9459Szrj 
91*a9fa9459Szrj     2)	dnHigh: High bound on array dimension.
92*a9fa9459Szrj 
93*a9fa9459Szrj     3)	isym: Index to the local symbol which is the start of the
94*a9fa9459Szrj 	function for the end of function first aux. entry.
95*a9fa9459Szrj 
96*a9fa9459Szrj     4)	width: Width of structures and bitfields.
97*a9fa9459Szrj 
98*a9fa9459Szrj     5)	count: Count of ranges for variant part.
99*a9fa9459Szrj 
100*a9fa9459Szrj     6)	rndx: A relative index into the symbol table.  The relative
101*a9fa9459Szrj 	index field has two parts: rfd which is a pointer into the
102*a9fa9459Szrj 	relative file index table or ST_RFDESCAPE which says the next
103*a9fa9459Szrj 	aux. entry is the file number, and index: which is the pointer
104*a9fa9459Szrj 	into the local symbol within a given file table.  This is for
105*a9fa9459Szrj 	things like references to types defined in another file.
106*a9fa9459Szrj 
107*a9fa9459Szrj     7)	Type information: This is like the COFF type bits, except it
108*a9fa9459Szrj 	is 32 bits instead of 16; they still have room to add new
109*a9fa9459Szrj 	basic types; and they can handle more than 6 levels of array,
110*a9fa9459Szrj 	pointer, function, etc.  Each type information field contains
111*a9fa9459Szrj 	the following structure members:
112*a9fa9459Szrj 
113*a9fa9459Szrj 	    a)	fBitfield: a bit that says this is a bitfield, and the
114*a9fa9459Szrj 		size in bits follows as the next aux. entry.
115*a9fa9459Szrj 
116*a9fa9459Szrj 	    b)	continued: a bit that says the next aux. entry is a
117*a9fa9459Szrj 		continuation of the current type information (in case
118*a9fa9459Szrj 		there are more than 6 levels of array/ptr/function).
119*a9fa9459Szrj 
120*a9fa9459Szrj 	    c)	bt: an integer containing the base type before adding
121*a9fa9459Szrj 		array, pointer, function, etc. qualifiers.  The
122*a9fa9459Szrj 		current base types that I have documentation for are:
123*a9fa9459Szrj 
124*a9fa9459Szrj 			btNil		-- undefined
125*a9fa9459Szrj 			btAdr		-- address - integer same size as ptr
126*a9fa9459Szrj 			btChar		-- character
127*a9fa9459Szrj 			btUChar		-- unsigned character
128*a9fa9459Szrj 			btShort		-- short
129*a9fa9459Szrj 			btUShort	-- unsigned short
130*a9fa9459Szrj 			btInt		-- int
131*a9fa9459Szrj 			btUInt		-- unsigned int
132*a9fa9459Szrj 			btLong		-- long
133*a9fa9459Szrj 			btULong		-- unsigned long
134*a9fa9459Szrj 			btFloat		-- float (real)
135*a9fa9459Szrj 			btDouble	-- Double (real)
136*a9fa9459Szrj 			btStruct	-- Structure (Record)
137*a9fa9459Szrj 			btUnion		-- Union (variant)
138*a9fa9459Szrj 			btEnum		-- Enumerated
139*a9fa9459Szrj 			btTypedef	-- defined via a typedef isymRef
140*a9fa9459Szrj 			btRange		-- subrange of int
141*a9fa9459Szrj 			btSet		-- pascal sets
142*a9fa9459Szrj 			btComplex	-- fortran complex
143*a9fa9459Szrj 			btDComplex	-- fortran double complex
144*a9fa9459Szrj 			btIndirect	-- forward or unnamed typedef
145*a9fa9459Szrj 			btFixedDec	-- Fixed Decimal
146*a9fa9459Szrj 			btFloatDec	-- Float Decimal
147*a9fa9459Szrj 			btString	-- Varying Length Character String
148*a9fa9459Szrj 			btBit		-- Aligned Bit String
149*a9fa9459Szrj 			btPicture	-- Picture
150*a9fa9459Szrj 			btVoid		-- Void (MIPS cc revision >= 2.00)
151*a9fa9459Szrj 
152*a9fa9459Szrj 	    d)	tq0 - tq5: type qualifier fields as needed.  The
153*a9fa9459Szrj 		current type qualifier fields I have documentation for
154*a9fa9459Szrj 		are:
155*a9fa9459Szrj 
156*a9fa9459Szrj 			tqNil		-- no more qualifiers
157*a9fa9459Szrj 			tqPtr		-- pointer
158*a9fa9459Szrj 			tqProc		-- procedure
159*a9fa9459Szrj 			tqArray		-- array
160*a9fa9459Szrj 			tqFar		-- 8086 far pointers
161*a9fa9459Szrj 			tqVol		-- volatile
162*a9fa9459Szrj 
163*a9fa9459Szrj    The dense number table is used in the front ends, and disappears by
164*a9fa9459Szrj    the time the .o is created.
165*a9fa9459Szrj 
166*a9fa9459Szrj    With the 1.31 compiler suite, the optimization symbols don't seem
167*a9fa9459Szrj    to be used as far as I can tell.
168*a9fa9459Szrj 
169*a9fa9459Szrj    The linker is the first entity that creates the relative file
170*a9fa9459Szrj    descriptor table, and I believe it is used so that the individual
171*a9fa9459Szrj    file table pointers don't have to be rewritten when the objects are
172*a9fa9459Szrj    merged together into the program file.
173*a9fa9459Szrj 
174*a9fa9459Szrj    Unlike COFF, the basic symbol & string tables are split into
175*a9fa9459Szrj    external and local symbols/strings.  The relocation information
176*a9fa9459Szrj    only goes off of the external symbol table, and the debug
177*a9fa9459Szrj    information only goes off of the internal symbol table.  The
178*a9fa9459Szrj    external symbols can have links to an appropriate file index and
179*a9fa9459Szrj    symbol within the file to give it the appropriate type information.
180*a9fa9459Szrj    Because of this, the external symbols are actually larger than the
181*a9fa9459Szrj    internal symbols (to contain the link information), and contain the
182*a9fa9459Szrj    local symbol structure as a member, though this member is not the
183*a9fa9459Szrj    first member of the external symbol structure (!).  I suspect this
184*a9fa9459Szrj    split is to make strip easier to deal with.
185*a9fa9459Szrj 
186*a9fa9459Szrj    Each file table has offsets for where the line numbers, local
187*a9fa9459Szrj    strings, local symbols, and procedure table starts from within the
188*a9fa9459Szrj    global tables, and the indexs are reset to 0 for each of those
189*a9fa9459Szrj    tables for the file.
190*a9fa9459Szrj 
191*a9fa9459Szrj    The procedure table contains the binary equivalents of the .ent
192*a9fa9459Szrj    (start of the function address), .frame (what register is the
193*a9fa9459Szrj    virtual frame pointer, constant offset from the register to obtain
194*a9fa9459Szrj    the VFP, and what register holds the return address), .mask/.fmask
195*a9fa9459Szrj    (bitmask of saved registers, and where the first register is stored
196*a9fa9459Szrj    relative to the VFP) assembler directives.  It also contains the
197*a9fa9459Szrj    low and high bounds of the line numbers if debugging is turned on.
198*a9fa9459Szrj 
199*a9fa9459Szrj    The line number table is a compressed form of the normal COFF line
200*a9fa9459Szrj    table.  Each line number entry is either 1 or 3 bytes long, and
201*a9fa9459Szrj    contains a signed delta from the previous line, and an unsigned
202*a9fa9459Szrj    count of the number of instructions this statement takes.
203*a9fa9459Szrj 
204*a9fa9459Szrj    The local symbol table contains the following fields:
205*a9fa9459Szrj 
206*a9fa9459Szrj     1)	iss: index to the local string table giving the name of the
207*a9fa9459Szrj 	symbol.
208*a9fa9459Szrj 
209*a9fa9459Szrj     2)	value: value of the symbol (address, register number, etc.).
210*a9fa9459Szrj 
211*a9fa9459Szrj     3)	st: symbol type.  The current symbol types are:
212*a9fa9459Szrj 
213*a9fa9459Szrj 	    stNil	  -- Nuthin' special
214*a9fa9459Szrj 	    stGlobal	  -- external symbol
215*a9fa9459Szrj 	    stStatic	  -- static
216*a9fa9459Szrj 	    stParam	  -- procedure argument
217*a9fa9459Szrj 	    stLocal	  -- local variable
218*a9fa9459Szrj 	    stLabel	  -- label
219*a9fa9459Szrj 	    stProc	  -- External Procedure
220*a9fa9459Szrj 	    stBlock	  -- beginning of block
221*a9fa9459Szrj 	    stEnd	  -- end (of anything)
222*a9fa9459Szrj 	    stMember	  -- member (of anything)
223*a9fa9459Szrj 	    stTypedef	  -- type definition
224*a9fa9459Szrj 	    stFile	  -- file name
225*a9fa9459Szrj 	    stRegReloc	  -- register relocation
226*a9fa9459Szrj 	    stForward	  -- forwarding address
227*a9fa9459Szrj 	    stStaticProc  -- Static procedure
228*a9fa9459Szrj 	    stConstant	  -- const
229*a9fa9459Szrj 
230*a9fa9459Szrj     4)	sc: storage class.  The current storage classes are:
231*a9fa9459Szrj 
232*a9fa9459Szrj 	    scText	  -- text symbol
233*a9fa9459Szrj 	    scData	  -- initialized data symbol
234*a9fa9459Szrj 	    scBss	  -- un-initialized data symbol
235*a9fa9459Szrj 	    scRegister	  -- value of symbol is register number
236*a9fa9459Szrj 	    scAbs	  -- value of symbol is absolute
237*a9fa9459Szrj 	    scUndefined   -- who knows?
238*a9fa9459Szrj 	    scCdbLocal	  -- variable's value is IN se->va.??
239*a9fa9459Szrj 	    scBits	  -- this is a bit field
240*a9fa9459Szrj 	    scCdbSystem	  -- value is IN debugger's address space
241*a9fa9459Szrj 	    scRegImage	  -- register value saved on stack
242*a9fa9459Szrj 	    scInfo	  -- symbol contains debugger information
243*a9fa9459Szrj 	    scUserStruct  -- addr in struct user for current process
244*a9fa9459Szrj 	    scSData	  -- load time only small data
245*a9fa9459Szrj 	    scSBss	  -- load time only small common
246*a9fa9459Szrj 	    scRData	  -- load time only read only data
247*a9fa9459Szrj 	    scVar	  -- Var parameter (fortranpascal)
248*a9fa9459Szrj 	    scCommon	  -- common variable
249*a9fa9459Szrj 	    scSCommon	  -- small common
250*a9fa9459Szrj 	    scVarRegister -- Var parameter in a register
251*a9fa9459Szrj 	    scVariant	  -- Variant record
252*a9fa9459Szrj 	    scSUndefined  -- small undefined(external) data
253*a9fa9459Szrj 	    scInit	  -- .init section symbol
254*a9fa9459Szrj 
255*a9fa9459Szrj     5)	index: pointer to a local symbol or aux. entry.
256*a9fa9459Szrj 
257*a9fa9459Szrj    For the following program:
258*a9fa9459Szrj 
259*a9fa9459Szrj 	#include <stdio.h>
260*a9fa9459Szrj 
261*a9fa9459Szrj 	main(){
262*a9fa9459Szrj 		printf("Hello World!\n");
263*a9fa9459Szrj 		return 0;
264*a9fa9459Szrj 	}
265*a9fa9459Szrj 
266*a9fa9459Szrj    Mips-tdump produces the following information:
267*a9fa9459Szrj 
268*a9fa9459Szrj    Global file header:
269*a9fa9459Szrj        magic number             0x162
270*a9fa9459Szrj        # sections               2
271*a9fa9459Szrj        timestamp                645311799, Wed Jun 13 17:16:39 1990
272*a9fa9459Szrj        symbolic header offset   284
273*a9fa9459Szrj        symbolic header size     96
274*a9fa9459Szrj        optional header          56
275*a9fa9459Szrj        flags                    0x0
276*a9fa9459Szrj 
277*a9fa9459Szrj    Symbolic header, magic number = 0x7009, vstamp = 1.31:
278*a9fa9459Szrj 
279*a9fa9459Szrj        Info                      Offset      Number       Bytes
280*a9fa9459Szrj        ====                      ======      ======      =====
281*a9fa9459Szrj 
282*a9fa9459Szrj        Line numbers                 380           4           4 [13]
283*a9fa9459Szrj        Dense numbers                  0           0           0
284*a9fa9459Szrj        Procedures Tables            384           1          52
285*a9fa9459Szrj        Local Symbols                436          16         192
286*a9fa9459Szrj        Optimization Symbols           0           0           0
287*a9fa9459Szrj        Auxiliary Symbols            628          39         156
288*a9fa9459Szrj        Local Strings                784          80          80
289*a9fa9459Szrj        External Strings             864         144         144
290*a9fa9459Szrj        File Tables                 1008           2         144
291*a9fa9459Szrj        Relative Files                 0           0           0
292*a9fa9459Szrj        External Symbols            1152          20         320
293*a9fa9459Szrj 
294*a9fa9459Szrj    File #0, "hello2.c"
295*a9fa9459Szrj 
296*a9fa9459Szrj        Name index  = 1          Readin      = No
297*a9fa9459Szrj        Merge       = No         Endian      = LITTLE
298*a9fa9459Szrj        Debug level = G2         Language    = C
299*a9fa9459Szrj        Adr         = 0x00000000
300*a9fa9459Szrj 
301*a9fa9459Szrj        Info                       Start      Number        Size      Offset
302*a9fa9459Szrj        ====                       =====      ======        ====      ======
303*a9fa9459Szrj        Local strings                  0          15          15         784
304*a9fa9459Szrj        Local symbols                  0           6          72         436
305*a9fa9459Szrj        Line numbers                   0          13          13         380
306*a9fa9459Szrj        Optimization symbols           0           0           0           0
307*a9fa9459Szrj        Procedures                     0           1          52         384
308*a9fa9459Szrj        Auxiliary symbols              0          14          56         628
309*a9fa9459Szrj        Relative Files                 0           0           0           0
310*a9fa9459Szrj 
311*a9fa9459Szrj     There are 6 local symbols, starting at 436
312*a9fa9459Szrj 
313*a9fa9459Szrj 	Symbol# 0: "hello2.c"
314*a9fa9459Szrj 	    End+1 symbol  = 6
315*a9fa9459Szrj 	    String index  = 1
316*a9fa9459Szrj 	    Storage class = Text        Index  = 6
317*a9fa9459Szrj 	    Symbol type   = File        Value  = 0
318*a9fa9459Szrj 
319*a9fa9459Szrj 	Symbol# 1: "main"
320*a9fa9459Szrj 	    End+1 symbol  = 5
321*a9fa9459Szrj 	    Type          = int
322*a9fa9459Szrj 	    String index  = 10
323*a9fa9459Szrj 	    Storage class = Text        Index  = 12
324*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
325*a9fa9459Szrj 
326*a9fa9459Szrj 	Symbol# 2: ""
327*a9fa9459Szrj 	    End+1 symbol  = 4
328*a9fa9459Szrj 	    String index  = 0
329*a9fa9459Szrj 	    Storage class = Text        Index  = 4
330*a9fa9459Szrj 	    Symbol type   = Block       Value  = 8
331*a9fa9459Szrj 
332*a9fa9459Szrj 	Symbol# 3: ""
333*a9fa9459Szrj 	    First symbol  = 2
334*a9fa9459Szrj 	    String index  = 0
335*a9fa9459Szrj 	    Storage class = Text        Index  = 2
336*a9fa9459Szrj 	    Symbol type   = End         Value  = 28
337*a9fa9459Szrj 
338*a9fa9459Szrj 	Symbol# 4: "main"
339*a9fa9459Szrj 	    First symbol  = 1
340*a9fa9459Szrj 	    String index  = 10
341*a9fa9459Szrj 	    Storage class = Text        Index  = 1
342*a9fa9459Szrj 	    Symbol type   = End         Value  = 52
343*a9fa9459Szrj 
344*a9fa9459Szrj 	Symbol# 5: "hello2.c"
345*a9fa9459Szrj 	    First symbol  = 0
346*a9fa9459Szrj 	    String index  = 1
347*a9fa9459Szrj 	    Storage class = Text        Index  = 0
348*a9fa9459Szrj 	    Symbol type   = End         Value  = 0
349*a9fa9459Szrj 
350*a9fa9459Szrj     There are 14 auxiliary table entries, starting at 628.
351*a9fa9459Szrj 
352*a9fa9459Szrj 	* #0               0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
353*a9fa9459Szrj 	* #1              24, [  24/      0], [ 6 0:0 0:0:0:0:0:0]
354*a9fa9459Szrj 	* #2               8, [   8/      0], [ 2 0:0 0:0:0:0:0:0]
355*a9fa9459Szrj 	* #3              16, [  16/      0], [ 4 0:0 0:0:0:0:0:0]
356*a9fa9459Szrj 	* #4              24, [  24/      0], [ 6 0:0 0:0:0:0:0:0]
357*a9fa9459Szrj 	* #5              32, [  32/      0], [ 8 0:0 0:0:0:0:0:0]
358*a9fa9459Szrj 	* #6              40, [  40/      0], [10 0:0 0:0:0:0:0:0]
359*a9fa9459Szrj 	* #7              44, [  44/      0], [11 0:0 0:0:0:0:0:0]
360*a9fa9459Szrj 	* #8              12, [  12/      0], [ 3 0:0 0:0:0:0:0:0]
361*a9fa9459Szrj 	* #9              20, [  20/      0], [ 5 0:0 0:0:0:0:0:0]
362*a9fa9459Szrj 	* #10             28, [  28/      0], [ 7 0:0 0:0:0:0:0:0]
363*a9fa9459Szrj 	* #11             36, [  36/      0], [ 9 0:0 0:0:0:0:0:0]
364*a9fa9459Szrj 	  #12              5, [   5/      0], [ 1 1:0 0:0:0:0:0:0]
365*a9fa9459Szrj 	  #13             24, [  24/      0], [ 6 0:0 0:0:0:0:0:0]
366*a9fa9459Szrj 
367*a9fa9459Szrj     There are 1 procedure descriptor entries, starting at 0.
368*a9fa9459Szrj 
369*a9fa9459Szrj 	Procedure descriptor 0:
370*a9fa9459Szrj 	    Name index   = 10          Name          = "main"
371*a9fa9459Szrj 	    .mask 0x80000000,-4        .fmask 0x00000000,0
372*a9fa9459Szrj 	    .frame $29,24,$31
373*a9fa9459Szrj 	    Opt. start   = -1          Symbols start = 1
374*a9fa9459Szrj 	    First line # = 3           Last line #   = 6
375*a9fa9459Szrj 	    Line Offset  = 0           Address       = 0x00000000
376*a9fa9459Szrj 
377*a9fa9459Szrj 	There are 4 bytes holding line numbers, starting at 380.
378*a9fa9459Szrj 	    Line           3,   delta     0,   count  2
379*a9fa9459Szrj 	    Line           4,   delta     1,   count  3
380*a9fa9459Szrj 	    Line           5,   delta     1,   count  2
381*a9fa9459Szrj 	    Line           6,   delta     1,   count  6
382*a9fa9459Szrj 
383*a9fa9459Szrj    File #1, "/usr/include/stdio.h"
384*a9fa9459Szrj 
385*a9fa9459Szrj     Name index  = 1          Readin      = No
386*a9fa9459Szrj     Merge       = Yes        Endian      = LITTLE
387*a9fa9459Szrj     Debug level = G2         Language    = C
388*a9fa9459Szrj     Adr         = 0x00000000
389*a9fa9459Szrj 
390*a9fa9459Szrj     Info                       Start      Number        Size      Offset
391*a9fa9459Szrj     ====                       =====      ======        ====      ======
392*a9fa9459Szrj     Local strings                 15          65          65         799
393*a9fa9459Szrj     Local symbols                  6          10         120         508
394*a9fa9459Szrj     Line numbers                   0           0           0         380
395*a9fa9459Szrj     Optimization symbols           0           0           0           0
396*a9fa9459Szrj     Procedures                     1           0           0         436
397*a9fa9459Szrj     Auxiliary symbols             14          25         100         684
398*a9fa9459Szrj     Relative Files                 0           0           0           0
399*a9fa9459Szrj 
400*a9fa9459Szrj     There are 10 local symbols, starting at 442
401*a9fa9459Szrj 
402*a9fa9459Szrj 	Symbol# 0: "/usr/include/stdio.h"
403*a9fa9459Szrj 	    End+1 symbol  = 10
404*a9fa9459Szrj 	    String index  = 1
405*a9fa9459Szrj 	    Storage class = Text        Index  = 10
406*a9fa9459Szrj 	    Symbol type   = File        Value  = 0
407*a9fa9459Szrj 
408*a9fa9459Szrj 	Symbol# 1: "_iobuf"
409*a9fa9459Szrj 	    End+1 symbol  = 9
410*a9fa9459Szrj 	    String index  = 22
411*a9fa9459Szrj 	    Storage class = Info        Index  = 9
412*a9fa9459Szrj 	    Symbol type   = Block       Value  = 20
413*a9fa9459Szrj 
414*a9fa9459Szrj 	Symbol# 2: "_cnt"
415*a9fa9459Szrj 	    Type          = int
416*a9fa9459Szrj 	    String index  = 29
417*a9fa9459Szrj 	    Storage class = Info        Index  = 4
418*a9fa9459Szrj 	    Symbol type   = Member      Value  = 0
419*a9fa9459Szrj 
420*a9fa9459Szrj 	Symbol# 3: "_ptr"
421*a9fa9459Szrj 	    Type          = ptr to char
422*a9fa9459Szrj 	    String index  = 34
423*a9fa9459Szrj 	    Storage class = Info        Index  = 15
424*a9fa9459Szrj 	    Symbol type   = Member      Value  = 32
425*a9fa9459Szrj 
426*a9fa9459Szrj 	Symbol# 4: "_base"
427*a9fa9459Szrj 	    Type          = ptr to char
428*a9fa9459Szrj 	    String index  = 39
429*a9fa9459Szrj 	    Storage class = Info        Index  = 16
430*a9fa9459Szrj 	    Symbol type   = Member      Value  = 64
431*a9fa9459Szrj 
432*a9fa9459Szrj 	Symbol# 5: "_bufsiz"
433*a9fa9459Szrj 	    Type          = int
434*a9fa9459Szrj 	    String index  = 45
435*a9fa9459Szrj 	    Storage class = Info        Index  = 4
436*a9fa9459Szrj 	    Symbol type   = Member      Value  = 96
437*a9fa9459Szrj 
438*a9fa9459Szrj 	Symbol# 6: "_flag"
439*a9fa9459Szrj 	    Type          = short
440*a9fa9459Szrj 	    String index  = 53
441*a9fa9459Szrj 	    Storage class = Info        Index  = 3
442*a9fa9459Szrj 	    Symbol type   = Member      Value  = 128
443*a9fa9459Szrj 
444*a9fa9459Szrj 	Symbol# 7: "_file"
445*a9fa9459Szrj 	    Type          = char
446*a9fa9459Szrj 	    String index  = 59
447*a9fa9459Szrj 	    Storage class = Info        Index  = 2
448*a9fa9459Szrj 	    Symbol type   = Member      Value  = 144
449*a9fa9459Szrj 
450*a9fa9459Szrj 	Symbol# 8: ""
451*a9fa9459Szrj 	    First symbol  = 1
452*a9fa9459Szrj 	    String index  = 0
453*a9fa9459Szrj 	    Storage class = Info        Index  = 1
454*a9fa9459Szrj 	    Symbol type   = End         Value  = 0
455*a9fa9459Szrj 
456*a9fa9459Szrj 	Symbol# 9: "/usr/include/stdio.h"
457*a9fa9459Szrj 	    First symbol  = 0
458*a9fa9459Szrj 	    String index  = 1
459*a9fa9459Szrj 	    Storage class = Text        Index  = 0
460*a9fa9459Szrj 	    Symbol type   = End         Value  = 0
461*a9fa9459Szrj 
462*a9fa9459Szrj     There are 25 auxiliary table entries, starting at 642.
463*a9fa9459Szrj 
464*a9fa9459Szrj 	* #14             -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
465*a9fa9459Szrj 	  #15          65544, [   8/     16], [ 2 0:0 1:0:0:0:0:0]
466*a9fa9459Szrj 	  #16          65544, [   8/     16], [ 2 0:0 1:0:0:0:0:0]
467*a9fa9459Szrj 	* #17         196656, [  48/     48], [12 0:0 3:0:0:0:0:0]
468*a9fa9459Szrj 	* #18           8191, [4095/      1], [63 1:1 0:0:0:0:f:1]
469*a9fa9459Szrj 	* #19              1, [   1/      0], [ 0 1:0 0:0:0:0:0:0]
470*a9fa9459Szrj 	* #20          20479, [4095/      4], [63 1:1 0:0:0:0:f:4]
471*a9fa9459Szrj 	* #21              1, [   1/      0], [ 0 1:0 0:0:0:0:0:0]
472*a9fa9459Szrj 	* #22              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
473*a9fa9459Szrj 	* #23              2, [   2/      0], [ 0 0:1 0:0:0:0:0:0]
474*a9fa9459Szrj 	* #24            160, [ 160/      0], [40 0:0 0:0:0:0:0:0]
475*a9fa9459Szrj 	* #25              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
476*a9fa9459Szrj 	* #26              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
477*a9fa9459Szrj 	* #27              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
478*a9fa9459Szrj 	* #28              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
479*a9fa9459Szrj 	* #29              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
480*a9fa9459Szrj 	* #30              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
481*a9fa9459Szrj 	* #31              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
482*a9fa9459Szrj 	* #32              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
483*a9fa9459Szrj 	* #33              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
484*a9fa9459Szrj 	* #34              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
485*a9fa9459Szrj 	* #35              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
486*a9fa9459Szrj 	* #36              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
487*a9fa9459Szrj 	* #37              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
488*a9fa9459Szrj 	* #38              0, [   0/      0], [ 0 0:0 0:0:0:0:0:0]
489*a9fa9459Szrj 
490*a9fa9459Szrj     There are 0 procedure descriptor entries, starting at 1.
491*a9fa9459Szrj 
492*a9fa9459Szrj    There are 20 external symbols, starting at 1152
493*a9fa9459Szrj 
494*a9fa9459Szrj 	Symbol# 0: "_iob"
495*a9fa9459Szrj 	    Type          = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
496*a9fa9459Szrj 	    String index  = 0           Ifd    = 1
497*a9fa9459Szrj 	    Storage class = Nil         Index  = 17
498*a9fa9459Szrj 	    Symbol type   = Global      Value  = 60
499*a9fa9459Szrj 
500*a9fa9459Szrj 	Symbol# 1: "fopen"
501*a9fa9459Szrj 	    String index  = 5           Ifd    = 1
502*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
503*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
504*a9fa9459Szrj 
505*a9fa9459Szrj 	Symbol# 2: "fdopen"
506*a9fa9459Szrj 	    String index  = 11          Ifd    = 1
507*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
508*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
509*a9fa9459Szrj 
510*a9fa9459Szrj 	Symbol# 3: "freopen"
511*a9fa9459Szrj 	    String index  = 18          Ifd    = 1
512*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
513*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
514*a9fa9459Szrj 
515*a9fa9459Szrj 	Symbol# 4: "popen"
516*a9fa9459Szrj 	    String index  = 26          Ifd    = 1
517*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
518*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
519*a9fa9459Szrj 
520*a9fa9459Szrj 	Symbol# 5: "tmpfile"
521*a9fa9459Szrj 	    String index  = 32          Ifd    = 1
522*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
523*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
524*a9fa9459Szrj 
525*a9fa9459Szrj 	Symbol# 6: "ftell"
526*a9fa9459Szrj 	    String index  = 40          Ifd    = 1
527*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
528*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
529*a9fa9459Szrj 
530*a9fa9459Szrj 	Symbol# 7: "rewind"
531*a9fa9459Szrj 	    String index  = 46          Ifd    = 1
532*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
533*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
534*a9fa9459Szrj 
535*a9fa9459Szrj 	Symbol# 8: "setbuf"
536*a9fa9459Szrj 	    String index  = 53          Ifd    = 1
537*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
538*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
539*a9fa9459Szrj 
540*a9fa9459Szrj 	Symbol# 9: "setbuffer"
541*a9fa9459Szrj 	    String index  = 60          Ifd    = 1
542*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
543*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
544*a9fa9459Szrj 
545*a9fa9459Szrj 	Symbol# 10: "setlinebuf"
546*a9fa9459Szrj 	    String index  = 70          Ifd    = 1
547*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
548*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
549*a9fa9459Szrj 
550*a9fa9459Szrj 	Symbol# 11: "fgets"
551*a9fa9459Szrj 	    String index  = 81          Ifd    = 1
552*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
553*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
554*a9fa9459Szrj 
555*a9fa9459Szrj 	Symbol# 12: "gets"
556*a9fa9459Szrj 	    String index  = 87          Ifd    = 1
557*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
558*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
559*a9fa9459Szrj 
560*a9fa9459Szrj 	Symbol# 13: "ctermid"
561*a9fa9459Szrj 	    String index  = 92          Ifd    = 1
562*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
563*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
564*a9fa9459Szrj 
565*a9fa9459Szrj 	Symbol# 14: "cuserid"
566*a9fa9459Szrj 	    String index  = 100         Ifd    = 1
567*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
568*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
569*a9fa9459Szrj 
570*a9fa9459Szrj 	Symbol# 15: "tempnam"
571*a9fa9459Szrj 	    String index  = 108         Ifd    = 1
572*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
573*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
574*a9fa9459Szrj 
575*a9fa9459Szrj 	Symbol# 16: "tmpnam"
576*a9fa9459Szrj 	    String index  = 116         Ifd    = 1
577*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
578*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
579*a9fa9459Szrj 
580*a9fa9459Szrj 	Symbol# 17: "sprintf"
581*a9fa9459Szrj 	    String index  = 123         Ifd    = 1
582*a9fa9459Szrj 	    Storage class = Nil         Index  = 1048575
583*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
584*a9fa9459Szrj 
585*a9fa9459Szrj 	Symbol# 18: "main"
586*a9fa9459Szrj 	    Type          = int
587*a9fa9459Szrj 	    String index  = 131         Ifd    = 0
588*a9fa9459Szrj 	    Storage class = Text        Index  = 1
589*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
590*a9fa9459Szrj 
591*a9fa9459Szrj 	Symbol# 19: "printf"
592*a9fa9459Szrj 	    String index  = 136         Ifd    = 0
593*a9fa9459Szrj 	    Storage class = Undefined   Index  = 1048575
594*a9fa9459Szrj 	    Symbol type   = Proc        Value  = 0
595*a9fa9459Szrj 
596*a9fa9459Szrj    The following auxiliary table entries were unused:
597*a9fa9459Szrj 
598*a9fa9459Szrj     #0               0  0x00000000  void
599*a9fa9459Szrj     #2               8  0x00000008  char
600*a9fa9459Szrj     #3              16  0x00000010  short
601*a9fa9459Szrj     #4              24  0x00000018  int
602*a9fa9459Szrj     #5              32  0x00000020  long
603*a9fa9459Szrj     #6              40  0x00000028  float
604*a9fa9459Szrj     #7              44  0x0000002c  double
605*a9fa9459Szrj     #8              12  0x0000000c  unsigned char
606*a9fa9459Szrj     #9              20  0x00000014  unsigned short
607*a9fa9459Szrj     #10             28  0x0000001c  unsigned int
608*a9fa9459Szrj     #11             36  0x00000024  unsigned long
609*a9fa9459Szrj     #14              0  0x00000000  void
610*a9fa9459Szrj     #15             24  0x00000018  int
611*a9fa9459Szrj     #19             32  0x00000020  long
612*a9fa9459Szrj     #20             40  0x00000028  float
613*a9fa9459Szrj     #21             44  0x0000002c  double
614*a9fa9459Szrj     #22             12  0x0000000c  unsigned char
615*a9fa9459Szrj     #23             20  0x00000014  unsigned short
616*a9fa9459Szrj     #24             28  0x0000001c  unsigned int
617*a9fa9459Szrj     #25             36  0x00000024  unsigned long
618*a9fa9459Szrj     #26             48  0x00000030  struct no name { ifd = -1, index = 1048575 }
619*a9fa9459Szrj */
620*a9fa9459Szrj 
621*a9fa9459Szrj /* Redefinition of of storage classes as an enumeration for better
622*a9fa9459Szrj    debugging.  */
623*a9fa9459Szrj 
624*a9fa9459Szrj typedef enum sc {
625*a9fa9459Szrj   sc_Nil	 = scNil,	  /* no storage class */
626*a9fa9459Szrj   sc_Text	 = scText,	  /* text symbol */
627*a9fa9459Szrj   sc_Data	 = scData,	  /* initialized data symbol */
628*a9fa9459Szrj   sc_Bss	 = scBss,	  /* un-initialized data symbol */
629*a9fa9459Szrj   sc_Register	 = scRegister,	  /* value of symbol is register number */
630*a9fa9459Szrj   sc_Abs	 = scAbs,	  /* value of symbol is absolute */
631*a9fa9459Szrj   sc_Undefined	 = scUndefined,	  /* who knows? */
632*a9fa9459Szrj   sc_CdbLocal	 = scCdbLocal,	  /* variable's value is IN se->va.?? */
633*a9fa9459Szrj   sc_Bits	 = scBits,	  /* this is a bit field */
634*a9fa9459Szrj   sc_CdbSystem	 = scCdbSystem,	  /* value is IN CDB's address space */
635*a9fa9459Szrj   sc_RegImage	 = scRegImage,	  /* register value saved on stack */
636*a9fa9459Szrj   sc_Info	 = scInfo,	  /* symbol contains debugger information */
637*a9fa9459Szrj   sc_UserStruct	 = scUserStruct,  /* addr in struct user for current process */
638*a9fa9459Szrj   sc_SData	 = scSData,	  /* load time only small data */
639*a9fa9459Szrj   sc_SBss	 = scSBss,	  /* load time only small common */
640*a9fa9459Szrj   sc_RData	 = scRData,	  /* load time only read only data */
641*a9fa9459Szrj   sc_Var	 = scVar,	  /* Var parameter (fortran,pascal) */
642*a9fa9459Szrj   sc_Common	 = scCommon,	  /* common variable */
643*a9fa9459Szrj   sc_SCommon	 = scSCommon,	  /* small common */
644*a9fa9459Szrj   sc_VarRegister = scVarRegister, /* Var parameter in a register */
645*a9fa9459Szrj   sc_Variant	 = scVariant,	  /* Variant record */
646*a9fa9459Szrj   sc_SUndefined	 = scSUndefined,  /* small undefined(external) data */
647*a9fa9459Szrj   sc_Init	 = scInit,	  /* .init section symbol */
648*a9fa9459Szrj   sc_Max	 = scMax	  /* Max storage class+1 */
649*a9fa9459Szrj } sc_t;
650*a9fa9459Szrj 
651*a9fa9459Szrj /* Redefinition of symbol type.  */
652*a9fa9459Szrj 
653*a9fa9459Szrj typedef enum st {
654*a9fa9459Szrj   st_Nil	= stNil,	/* Nuthin' special */
655*a9fa9459Szrj   st_Global	= stGlobal,	/* external symbol */
656*a9fa9459Szrj   st_Static	= stStatic,	/* static */
657*a9fa9459Szrj   st_Param	= stParam,	/* procedure argument */
658*a9fa9459Szrj   st_Local	= stLocal,	/* local variable */
659*a9fa9459Szrj   st_Label	= stLabel,	/* label */
660*a9fa9459Szrj   st_Proc	= stProc,	/*     "      "	 Procedure */
661*a9fa9459Szrj   st_Block	= stBlock,	/* beginning of block */
662*a9fa9459Szrj   st_End	= stEnd,	/* end (of anything) */
663*a9fa9459Szrj   st_Member	= stMember,	/* member (of anything	- struct/union/enum */
664*a9fa9459Szrj   st_Typedef	= stTypedef,	/* type definition */
665*a9fa9459Szrj   st_File	= stFile,	/* file name */
666*a9fa9459Szrj   st_RegReloc	= stRegReloc,	/* register relocation */
667*a9fa9459Szrj   st_Forward	= stForward,	/* forwarding address */
668*a9fa9459Szrj   st_StaticProc	= stStaticProc,	/* load time only static procs */
669*a9fa9459Szrj   st_Constant	= stConstant,	/* const */
670*a9fa9459Szrj   st_Str	= stStr,	/* string */
671*a9fa9459Szrj   st_Number	= stNumber,	/* pure number (ie. 4 NOR 2+2) */
672*a9fa9459Szrj   st_Expr	= stExpr,	/* 2+2 vs. 4 */
673*a9fa9459Szrj   st_Type	= stType,	/* post-coercion SER */
674*a9fa9459Szrj   st_Max	= stMax		/* max type+1 */
675*a9fa9459Szrj } st_t;
676*a9fa9459Szrj 
677*a9fa9459Szrj /* Redefinition of type qualifiers.  */
678*a9fa9459Szrj 
679*a9fa9459Szrj typedef enum tq {
680*a9fa9459Szrj   tq_Nil	= tqNil,	/* bt is what you see */
681*a9fa9459Szrj   tq_Ptr	= tqPtr,	/* pointer */
682*a9fa9459Szrj   tq_Proc	= tqProc,	/* procedure */
683*a9fa9459Szrj   tq_Array	= tqArray,	/* duh */
684*a9fa9459Szrj   tq_Far	= tqFar,	/* longer addressing - 8086/8 land */
685*a9fa9459Szrj   tq_Vol	= tqVol,	/* volatile */
686*a9fa9459Szrj   tq_Max	= tqMax		/* Max type qualifier+1 */
687*a9fa9459Szrj } tq_t;
688*a9fa9459Szrj 
689*a9fa9459Szrj /* Redefinition of basic types.  */
690*a9fa9459Szrj 
691*a9fa9459Szrj typedef enum bt {
692*a9fa9459Szrj   bt_Nil	= btNil,	/* undefined */
693*a9fa9459Szrj   bt_Adr	= btAdr,	/* address - integer same size as pointer */
694*a9fa9459Szrj   bt_Char	= btChar,	/* character */
695*a9fa9459Szrj   bt_UChar	= btUChar,	/* unsigned character */
696*a9fa9459Szrj   bt_Short	= btShort,	/* short */
697*a9fa9459Szrj   bt_UShort	= btUShort,	/* unsigned short */
698*a9fa9459Szrj   bt_Int	= btInt,	/* int */
699*a9fa9459Szrj   bt_UInt	= btUInt,	/* unsigned int */
700*a9fa9459Szrj   bt_Long	= btLong,	/* long */
701*a9fa9459Szrj   bt_ULong	= btULong,	/* unsigned long */
702*a9fa9459Szrj   bt_Float	= btFloat,	/* float (real) */
703*a9fa9459Szrj   bt_Double	= btDouble,	/* Double (real) */
704*a9fa9459Szrj   bt_Struct	= btStruct,	/* Structure (Record) */
705*a9fa9459Szrj   bt_Union	= btUnion,	/* Union (variant) */
706*a9fa9459Szrj   bt_Enum	= btEnum,	/* Enumerated */
707*a9fa9459Szrj   bt_Typedef	= btTypedef,	/* defined via a typedef, isymRef points */
708*a9fa9459Szrj   bt_Range	= btRange,	/* subrange of int */
709*a9fa9459Szrj   bt_Set	= btSet,	/* pascal sets */
710*a9fa9459Szrj   bt_Complex	= btComplex,	/* fortran complex */
711*a9fa9459Szrj   bt_DComplex	= btDComplex,	/* fortran double complex */
712*a9fa9459Szrj   bt_Indirect	= btIndirect,	/* forward or unnamed typedef */
713*a9fa9459Szrj   bt_FixedDec	= btFixedDec,	/* Fixed Decimal */
714*a9fa9459Szrj   bt_FloatDec	= btFloatDec,	/* Float Decimal */
715*a9fa9459Szrj   bt_String	= btString,	/* Varying Length Character String */
716*a9fa9459Szrj   bt_Bit	= btBit,	/* Aligned Bit String */
717*a9fa9459Szrj   bt_Picture	= btPicture,	/* Picture */
718*a9fa9459Szrj   bt_Void	= btVoid,	/* Void */
719*a9fa9459Szrj   bt_Max	= btMax		/* Max basic type+1 */
720*a9fa9459Szrj } bt_t;
721*a9fa9459Szrj 
722*a9fa9459Szrj #define N_TQ itqMax
723*a9fa9459Szrj 
724*a9fa9459Szrj /* States for whether to hash type or not.  */
725*a9fa9459Szrj typedef enum hash_state {
726*a9fa9459Szrj   hash_no	= 0,		/* Don't hash type */
727*a9fa9459Szrj   hash_yes	= 1,		/* OK to hash type, or use previous hash */
728*a9fa9459Szrj   hash_record	= 2		/* OK to record hash, but don't use prev.  */
729*a9fa9459Szrj } hash_state_t;
730*a9fa9459Szrj 
731*a9fa9459Szrj /* Types of different sized allocation requests.  */
732*a9fa9459Szrj enum alloc_type {
733*a9fa9459Szrj   alloc_type_none,		/* dummy value */
734*a9fa9459Szrj   alloc_type_scope,		/* nested scopes linked list */
735*a9fa9459Szrj   alloc_type_vlinks,		/* glue linking pages in varray */
736*a9fa9459Szrj   alloc_type_shash,		/* string hash element */
737*a9fa9459Szrj   alloc_type_thash,		/* type hash element */
738*a9fa9459Szrj   alloc_type_tag,		/* struct/union/tag element */
739*a9fa9459Szrj   alloc_type_forward,		/* element to hold unknown tag */
740*a9fa9459Szrj   alloc_type_thead,		/* head of type hash list */
741*a9fa9459Szrj   alloc_type_varray,		/* general varray allocation */
742*a9fa9459Szrj   alloc_type_lineno,		/* line number list */
743*a9fa9459Szrj   alloc_type_last		/* last+1 element for array bounds */
744*a9fa9459Szrj };
745*a9fa9459Szrj 
746*a9fa9459Szrj /* Types of auxiliary type information.  */
747*a9fa9459Szrj enum aux_type {
748*a9fa9459Szrj   aux_tir,			/* TIR type information */
749*a9fa9459Szrj   aux_rndx,			/* relative index into symbol table */
750*a9fa9459Szrj   aux_dnLow,			/* low dimension */
751*a9fa9459Szrj   aux_dnHigh,			/* high dimension */
752*a9fa9459Szrj   aux_isym,			/* symbol table index (end of proc) */
753*a9fa9459Szrj   aux_iss,			/* index into string space (not used) */
754*a9fa9459Szrj   aux_width,			/* width for non-default sized struc fields */
755*a9fa9459Szrj   aux_count			/* count of ranges for variant arm */
756*a9fa9459Szrj };
757*a9fa9459Szrj 
758*a9fa9459Szrj /* Structures to provide n-number of virtual arrays, each of which can
759*a9fa9459Szrj    grow linearly, and which are written in the object file as
760*a9fa9459Szrj    sequential pages.  On systems with a BSD malloc, the
761*a9fa9459Szrj    MAX_CLUSTER_PAGES should be 1 less than a power of two, since
762*a9fa9459Szrj    malloc adds it's overhead, and rounds up to the next power of 2.
763*a9fa9459Szrj    Pages are linked together via a linked list.
764*a9fa9459Szrj 
765*a9fa9459Szrj    If PAGE_SIZE is > 4096, the string length in the shash_t structure
766*a9fa9459Szrj    can't be represented (assuming there are strings > 4096 bytes).  */
767*a9fa9459Szrj 
768*a9fa9459Szrj /* FIXME: Yes, there can be such strings while emitting C++ class debug
769*a9fa9459Szrj    info.  Templates are the offender here, the test case in question
770*a9fa9459Szrj    having a mangled class name of
771*a9fa9459Szrj 
772*a9fa9459Szrj      t7rb_tree4Z4xkeyZt4pair2ZC4xkeyZt7xsocket1Z4UserZt9select1st2Zt4pair\
773*a9fa9459Szrj      2ZC4xkeyZt7xsocket1Z4UserZ4xkeyZt4less1Z4xkey
774*a9fa9459Szrj 
775*a9fa9459Szrj    Repeat that a couple dozen times while listing the class members and
776*a9fa9459Szrj    you've got strings over 4k.  Hack around this for now by increasing
777*a9fa9459Szrj    the page size.  A proper solution would abandon this structure scheme
778*a9fa9459Szrj    certainly for very large strings, and possibly entirely.  */
779*a9fa9459Szrj 
780*a9fa9459Szrj #ifndef PAGE_SIZE
781*a9fa9459Szrj #define PAGE_SIZE (8*1024)	/* size of varray pages */
782*a9fa9459Szrj #endif
783*a9fa9459Szrj 
784*a9fa9459Szrj #define PAGE_USIZE ((unsigned long) PAGE_SIZE)
785*a9fa9459Szrj 
786*a9fa9459Szrj #ifndef MAX_CLUSTER_PAGES	/* # pages to get from system */
787*a9fa9459Szrj #define MAX_CLUSTER_PAGES 63
788*a9fa9459Szrj #endif
789*a9fa9459Szrj 
790*a9fa9459Szrj /* Linked list connecting separate page allocations.  */
791*a9fa9459Szrj typedef struct vlinks {
792*a9fa9459Szrj   struct vlinks	*prev;		/* previous set of pages */
793*a9fa9459Szrj   struct vlinks *next;		/* next set of pages */
794*a9fa9459Szrj   union  page   *datum;		/* start of page */
795*a9fa9459Szrj   unsigned long	 start_index;	/* starting index # of page */
796*a9fa9459Szrj } vlinks_t;
797*a9fa9459Szrj 
798*a9fa9459Szrj /* Virtual array header.  */
799*a9fa9459Szrj typedef struct varray {
800*a9fa9459Szrj   vlinks_t	*first;			/* first page link */
801*a9fa9459Szrj   vlinks_t	*last;			/* last page link */
802*a9fa9459Szrj   unsigned long	 num_allocated;		/* # objects allocated */
803*a9fa9459Szrj   unsigned short object_size;		/* size in bytes of each object */
804*a9fa9459Szrj   unsigned short objects_per_page;	/* # objects that can fit on a page */
805*a9fa9459Szrj   unsigned short objects_last_page;	/* # objects allocated on last page */
806*a9fa9459Szrj } varray_t;
807*a9fa9459Szrj 
808*a9fa9459Szrj #ifndef MALLOC_CHECK
809*a9fa9459Szrj #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
810*a9fa9459Szrj #else
811*a9fa9459Szrj #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
812*a9fa9459Szrj #endif
813*a9fa9459Szrj 
814*a9fa9459Szrj #define INIT_VARRAY(type) {	/* macro to initialize a varray */	\
815*a9fa9459Szrj   (vlinks_t *)0,		/* first */				\
816*a9fa9459Szrj   (vlinks_t *)0,		/* last */				\
817*a9fa9459Szrj   0,				/* num_allocated */			\
818*a9fa9459Szrj   sizeof (type),		/* object_size */			\
819*a9fa9459Szrj   OBJECTS_PER_PAGE (type),	/* objects_per_page */			\
820*a9fa9459Szrj   OBJECTS_PER_PAGE (type),	/* objects_last_page */			\
821*a9fa9459Szrj }
822*a9fa9459Szrj 
823*a9fa9459Szrj /* Master type for indexes within the symbol table.  */
824*a9fa9459Szrj typedef unsigned long symint_t;
825*a9fa9459Szrj 
826*a9fa9459Szrj /* Linked list support for nested scopes (file, block, structure, etc.).  */
827*a9fa9459Szrj typedef struct scope {
828*a9fa9459Szrj   struct scope	*prev;		/* previous scope level */
829*a9fa9459Szrj   struct scope	*free;		/* free list pointer */
830*a9fa9459Szrj   struct localsym *lsym;	/* pointer to local symbol node */
831*a9fa9459Szrj   st_t		 type;		/* type of the node */
832*a9fa9459Szrj } scope_t;
833*a9fa9459Szrj 
834*a9fa9459Szrj /* For a local symbol we store a gas symbol as well as the debugging
835*a9fa9459Szrj    information we generate.  The gas symbol will be NULL if this is
836*a9fa9459Szrj    only a debugging symbol.  */
837*a9fa9459Szrj typedef struct localsym {
838*a9fa9459Szrj   const char *name;		/* symbol name */
839*a9fa9459Szrj   symbolS *as_sym;		/* symbol as seen by gas */
840*a9fa9459Szrj   bfd_vma addend;		/* addend to as_sym value */
841*a9fa9459Szrj   struct efdr *file_ptr;	/* file pointer */
842*a9fa9459Szrj   struct ecoff_proc *proc_ptr;	/* proc pointer */
843*a9fa9459Szrj   struct localsym *begin_ptr;	/* symbol at start of block */
844*a9fa9459Szrj   struct ecoff_aux *index_ptr;	/* index value to be filled in */
845*a9fa9459Szrj   struct forward *forward_ref;	/* forward references to this symbol */
846*a9fa9459Szrj   long sym_index;		/* final symbol index */
847*a9fa9459Szrj   EXTR ecoff_sym;		/* ECOFF debugging symbol */
848*a9fa9459Szrj } localsym_t;
849*a9fa9459Szrj 
850*a9fa9459Szrj /* For aux information we keep the type and the data.  */
851*a9fa9459Szrj typedef struct ecoff_aux {
852*a9fa9459Szrj   enum aux_type type;		/* aux type */
853*a9fa9459Szrj   AUXU data;			/* aux data */
854*a9fa9459Szrj } aux_t;
855*a9fa9459Szrj 
856*a9fa9459Szrj /* For a procedure we store the gas symbol as well as the PDR
857*a9fa9459Szrj    debugging information.  */
858*a9fa9459Szrj typedef struct ecoff_proc {
859*a9fa9459Szrj   localsym_t *sym;		/* associated symbol */
860*a9fa9459Szrj   PDR pdr;			/* ECOFF debugging info */
861*a9fa9459Szrj } proc_t;
862*a9fa9459Szrj 
863*a9fa9459Szrj /* Number of proc_t structures allocated.  */
864*a9fa9459Szrj static unsigned long proc_cnt;
865*a9fa9459Szrj 
866*a9fa9459Szrj /* Forward reference list for tags referenced, but not yet defined.  */
867*a9fa9459Szrj typedef struct forward {
868*a9fa9459Szrj   struct forward *next;		/* next forward reference */
869*a9fa9459Szrj   struct forward *free;		/* free list pointer */
870*a9fa9459Szrj   aux_t		 *ifd_ptr;	/* pointer to store file index */
871*a9fa9459Szrj   aux_t		 *index_ptr;	/* pointer to store symbol index */
872*a9fa9459Szrj } forward_t;
873*a9fa9459Szrj 
874*a9fa9459Szrj /* Linked list support for tags.  The first tag in the list is always
875*a9fa9459Szrj    the current tag for that block.  */
876*a9fa9459Szrj typedef struct tag {
877*a9fa9459Szrj   struct tag	 *free;		/* free list pointer */
878*a9fa9459Szrj   struct shash	 *hash_ptr;	/* pointer to the hash table head */
879*a9fa9459Szrj   struct tag	 *same_name;	/* tag with same name in outer scope */
880*a9fa9459Szrj   struct tag	 *same_block;	/* next tag defined in the same block.  */
881*a9fa9459Szrj   struct forward *forward_ref;	/* list of forward references */
882*a9fa9459Szrj   bt_t		  basic_type;	/* bt_Struct, bt_Union, or bt_Enum */
883*a9fa9459Szrj   symint_t	  ifd;		/* file # tag defined in */
884*a9fa9459Szrj   localsym_t	 *sym;		/* file's local symbols */
885*a9fa9459Szrj } tag_t;
886*a9fa9459Szrj 
887*a9fa9459Szrj /* Head of a block's linked list of tags.  */
888*a9fa9459Szrj typedef struct thead {
889*a9fa9459Szrj   struct thead	*prev;		/* previous block */
890*a9fa9459Szrj   struct thead	*free;		/* free list pointer */
891*a9fa9459Szrj   struct tag	*first_tag;	/* first tag in block defined */
892*a9fa9459Szrj } thead_t;
893*a9fa9459Szrj 
894*a9fa9459Szrj /* Union containing pointers to each the small structures which are freed up.  */
895*a9fa9459Szrj typedef union small_free {
896*a9fa9459Szrj   scope_t	*f_scope;	/* scope structure */
897*a9fa9459Szrj   thead_t	*f_thead;	/* tag head structure */
898*a9fa9459Szrj   tag_t		*f_tag;		/* tag element structure */
899*a9fa9459Szrj   forward_t	*f_forward;	/* forward tag reference */
900*a9fa9459Szrj } small_free_t;
901*a9fa9459Szrj 
902*a9fa9459Szrj /* String hash table entry.  */
903*a9fa9459Szrj 
904*a9fa9459Szrj typedef struct shash {
905*a9fa9459Szrj   char		*string;	/* string we are hashing */
906*a9fa9459Szrj   symint_t	 indx;		/* index within string table */
907*a9fa9459Szrj   EXTR		*esym_ptr;	/* global symbol pointer */
908*a9fa9459Szrj   localsym_t	*sym_ptr;	/* local symbol pointer */
909*a9fa9459Szrj   localsym_t	*end_ptr;	/* symbol pointer to end block */
910*a9fa9459Szrj   tag_t		*tag_ptr;	/* tag pointer */
911*a9fa9459Szrj   proc_t	*proc_ptr;	/* procedure descriptor pointer */
912*a9fa9459Szrj } shash_t;
913*a9fa9459Szrj 
914*a9fa9459Szrj /* Type hash table support.  The size of the hash table must fit
915*a9fa9459Szrj    within a page with the other extended file descriptor information.
916*a9fa9459Szrj    Because unique types which are hashed are fewer in number than
917*a9fa9459Szrj    strings, we use a smaller hash value.  */
918*a9fa9459Szrj 
919*a9fa9459Szrj #define HASHBITS 30
920*a9fa9459Szrj 
921*a9fa9459Szrj #ifndef THASH_SIZE
922*a9fa9459Szrj #define THASH_SIZE 113
923*a9fa9459Szrj #endif
924*a9fa9459Szrj 
925*a9fa9459Szrj typedef struct thash {
926*a9fa9459Szrj   struct thash	*next;		/* next hash value */
927*a9fa9459Szrj   AUXU		 type;		/* type we are hashing */
928*a9fa9459Szrj   symint_t	 indx;		/* index within string table */
929*a9fa9459Szrj } thash_t;
930*a9fa9459Szrj 
931*a9fa9459Szrj /* Extended file descriptor that contains all of the support necessary
932*a9fa9459Szrj    to add things to each file separately.  */
933*a9fa9459Szrj typedef struct efdr {
934*a9fa9459Szrj   FDR		 fdr;		/* File header to be written out */
935*a9fa9459Szrj   FDR		*orig_fdr;	/* original file header */
936*a9fa9459Szrj   char		*name;		/* filename */
937*a9fa9459Szrj   int		 fake;		/* whether this is faked .file */
938*a9fa9459Szrj   symint_t	 void_type;	/* aux. pointer to 'void' type */
939*a9fa9459Szrj   symint_t	 int_type;	/* aux. pointer to 'int' type */
940*a9fa9459Szrj   scope_t	*cur_scope;	/* current nested scopes */
941*a9fa9459Szrj   symint_t	 file_index;	/* current file number */
942*a9fa9459Szrj   int		 nested_scopes;	/* # nested scopes */
943*a9fa9459Szrj   varray_t	 strings;	/* local strings */
944*a9fa9459Szrj   varray_t	 symbols;	/* local symbols */
945*a9fa9459Szrj   varray_t	 procs;		/* procedures */
946*a9fa9459Szrj   varray_t	 aux_syms;	/* auxiliary symbols */
947*a9fa9459Szrj   struct efdr	*next_file;	/* next file descriptor */
948*a9fa9459Szrj 				/* string/type hash tables */
949*a9fa9459Szrj   struct hash_control *str_hash;	/* string hash table */
950*a9fa9459Szrj   thash_t	*thash_head[THASH_SIZE];
951*a9fa9459Szrj } efdr_t;
952*a9fa9459Szrj 
953*a9fa9459Szrj /* Pre-initialized extended file structure.  */
954*a9fa9459Szrj static const efdr_t init_file = {
955*a9fa9459Szrj   {			/* FDR structure */
956*a9fa9459Szrj     0,			/* adr:		memory address of beginning of file */
957*a9fa9459Szrj     0,			/* rss:		file name (of source, if known) */
958*a9fa9459Szrj     0,			/* issBase:	file's string space */
959*a9fa9459Szrj     0,			/* cbSs:	number of bytes in the ss */
960*a9fa9459Szrj     0,			/* isymBase:	beginning of symbols */
961*a9fa9459Szrj     0,			/* csym:	count file's of symbols */
962*a9fa9459Szrj     0,			/* ilineBase:	file's line symbols */
963*a9fa9459Szrj     0,			/* cline:	count of file's line symbols */
964*a9fa9459Szrj     0,			/* ioptBase:	file's optimization entries */
965*a9fa9459Szrj     0,			/* copt:	count of file's optimization entries */
966*a9fa9459Szrj     0,			/* ipdFirst:	start of procedures for this file */
967*a9fa9459Szrj     0,			/* cpd:		count of procedures for this file */
968*a9fa9459Szrj     0,			/* iauxBase:	file's auxiliary entries */
969*a9fa9459Szrj     0,			/* caux:	count of file's auxiliary entries */
970*a9fa9459Szrj     0,			/* rfdBase:	index into the file indirect table */
971*a9fa9459Szrj     0,			/* crfd:	count file indirect entries */
972*a9fa9459Szrj     langC,		/* lang:	language for this file */
973*a9fa9459Szrj     1,			/* fMerge:	whether this file can be merged */
974*a9fa9459Szrj     0,			/* fReadin:	true if read in (not just created) */
975*a9fa9459Szrj     TARGET_BYTES_BIG_ENDIAN,  /* fBigendian:	if 1, compiled on big endian machine */
976*a9fa9459Szrj     GLEVEL_2,		/* glevel:	level this file was compiled with */
977*a9fa9459Szrj     0,			/* reserved:	reserved for future use */
978*a9fa9459Szrj     0,			/* cbLineOffset: byte offset from header for this file ln's */
979*a9fa9459Szrj     0,			/* cbLine:	size of lines for this file */
980*a9fa9459Szrj   },
981*a9fa9459Szrj 
982*a9fa9459Szrj   (FDR *)0,		/* orig_fdr:	original file header pointer */
983*a9fa9459Szrj   (char *)0,		/* name:	pointer to filename */
984*a9fa9459Szrj   0,			/* fake:	whether this is a faked .file */
985*a9fa9459Szrj   0,			/* void_type:	ptr to aux node for void type */
986*a9fa9459Szrj   0,			/* int_type:	ptr to aux node for int type */
987*a9fa9459Szrj   (scope_t *)0,		/* cur_scope:	current scope being processed */
988*a9fa9459Szrj   0,			/* file_index:	current file # */
989*a9fa9459Szrj   0,			/* nested_scopes: # nested scopes */
990*a9fa9459Szrj   INIT_VARRAY (char),	/* strings:	local string varray */
991*a9fa9459Szrj   INIT_VARRAY (localsym_t),	/* symbols:	local symbols varray */
992*a9fa9459Szrj   INIT_VARRAY (proc_t),	/* procs:	procedure varray */
993*a9fa9459Szrj   INIT_VARRAY (aux_t),	/* aux_syms:	auxiliary symbols varray */
994*a9fa9459Szrj 
995*a9fa9459Szrj   (struct efdr *)0,	/* next_file:	next file structure */
996*a9fa9459Szrj 
997*a9fa9459Szrj   (struct hash_control *)0,	/* str_hash:	string hash table */
998*a9fa9459Szrj   { 0 },		/* thash_head:	type hash table */
999*a9fa9459Szrj };
1000*a9fa9459Szrj 
1001*a9fa9459Szrj static efdr_t *first_file;			/* first file descriptor */
1002*a9fa9459Szrj static efdr_t **last_file_ptr = &first_file;	/* file descriptor tail */
1003*a9fa9459Szrj 
1004*a9fa9459Szrj /* Line number information is kept in a list until the assembly is
1005*a9fa9459Szrj    finished.  */
1006*a9fa9459Szrj typedef struct lineno_list {
1007*a9fa9459Szrj   struct lineno_list *next;	/* next element in list */
1008*a9fa9459Szrj   efdr_t *file;			/* file this line is in */
1009*a9fa9459Szrj   proc_t *proc;			/* procedure this line is in */
1010*a9fa9459Szrj   fragS *frag;			/* fragment this line number is in */
1011*a9fa9459Szrj   unsigned long paddr;		/* offset within fragment */
1012*a9fa9459Szrj   long lineno;			/* actual line number */
1013*a9fa9459Szrj } lineno_list_t;
1014*a9fa9459Szrj 
1015*a9fa9459Szrj static lineno_list_t *first_lineno;
1016*a9fa9459Szrj static lineno_list_t *last_lineno;
1017*a9fa9459Szrj static lineno_list_t **last_lineno_ptr = &first_lineno;
1018*a9fa9459Szrj 
1019*a9fa9459Szrj /* Sometimes there will be some .loc statements before a .ent.  We
1020*a9fa9459Szrj    keep them in this list so that we can fill in the procedure pointer
1021*a9fa9459Szrj    after we see the .ent.  */
1022*a9fa9459Szrj static lineno_list_t *noproc_lineno;
1023*a9fa9459Szrj 
1024*a9fa9459Szrj /* Union of various things that are held in pages.  */
1025*a9fa9459Szrj typedef union page {
1026*a9fa9459Szrj   char		byte	[ PAGE_SIZE ];
1027*a9fa9459Szrj   unsigned char	ubyte	[ PAGE_SIZE ];
1028*a9fa9459Szrj   efdr_t	file	[ PAGE_SIZE / sizeof (efdr_t)	     ];
1029*a9fa9459Szrj   FDR		ofile	[ PAGE_SIZE / sizeof (FDR)	     ];
1030*a9fa9459Szrj   proc_t	proc	[ PAGE_SIZE / sizeof (proc_t)	     ];
1031*a9fa9459Szrj   localsym_t	sym	[ PAGE_SIZE / sizeof (localsym_t)    ];
1032*a9fa9459Szrj   aux_t		aux	[ PAGE_SIZE / sizeof (aux_t)	     ];
1033*a9fa9459Szrj   DNR		dense	[ PAGE_SIZE / sizeof (DNR)	     ];
1034*a9fa9459Szrj   scope_t	scope	[ PAGE_SIZE / sizeof (scope_t)	     ];
1035*a9fa9459Szrj   vlinks_t	vlinks	[ PAGE_SIZE / sizeof (vlinks_t)	     ];
1036*a9fa9459Szrj   shash_t	shash	[ PAGE_SIZE / sizeof (shash_t)	     ];
1037*a9fa9459Szrj   thash_t	thash	[ PAGE_SIZE / sizeof (thash_t)	     ];
1038*a9fa9459Szrj   tag_t		tag	[ PAGE_SIZE / sizeof (tag_t)	     ];
1039*a9fa9459Szrj   forward_t	forward	[ PAGE_SIZE / sizeof (forward_t)     ];
1040*a9fa9459Szrj   thead_t	thead	[ PAGE_SIZE / sizeof (thead_t)	     ];
1041*a9fa9459Szrj   lineno_list_t	lineno	[ PAGE_SIZE / sizeof (lineno_list_t) ];
1042*a9fa9459Szrj } page_type;
1043*a9fa9459Szrj 
1044*a9fa9459Szrj /* Structure holding allocation information for small sized structures.  */
1045*a9fa9459Szrj typedef struct alloc_info {
1046*a9fa9459Szrj   char		*alloc_name;	/* name of this allocation type (must be first) */
1047*a9fa9459Szrj   page_type	*cur_page;	/* current page being allocated from */
1048*a9fa9459Szrj   small_free_t	 free_list;	/* current free list if any */
1049*a9fa9459Szrj   int		 unallocated;	/* number of elements unallocated on page */
1050*a9fa9459Szrj   int		 total_alloc;	/* total number of allocations */
1051*a9fa9459Szrj   int		 total_free;	/* total number of frees */
1052*a9fa9459Szrj   int		 total_pages;	/* total number of pages allocated */
1053*a9fa9459Szrj } alloc_info_t;
1054*a9fa9459Szrj 
1055*a9fa9459Szrj /* Type information collected together.  */
1056*a9fa9459Szrj typedef struct type_info {
1057*a9fa9459Szrj   bt_t	      basic_type;		/* basic type */
1058*a9fa9459Szrj   int	      orig_type;		/* original COFF-based type */
1059*a9fa9459Szrj   int	      num_tq;			/* # type qualifiers */
1060*a9fa9459Szrj   int	      num_dims;			/* # dimensions */
1061*a9fa9459Szrj   int	      num_sizes;		/* # sizes */
1062*a9fa9459Szrj   int	      extra_sizes;		/* # extra sizes not tied with dims */
1063*a9fa9459Szrj   tag_t *     tag_ptr;			/* tag pointer */
1064*a9fa9459Szrj   int	      bitfield;			/* symbol is a bitfield */
1065*a9fa9459Szrj   tq_t	      type_qualifiers[N_TQ];	/* type qualifiers (ptr, func, array)*/
1066*a9fa9459Szrj   symint_t    dimensions     [N_TQ];	/* dimensions for each array */
1067*a9fa9459Szrj   symint_t    sizes	     [N_TQ+2];	/* sizes of each array slice + size of
1068*a9fa9459Szrj 					   struct/union/enum + bitfield size */
1069*a9fa9459Szrj } type_info_t;
1070*a9fa9459Szrj 
1071*a9fa9459Szrj /* Pre-initialized type_info struct.  */
1072*a9fa9459Szrj static const type_info_t type_info_init = {
1073*a9fa9459Szrj   bt_Nil,				/* basic type */
1074*a9fa9459Szrj   T_NULL,				/* original COFF-based type */
1075*a9fa9459Szrj   0,					/* # type qualifiers */
1076*a9fa9459Szrj   0,					/* # dimensions */
1077*a9fa9459Szrj   0,					/* # sizes */
1078*a9fa9459Szrj   0,					/* sizes not tied with dims */
1079*a9fa9459Szrj   NULL,					/* ptr to tag */
1080*a9fa9459Szrj   0,					/* bitfield */
1081*a9fa9459Szrj   {					/* type qualifiers */
1082*a9fa9459Szrj     tq_Nil,
1083*a9fa9459Szrj     tq_Nil,
1084*a9fa9459Szrj     tq_Nil,
1085*a9fa9459Szrj     tq_Nil,
1086*a9fa9459Szrj     tq_Nil,
1087*a9fa9459Szrj     tq_Nil,
1088*a9fa9459Szrj   },
1089*a9fa9459Szrj   {					/* dimensions */
1090*a9fa9459Szrj     0,
1091*a9fa9459Szrj     0,
1092*a9fa9459Szrj     0,
1093*a9fa9459Szrj     0,
1094*a9fa9459Szrj     0,
1095*a9fa9459Szrj     0
1096*a9fa9459Szrj   },
1097*a9fa9459Szrj   {					/* sizes */
1098*a9fa9459Szrj     0,
1099*a9fa9459Szrj     0,
1100*a9fa9459Szrj     0,
1101*a9fa9459Szrj     0,
1102*a9fa9459Szrj     0,
1103*a9fa9459Szrj     0,
1104*a9fa9459Szrj     0,
1105*a9fa9459Szrj     0,
1106*a9fa9459Szrj   },
1107*a9fa9459Szrj };
1108*a9fa9459Szrj 
1109*a9fa9459Szrj /* Global hash table for the tags table and global table for file
1110*a9fa9459Szrj    descriptors.  */
1111*a9fa9459Szrj 
1112*a9fa9459Szrj static varray_t file_desc = INIT_VARRAY (efdr_t);
1113*a9fa9459Szrj 
1114*a9fa9459Szrj static struct hash_control *tag_hash;
1115*a9fa9459Szrj 
1116*a9fa9459Szrj /* Static types for int and void.  Also, remember the last function's
1117*a9fa9459Szrj    type (which is set up when we encounter the declaration for the
1118*a9fa9459Szrj    function, and used when the end block for the function is emitted.  */
1119*a9fa9459Szrj 
1120*a9fa9459Szrj static type_info_t int_type_info;
1121*a9fa9459Szrj static type_info_t void_type_info;
1122*a9fa9459Szrj static type_info_t last_func_type_info;
1123*a9fa9459Szrj static symbolS *last_func_sym_value;
1124*a9fa9459Szrj 
1125*a9fa9459Szrj /* Convert COFF basic type to ECOFF basic type.  The T_NULL type
1126*a9fa9459Szrj    really should use bt_Void, but this causes the current ecoff GDB to
1127*a9fa9459Szrj    issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
1128*a9fa9459Szrj    2.0) doesn't understand it, even though the compiler generates it.
1129*a9fa9459Szrj    Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
1130*a9fa9459Szrj    suite, but for now go with what works.
1131*a9fa9459Szrj 
1132*a9fa9459Szrj    It would make sense for the .type and .scl directives to use the
1133*a9fa9459Szrj    ECOFF numbers directly, rather than using the COFF numbers and
1134*a9fa9459Szrj    mapping them.  Unfortunately, this is historically what mips-tfile
1135*a9fa9459Szrj    expects, and changing gcc now would be a considerable pain (the
1136*a9fa9459Szrj    native compiler generates debugging information internally, rather
1137*a9fa9459Szrj    than via the assembler, so it will never use .type or .scl).  */
1138*a9fa9459Szrj 
1139*a9fa9459Szrj static const bt_t map_coff_types[] = {
1140*a9fa9459Szrj   bt_Nil,			/* T_NULL */
1141*a9fa9459Szrj   bt_Nil,			/* T_ARG */
1142*a9fa9459Szrj   bt_Char,			/* T_CHAR */
1143*a9fa9459Szrj   bt_Short,			/* T_SHORT */
1144*a9fa9459Szrj   bt_Int,			/* T_INT */
1145*a9fa9459Szrj   bt_Long,			/* T_LONG */
1146*a9fa9459Szrj   bt_Float,			/* T_FLOAT */
1147*a9fa9459Szrj   bt_Double,			/* T_DOUBLE */
1148*a9fa9459Szrj   bt_Struct,			/* T_STRUCT */
1149*a9fa9459Szrj   bt_Union,			/* T_UNION */
1150*a9fa9459Szrj   bt_Enum,			/* T_ENUM */
1151*a9fa9459Szrj   bt_Enum,			/* T_MOE */
1152*a9fa9459Szrj   bt_UChar,			/* T_UCHAR */
1153*a9fa9459Szrj   bt_UShort,			/* T_USHORT */
1154*a9fa9459Szrj   bt_UInt,			/* T_UINT */
1155*a9fa9459Szrj   bt_ULong			/* T_ULONG */
1156*a9fa9459Szrj };
1157*a9fa9459Szrj 
1158*a9fa9459Szrj /* Convert COFF storage class to ECOFF storage class.  */
1159*a9fa9459Szrj static const sc_t map_coff_storage[] = {
1160*a9fa9459Szrj   sc_Nil,			/*   0: C_NULL */
1161*a9fa9459Szrj   sc_Abs,			/*   1: C_AUTO	  auto var */
1162*a9fa9459Szrj   sc_Undefined,			/*   2: C_EXT	  external */
1163*a9fa9459Szrj   sc_Data,			/*   3: C_STAT	  static */
1164*a9fa9459Szrj   sc_Register,			/*   4: C_REG	  register */
1165*a9fa9459Szrj   sc_Undefined,			/*   5: C_EXTDEF  ??? */
1166*a9fa9459Szrj   sc_Text,			/*   6: C_LABEL	  label */
1167*a9fa9459Szrj   sc_Text,			/*   7: C_ULABEL  user label */
1168*a9fa9459Szrj   sc_Info,			/*   8: C_MOS	  member of struct */
1169*a9fa9459Szrj   sc_Abs,			/*   9: C_ARG	  argument */
1170*a9fa9459Szrj   sc_Info,			/*  10: C_STRTAG  struct tag */
1171*a9fa9459Szrj   sc_Info,			/*  11: C_MOU	  member of union */
1172*a9fa9459Szrj   sc_Info,			/*  12: C_UNTAG   union tag */
1173*a9fa9459Szrj   sc_Info,			/*  13: C_TPDEF	  typedef */
1174*a9fa9459Szrj   sc_Data,			/*  14: C_USTATIC ??? */
1175*a9fa9459Szrj   sc_Info,			/*  15: C_ENTAG	  enum tag */
1176*a9fa9459Szrj   sc_Info,			/*  16: C_MOE	  member of enum */
1177*a9fa9459Szrj   sc_Register,			/*  17: C_REGPARM register parameter */
1178*a9fa9459Szrj   sc_Bits,			/*  18; C_FIELD	  bitfield */
1179*a9fa9459Szrj   sc_Nil,			/*  19 */
1180*a9fa9459Szrj   sc_Nil,			/*  20 */
1181*a9fa9459Szrj   sc_Nil,			/*  21 */
1182*a9fa9459Szrj   sc_Nil,			/*  22 */
1183*a9fa9459Szrj   sc_Nil,			/*  23 */
1184*a9fa9459Szrj   sc_Nil,			/*  24 */
1185*a9fa9459Szrj   sc_Nil,			/*  25 */
1186*a9fa9459Szrj   sc_Nil,			/*  26 */
1187*a9fa9459Szrj   sc_Nil,			/*  27 */
1188*a9fa9459Szrj   sc_Nil,			/*  28 */
1189*a9fa9459Szrj   sc_Nil,			/*  29 */
1190*a9fa9459Szrj   sc_Nil,			/*  30 */
1191*a9fa9459Szrj   sc_Nil,			/*  31 */
1192*a9fa9459Szrj   sc_Nil,			/*  32 */
1193*a9fa9459Szrj   sc_Nil,			/*  33 */
1194*a9fa9459Szrj   sc_Nil,			/*  34 */
1195*a9fa9459Szrj   sc_Nil,			/*  35 */
1196*a9fa9459Szrj   sc_Nil,			/*  36 */
1197*a9fa9459Szrj   sc_Nil,			/*  37 */
1198*a9fa9459Szrj   sc_Nil,			/*  38 */
1199*a9fa9459Szrj   sc_Nil,			/*  39 */
1200*a9fa9459Szrj   sc_Nil,			/*  40 */
1201*a9fa9459Szrj   sc_Nil,			/*  41 */
1202*a9fa9459Szrj   sc_Nil,			/*  42 */
1203*a9fa9459Szrj   sc_Nil,			/*  43 */
1204*a9fa9459Szrj   sc_Nil,			/*  44 */
1205*a9fa9459Szrj   sc_Nil,			/*  45 */
1206*a9fa9459Szrj   sc_Nil,			/*  46 */
1207*a9fa9459Szrj   sc_Nil,			/*  47 */
1208*a9fa9459Szrj   sc_Nil,			/*  48 */
1209*a9fa9459Szrj   sc_Nil,			/*  49 */
1210*a9fa9459Szrj   sc_Nil,			/*  50 */
1211*a9fa9459Szrj   sc_Nil,			/*  51 */
1212*a9fa9459Szrj   sc_Nil,			/*  52 */
1213*a9fa9459Szrj   sc_Nil,			/*  53 */
1214*a9fa9459Szrj   sc_Nil,			/*  54 */
1215*a9fa9459Szrj   sc_Nil,			/*  55 */
1216*a9fa9459Szrj   sc_Nil,			/*  56 */
1217*a9fa9459Szrj   sc_Nil,			/*  57 */
1218*a9fa9459Szrj   sc_Nil,			/*  58 */
1219*a9fa9459Szrj   sc_Nil,			/*  59 */
1220*a9fa9459Szrj   sc_Nil,			/*  60 */
1221*a9fa9459Szrj   sc_Nil,			/*  61 */
1222*a9fa9459Szrj   sc_Nil,			/*  62 */
1223*a9fa9459Szrj   sc_Nil,			/*  63 */
1224*a9fa9459Szrj   sc_Nil,			/*  64 */
1225*a9fa9459Szrj   sc_Nil,			/*  65 */
1226*a9fa9459Szrj   sc_Nil,			/*  66 */
1227*a9fa9459Szrj   sc_Nil,			/*  67 */
1228*a9fa9459Szrj   sc_Nil,			/*  68 */
1229*a9fa9459Szrj   sc_Nil,			/*  69 */
1230*a9fa9459Szrj   sc_Nil,			/*  70 */
1231*a9fa9459Szrj   sc_Nil,			/*  71 */
1232*a9fa9459Szrj   sc_Nil,			/*  72 */
1233*a9fa9459Szrj   sc_Nil,			/*  73 */
1234*a9fa9459Szrj   sc_Nil,			/*  74 */
1235*a9fa9459Szrj   sc_Nil,			/*  75 */
1236*a9fa9459Szrj   sc_Nil,			/*  76 */
1237*a9fa9459Szrj   sc_Nil,			/*  77 */
1238*a9fa9459Szrj   sc_Nil,			/*  78 */
1239*a9fa9459Szrj   sc_Nil,			/*  79 */
1240*a9fa9459Szrj   sc_Nil,			/*  80 */
1241*a9fa9459Szrj   sc_Nil,			/*  81 */
1242*a9fa9459Szrj   sc_Nil,			/*  82 */
1243*a9fa9459Szrj   sc_Nil,			/*  83 */
1244*a9fa9459Szrj   sc_Nil,			/*  84 */
1245*a9fa9459Szrj   sc_Nil,			/*  85 */
1246*a9fa9459Szrj   sc_Nil,			/*  86 */
1247*a9fa9459Szrj   sc_Nil,			/*  87 */
1248*a9fa9459Szrj   sc_Nil,			/*  88 */
1249*a9fa9459Szrj   sc_Nil,			/*  89 */
1250*a9fa9459Szrj   sc_Nil,			/*  90 */
1251*a9fa9459Szrj   sc_Nil,			/*  91 */
1252*a9fa9459Szrj   sc_Nil,			/*  92 */
1253*a9fa9459Szrj   sc_Nil,			/*  93 */
1254*a9fa9459Szrj   sc_Nil,			/*  94 */
1255*a9fa9459Szrj   sc_Nil,			/*  95 */
1256*a9fa9459Szrj   sc_Nil,			/*  96 */
1257*a9fa9459Szrj   sc_Nil,			/*  97 */
1258*a9fa9459Szrj   sc_Nil,			/*  98 */
1259*a9fa9459Szrj   sc_Nil,			/*  99 */
1260*a9fa9459Szrj   sc_Text,			/* 100: C_BLOCK  block start/end */
1261*a9fa9459Szrj   sc_Text,			/* 101: C_FCN	 function start/end */
1262*a9fa9459Szrj   sc_Info,			/* 102: C_EOS	 end of struct/union/enum */
1263*a9fa9459Szrj   sc_Nil,			/* 103: C_FILE	 file start */
1264*a9fa9459Szrj   sc_Nil,			/* 104: C_LINE	 line number */
1265*a9fa9459Szrj   sc_Nil,			/* 105: C_ALIAS	 combined type info */
1266*a9fa9459Szrj   sc_Nil,			/* 106: C_HIDDEN ??? */
1267*a9fa9459Szrj };
1268*a9fa9459Szrj 
1269*a9fa9459Szrj /* Convert COFF storage class to ECOFF symbol type.  */
1270*a9fa9459Szrj static const st_t map_coff_sym_type[] = {
1271*a9fa9459Szrj   st_Nil,			/*   0: C_NULL */
1272*a9fa9459Szrj   st_Local,			/*   1: C_AUTO	  auto var */
1273*a9fa9459Szrj   st_Global,			/*   2: C_EXT	  external */
1274*a9fa9459Szrj   st_Static,			/*   3: C_STAT	  static */
1275*a9fa9459Szrj   st_Local,			/*   4: C_REG	  register */
1276*a9fa9459Szrj   st_Global,			/*   5: C_EXTDEF  ??? */
1277*a9fa9459Szrj   st_Label,			/*   6: C_LABEL	  label */
1278*a9fa9459Szrj   st_Label,			/*   7: C_ULABEL  user label */
1279*a9fa9459Szrj   st_Member,			/*   8: C_MOS	  member of struct */
1280*a9fa9459Szrj   st_Param,			/*   9: C_ARG	  argument */
1281*a9fa9459Szrj   st_Block,			/*  10: C_STRTAG  struct tag */
1282*a9fa9459Szrj   st_Member,			/*  11: C_MOU	  member of union */
1283*a9fa9459Szrj   st_Block,			/*  12: C_UNTAG   union tag */
1284*a9fa9459Szrj   st_Typedef,			/*  13: C_TPDEF	  typedef */
1285*a9fa9459Szrj   st_Static,			/*  14: C_USTATIC ??? */
1286*a9fa9459Szrj   st_Block,			/*  15: C_ENTAG	  enum tag */
1287*a9fa9459Szrj   st_Member,			/*  16: C_MOE	  member of enum */
1288*a9fa9459Szrj   st_Param,			/*  17: C_REGPARM register parameter */
1289*a9fa9459Szrj   st_Member,			/*  18; C_FIELD	  bitfield */
1290*a9fa9459Szrj   st_Nil,			/*  19 */
1291*a9fa9459Szrj   st_Nil,			/*  20 */
1292*a9fa9459Szrj   st_Nil,			/*  21 */
1293*a9fa9459Szrj   st_Nil,			/*  22 */
1294*a9fa9459Szrj   st_Nil,			/*  23 */
1295*a9fa9459Szrj   st_Nil,			/*  24 */
1296*a9fa9459Szrj   st_Nil,			/*  25 */
1297*a9fa9459Szrj   st_Nil,			/*  26 */
1298*a9fa9459Szrj   st_Nil,			/*  27 */
1299*a9fa9459Szrj   st_Nil,			/*  28 */
1300*a9fa9459Szrj   st_Nil,			/*  29 */
1301*a9fa9459Szrj   st_Nil,			/*  30 */
1302*a9fa9459Szrj   st_Nil,			/*  31 */
1303*a9fa9459Szrj   st_Nil,			/*  32 */
1304*a9fa9459Szrj   st_Nil,			/*  33 */
1305*a9fa9459Szrj   st_Nil,			/*  34 */
1306*a9fa9459Szrj   st_Nil,			/*  35 */
1307*a9fa9459Szrj   st_Nil,			/*  36 */
1308*a9fa9459Szrj   st_Nil,			/*  37 */
1309*a9fa9459Szrj   st_Nil,			/*  38 */
1310*a9fa9459Szrj   st_Nil,			/*  39 */
1311*a9fa9459Szrj   st_Nil,			/*  40 */
1312*a9fa9459Szrj   st_Nil,			/*  41 */
1313*a9fa9459Szrj   st_Nil,			/*  42 */
1314*a9fa9459Szrj   st_Nil,			/*  43 */
1315*a9fa9459Szrj   st_Nil,			/*  44 */
1316*a9fa9459Szrj   st_Nil,			/*  45 */
1317*a9fa9459Szrj   st_Nil,			/*  46 */
1318*a9fa9459Szrj   st_Nil,			/*  47 */
1319*a9fa9459Szrj   st_Nil,			/*  48 */
1320*a9fa9459Szrj   st_Nil,			/*  49 */
1321*a9fa9459Szrj   st_Nil,			/*  50 */
1322*a9fa9459Szrj   st_Nil,			/*  51 */
1323*a9fa9459Szrj   st_Nil,			/*  52 */
1324*a9fa9459Szrj   st_Nil,			/*  53 */
1325*a9fa9459Szrj   st_Nil,			/*  54 */
1326*a9fa9459Szrj   st_Nil,			/*  55 */
1327*a9fa9459Szrj   st_Nil,			/*  56 */
1328*a9fa9459Szrj   st_Nil,			/*  57 */
1329*a9fa9459Szrj   st_Nil,			/*  58 */
1330*a9fa9459Szrj   st_Nil,			/*  59 */
1331*a9fa9459Szrj   st_Nil,			/*  60 */
1332*a9fa9459Szrj   st_Nil,			/*  61 */
1333*a9fa9459Szrj   st_Nil,			/*  62 */
1334*a9fa9459Szrj   st_Nil,			/*  63 */
1335*a9fa9459Szrj   st_Nil,			/*  64 */
1336*a9fa9459Szrj   st_Nil,			/*  65 */
1337*a9fa9459Szrj   st_Nil,			/*  66 */
1338*a9fa9459Szrj   st_Nil,			/*  67 */
1339*a9fa9459Szrj   st_Nil,			/*  68 */
1340*a9fa9459Szrj   st_Nil,			/*  69 */
1341*a9fa9459Szrj   st_Nil,			/*  70 */
1342*a9fa9459Szrj   st_Nil,			/*  71 */
1343*a9fa9459Szrj   st_Nil,			/*  72 */
1344*a9fa9459Szrj   st_Nil,			/*  73 */
1345*a9fa9459Szrj   st_Nil,			/*  74 */
1346*a9fa9459Szrj   st_Nil,			/*  75 */
1347*a9fa9459Szrj   st_Nil,			/*  76 */
1348*a9fa9459Szrj   st_Nil,			/*  77 */
1349*a9fa9459Szrj   st_Nil,			/*  78 */
1350*a9fa9459Szrj   st_Nil,			/*  79 */
1351*a9fa9459Szrj   st_Nil,			/*  80 */
1352*a9fa9459Szrj   st_Nil,			/*  81 */
1353*a9fa9459Szrj   st_Nil,			/*  82 */
1354*a9fa9459Szrj   st_Nil,			/*  83 */
1355*a9fa9459Szrj   st_Nil,			/*  84 */
1356*a9fa9459Szrj   st_Nil,			/*  85 */
1357*a9fa9459Szrj   st_Nil,			/*  86 */
1358*a9fa9459Szrj   st_Nil,			/*  87 */
1359*a9fa9459Szrj   st_Nil,			/*  88 */
1360*a9fa9459Szrj   st_Nil,			/*  89 */
1361*a9fa9459Szrj   st_Nil,			/*  90 */
1362*a9fa9459Szrj   st_Nil,			/*  91 */
1363*a9fa9459Szrj   st_Nil,			/*  92 */
1364*a9fa9459Szrj   st_Nil,			/*  93 */
1365*a9fa9459Szrj   st_Nil,			/*  94 */
1366*a9fa9459Szrj   st_Nil,			/*  95 */
1367*a9fa9459Szrj   st_Nil,			/*  96 */
1368*a9fa9459Szrj   st_Nil,			/*  97 */
1369*a9fa9459Szrj   st_Nil,			/*  98 */
1370*a9fa9459Szrj   st_Nil,			/*  99 */
1371*a9fa9459Szrj   st_Block,			/* 100: C_BLOCK  block start/end */
1372*a9fa9459Szrj   st_Proc,			/* 101: C_FCN	 function start/end */
1373*a9fa9459Szrj   st_End,			/* 102: C_EOS	 end of struct/union/enum */
1374*a9fa9459Szrj   st_File,			/* 103: C_FILE	 file start */
1375*a9fa9459Szrj   st_Nil,			/* 104: C_LINE	 line number */
1376*a9fa9459Szrj   st_Nil,			/* 105: C_ALIAS	 combined type info */
1377*a9fa9459Szrj   st_Nil,			/* 106: C_HIDDEN ??? */
1378*a9fa9459Szrj };
1379*a9fa9459Szrj 
1380*a9fa9459Szrj /* Keep track of different sized allocation requests.  */
1381*a9fa9459Szrj static alloc_info_t alloc_counts[(int) alloc_type_last];
1382*a9fa9459Szrj 
1383*a9fa9459Szrj /* Record whether we have seen any debugging information.  */
1384*a9fa9459Szrj int ecoff_debugging_seen = 0;
1385*a9fa9459Szrj 
1386*a9fa9459Szrj /* Various statics.  */
1387*a9fa9459Szrj static efdr_t  *cur_file_ptr	= (efdr_t *) 0;	/* current file desc. header */
1388*a9fa9459Szrj static proc_t  *cur_proc_ptr	= (proc_t *) 0;	/* current procedure header */
1389*a9fa9459Szrj static proc_t  *first_proc_ptr  = (proc_t *) 0; /* first procedure header */
1390*a9fa9459Szrj static thead_t *top_tag_head	= (thead_t *) 0; /* top level tag head */
1391*a9fa9459Szrj static thead_t *cur_tag_head	= (thead_t *) 0; /* current tag head */
1392*a9fa9459Szrj #ifdef ECOFF_DEBUG
1393*a9fa9459Szrj static int	debug		= 0; 		/* trace functions */
1394*a9fa9459Szrj #endif
1395*a9fa9459Szrj static int	stabs_seen	= 0;		/* != 0 if stabs have been seen */
1396*a9fa9459Szrj 
1397*a9fa9459Szrj static int current_file_idx;
1398*a9fa9459Szrj static const char *current_stabs_filename;
1399*a9fa9459Szrj 
1400*a9fa9459Szrj /* Pseudo symbol to use when putting stabs into the symbol table.  */
1401*a9fa9459Szrj #ifndef STABS_SYMBOL
1402*a9fa9459Szrj #define STABS_SYMBOL "@stabs"
1403*a9fa9459Szrj #endif
1404*a9fa9459Szrj 
1405*a9fa9459Szrj static char stabs_symbol[] = STABS_SYMBOL;
1406*a9fa9459Szrj 
1407*a9fa9459Szrj /* Prototypes for functions defined in this file.  */
1408*a9fa9459Szrj 
1409*a9fa9459Szrj static void add_varray_page (varray_t *vp);
1410*a9fa9459Szrj static symint_t add_string (varray_t *vp,
1411*a9fa9459Szrj 			    struct hash_control *hash_tbl,
1412*a9fa9459Szrj 			    const char *str,
1413*a9fa9459Szrj 			    shash_t **ret_hash);
1414*a9fa9459Szrj static localsym_t *add_ecoff_symbol (const char *str, st_t type,
1415*a9fa9459Szrj 				     sc_t storage, symbolS *sym,
1416*a9fa9459Szrj 				     bfd_vma addend, symint_t value,
1417*a9fa9459Szrj 				     symint_t indx);
1418*a9fa9459Szrj static symint_t add_aux_sym_symint (symint_t aux_word);
1419*a9fa9459Szrj static symint_t add_aux_sym_rndx (int file_index, symint_t sym_index);
1420*a9fa9459Szrj static symint_t add_aux_sym_tir (type_info_t *t,
1421*a9fa9459Szrj 				 hash_state_t state,
1422*a9fa9459Szrj 				 thash_t **hash_tbl);
1423*a9fa9459Szrj static tag_t *get_tag (const char *tag, localsym_t *sym, bt_t basic_type);
1424*a9fa9459Szrj static void add_unknown_tag (tag_t *ptag);
1425*a9fa9459Szrj static void add_procedure (char *func);
1426*a9fa9459Szrj static void add_file (const char *file_name, int indx, int fake);
1427*a9fa9459Szrj #ifdef ECOFF_DEBUG
1428*a9fa9459Szrj static char *sc_to_string (sc_t storage_class);
1429*a9fa9459Szrj static char *st_to_string (st_t symbol_type);
1430*a9fa9459Szrj #endif
1431*a9fa9459Szrj static void mark_stabs (int);
1432*a9fa9459Szrj static char *ecoff_add_bytes (char **buf, char **bufend,
1433*a9fa9459Szrj 			      char *bufptr, unsigned long need);
1434*a9fa9459Szrj static unsigned long ecoff_padding_adjust
1435*a9fa9459Szrj   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1436*a9fa9459Szrj    unsigned long offset, char **bufptrptr);
1437*a9fa9459Szrj static unsigned long ecoff_build_lineno
1438*a9fa9459Szrj   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1439*a9fa9459Szrj    unsigned long offset, long *linecntptr);
1440*a9fa9459Szrj static unsigned long ecoff_build_symbols
1441*a9fa9459Szrj   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1442*a9fa9459Szrj    unsigned long offset);
1443*a9fa9459Szrj static unsigned long ecoff_build_procs
1444*a9fa9459Szrj   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1445*a9fa9459Szrj    unsigned long offset);
1446*a9fa9459Szrj static unsigned long ecoff_build_aux
1447*a9fa9459Szrj   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1448*a9fa9459Szrj    unsigned long offset);
1449*a9fa9459Szrj static unsigned long ecoff_build_strings (char **buf, char **bufend,
1450*a9fa9459Szrj 					  unsigned long offset,
1451*a9fa9459Szrj 					  varray_t *vp);
1452*a9fa9459Szrj static unsigned long ecoff_build_ss
1453*a9fa9459Szrj   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1454*a9fa9459Szrj    unsigned long offset);
1455*a9fa9459Szrj static unsigned long ecoff_build_fdr
1456*a9fa9459Szrj   (const struct ecoff_debug_swap *backend, char **buf, char **bufend,
1457*a9fa9459Szrj    unsigned long offset);
1458*a9fa9459Szrj static void ecoff_setup_ext (void);
1459*a9fa9459Szrj static page_type *allocate_cluster (unsigned long npages);
1460*a9fa9459Szrj static page_type *allocate_page (void);
1461*a9fa9459Szrj static scope_t *allocate_scope (void);
1462*a9fa9459Szrj static void free_scope (scope_t *ptr);
1463*a9fa9459Szrj static vlinks_t *allocate_vlinks (void);
1464*a9fa9459Szrj static shash_t *allocate_shash (void);
1465*a9fa9459Szrj static thash_t *allocate_thash (void);
1466*a9fa9459Szrj static tag_t *allocate_tag (void);
1467*a9fa9459Szrj static void free_tag (tag_t *ptr);
1468*a9fa9459Szrj static forward_t *allocate_forward (void);
1469*a9fa9459Szrj static thead_t *allocate_thead (void);
1470*a9fa9459Szrj static void free_thead (thead_t *ptr);
1471*a9fa9459Szrj static lineno_list_t *allocate_lineno_list (void);
1472*a9fa9459Szrj 
1473*a9fa9459Szrj /* This function should be called when the assembler starts up.  */
1474*a9fa9459Szrj 
1475*a9fa9459Szrj void
ecoff_read_begin_hook(void)1476*a9fa9459Szrj ecoff_read_begin_hook (void)
1477*a9fa9459Szrj {
1478*a9fa9459Szrj   tag_hash = hash_new ();
1479*a9fa9459Szrj   top_tag_head = allocate_thead ();
1480*a9fa9459Szrj   top_tag_head->first_tag = (tag_t *) NULL;
1481*a9fa9459Szrj   top_tag_head->free = (thead_t *) NULL;
1482*a9fa9459Szrj   top_tag_head->prev = cur_tag_head;
1483*a9fa9459Szrj   cur_tag_head = top_tag_head;
1484*a9fa9459Szrj }
1485*a9fa9459Szrj 
1486*a9fa9459Szrj /* This function should be called when a symbol is created.  */
1487*a9fa9459Szrj 
1488*a9fa9459Szrj void
ecoff_symbol_new_hook(symbolS * symbolP)1489*a9fa9459Szrj ecoff_symbol_new_hook (symbolS *symbolP)
1490*a9fa9459Szrj {
1491*a9fa9459Szrj   OBJ_SYMFIELD_TYPE *obj;
1492*a9fa9459Szrj 
1493*a9fa9459Szrj   /* Make sure that we have a file pointer, but only if we have seen a
1494*a9fa9459Szrj      file.  If we haven't seen a file, then this is a probably special
1495*a9fa9459Szrj      symbol created by md_begin which may required special handling at
1496*a9fa9459Szrj      some point.  Creating a dummy file with a dummy name is certainly
1497*a9fa9459Szrj      wrong.  */
1498*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL
1499*a9fa9459Szrj       && seen_at_least_1_file ())
1500*a9fa9459Szrj     add_file ((const char *) NULL, 0, 1);
1501*a9fa9459Szrj   obj = symbol_get_obj (symbolP);
1502*a9fa9459Szrj   obj->ecoff_file = cur_file_ptr;
1503*a9fa9459Szrj   obj->ecoff_symbol = NULL;
1504*a9fa9459Szrj   obj->ecoff_extern_size = 0;
1505*a9fa9459Szrj }
1506*a9fa9459Szrj 
1507*a9fa9459Szrj void
ecoff_symbol_clone_hook(symbolS * newsymP,symbolS * orgsymP)1508*a9fa9459Szrj ecoff_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
1509*a9fa9459Szrj {
1510*a9fa9459Szrj   OBJ_SYMFIELD_TYPE *n, *o;
1511*a9fa9459Szrj 
1512*a9fa9459Szrj   n = symbol_get_obj (newsymP);
1513*a9fa9459Szrj   o = symbol_get_obj (orgsymP);
1514*a9fa9459Szrj   memcpy (n, o, sizeof *n);
1515*a9fa9459Szrj }
1516*a9fa9459Szrj 
1517*a9fa9459Szrj /* Add a page to a varray object.  */
1518*a9fa9459Szrj 
1519*a9fa9459Szrj static void
add_varray_page(varray_t * vp)1520*a9fa9459Szrj add_varray_page (varray_t *vp /* varray to add page to */)
1521*a9fa9459Szrj {
1522*a9fa9459Szrj   vlinks_t *new_links = allocate_vlinks ();
1523*a9fa9459Szrj 
1524*a9fa9459Szrj #ifdef MALLOC_CHECK
1525*a9fa9459Szrj   if (vp->object_size > 1)
1526*a9fa9459Szrj     new_links->datum = (page_type *) xcalloc (1, vp->object_size);
1527*a9fa9459Szrj   else
1528*a9fa9459Szrj #endif
1529*a9fa9459Szrj     new_links->datum = allocate_page ();
1530*a9fa9459Szrj 
1531*a9fa9459Szrj   alloc_counts[(int) alloc_type_varray].total_alloc++;
1532*a9fa9459Szrj   alloc_counts[(int) alloc_type_varray].total_pages++;
1533*a9fa9459Szrj 
1534*a9fa9459Szrj   new_links->start_index = vp->num_allocated;
1535*a9fa9459Szrj   vp->objects_last_page = 0;
1536*a9fa9459Szrj 
1537*a9fa9459Szrj   if (vp->first == (vlinks_t *) NULL)		/* first allocation? */
1538*a9fa9459Szrj     vp->first = vp->last = new_links;
1539*a9fa9459Szrj   else
1540*a9fa9459Szrj     {						/* 2nd or greater allocation */
1541*a9fa9459Szrj       new_links->prev = vp->last;
1542*a9fa9459Szrj       vp->last->next = new_links;
1543*a9fa9459Szrj       vp->last = new_links;
1544*a9fa9459Szrj     }
1545*a9fa9459Szrj }
1546*a9fa9459Szrj 
1547*a9fa9459Szrj /* Add a string (and null pad) to one of the string tables.  */
1548*a9fa9459Szrj 
1549*a9fa9459Szrj static symint_t
add_string(varray_t * vp,struct hash_control * hash_tbl,const char * str,shash_t ** ret_hash)1550*a9fa9459Szrj add_string (varray_t *vp,			/* string obstack */
1551*a9fa9459Szrj 	    struct hash_control *hash_tbl,	/* ptr to hash table */
1552*a9fa9459Szrj 	    const char *str,			/* string */
1553*a9fa9459Szrj 	    shash_t **ret_hash			/* return hash pointer */)
1554*a9fa9459Szrj {
1555*a9fa9459Szrj   unsigned long len = strlen (str);
1556*a9fa9459Szrj   shash_t *hash_ptr;
1557*a9fa9459Szrj 
1558*a9fa9459Szrj   if (len >= PAGE_USIZE)
1559*a9fa9459Szrj     as_fatal (_("string too big (%lu bytes)"), len);
1560*a9fa9459Szrj 
1561*a9fa9459Szrj   hash_ptr = (shash_t *) hash_find (hash_tbl, str);
1562*a9fa9459Szrj   if (hash_ptr == (shash_t *) NULL)
1563*a9fa9459Szrj     {
1564*a9fa9459Szrj       const char *err;
1565*a9fa9459Szrj 
1566*a9fa9459Szrj       if (vp->objects_last_page + len >= PAGE_USIZE)
1567*a9fa9459Szrj 	{
1568*a9fa9459Szrj 	  vp->num_allocated =
1569*a9fa9459Szrj 	    ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
1570*a9fa9459Szrj 	  add_varray_page (vp);
1571*a9fa9459Szrj 	}
1572*a9fa9459Szrj 
1573*a9fa9459Szrj       hash_ptr = allocate_shash ();
1574*a9fa9459Szrj       hash_ptr->indx = vp->num_allocated;
1575*a9fa9459Szrj 
1576*a9fa9459Szrj       hash_ptr->string = &vp->last->datum->byte[vp->objects_last_page];
1577*a9fa9459Szrj 
1578*a9fa9459Szrj       vp->objects_last_page += len + 1;
1579*a9fa9459Szrj       vp->num_allocated += len + 1;
1580*a9fa9459Szrj 
1581*a9fa9459Szrj       strcpy (hash_ptr->string, str);
1582*a9fa9459Szrj 
1583*a9fa9459Szrj       err = hash_insert (hash_tbl, str, (char *) hash_ptr);
1584*a9fa9459Szrj       if (err)
1585*a9fa9459Szrj 	as_fatal (_("inserting \"%s\" into string hash table: %s"),
1586*a9fa9459Szrj 		  str, err);
1587*a9fa9459Szrj     }
1588*a9fa9459Szrj 
1589*a9fa9459Szrj   if (ret_hash != (shash_t **) NULL)
1590*a9fa9459Szrj     *ret_hash = hash_ptr;
1591*a9fa9459Szrj 
1592*a9fa9459Szrj   return hash_ptr->indx;
1593*a9fa9459Szrj }
1594*a9fa9459Szrj 
1595*a9fa9459Szrj /* Add debugging information for a symbol.  */
1596*a9fa9459Szrj 
1597*a9fa9459Szrj 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)1598*a9fa9459Szrj add_ecoff_symbol (const char *str,	/* symbol name */
1599*a9fa9459Szrj 		  st_t type,		/* symbol type */
1600*a9fa9459Szrj 		  sc_t storage,		/* storage class */
1601*a9fa9459Szrj 		  symbolS *sym_value,	/* associated symbol.  */
1602*a9fa9459Szrj 		  bfd_vma addend,	/* addend to sym_value.  */
1603*a9fa9459Szrj 		  symint_t value,	/* value of symbol */
1604*a9fa9459Szrj 		  symint_t indx		/* index to local/aux. syms */)
1605*a9fa9459Szrj {
1606*a9fa9459Szrj   localsym_t *psym;
1607*a9fa9459Szrj   scope_t *pscope;
1608*a9fa9459Szrj   thead_t *ptag_head;
1609*a9fa9459Szrj   tag_t *ptag;
1610*a9fa9459Szrj   tag_t *ptag_next;
1611*a9fa9459Szrj   varray_t *vp;
1612*a9fa9459Szrj   int scope_delta = 0;
1613*a9fa9459Szrj   shash_t *hash_ptr = (shash_t *) NULL;
1614*a9fa9459Szrj 
1615*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
1616*a9fa9459Szrj     as_fatal (_("no current file pointer"));
1617*a9fa9459Szrj 
1618*a9fa9459Szrj   vp = &cur_file_ptr->symbols;
1619*a9fa9459Szrj 
1620*a9fa9459Szrj   if (vp->objects_last_page == vp->objects_per_page)
1621*a9fa9459Szrj     add_varray_page (vp);
1622*a9fa9459Szrj 
1623*a9fa9459Szrj   psym = &vp->last->datum->sym[vp->objects_last_page++];
1624*a9fa9459Szrj 
1625*a9fa9459Szrj   if (str == (const char *) NULL && sym_value != (symbolS *) NULL)
1626*a9fa9459Szrj     psym->name = S_GET_NAME (sym_value);
1627*a9fa9459Szrj   else
1628*a9fa9459Szrj     psym->name = str;
1629*a9fa9459Szrj   psym->as_sym = sym_value;
1630*a9fa9459Szrj   if (sym_value != (symbolS *) NULL)
1631*a9fa9459Szrj     symbol_get_obj (sym_value)->ecoff_symbol = psym;
1632*a9fa9459Szrj   psym->addend = addend;
1633*a9fa9459Szrj   psym->file_ptr = cur_file_ptr;
1634*a9fa9459Szrj   psym->proc_ptr = cur_proc_ptr;
1635*a9fa9459Szrj   psym->begin_ptr = (localsym_t *) NULL;
1636*a9fa9459Szrj   psym->index_ptr = (aux_t *) NULL;
1637*a9fa9459Szrj   psym->forward_ref = (forward_t *) NULL;
1638*a9fa9459Szrj   psym->sym_index = -1;
1639*a9fa9459Szrj   memset (&psym->ecoff_sym, 0, sizeof (EXTR));
1640*a9fa9459Szrj   psym->ecoff_sym.asym.value = value;
1641*a9fa9459Szrj   psym->ecoff_sym.asym.st = (unsigned) type;
1642*a9fa9459Szrj   psym->ecoff_sym.asym.sc = (unsigned) storage;
1643*a9fa9459Szrj   psym->ecoff_sym.asym.index = indx;
1644*a9fa9459Szrj 
1645*a9fa9459Szrj   /* If there is an associated symbol, we wait until the end of the
1646*a9fa9459Szrj      assembly before deciding where to put the name (it may be just an
1647*a9fa9459Szrj      external symbol).  Otherwise, this is just a debugging symbol and
1648*a9fa9459Szrj      the name should go with the current file.  */
1649*a9fa9459Szrj   if (sym_value == (symbolS *) NULL)
1650*a9fa9459Szrj     psym->ecoff_sym.asym.iss = ((str == (const char *) NULL)
1651*a9fa9459Szrj 				? 0
1652*a9fa9459Szrj 				: add_string (&cur_file_ptr->strings,
1653*a9fa9459Szrj 					      cur_file_ptr->str_hash,
1654*a9fa9459Szrj 					      str,
1655*a9fa9459Szrj 					      &hash_ptr));
1656*a9fa9459Szrj 
1657*a9fa9459Szrj   ++vp->num_allocated;
1658*a9fa9459Szrj 
1659*a9fa9459Szrj   if (ECOFF_IS_STAB (&psym->ecoff_sym.asym))
1660*a9fa9459Szrj     return psym;
1661*a9fa9459Szrj 
1662*a9fa9459Szrj   /* Save the symbol within the hash table if this is a static
1663*a9fa9459Szrj      item, and it has a name.  */
1664*a9fa9459Szrj   if (hash_ptr != (shash_t *) NULL
1665*a9fa9459Szrj       && (type == st_Global || type == st_Static || type == st_Label
1666*a9fa9459Szrj 	  || type == st_Proc || type == st_StaticProc))
1667*a9fa9459Szrj     hash_ptr->sym_ptr = psym;
1668*a9fa9459Szrj 
1669*a9fa9459Szrj   /* push or pop a scope if appropriate.  */
1670*a9fa9459Szrj   switch (type)
1671*a9fa9459Szrj     {
1672*a9fa9459Szrj     default:
1673*a9fa9459Szrj       break;
1674*a9fa9459Szrj 
1675*a9fa9459Szrj     case st_File:			/* beginning of file */
1676*a9fa9459Szrj     case st_Proc:			/* procedure */
1677*a9fa9459Szrj     case st_StaticProc:			/* static procedure */
1678*a9fa9459Szrj     case st_Block:			/* begin scope */
1679*a9fa9459Szrj       pscope = allocate_scope ();
1680*a9fa9459Szrj       pscope->prev = cur_file_ptr->cur_scope;
1681*a9fa9459Szrj       pscope->lsym = psym;
1682*a9fa9459Szrj       pscope->type = type;
1683*a9fa9459Szrj       cur_file_ptr->cur_scope = pscope;
1684*a9fa9459Szrj 
1685*a9fa9459Szrj       if (type != st_File)
1686*a9fa9459Szrj 	scope_delta = 1;
1687*a9fa9459Szrj 
1688*a9fa9459Szrj       /* For every block type except file, struct, union, or
1689*a9fa9459Szrj          enumeration blocks, push a level on the tag stack.  We omit
1690*a9fa9459Szrj          file types, so that tags can span file boundaries.  */
1691*a9fa9459Szrj       if (type != st_File && storage != sc_Info)
1692*a9fa9459Szrj 	{
1693*a9fa9459Szrj 	  ptag_head = allocate_thead ();
1694*a9fa9459Szrj 	  ptag_head->first_tag = 0;
1695*a9fa9459Szrj 	  ptag_head->prev = cur_tag_head;
1696*a9fa9459Szrj 	  cur_tag_head = ptag_head;
1697*a9fa9459Szrj 	}
1698*a9fa9459Szrj       break;
1699*a9fa9459Szrj 
1700*a9fa9459Szrj     case st_End:
1701*a9fa9459Szrj       pscope = cur_file_ptr->cur_scope;
1702*a9fa9459Szrj       if (pscope == (scope_t *) NULL)
1703*a9fa9459Szrj 	as_fatal (_("too many st_End's"));
1704*a9fa9459Szrj       else
1705*a9fa9459Szrj 	{
1706*a9fa9459Szrj 	  st_t begin_type = (st_t) pscope->lsym->ecoff_sym.asym.st;
1707*a9fa9459Szrj 
1708*a9fa9459Szrj 	  psym->begin_ptr = pscope->lsym;
1709*a9fa9459Szrj 
1710*a9fa9459Szrj 	  if (begin_type != st_File)
1711*a9fa9459Szrj 	    scope_delta = -1;
1712*a9fa9459Szrj 
1713*a9fa9459Szrj 	  /* Except for file, structure, union, or enumeration end
1714*a9fa9459Szrj 	     blocks remove all tags created within this scope.  */
1715*a9fa9459Szrj 	  if (begin_type != st_File && storage != sc_Info)
1716*a9fa9459Szrj 	    {
1717*a9fa9459Szrj 	      ptag_head = cur_tag_head;
1718*a9fa9459Szrj 	      cur_tag_head = ptag_head->prev;
1719*a9fa9459Szrj 
1720*a9fa9459Szrj 	      for (ptag = ptag_head->first_tag;
1721*a9fa9459Szrj 		   ptag != (tag_t *) NULL;
1722*a9fa9459Szrj 		   ptag = ptag_next)
1723*a9fa9459Szrj 		{
1724*a9fa9459Szrj 		  if (ptag->forward_ref != (forward_t *) NULL)
1725*a9fa9459Szrj 		    add_unknown_tag (ptag);
1726*a9fa9459Szrj 
1727*a9fa9459Szrj 		  ptag_next = ptag->same_block;
1728*a9fa9459Szrj 		  ptag->hash_ptr->tag_ptr = ptag->same_name;
1729*a9fa9459Szrj 		  free_tag (ptag);
1730*a9fa9459Szrj 		}
1731*a9fa9459Szrj 
1732*a9fa9459Szrj 	      free_thead (ptag_head);
1733*a9fa9459Szrj 	    }
1734*a9fa9459Szrj 
1735*a9fa9459Szrj 	  cur_file_ptr->cur_scope = pscope->prev;
1736*a9fa9459Szrj 
1737*a9fa9459Szrj 	  /* block begin gets next sym #.  This is set when we know
1738*a9fa9459Szrj 	     the symbol index value.  */
1739*a9fa9459Szrj 
1740*a9fa9459Szrj 	  /* Functions push two or more aux words as follows:
1741*a9fa9459Szrj 	     1st word: index+1 of the end symbol (filled in later).
1742*a9fa9459Szrj 	     2nd word: type of the function (plus any aux words needed).
1743*a9fa9459Szrj 	     Also, tie the external pointer back to the function begin symbol.  */
1744*a9fa9459Szrj 	  if (begin_type != st_File && begin_type != st_Block)
1745*a9fa9459Szrj 	    {
1746*a9fa9459Szrj 	      symint_t ty;
1747*a9fa9459Szrj 	      varray_t *svp = &cur_file_ptr->aux_syms;
1748*a9fa9459Szrj 
1749*a9fa9459Szrj 	      pscope->lsym->ecoff_sym.asym.index = add_aux_sym_symint (0);
1750*a9fa9459Szrj 	      pscope->lsym->index_ptr =
1751*a9fa9459Szrj 		&svp->last->datum->aux[svp->objects_last_page - 1];
1752*a9fa9459Szrj 	      ty = add_aux_sym_tir (&last_func_type_info,
1753*a9fa9459Szrj 				    hash_no,
1754*a9fa9459Szrj 				    &cur_file_ptr->thash_head[0]);
1755*a9fa9459Szrj 	      (void) ty;
1756*a9fa9459Szrj /* This seems to be unnecessary.  I'm not even sure what it is
1757*a9fa9459Szrj  * intended to do.  It's from mips-tfile.
1758*a9fa9459Szrj  *	      if (last_func_sym_value != (symbolS *) NULL)
1759*a9fa9459Szrj  *		{
1760*a9fa9459Szrj  *		  last_func_sym_value->ifd = cur_file_ptr->file_index;
1761*a9fa9459Szrj  *		  last_func_sym_value->index = ty;
1762*a9fa9459Szrj  *		}
1763*a9fa9459Szrj  */
1764*a9fa9459Szrj 	    }
1765*a9fa9459Szrj 
1766*a9fa9459Szrj 	  free_scope (pscope);
1767*a9fa9459Szrj 	}
1768*a9fa9459Szrj     }
1769*a9fa9459Szrj 
1770*a9fa9459Szrj   cur_file_ptr->nested_scopes += scope_delta;
1771*a9fa9459Szrj 
1772*a9fa9459Szrj #ifdef ECOFF_DEBUG
1773*a9fa9459Szrj   if (debug && type != st_File
1774*a9fa9459Szrj       && (debug > 2 || type == st_Block || type == st_End
1775*a9fa9459Szrj 	  || type == st_Proc || type == st_StaticProc))
1776*a9fa9459Szrj     {
1777*a9fa9459Szrj       char *sc_str = sc_to_string (storage);
1778*a9fa9459Szrj       char *st_str = st_to_string (type);
1779*a9fa9459Szrj       int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
1780*a9fa9459Szrj 
1781*a9fa9459Szrj       fprintf (stderr,
1782*a9fa9459Szrj 	       "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
1783*a9fa9459Szrj 	       value, depth, sc_str);
1784*a9fa9459Szrj 
1785*a9fa9459Szrj       if (str_start && str_end_p1 - str_start > 0)
1786*a9fa9459Szrj 	fprintf (stderr, " st= %-11s name= %.*s\n",
1787*a9fa9459Szrj 		 st_str, str_end_p1 - str_start, str_start);
1788*a9fa9459Szrj       else
1789*a9fa9459Szrj 	{
1790*a9fa9459Szrj 	  unsigned long len = strlen (st_str);
1791*a9fa9459Szrj 	  fprintf (stderr, " st= %.*s\n", len - 1, st_str);
1792*a9fa9459Szrj 	}
1793*a9fa9459Szrj     }
1794*a9fa9459Szrj #endif
1795*a9fa9459Szrj 
1796*a9fa9459Szrj   return psym;
1797*a9fa9459Szrj }
1798*a9fa9459Szrj 
1799*a9fa9459Szrj /* Add an auxiliary symbol (passing a symint).  This is actually used
1800*a9fa9459Szrj    for integral aux types, not just symints.  */
1801*a9fa9459Szrj 
1802*a9fa9459Szrj static symint_t
add_aux_sym_symint(symint_t aux_word)1803*a9fa9459Szrj add_aux_sym_symint (symint_t aux_word /* auxiliary information word */)
1804*a9fa9459Szrj {
1805*a9fa9459Szrj   varray_t *vp;
1806*a9fa9459Szrj   aux_t *aux_ptr;
1807*a9fa9459Szrj 
1808*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
1809*a9fa9459Szrj     as_fatal (_("no current file pointer"));
1810*a9fa9459Szrj 
1811*a9fa9459Szrj   vp = &cur_file_ptr->aux_syms;
1812*a9fa9459Szrj 
1813*a9fa9459Szrj   if (vp->objects_last_page == vp->objects_per_page)
1814*a9fa9459Szrj     add_varray_page (vp);
1815*a9fa9459Szrj 
1816*a9fa9459Szrj   aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
1817*a9fa9459Szrj   aux_ptr->type = aux_isym;
1818*a9fa9459Szrj   aux_ptr->data.isym = aux_word;
1819*a9fa9459Szrj 
1820*a9fa9459Szrj   return vp->num_allocated++;
1821*a9fa9459Szrj }
1822*a9fa9459Szrj 
1823*a9fa9459Szrj /* Add an auxiliary symbol (passing a file/symbol index combo).  */
1824*a9fa9459Szrj 
1825*a9fa9459Szrj static symint_t
add_aux_sym_rndx(int file_index,symint_t sym_index)1826*a9fa9459Szrj add_aux_sym_rndx (int file_index, symint_t sym_index)
1827*a9fa9459Szrj {
1828*a9fa9459Szrj   varray_t *vp;
1829*a9fa9459Szrj   aux_t *aux_ptr;
1830*a9fa9459Szrj 
1831*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
1832*a9fa9459Szrj     as_fatal (_("no current file pointer"));
1833*a9fa9459Szrj 
1834*a9fa9459Szrj   vp = &cur_file_ptr->aux_syms;
1835*a9fa9459Szrj 
1836*a9fa9459Szrj   if (vp->objects_last_page == vp->objects_per_page)
1837*a9fa9459Szrj     add_varray_page (vp);
1838*a9fa9459Szrj 
1839*a9fa9459Szrj   aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
1840*a9fa9459Szrj   aux_ptr->type = aux_rndx;
1841*a9fa9459Szrj   aux_ptr->data.rndx.rfd   = file_index;
1842*a9fa9459Szrj   aux_ptr->data.rndx.index = sym_index;
1843*a9fa9459Szrj 
1844*a9fa9459Szrj   return vp->num_allocated++;
1845*a9fa9459Szrj }
1846*a9fa9459Szrj 
1847*a9fa9459Szrj /* Add an auxiliary symbol (passing the basic type and possibly
1848*a9fa9459Szrj    type qualifiers).  */
1849*a9fa9459Szrj 
1850*a9fa9459Szrj static symint_t
add_aux_sym_tir(type_info_t * t,hash_state_t state,thash_t ** hash_tbl)1851*a9fa9459Szrj add_aux_sym_tir (type_info_t *t,	/* current type information */
1852*a9fa9459Szrj 		 hash_state_t state,	/* whether to hash type or not */
1853*a9fa9459Szrj 		 thash_t **hash_tbl	/* pointer to hash table to use */)
1854*a9fa9459Szrj {
1855*a9fa9459Szrj   varray_t *vp;
1856*a9fa9459Szrj   aux_t *aux_ptr;
1857*a9fa9459Szrj   static AUXU init_aux;
1858*a9fa9459Szrj   symint_t ret;
1859*a9fa9459Szrj   int i;
1860*a9fa9459Szrj   AUXU aux;
1861*a9fa9459Szrj 
1862*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
1863*a9fa9459Szrj     as_fatal (_("no current file pointer"));
1864*a9fa9459Szrj 
1865*a9fa9459Szrj   vp = &cur_file_ptr->aux_syms;
1866*a9fa9459Szrj 
1867*a9fa9459Szrj   aux = init_aux;
1868*a9fa9459Szrj   aux.ti.bt = (int) t->basic_type;
1869*a9fa9459Szrj   aux.ti.continued = 0;
1870*a9fa9459Szrj   aux.ti.fBitfield = t->bitfield;
1871*a9fa9459Szrj 
1872*a9fa9459Szrj   aux.ti.tq0 = (int) t->type_qualifiers[0];
1873*a9fa9459Szrj   aux.ti.tq1 = (int) t->type_qualifiers[1];
1874*a9fa9459Szrj   aux.ti.tq2 = (int) t->type_qualifiers[2];
1875*a9fa9459Szrj   aux.ti.tq3 = (int) t->type_qualifiers[3];
1876*a9fa9459Szrj   aux.ti.tq4 = (int) t->type_qualifiers[4];
1877*a9fa9459Szrj   aux.ti.tq5 = (int) t->type_qualifiers[5];
1878*a9fa9459Szrj 
1879*a9fa9459Szrj   /* For anything that adds additional information, we must not hash,
1880*a9fa9459Szrj      so check here, and reset our state.  */
1881*a9fa9459Szrj 
1882*a9fa9459Szrj   if (state != hash_no
1883*a9fa9459Szrj       && (t->type_qualifiers[0] == tq_Array
1884*a9fa9459Szrj 	  || t->type_qualifiers[1] == tq_Array
1885*a9fa9459Szrj 	  || t->type_qualifiers[2] == tq_Array
1886*a9fa9459Szrj 	  || t->type_qualifiers[3] == tq_Array
1887*a9fa9459Szrj 	  || t->type_qualifiers[4] == tq_Array
1888*a9fa9459Szrj 	  || t->type_qualifiers[5] == tq_Array
1889*a9fa9459Szrj 	  || t->basic_type == bt_Struct
1890*a9fa9459Szrj 	  || t->basic_type == bt_Union
1891*a9fa9459Szrj 	  || t->basic_type == bt_Enum
1892*a9fa9459Szrj 	  || t->bitfield
1893*a9fa9459Szrj 	  || t->num_dims > 0))
1894*a9fa9459Szrj     state = hash_no;
1895*a9fa9459Szrj 
1896*a9fa9459Szrj   /* See if we can hash this type, and save some space, but some types
1897*a9fa9459Szrj      can't be hashed (because they contain arrays or continuations),
1898*a9fa9459Szrj      and others can be put into the hash list, but cannot use existing
1899*a9fa9459Szrj      types because other aux entries precede this one.  */
1900*a9fa9459Szrj 
1901*a9fa9459Szrj   if (state != hash_no)
1902*a9fa9459Szrj     {
1903*a9fa9459Szrj       thash_t *hash_ptr;
1904*a9fa9459Szrj       symint_t hi;
1905*a9fa9459Szrj 
1906*a9fa9459Szrj       hi = aux.isym & ((1 << HASHBITS) - 1);
1907*a9fa9459Szrj       hi %= THASH_SIZE;
1908*a9fa9459Szrj 
1909*a9fa9459Szrj       for (hash_ptr = hash_tbl[hi];
1910*a9fa9459Szrj 	   hash_ptr != (thash_t *)0;
1911*a9fa9459Szrj 	   hash_ptr = hash_ptr->next)
1912*a9fa9459Szrj 	{
1913*a9fa9459Szrj 	  if (aux.isym == hash_ptr->type.isym)
1914*a9fa9459Szrj 	    break;
1915*a9fa9459Szrj 	}
1916*a9fa9459Szrj 
1917*a9fa9459Szrj       if (hash_ptr != (thash_t *) NULL && state == hash_yes)
1918*a9fa9459Szrj 	return hash_ptr->indx;
1919*a9fa9459Szrj 
1920*a9fa9459Szrj       if (hash_ptr == (thash_t *) NULL)
1921*a9fa9459Szrj 	{
1922*a9fa9459Szrj 	  hash_ptr = allocate_thash ();
1923*a9fa9459Szrj 	  hash_ptr->next = hash_tbl[hi];
1924*a9fa9459Szrj 	  hash_ptr->type = aux;
1925*a9fa9459Szrj 	  hash_ptr->indx = vp->num_allocated;
1926*a9fa9459Szrj 	  hash_tbl[hi] = hash_ptr;
1927*a9fa9459Szrj 	}
1928*a9fa9459Szrj     }
1929*a9fa9459Szrj 
1930*a9fa9459Szrj   /* Everything is set up, add the aux symbol.  */
1931*a9fa9459Szrj   if (vp->objects_last_page == vp->objects_per_page)
1932*a9fa9459Szrj     add_varray_page (vp);
1933*a9fa9459Szrj 
1934*a9fa9459Szrj   aux_ptr = &vp->last->datum->aux[vp->objects_last_page++];
1935*a9fa9459Szrj   aux_ptr->type = aux_tir;
1936*a9fa9459Szrj   aux_ptr->data = aux;
1937*a9fa9459Szrj 
1938*a9fa9459Szrj   ret = vp->num_allocated++;
1939*a9fa9459Szrj 
1940*a9fa9459Szrj   /* Add bitfield length if it exists.
1941*a9fa9459Szrj 
1942*a9fa9459Szrj      NOTE:  Mips documentation claims bitfield goes at the end of the
1943*a9fa9459Szrj      AUX record, but the DECstation compiler emits it here.
1944*a9fa9459Szrj      (This would only make a difference for enum bitfields.)
1945*a9fa9459Szrj 
1946*a9fa9459Szrj      Also note:  We use the last size given since gcc may emit 2
1947*a9fa9459Szrj      for an enum bitfield.  */
1948*a9fa9459Szrj 
1949*a9fa9459Szrj   if (t->bitfield)
1950*a9fa9459Szrj     (void) add_aux_sym_symint ((symint_t) t->sizes[t->num_sizes - 1]);
1951*a9fa9459Szrj 
1952*a9fa9459Szrj   /* Add tag information if needed.  Structure, union, and enum
1953*a9fa9459Szrj      references add 2 aux symbols: a [file index, symbol index]
1954*a9fa9459Szrj      pointer to the structure type, and the current file index.  */
1955*a9fa9459Szrj 
1956*a9fa9459Szrj   if (t->basic_type == bt_Struct
1957*a9fa9459Szrj       || t->basic_type == bt_Union
1958*a9fa9459Szrj       || t->basic_type == bt_Enum)
1959*a9fa9459Szrj     {
1960*a9fa9459Szrj       symint_t file_index = t->tag_ptr->ifd;
1961*a9fa9459Szrj       localsym_t *sym = t->tag_ptr->sym;
1962*a9fa9459Szrj       forward_t *forward_ref = allocate_forward ();
1963*a9fa9459Szrj 
1964*a9fa9459Szrj       if (sym != (localsym_t *) NULL)
1965*a9fa9459Szrj 	{
1966*a9fa9459Szrj 	  forward_ref->next = sym->forward_ref;
1967*a9fa9459Szrj 	  sym->forward_ref = forward_ref;
1968*a9fa9459Szrj 	}
1969*a9fa9459Szrj       else
1970*a9fa9459Szrj 	{
1971*a9fa9459Szrj 	  forward_ref->next = t->tag_ptr->forward_ref;
1972*a9fa9459Szrj 	  t->tag_ptr->forward_ref = forward_ref;
1973*a9fa9459Szrj 	}
1974*a9fa9459Szrj 
1975*a9fa9459Szrj       (void) add_aux_sym_rndx (ST_RFDESCAPE, indexNil);
1976*a9fa9459Szrj       forward_ref->index_ptr
1977*a9fa9459Szrj 	= &vp->last->datum->aux[vp->objects_last_page - 1];
1978*a9fa9459Szrj 
1979*a9fa9459Szrj       (void) add_aux_sym_symint (file_index);
1980*a9fa9459Szrj       forward_ref->ifd_ptr
1981*a9fa9459Szrj 	= &vp->last->datum->aux[vp->objects_last_page - 1];
1982*a9fa9459Szrj     }
1983*a9fa9459Szrj 
1984*a9fa9459Szrj   /* Add information about array bounds if they exist.  */
1985*a9fa9459Szrj   for (i = 0; i < t->num_dims; i++)
1986*a9fa9459Szrj     {
1987*a9fa9459Szrj       (void) add_aux_sym_rndx (ST_RFDESCAPE,
1988*a9fa9459Szrj 			       cur_file_ptr->int_type);
1989*a9fa9459Szrj 
1990*a9fa9459Szrj       (void) add_aux_sym_symint (cur_file_ptr->file_index);	/* file index*/
1991*a9fa9459Szrj       (void) add_aux_sym_symint ((symint_t) 0);			/* low bound */
1992*a9fa9459Szrj       (void) add_aux_sym_symint (t->dimensions[i] - 1);		/* high bound*/
1993*a9fa9459Szrj       (void) add_aux_sym_symint ((t->dimensions[i] == 0)	/* stride */
1994*a9fa9459Szrj 				 ? 0
1995*a9fa9459Szrj 				 : (t->sizes[i] * 8) / t->dimensions[i]);
1996*a9fa9459Szrj     };
1997*a9fa9459Szrj 
1998*a9fa9459Szrj   /* NOTE:  Mips documentation claims that the bitfield width goes here.
1999*a9fa9459Szrj      But it needs to be emitted earlier.  */
2000*a9fa9459Szrj 
2001*a9fa9459Szrj   return ret;
2002*a9fa9459Szrj }
2003*a9fa9459Szrj 
2004*a9fa9459Szrj /* Add a tag to the tag table (unless it already exists).  */
2005*a9fa9459Szrj 
2006*a9fa9459Szrj static tag_t *
get_tag(const char * tag,localsym_t * sym,bt_t basic_type)2007*a9fa9459Szrj get_tag (const char *tag,	/* tag name */
2008*a9fa9459Szrj 	 localsym_t *sym,	/* tag start block */
2009*a9fa9459Szrj 	 bt_t basic_type	/* bt_Struct, bt_Union, or bt_Enum */)
2010*a9fa9459Szrj {
2011*a9fa9459Szrj   shash_t *hash_ptr;
2012*a9fa9459Szrj   const char *err;
2013*a9fa9459Szrj   tag_t *tag_ptr;
2014*a9fa9459Szrj 
2015*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
2016*a9fa9459Szrj     as_fatal (_("no current file pointer"));
2017*a9fa9459Szrj 
2018*a9fa9459Szrj   hash_ptr = (shash_t *) hash_find (tag_hash, tag);
2019*a9fa9459Szrj 
2020*a9fa9459Szrj   if (hash_ptr != (shash_t *) NULL
2021*a9fa9459Szrj       && hash_ptr->tag_ptr != (tag_t *) NULL)
2022*a9fa9459Szrj     {
2023*a9fa9459Szrj       tag_ptr = hash_ptr->tag_ptr;
2024*a9fa9459Szrj       if (sym != (localsym_t *) NULL)
2025*a9fa9459Szrj 	{
2026*a9fa9459Szrj 	  tag_ptr->basic_type = basic_type;
2027*a9fa9459Szrj 	  tag_ptr->ifd        = cur_file_ptr->file_index;
2028*a9fa9459Szrj 	  tag_ptr->sym        = sym;
2029*a9fa9459Szrj 	}
2030*a9fa9459Szrj       return tag_ptr;
2031*a9fa9459Szrj     }
2032*a9fa9459Szrj 
2033*a9fa9459Szrj   if (hash_ptr == (shash_t *) NULL)
2034*a9fa9459Szrj     {
2035*a9fa9459Szrj       char *perm;
2036*a9fa9459Szrj 
2037*a9fa9459Szrj       perm = xstrdup (tag);
2038*a9fa9459Szrj       hash_ptr = allocate_shash ();
2039*a9fa9459Szrj       err = hash_insert (tag_hash, perm, (char *) hash_ptr);
2040*a9fa9459Szrj       if (err)
2041*a9fa9459Szrj 	as_fatal (_("inserting \"%s\" into tag hash table: %s"),
2042*a9fa9459Szrj 		  tag, err);
2043*a9fa9459Szrj       hash_ptr->string = perm;
2044*a9fa9459Szrj     }
2045*a9fa9459Szrj 
2046*a9fa9459Szrj   tag_ptr = allocate_tag ();
2047*a9fa9459Szrj   tag_ptr->forward_ref	= (forward_t *) NULL;
2048*a9fa9459Szrj   tag_ptr->hash_ptr	= hash_ptr;
2049*a9fa9459Szrj   tag_ptr->same_name	= hash_ptr->tag_ptr;
2050*a9fa9459Szrj   tag_ptr->basic_type	= basic_type;
2051*a9fa9459Szrj   tag_ptr->sym		= sym;
2052*a9fa9459Szrj   tag_ptr->ifd		= ((sym == (localsym_t *) NULL)
2053*a9fa9459Szrj 			   ? (symint_t) -1
2054*a9fa9459Szrj 			   : cur_file_ptr->file_index);
2055*a9fa9459Szrj   tag_ptr->same_block	= cur_tag_head->first_tag;
2056*a9fa9459Szrj 
2057*a9fa9459Szrj   cur_tag_head->first_tag = tag_ptr;
2058*a9fa9459Szrj   hash_ptr->tag_ptr	  = tag_ptr;
2059*a9fa9459Szrj 
2060*a9fa9459Szrj   return tag_ptr;
2061*a9fa9459Szrj }
2062*a9fa9459Szrj 
2063*a9fa9459Szrj /* Add an unknown {struct, union, enum} tag.  */
2064*a9fa9459Szrj 
2065*a9fa9459Szrj static void
add_unknown_tag(tag_t * ptag)2066*a9fa9459Szrj add_unknown_tag (tag_t *ptag /* pointer to tag information */)
2067*a9fa9459Szrj {
2068*a9fa9459Szrj   shash_t *hash_ptr	= ptag->hash_ptr;
2069*a9fa9459Szrj   char *name		= hash_ptr->string;
2070*a9fa9459Szrj   localsym_t *sym;
2071*a9fa9459Szrj   forward_t **pf;
2072*a9fa9459Szrj 
2073*a9fa9459Szrj #ifdef ECOFF_DEBUG
2074*a9fa9459Szrj   if (debug > 1)
2075*a9fa9459Szrj     {
2076*a9fa9459Szrj       char *agg_type = "{unknown aggregate type}";
2077*a9fa9459Szrj       switch (ptag->basic_type)
2078*a9fa9459Szrj 	{
2079*a9fa9459Szrj 	case bt_Struct:	agg_type = "struct";	break;
2080*a9fa9459Szrj 	case bt_Union:	agg_type = "union";	break;
2081*a9fa9459Szrj 	case bt_Enum:	agg_type = "enum";	break;
2082*a9fa9459Szrj 	default:				break;
2083*a9fa9459Szrj 	}
2084*a9fa9459Szrj 
2085*a9fa9459Szrj       fprintf (stderr, "unknown %s %.*s found\n", agg_type,
2086*a9fa9459Szrj 	       hash_ptr->len, name_start);
2087*a9fa9459Szrj     }
2088*a9fa9459Szrj #endif
2089*a9fa9459Szrj 
2090*a9fa9459Szrj   sym = add_ecoff_symbol (name,
2091*a9fa9459Szrj 			  st_Block,
2092*a9fa9459Szrj 			  sc_Info,
2093*a9fa9459Szrj 			  (symbolS *) NULL,
2094*a9fa9459Szrj 			  (bfd_vma) 0,
2095*a9fa9459Szrj 			  (symint_t) 0,
2096*a9fa9459Szrj 			  (symint_t) 0);
2097*a9fa9459Szrj 
2098*a9fa9459Szrj   (void) add_ecoff_symbol (name,
2099*a9fa9459Szrj 			   st_End,
2100*a9fa9459Szrj 			   sc_Info,
2101*a9fa9459Szrj 			   (symbolS *) NULL,
2102*a9fa9459Szrj 			   (bfd_vma) 0,
2103*a9fa9459Szrj 			   (symint_t) 0,
2104*a9fa9459Szrj 			   (symint_t) 0);
2105*a9fa9459Szrj 
2106*a9fa9459Szrj   for (pf = &sym->forward_ref; *pf != (forward_t *) NULL; pf = &(*pf)->next)
2107*a9fa9459Szrj     ;
2108*a9fa9459Szrj   *pf = ptag->forward_ref;
2109*a9fa9459Szrj }
2110*a9fa9459Szrj 
2111*a9fa9459Szrj /* Add a procedure to the current file's list of procedures, and record
2112*a9fa9459Szrj    this is the current procedure.  */
2113*a9fa9459Szrj 
2114*a9fa9459Szrj static void
add_procedure(char * func)2115*a9fa9459Szrj add_procedure (char *func /* func name */)
2116*a9fa9459Szrj {
2117*a9fa9459Szrj   varray_t *vp;
2118*a9fa9459Szrj   proc_t *new_proc_ptr;
2119*a9fa9459Szrj   symbolS *sym;
2120*a9fa9459Szrj 
2121*a9fa9459Szrj #ifdef ECOFF_DEBUG
2122*a9fa9459Szrj   if (debug)
2123*a9fa9459Szrj     fputc ('\n', stderr);
2124*a9fa9459Szrj #endif
2125*a9fa9459Szrj 
2126*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
2127*a9fa9459Szrj     as_fatal (_("no current file pointer"));
2128*a9fa9459Szrj 
2129*a9fa9459Szrj   vp = &cur_file_ptr->procs;
2130*a9fa9459Szrj 
2131*a9fa9459Szrj   if (vp->objects_last_page == vp->objects_per_page)
2132*a9fa9459Szrj     add_varray_page (vp);
2133*a9fa9459Szrj 
2134*a9fa9459Szrj   cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[vp->objects_last_page++];
2135*a9fa9459Szrj 
2136*a9fa9459Szrj   if (first_proc_ptr == (proc_t *) NULL)
2137*a9fa9459Szrj     first_proc_ptr = new_proc_ptr;
2138*a9fa9459Szrj 
2139*a9fa9459Szrj   vp->num_allocated++;
2140*a9fa9459Szrj 
2141*a9fa9459Szrj   new_proc_ptr->pdr.isym = -1;
2142*a9fa9459Szrj   new_proc_ptr->pdr.iline = -1;
2143*a9fa9459Szrj   new_proc_ptr->pdr.lnLow = -1;
2144*a9fa9459Szrj   new_proc_ptr->pdr.lnHigh = -1;
2145*a9fa9459Szrj 
2146*a9fa9459Szrj   /* Set the BSF_FUNCTION flag for the symbol.  */
2147*a9fa9459Szrj   sym = symbol_find_or_make (func);
2148*a9fa9459Szrj   symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
2149*a9fa9459Szrj 
2150*a9fa9459Szrj   /* Push the start of the function.  */
2151*a9fa9459Szrj   new_proc_ptr->sym = add_ecoff_symbol ((const char *) NULL, st_Proc, sc_Text,
2152*a9fa9459Szrj 					sym, (bfd_vma) 0, (symint_t) 0,
2153*a9fa9459Szrj 					(symint_t) 0);
2154*a9fa9459Szrj 
2155*a9fa9459Szrj   ++proc_cnt;
2156*a9fa9459Szrj 
2157*a9fa9459Szrj   /* Fill in the linenos preceding the .ent, if any.  */
2158*a9fa9459Szrj   if (noproc_lineno != (lineno_list_t *) NULL)
2159*a9fa9459Szrj     {
2160*a9fa9459Szrj       lineno_list_t *l;
2161*a9fa9459Szrj 
2162*a9fa9459Szrj       for (l = noproc_lineno; l != (lineno_list_t *) NULL; l = l->next)
2163*a9fa9459Szrj 	l->proc = new_proc_ptr;
2164*a9fa9459Szrj       *last_lineno_ptr = noproc_lineno;
2165*a9fa9459Szrj       while (*last_lineno_ptr != NULL)
2166*a9fa9459Szrj 	{
2167*a9fa9459Szrj 	  last_lineno = *last_lineno_ptr;
2168*a9fa9459Szrj 	  last_lineno_ptr = &last_lineno->next;
2169*a9fa9459Szrj 	}
2170*a9fa9459Szrj       noproc_lineno = (lineno_list_t *) NULL;
2171*a9fa9459Szrj     }
2172*a9fa9459Szrj }
2173*a9fa9459Szrj 
2174*a9fa9459Szrj symbolS *
ecoff_get_cur_proc_sym(void)2175*a9fa9459Szrj ecoff_get_cur_proc_sym (void)
2176*a9fa9459Szrj {
2177*a9fa9459Szrj   return (cur_proc_ptr ? cur_proc_ptr->sym->as_sym : NULL);
2178*a9fa9459Szrj }
2179*a9fa9459Szrj 
2180*a9fa9459Szrj /* Add a new filename, and set up all of the file relative
2181*a9fa9459Szrj    virtual arrays (strings, symbols, aux syms, etc.).  Record
2182*a9fa9459Szrj    where the current file structure lives.  */
2183*a9fa9459Szrj 
2184*a9fa9459Szrj static void
add_file(const char * file_name,int indx ATTRIBUTE_UNUSED,int fake)2185*a9fa9459Szrj add_file (const char *file_name, int indx ATTRIBUTE_UNUSED, int fake)
2186*a9fa9459Szrj {
2187*a9fa9459Szrj   int first_ch;
2188*a9fa9459Szrj   efdr_t *fil_ptr;
2189*a9fa9459Szrj 
2190*a9fa9459Szrj #ifdef ECOFF_DEBUG
2191*a9fa9459Szrj   if (debug)
2192*a9fa9459Szrj     fprintf (stderr, "\tfile\t%.*s\n", len, file_start);
2193*a9fa9459Szrj #endif
2194*a9fa9459Szrj 
2195*a9fa9459Szrj   /* If the file name is NULL, then no .file symbol appeared, and we
2196*a9fa9459Szrj      want to use the actual file name.  */
2197*a9fa9459Szrj   if (file_name == (const char *) NULL)
2198*a9fa9459Szrj     {
2199*a9fa9459Szrj       if (first_file != (efdr_t *) NULL)
2200*a9fa9459Szrj 	as_fatal (_("fake .file after real one"));
2201*a9fa9459Szrj       file_name = as_where ((unsigned int *) NULL);
2202*a9fa9459Szrj 
2203*a9fa9459Szrj       /* Automatically generate ECOFF debugging information, since I
2204*a9fa9459Szrj          think that's what other ECOFF assemblers do.  We don't do
2205*a9fa9459Szrj          this if we see a .file directive with a string, since that
2206*a9fa9459Szrj          implies that some sort of debugging information is being
2207*a9fa9459Szrj          provided.  */
2208*a9fa9459Szrj       if (! symbol_table_frozen && debug_type == DEBUG_UNSPECIFIED)
2209*a9fa9459Szrj 	debug_type = DEBUG_ECOFF;
2210*a9fa9459Szrj     }
2211*a9fa9459Szrj   else if (debug_type == DEBUG_UNSPECIFIED)
2212*a9fa9459Szrj     debug_type = DEBUG_NONE;
2213*a9fa9459Szrj 
2214*a9fa9459Szrj #ifndef NO_LISTING
2215*a9fa9459Szrj   if (listing)
2216*a9fa9459Szrj     listing_source_file (file_name);
2217*a9fa9459Szrj #endif
2218*a9fa9459Szrj 
2219*a9fa9459Szrj   current_stabs_filename = file_name;
2220*a9fa9459Szrj 
2221*a9fa9459Szrj   /* If we're creating stabs, then we don't actually make a new FDR.
2222*a9fa9459Szrj      Instead, we just create a stabs symbol.  */
2223*a9fa9459Szrj   if (stabs_seen)
2224*a9fa9459Szrj     {
2225*a9fa9459Szrj       (void) add_ecoff_symbol (file_name, st_Nil, sc_Nil,
2226*a9fa9459Szrj 			       symbol_new ("L0\001", now_seg,
2227*a9fa9459Szrj 					   (valueT) frag_now_fix (),
2228*a9fa9459Szrj 					   frag_now),
2229*a9fa9459Szrj 			       (bfd_vma) 0, 0, ECOFF_MARK_STAB (N_SOL));
2230*a9fa9459Szrj       return;
2231*a9fa9459Szrj     }
2232*a9fa9459Szrj 
2233*a9fa9459Szrj   first_ch = *file_name;
2234*a9fa9459Szrj 
2235*a9fa9459Szrj   /* FIXME: We can't safely merge files which have line number
2236*a9fa9459Szrj      information (fMerge will be zero in this case).  Otherwise, we
2237*a9fa9459Szrj      get incorrect line number debugging info.  See for instance
2238*a9fa9459Szrj      ecoff_build_lineno, which will end up setting all file->fdr.*
2239*a9fa9459Szrj      fields multiple times, resulting in incorrect debug info.  In
2240*a9fa9459Szrj      order to make this work right, all line number and symbol info
2241*a9fa9459Szrj      for the same source file has to be adjacent in the object file,
2242*a9fa9459Szrj      so that a single file descriptor can be used to point to them.
2243*a9fa9459Szrj      This would require maintaining file specific lists of line
2244*a9fa9459Szrj      numbers and symbols for each file, so that they can be merged
2245*a9fa9459Szrj      together (or output together) when two .file pseudo-ops are
2246*a9fa9459Szrj      merged into one file descriptor.  */
2247*a9fa9459Szrj 
2248*a9fa9459Szrj   /* See if the file has already been created.  */
2249*a9fa9459Szrj   for (fil_ptr = first_file;
2250*a9fa9459Szrj        fil_ptr != (efdr_t *) NULL;
2251*a9fa9459Szrj        fil_ptr = fil_ptr->next_file)
2252*a9fa9459Szrj     {
2253*a9fa9459Szrj       if (first_ch == fil_ptr->name[0]
2254*a9fa9459Szrj 	  && filename_cmp (file_name, fil_ptr->name) == 0
2255*a9fa9459Szrj 	  && fil_ptr->fdr.fMerge)
2256*a9fa9459Szrj 	{
2257*a9fa9459Szrj 	  cur_file_ptr = fil_ptr;
2258*a9fa9459Szrj 	  if (! fake)
2259*a9fa9459Szrj 	    cur_file_ptr->fake = 0;
2260*a9fa9459Szrj 	  break;
2261*a9fa9459Szrj 	}
2262*a9fa9459Szrj     }
2263*a9fa9459Szrj 
2264*a9fa9459Szrj   /* If this is a new file, create it.  */
2265*a9fa9459Szrj   if (fil_ptr == (efdr_t *) NULL)
2266*a9fa9459Szrj     {
2267*a9fa9459Szrj       if (file_desc.objects_last_page == file_desc.objects_per_page)
2268*a9fa9459Szrj 	add_varray_page (&file_desc);
2269*a9fa9459Szrj 
2270*a9fa9459Szrj       fil_ptr = cur_file_ptr =
2271*a9fa9459Szrj 	&file_desc.last->datum->file[file_desc.objects_last_page++];
2272*a9fa9459Szrj       *fil_ptr = init_file;
2273*a9fa9459Szrj 
2274*a9fa9459Szrj       fil_ptr->file_index = current_file_idx++;
2275*a9fa9459Szrj       ++file_desc.num_allocated;
2276*a9fa9459Szrj 
2277*a9fa9459Szrj       fil_ptr->fake = fake;
2278*a9fa9459Szrj 
2279*a9fa9459Szrj       /* Allocate the string hash table.  */
2280*a9fa9459Szrj       fil_ptr->str_hash = hash_new ();
2281*a9fa9459Szrj 
2282*a9fa9459Szrj       /* Make sure 0 byte in string table is null  */
2283*a9fa9459Szrj       add_string (&fil_ptr->strings,
2284*a9fa9459Szrj 		  fil_ptr->str_hash,
2285*a9fa9459Szrj 		  "",
2286*a9fa9459Szrj 		  (shash_t **)0);
2287*a9fa9459Szrj 
2288*a9fa9459Szrj       if (strlen (file_name) > PAGE_USIZE - 2)
2289*a9fa9459Szrj 	as_fatal (_("filename goes over one page boundary"));
2290*a9fa9459Szrj 
2291*a9fa9459Szrj       /* Push the start of the filename. We assume that the filename
2292*a9fa9459Szrj          will be stored at string offset 1.  */
2293*a9fa9459Szrj       (void) add_ecoff_symbol (file_name, st_File, sc_Text,
2294*a9fa9459Szrj 			       (symbolS *) NULL, (bfd_vma) 0,
2295*a9fa9459Szrj 			       (symint_t) 0, (symint_t) 0);
2296*a9fa9459Szrj       fil_ptr->fdr.rss = 1;
2297*a9fa9459Szrj       fil_ptr->name = &fil_ptr->strings.last->datum->byte[1];
2298*a9fa9459Szrj 
2299*a9fa9459Szrj       /* Update the linked list of file descriptors.  */
2300*a9fa9459Szrj       *last_file_ptr = fil_ptr;
2301*a9fa9459Szrj       last_file_ptr = &fil_ptr->next_file;
2302*a9fa9459Szrj 
2303*a9fa9459Szrj       /* Add void & int types to the file (void should be first to catch
2304*a9fa9459Szrj          errant 0's within the index fields).  */
2305*a9fa9459Szrj       fil_ptr->void_type = add_aux_sym_tir (&void_type_info,
2306*a9fa9459Szrj 					    hash_yes,
2307*a9fa9459Szrj 					    &cur_file_ptr->thash_head[0]);
2308*a9fa9459Szrj 
2309*a9fa9459Szrj       fil_ptr->int_type = add_aux_sym_tir (&int_type_info,
2310*a9fa9459Szrj 					   hash_yes,
2311*a9fa9459Szrj 					   &cur_file_ptr->thash_head[0]);
2312*a9fa9459Szrj     }
2313*a9fa9459Szrj }
2314*a9fa9459Szrj 
2315*a9fa9459Szrj /* This function is called when the assembler notices a preprocessor
2316*a9fa9459Szrj    directive switching to a new file.  This will not happen in
2317*a9fa9459Szrj    compiler output, only in hand coded assembler.  */
2318*a9fa9459Szrj 
2319*a9fa9459Szrj void
ecoff_new_file(const char * name,int appfile ATTRIBUTE_UNUSED)2320*a9fa9459Szrj ecoff_new_file (const char *name, int appfile ATTRIBUTE_UNUSED)
2321*a9fa9459Szrj {
2322*a9fa9459Szrj   if (cur_file_ptr != NULL && filename_cmp (cur_file_ptr->name, name) == 0)
2323*a9fa9459Szrj     return;
2324*a9fa9459Szrj   add_file (name, 0, 0);
2325*a9fa9459Szrj 
2326*a9fa9459Szrj   /* This is a hand coded assembler file, so automatically turn on
2327*a9fa9459Szrj      debugging information.  */
2328*a9fa9459Szrj   if (debug_type == DEBUG_UNSPECIFIED)
2329*a9fa9459Szrj     debug_type = DEBUG_ECOFF;
2330*a9fa9459Szrj }
2331*a9fa9459Szrj 
2332*a9fa9459Szrj #ifdef ECOFF_DEBUG
2333*a9fa9459Szrj 
2334*a9fa9459Szrj /* Convert storage class to string.  */
2335*a9fa9459Szrj 
2336*a9fa9459Szrj static char *
sc_to_string(storage_class)2337*a9fa9459Szrj sc_to_string (storage_class)
2338*a9fa9459Szrj      sc_t storage_class;
2339*a9fa9459Szrj {
2340*a9fa9459Szrj   switch (storage_class)
2341*a9fa9459Szrj     {
2342*a9fa9459Szrj     case sc_Nil:	 return "Nil,";
2343*a9fa9459Szrj     case sc_Text:	 return "Text,";
2344*a9fa9459Szrj     case sc_Data:	 return "Data,";
2345*a9fa9459Szrj     case sc_Bss:	 return "Bss,";
2346*a9fa9459Szrj     case sc_Register:	 return "Register,";
2347*a9fa9459Szrj     case sc_Abs:	 return "Abs,";
2348*a9fa9459Szrj     case sc_Undefined:	 return "Undefined,";
2349*a9fa9459Szrj     case sc_CdbLocal:	 return "CdbLocal,";
2350*a9fa9459Szrj     case sc_Bits:	 return "Bits,";
2351*a9fa9459Szrj     case sc_CdbSystem:	 return "CdbSystem,";
2352*a9fa9459Szrj     case sc_RegImage:	 return "RegImage,";
2353*a9fa9459Szrj     case sc_Info:	 return "Info,";
2354*a9fa9459Szrj     case sc_UserStruct:	 return "UserStruct,";
2355*a9fa9459Szrj     case sc_SData:	 return "SData,";
2356*a9fa9459Szrj     case sc_SBss:	 return "SBss,";
2357*a9fa9459Szrj     case sc_RData:	 return "RData,";
2358*a9fa9459Szrj     case sc_Var:	 return "Var,";
2359*a9fa9459Szrj     case sc_Common:	 return "Common,";
2360*a9fa9459Szrj     case sc_SCommon:	 return "SCommon,";
2361*a9fa9459Szrj     case sc_VarRegister: return "VarRegister,";
2362*a9fa9459Szrj     case sc_Variant:	 return "Variant,";
2363*a9fa9459Szrj     case sc_SUndefined:	 return "SUndefined,";
2364*a9fa9459Szrj     case sc_Init:	 return "Init,";
2365*a9fa9459Szrj     case sc_Max:	 return "Max,";
2366*a9fa9459Szrj     }
2367*a9fa9459Szrj 
2368*a9fa9459Szrj   return "???,";
2369*a9fa9459Szrj }
2370*a9fa9459Szrj 
2371*a9fa9459Szrj #endif /* DEBUG */
2372*a9fa9459Szrj 
2373*a9fa9459Szrj #ifdef ECOFF_DEBUG
2374*a9fa9459Szrj 
2375*a9fa9459Szrj /* Convert symbol type to string.  */
2376*a9fa9459Szrj 
2377*a9fa9459Szrj static char *
st_to_string(symbol_type)2378*a9fa9459Szrj st_to_string (symbol_type)
2379*a9fa9459Szrj      st_t symbol_type;
2380*a9fa9459Szrj {
2381*a9fa9459Szrj   switch (symbol_type)
2382*a9fa9459Szrj     {
2383*a9fa9459Szrj     case st_Nil:	return "Nil,";
2384*a9fa9459Szrj     case st_Global:	return "Global,";
2385*a9fa9459Szrj     case st_Static:	return "Static,";
2386*a9fa9459Szrj     case st_Param:	return "Param,";
2387*a9fa9459Szrj     case st_Local:	return "Local,";
2388*a9fa9459Szrj     case st_Label:	return "Label,";
2389*a9fa9459Szrj     case st_Proc:	return "Proc,";
2390*a9fa9459Szrj     case st_Block:	return "Block,";
2391*a9fa9459Szrj     case st_End:	return "End,";
2392*a9fa9459Szrj     case st_Member:	return "Member,";
2393*a9fa9459Szrj     case st_Typedef:	return "Typedef,";
2394*a9fa9459Szrj     case st_File:	return "File,";
2395*a9fa9459Szrj     case st_RegReloc:	return "RegReloc,";
2396*a9fa9459Szrj     case st_Forward:	return "Forward,";
2397*a9fa9459Szrj     case st_StaticProc:	return "StaticProc,";
2398*a9fa9459Szrj     case st_Constant:	return "Constant,";
2399*a9fa9459Szrj     case st_Str:	return "String,";
2400*a9fa9459Szrj     case st_Number:	return "Number,";
2401*a9fa9459Szrj     case st_Expr:	return "Expr,";
2402*a9fa9459Szrj     case st_Type:	return "Type,";
2403*a9fa9459Szrj     case st_Max:	return "Max,";
2404*a9fa9459Szrj     }
2405*a9fa9459Szrj 
2406*a9fa9459Szrj   return "???,";
2407*a9fa9459Szrj }
2408*a9fa9459Szrj 
2409*a9fa9459Szrj #endif /* DEBUG */
2410*a9fa9459Szrj 
2411*a9fa9459Szrj /* Parse .begin directives which have a label as the first argument
2412*a9fa9459Szrj    which gives the location of the start of the block.  */
2413*a9fa9459Szrj 
2414*a9fa9459Szrj void
ecoff_directive_begin(int ignore ATTRIBUTE_UNUSED)2415*a9fa9459Szrj ecoff_directive_begin (int ignore ATTRIBUTE_UNUSED)
2416*a9fa9459Szrj {
2417*a9fa9459Szrj   char *name;
2418*a9fa9459Szrj   char name_end;
2419*a9fa9459Szrj 
2420*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
2421*a9fa9459Szrj     {
2422*a9fa9459Szrj       as_warn (_(".begin directive without a preceding .file directive"));
2423*a9fa9459Szrj       demand_empty_rest_of_line ();
2424*a9fa9459Szrj       return;
2425*a9fa9459Szrj     }
2426*a9fa9459Szrj 
2427*a9fa9459Szrj   if (cur_proc_ptr == (proc_t *) NULL)
2428*a9fa9459Szrj     {
2429*a9fa9459Szrj       as_warn (_(".begin directive without a preceding .ent directive"));
2430*a9fa9459Szrj       demand_empty_rest_of_line ();
2431*a9fa9459Szrj       return;
2432*a9fa9459Szrj     }
2433*a9fa9459Szrj 
2434*a9fa9459Szrj   name_end = get_symbol_name (&name);
2435*a9fa9459Szrj 
2436*a9fa9459Szrj   (void) add_ecoff_symbol ((const char *) NULL, st_Block, sc_Text,
2437*a9fa9459Szrj 			   symbol_find_or_make (name),
2438*a9fa9459Szrj 			   (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
2439*a9fa9459Szrj 
2440*a9fa9459Szrj   (void) restore_line_pointer (name_end);
2441*a9fa9459Szrj 
2442*a9fa9459Szrj   /* The line number follows, but we don't use it.  */
2443*a9fa9459Szrj   (void) get_absolute_expression ();
2444*a9fa9459Szrj   demand_empty_rest_of_line ();
2445*a9fa9459Szrj }
2446*a9fa9459Szrj 
2447*a9fa9459Szrj /* Parse .bend directives which have a label as the first argument
2448*a9fa9459Szrj    which gives the location of the end of the block.  */
2449*a9fa9459Szrj 
2450*a9fa9459Szrj void
ecoff_directive_bend(int ignore ATTRIBUTE_UNUSED)2451*a9fa9459Szrj ecoff_directive_bend (int ignore ATTRIBUTE_UNUSED)
2452*a9fa9459Szrj {
2453*a9fa9459Szrj   char *name;
2454*a9fa9459Szrj   char name_end;
2455*a9fa9459Szrj   symbolS *endsym;
2456*a9fa9459Szrj 
2457*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
2458*a9fa9459Szrj     {
2459*a9fa9459Szrj       as_warn (_(".bend directive without a preceding .file directive"));
2460*a9fa9459Szrj       demand_empty_rest_of_line ();
2461*a9fa9459Szrj       return;
2462*a9fa9459Szrj     }
2463*a9fa9459Szrj 
2464*a9fa9459Szrj   if (cur_proc_ptr == (proc_t *) NULL)
2465*a9fa9459Szrj     {
2466*a9fa9459Szrj       as_warn (_(".bend directive without a preceding .ent directive"));
2467*a9fa9459Szrj       demand_empty_rest_of_line ();
2468*a9fa9459Szrj       return;
2469*a9fa9459Szrj     }
2470*a9fa9459Szrj 
2471*a9fa9459Szrj   name_end = get_symbol_name (&name);
2472*a9fa9459Szrj 
2473*a9fa9459Szrj   /* The value is the distance between the .bend directive and the
2474*a9fa9459Szrj      corresponding symbol.  We fill in the offset when we write out
2475*a9fa9459Szrj      the symbol.  */
2476*a9fa9459Szrj   endsym = symbol_find (name);
2477*a9fa9459Szrj   if (endsym == (symbolS *) NULL)
2478*a9fa9459Szrj     as_warn (_(".bend directive names unknown symbol"));
2479*a9fa9459Szrj   else
2480*a9fa9459Szrj     (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym,
2481*a9fa9459Szrj 			     (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
2482*a9fa9459Szrj 
2483*a9fa9459Szrj   restore_line_pointer (name_end);
2484*a9fa9459Szrj 
2485*a9fa9459Szrj   /* The line number follows, but we don't use it.  */
2486*a9fa9459Szrj   (void) get_absolute_expression ();
2487*a9fa9459Szrj   demand_empty_rest_of_line ();
2488*a9fa9459Szrj }
2489*a9fa9459Szrj 
2490*a9fa9459Szrj /* COFF debugging information is provided as a series of directives
2491*a9fa9459Szrj    (.def, .scl, etc.).  We build up information as we read the
2492*a9fa9459Szrj    directives in the following static variables, and file it away when
2493*a9fa9459Szrj    we reach the .endef directive.  */
2494*a9fa9459Szrj static char *coff_sym_name;
2495*a9fa9459Szrj static type_info_t coff_type;
2496*a9fa9459Szrj static sc_t coff_storage_class;
2497*a9fa9459Szrj static st_t coff_symbol_typ;
2498*a9fa9459Szrj static int coff_is_function;
2499*a9fa9459Szrj static char *coff_tag;
2500*a9fa9459Szrj static valueT coff_value;
2501*a9fa9459Szrj static symbolS *coff_sym_value;
2502*a9fa9459Szrj static bfd_vma coff_sym_addend;
2503*a9fa9459Szrj static int coff_inside_enumeration;
2504*a9fa9459Szrj 
2505*a9fa9459Szrj /* Handle a .def directive: start defining a symbol.  */
2506*a9fa9459Szrj 
2507*a9fa9459Szrj void
ecoff_directive_def(int ignore ATTRIBUTE_UNUSED)2508*a9fa9459Szrj ecoff_directive_def (int ignore ATTRIBUTE_UNUSED)
2509*a9fa9459Szrj {
2510*a9fa9459Szrj   char *name;
2511*a9fa9459Szrj   char name_end;
2512*a9fa9459Szrj 
2513*a9fa9459Szrj   ecoff_debugging_seen = 1;
2514*a9fa9459Szrj 
2515*a9fa9459Szrj   SKIP_WHITESPACE ();
2516*a9fa9459Szrj 
2517*a9fa9459Szrj   name_end = get_symbol_name (&name);
2518*a9fa9459Szrj 
2519*a9fa9459Szrj   if (coff_sym_name != (char *) NULL)
2520*a9fa9459Szrj     as_warn (_(".def pseudo-op used inside of .def/.endef; ignored"));
2521*a9fa9459Szrj   else if (*name == '\0')
2522*a9fa9459Szrj     as_warn (_("empty symbol name in .def; ignored"));
2523*a9fa9459Szrj   else
2524*a9fa9459Szrj     {
2525*a9fa9459Szrj       if (coff_sym_name != (char *) NULL)
2526*a9fa9459Szrj 	free (coff_sym_name);
2527*a9fa9459Szrj       if (coff_tag != (char *) NULL)
2528*a9fa9459Szrj 	free (coff_tag);
2529*a9fa9459Szrj 
2530*a9fa9459Szrj       coff_sym_name = xstrdup (name);
2531*a9fa9459Szrj       coff_type = type_info_init;
2532*a9fa9459Szrj       coff_storage_class = sc_Nil;
2533*a9fa9459Szrj       coff_symbol_typ = st_Nil;
2534*a9fa9459Szrj       coff_is_function = 0;
2535*a9fa9459Szrj       coff_tag = (char *) NULL;
2536*a9fa9459Szrj       coff_value = 0;
2537*a9fa9459Szrj       coff_sym_value = (symbolS *) NULL;
2538*a9fa9459Szrj       coff_sym_addend = 0;
2539*a9fa9459Szrj     }
2540*a9fa9459Szrj 
2541*a9fa9459Szrj   restore_line_pointer (name_end);
2542*a9fa9459Szrj 
2543*a9fa9459Szrj   demand_empty_rest_of_line ();
2544*a9fa9459Szrj }
2545*a9fa9459Szrj 
2546*a9fa9459Szrj /* Handle a .dim directive, used to give dimensions for an array.  The
2547*a9fa9459Szrj    arguments are comma separated numbers.  mips-tfile assumes that
2548*a9fa9459Szrj    there will not be more than 6 dimensions, and gdb won't read any
2549*a9fa9459Szrj    more than that anyhow, so I will also make that assumption.  */
2550*a9fa9459Szrj 
2551*a9fa9459Szrj void
ecoff_directive_dim(int ignore ATTRIBUTE_UNUSED)2552*a9fa9459Szrj ecoff_directive_dim (int ignore ATTRIBUTE_UNUSED)
2553*a9fa9459Szrj {
2554*a9fa9459Szrj   int dimens[N_TQ];
2555*a9fa9459Szrj   int i;
2556*a9fa9459Szrj 
2557*a9fa9459Szrj   if (coff_sym_name == (char *) NULL)
2558*a9fa9459Szrj     {
2559*a9fa9459Szrj       as_warn (_(".dim pseudo-op used outside of .def/.endef; ignored"));
2560*a9fa9459Szrj       demand_empty_rest_of_line ();
2561*a9fa9459Szrj       return;
2562*a9fa9459Szrj     }
2563*a9fa9459Szrj 
2564*a9fa9459Szrj   for (i = 0; i < N_TQ; i++)
2565*a9fa9459Szrj     {
2566*a9fa9459Szrj       SKIP_WHITESPACE ();
2567*a9fa9459Szrj       dimens[i] = get_absolute_expression ();
2568*a9fa9459Szrj       if (*input_line_pointer == ',')
2569*a9fa9459Szrj 	++input_line_pointer;
2570*a9fa9459Szrj       else
2571*a9fa9459Szrj 	{
2572*a9fa9459Szrj 	  if (*input_line_pointer != '\n'
2573*a9fa9459Szrj 	      && *input_line_pointer != ';')
2574*a9fa9459Szrj 	    as_warn (_("badly formed .dim directive"));
2575*a9fa9459Szrj 	  break;
2576*a9fa9459Szrj 	}
2577*a9fa9459Szrj     }
2578*a9fa9459Szrj 
2579*a9fa9459Szrj   if (i == N_TQ)
2580*a9fa9459Szrj     --i;
2581*a9fa9459Szrj 
2582*a9fa9459Szrj   /* The dimensions are stored away in reverse order.  */
2583*a9fa9459Szrj   for (; i >= 0; i--)
2584*a9fa9459Szrj     {
2585*a9fa9459Szrj       if (coff_type.num_dims >= N_TQ)
2586*a9fa9459Szrj 	{
2587*a9fa9459Szrj 	  as_warn (_("too many .dim entries"));
2588*a9fa9459Szrj 	  break;
2589*a9fa9459Szrj 	}
2590*a9fa9459Szrj       coff_type.dimensions[coff_type.num_dims] = dimens[i];
2591*a9fa9459Szrj       ++coff_type.num_dims;
2592*a9fa9459Szrj     }
2593*a9fa9459Szrj 
2594*a9fa9459Szrj   demand_empty_rest_of_line ();
2595*a9fa9459Szrj }
2596*a9fa9459Szrj 
2597*a9fa9459Szrj /* Handle a .scl directive, which sets the COFF storage class of the
2598*a9fa9459Szrj    symbol.  */
2599*a9fa9459Szrj 
2600*a9fa9459Szrj void
ecoff_directive_scl(int ignore ATTRIBUTE_UNUSED)2601*a9fa9459Szrj ecoff_directive_scl (int ignore ATTRIBUTE_UNUSED)
2602*a9fa9459Szrj {
2603*a9fa9459Szrj   long val;
2604*a9fa9459Szrj 
2605*a9fa9459Szrj   if (coff_sym_name == (char *) NULL)
2606*a9fa9459Szrj     {
2607*a9fa9459Szrj       as_warn (_(".scl pseudo-op used outside of .def/.endef; ignored"));
2608*a9fa9459Szrj       demand_empty_rest_of_line ();
2609*a9fa9459Szrj       return;
2610*a9fa9459Szrj     }
2611*a9fa9459Szrj 
2612*a9fa9459Szrj   val = get_absolute_expression ();
2613*a9fa9459Szrj 
2614*a9fa9459Szrj   coff_symbol_typ = map_coff_sym_type[val];
2615*a9fa9459Szrj   coff_storage_class = map_coff_storage[val];
2616*a9fa9459Szrj 
2617*a9fa9459Szrj   demand_empty_rest_of_line ();
2618*a9fa9459Szrj }
2619*a9fa9459Szrj 
2620*a9fa9459Szrj /* Handle a .size directive.  For some reason mips-tfile.c thinks that
2621*a9fa9459Szrj    .size can have multiple arguments.  We humor it, although gcc will
2622*a9fa9459Szrj    never generate more than one argument.  */
2623*a9fa9459Szrj 
2624*a9fa9459Szrj void
ecoff_directive_size(int ignore ATTRIBUTE_UNUSED)2625*a9fa9459Szrj ecoff_directive_size (int ignore ATTRIBUTE_UNUSED)
2626*a9fa9459Szrj {
2627*a9fa9459Szrj   int sizes[N_TQ];
2628*a9fa9459Szrj   int i;
2629*a9fa9459Szrj 
2630*a9fa9459Szrj   if (coff_sym_name == (char *) NULL)
2631*a9fa9459Szrj     {
2632*a9fa9459Szrj       as_warn (_(".size pseudo-op used outside of .def/.endef; ignored"));
2633*a9fa9459Szrj       demand_empty_rest_of_line ();
2634*a9fa9459Szrj       return;
2635*a9fa9459Szrj     }
2636*a9fa9459Szrj 
2637*a9fa9459Szrj   for (i = 0; i < N_TQ; i++)
2638*a9fa9459Szrj     {
2639*a9fa9459Szrj       SKIP_WHITESPACE ();
2640*a9fa9459Szrj       sizes[i] = get_absolute_expression ();
2641*a9fa9459Szrj       if (*input_line_pointer == ',')
2642*a9fa9459Szrj 	++input_line_pointer;
2643*a9fa9459Szrj       else
2644*a9fa9459Szrj 	{
2645*a9fa9459Szrj 	  if (*input_line_pointer != '\n'
2646*a9fa9459Szrj 	      && *input_line_pointer != ';')
2647*a9fa9459Szrj 	    as_warn (_("badly formed .size directive"));
2648*a9fa9459Szrj 	  break;
2649*a9fa9459Szrj 	}
2650*a9fa9459Szrj     }
2651*a9fa9459Szrj 
2652*a9fa9459Szrj   if (i == N_TQ)
2653*a9fa9459Szrj     --i;
2654*a9fa9459Szrj 
2655*a9fa9459Szrj   /* The sizes are stored away in reverse order.  */
2656*a9fa9459Szrj   for (; i >= 0; i--)
2657*a9fa9459Szrj     {
2658*a9fa9459Szrj       if (coff_type.num_sizes >= N_TQ)
2659*a9fa9459Szrj 	{
2660*a9fa9459Szrj 	  as_warn (_("too many .size entries"));
2661*a9fa9459Szrj 	  break;
2662*a9fa9459Szrj 	}
2663*a9fa9459Szrj       coff_type.sizes[coff_type.num_sizes] = sizes[i];
2664*a9fa9459Szrj       ++coff_type.num_sizes;
2665*a9fa9459Szrj     }
2666*a9fa9459Szrj 
2667*a9fa9459Szrj   demand_empty_rest_of_line ();
2668*a9fa9459Szrj }
2669*a9fa9459Szrj 
2670*a9fa9459Szrj /* Handle the .type directive, which gives the COFF type of the
2671*a9fa9459Szrj    symbol.  */
2672*a9fa9459Szrj 
2673*a9fa9459Szrj void
ecoff_directive_type(int ignore ATTRIBUTE_UNUSED)2674*a9fa9459Szrj ecoff_directive_type (int ignore ATTRIBUTE_UNUSED)
2675*a9fa9459Szrj {
2676*a9fa9459Szrj   long val;
2677*a9fa9459Szrj   tq_t *tq_ptr;
2678*a9fa9459Szrj   tq_t *tq_shft;
2679*a9fa9459Szrj 
2680*a9fa9459Szrj   if (coff_sym_name == (char *) NULL)
2681*a9fa9459Szrj     {
2682*a9fa9459Szrj       as_warn (_(".type pseudo-op used outside of .def/.endef; ignored"));
2683*a9fa9459Szrj       demand_empty_rest_of_line ();
2684*a9fa9459Szrj       return;
2685*a9fa9459Szrj     }
2686*a9fa9459Szrj 
2687*a9fa9459Szrj   val = get_absolute_expression ();
2688*a9fa9459Szrj 
2689*a9fa9459Szrj   coff_type.orig_type = BTYPE (val);
2690*a9fa9459Szrj   coff_type.basic_type = map_coff_types[coff_type.orig_type];
2691*a9fa9459Szrj 
2692*a9fa9459Szrj   tq_ptr = &coff_type.type_qualifiers[N_TQ];
2693*a9fa9459Szrj   while (val & ~N_BTMASK)
2694*a9fa9459Szrj     {
2695*a9fa9459Szrj       if (tq_ptr == &coff_type.type_qualifiers[0])
2696*a9fa9459Szrj 	{
2697*a9fa9459Szrj 	  /* FIXME: We could handle this by setting the continued bit.
2698*a9fa9459Szrj 	     There would still be a limit: the .type argument can not
2699*a9fa9459Szrj 	     be infinite.  */
2700*a9fa9459Szrj 	  as_warn (_("the type of %s is too complex; it will be simplified"),
2701*a9fa9459Szrj 		   coff_sym_name);
2702*a9fa9459Szrj 	  break;
2703*a9fa9459Szrj 	}
2704*a9fa9459Szrj       if (ISPTR (val))
2705*a9fa9459Szrj 	*--tq_ptr = tq_Ptr;
2706*a9fa9459Szrj       else if (ISFCN (val))
2707*a9fa9459Szrj 	*--tq_ptr = tq_Proc;
2708*a9fa9459Szrj       else if (ISARY (val))
2709*a9fa9459Szrj 	*--tq_ptr = tq_Array;
2710*a9fa9459Szrj       else
2711*a9fa9459Szrj 	as_fatal (_("Unrecognized .type argument"));
2712*a9fa9459Szrj 
2713*a9fa9459Szrj       val = DECREF (val);
2714*a9fa9459Szrj     }
2715*a9fa9459Szrj 
2716*a9fa9459Szrj   tq_shft = &coff_type.type_qualifiers[0];
2717*a9fa9459Szrj   while (tq_ptr != &coff_type.type_qualifiers[N_TQ])
2718*a9fa9459Szrj     *tq_shft++ = *tq_ptr++;
2719*a9fa9459Szrj 
2720*a9fa9459Szrj   if (tq_shft != &coff_type.type_qualifiers[0] && tq_shft[-1] == tq_Proc)
2721*a9fa9459Szrj     {
2722*a9fa9459Szrj       /* If this is a function, ignore it, so that we don't get two
2723*a9fa9459Szrj          entries (one from the .ent, and one for the .def that
2724*a9fa9459Szrj          precedes it).  Save the type information so that the end
2725*a9fa9459Szrj          block can properly add it after the begin block index.  For
2726*a9fa9459Szrj          MIPS knows what reason, we must strip off the function type
2727*a9fa9459Szrj          at this point.  */
2728*a9fa9459Szrj       coff_is_function = 1;
2729*a9fa9459Szrj       tq_shft[-1] = tq_Nil;
2730*a9fa9459Szrj     }
2731*a9fa9459Szrj 
2732*a9fa9459Szrj   while (tq_shft != &coff_type.type_qualifiers[N_TQ])
2733*a9fa9459Szrj     *tq_shft++ = tq_Nil;
2734*a9fa9459Szrj 
2735*a9fa9459Szrj   demand_empty_rest_of_line ();
2736*a9fa9459Szrj }
2737*a9fa9459Szrj 
2738*a9fa9459Szrj /* Handle the .tag directive, which gives the name of a structure,
2739*a9fa9459Szrj    union or enum.  */
2740*a9fa9459Szrj 
2741*a9fa9459Szrj void
ecoff_directive_tag(int ignore ATTRIBUTE_UNUSED)2742*a9fa9459Szrj ecoff_directive_tag (int ignore ATTRIBUTE_UNUSED)
2743*a9fa9459Szrj {
2744*a9fa9459Szrj   char *name;
2745*a9fa9459Szrj   char name_end;
2746*a9fa9459Szrj 
2747*a9fa9459Szrj   if (coff_sym_name == (char *) NULL)
2748*a9fa9459Szrj     {
2749*a9fa9459Szrj       as_warn (_(".tag pseudo-op used outside of .def/.endef; ignored"));
2750*a9fa9459Szrj       demand_empty_rest_of_line ();
2751*a9fa9459Szrj       return;
2752*a9fa9459Szrj     }
2753*a9fa9459Szrj 
2754*a9fa9459Szrj   name_end = get_symbol_name (&name);
2755*a9fa9459Szrj 
2756*a9fa9459Szrj   coff_tag = xstrdup (name);
2757*a9fa9459Szrj 
2758*a9fa9459Szrj   (void) restore_line_pointer (name_end);
2759*a9fa9459Szrj 
2760*a9fa9459Szrj   demand_empty_rest_of_line ();
2761*a9fa9459Szrj }
2762*a9fa9459Szrj 
2763*a9fa9459Szrj /* Handle the .val directive, which gives the value of the symbol.  It
2764*a9fa9459Szrj    may be the name of a static or global symbol.  */
2765*a9fa9459Szrj 
2766*a9fa9459Szrj void
ecoff_directive_val(int ignore ATTRIBUTE_UNUSED)2767*a9fa9459Szrj ecoff_directive_val (int ignore ATTRIBUTE_UNUSED)
2768*a9fa9459Szrj {
2769*a9fa9459Szrj   expressionS exp;
2770*a9fa9459Szrj 
2771*a9fa9459Szrj   if (coff_sym_name == (char *) NULL)
2772*a9fa9459Szrj     {
2773*a9fa9459Szrj       as_warn (_(".val pseudo-op used outside of .def/.endef; ignored"));
2774*a9fa9459Szrj       demand_empty_rest_of_line ();
2775*a9fa9459Szrj       return;
2776*a9fa9459Szrj     }
2777*a9fa9459Szrj 
2778*a9fa9459Szrj   expression (&exp);
2779*a9fa9459Szrj   if (exp.X_op != O_constant && exp.X_op != O_symbol)
2780*a9fa9459Szrj     {
2781*a9fa9459Szrj       as_bad (_(".val expression is too complex"));
2782*a9fa9459Szrj       demand_empty_rest_of_line ();
2783*a9fa9459Szrj       return;
2784*a9fa9459Szrj     }
2785*a9fa9459Szrj 
2786*a9fa9459Szrj   if (exp.X_op == O_constant)
2787*a9fa9459Szrj     coff_value = exp.X_add_number;
2788*a9fa9459Szrj   else
2789*a9fa9459Szrj     {
2790*a9fa9459Szrj       coff_sym_value = exp.X_add_symbol;
2791*a9fa9459Szrj       coff_sym_addend = exp.X_add_number;
2792*a9fa9459Szrj     }
2793*a9fa9459Szrj 
2794*a9fa9459Szrj   demand_empty_rest_of_line ();
2795*a9fa9459Szrj }
2796*a9fa9459Szrj 
2797*a9fa9459Szrj /* Handle the .endef directive, which terminates processing of COFF
2798*a9fa9459Szrj    debugging information for a symbol.  */
2799*a9fa9459Szrj 
2800*a9fa9459Szrj void
ecoff_directive_endef(int ignore ATTRIBUTE_UNUSED)2801*a9fa9459Szrj ecoff_directive_endef (int ignore ATTRIBUTE_UNUSED)
2802*a9fa9459Szrj {
2803*a9fa9459Szrj   char *name;
2804*a9fa9459Szrj   symint_t indx;
2805*a9fa9459Szrj   localsym_t *sym;
2806*a9fa9459Szrj 
2807*a9fa9459Szrj   demand_empty_rest_of_line ();
2808*a9fa9459Szrj 
2809*a9fa9459Szrj   if (coff_sym_name == (char *) NULL)
2810*a9fa9459Szrj     {
2811*a9fa9459Szrj       as_warn (_(".endef pseudo-op used before .def; ignored"));
2812*a9fa9459Szrj       return;
2813*a9fa9459Szrj     }
2814*a9fa9459Szrj 
2815*a9fa9459Szrj   name = coff_sym_name;
2816*a9fa9459Szrj   coff_sym_name = (char *) NULL;
2817*a9fa9459Szrj 
2818*a9fa9459Szrj   /* If the symbol is a static or external, we have already gotten the
2819*a9fa9459Szrj      appropriate type and class, so make sure we don't override those
2820*a9fa9459Szrj      values.  This is needed because there are some type and classes
2821*a9fa9459Szrj      that are not in COFF, such as short data, etc.  */
2822*a9fa9459Szrj   if (coff_sym_value != (symbolS *) NULL)
2823*a9fa9459Szrj     {
2824*a9fa9459Szrj       coff_symbol_typ = st_Nil;
2825*a9fa9459Szrj       coff_storage_class = sc_Nil;
2826*a9fa9459Szrj     }
2827*a9fa9459Szrj 
2828*a9fa9459Szrj   coff_type.extra_sizes = coff_tag != (char *) NULL;
2829*a9fa9459Szrj   if (coff_type.num_dims > 0)
2830*a9fa9459Szrj     {
2831*a9fa9459Szrj       int diff = coff_type.num_dims - coff_type.num_sizes;
2832*a9fa9459Szrj       int i = coff_type.num_dims - 1;
2833*a9fa9459Szrj       int j;
2834*a9fa9459Szrj 
2835*a9fa9459Szrj       if (coff_type.num_sizes != 1 || diff < 0)
2836*a9fa9459Szrj 	{
2837*a9fa9459Szrj 	  as_warn (_("bad COFF debugging information"));
2838*a9fa9459Szrj 	  return;
2839*a9fa9459Szrj 	}
2840*a9fa9459Szrj 
2841*a9fa9459Szrj       /* If this is an array, make sure the same number of dimensions
2842*a9fa9459Szrj          and sizes were passed, creating extra sizes for multiply
2843*a9fa9459Szrj          dimensioned arrays if not passed.  */
2844*a9fa9459Szrj       coff_type.extra_sizes = 0;
2845*a9fa9459Szrj       if (diff)
2846*a9fa9459Szrj 	{
2847*a9fa9459Szrj 	  j = (sizeof (coff_type.sizes) / sizeof (coff_type.sizes[0])) - 1;
2848*a9fa9459Szrj 	  while (j >= 0)
2849*a9fa9459Szrj 	    {
2850*a9fa9459Szrj 	      coff_type.sizes[j] = (((j - diff) >= 0)
2851*a9fa9459Szrj 				    ? coff_type.sizes[j - diff]
2852*a9fa9459Szrj 				    : 0);
2853*a9fa9459Szrj 	      j--;
2854*a9fa9459Szrj 	    }
2855*a9fa9459Szrj 
2856*a9fa9459Szrj 	  coff_type.num_sizes = i + 1;
2857*a9fa9459Szrj 	  for (i--; i >= 0; i--)
2858*a9fa9459Szrj 	    coff_type.sizes[i] = (coff_type.dimensions[i + 1] == 0
2859*a9fa9459Szrj 				  ? 0
2860*a9fa9459Szrj 				  : (coff_type.sizes[i + 1]
2861*a9fa9459Szrj 				     / coff_type.dimensions[i + 1]));
2862*a9fa9459Szrj 	}
2863*a9fa9459Szrj     }
2864*a9fa9459Szrj   else if (coff_symbol_typ == st_Member
2865*a9fa9459Szrj 	   && coff_type.num_sizes - coff_type.extra_sizes == 1)
2866*a9fa9459Szrj     {
2867*a9fa9459Szrj       /* Is this a bitfield?  This is indicated by a structure member
2868*a9fa9459Szrj          having a size field that isn't an array.  */
2869*a9fa9459Szrj       coff_type.bitfield = 1;
2870*a9fa9459Szrj     }
2871*a9fa9459Szrj 
2872*a9fa9459Szrj   /* Except for enumeration members & begin/ending of scopes, put the
2873*a9fa9459Szrj      type word in the aux. symbol table.  */
2874*a9fa9459Szrj   if (coff_symbol_typ == st_Block || coff_symbol_typ == st_End)
2875*a9fa9459Szrj     indx = 0;
2876*a9fa9459Szrj   else if (coff_inside_enumeration)
2877*a9fa9459Szrj     indx = cur_file_ptr->void_type;
2878*a9fa9459Szrj   else
2879*a9fa9459Szrj     {
2880*a9fa9459Szrj       if (coff_type.basic_type == bt_Struct
2881*a9fa9459Szrj 	  || coff_type.basic_type == bt_Union
2882*a9fa9459Szrj 	  || coff_type.basic_type == bt_Enum)
2883*a9fa9459Szrj 	{
2884*a9fa9459Szrj 	  if (coff_tag == (char *) NULL)
2885*a9fa9459Szrj 	    {
2886*a9fa9459Szrj 	      as_warn (_("no tag specified for %s"), name);
2887*a9fa9459Szrj 	      return;
2888*a9fa9459Szrj 	    }
2889*a9fa9459Szrj 
2890*a9fa9459Szrj 	  coff_type.tag_ptr = get_tag (coff_tag, (localsym_t *) NULL,
2891*a9fa9459Szrj 				       coff_type.basic_type);
2892*a9fa9459Szrj 	}
2893*a9fa9459Szrj 
2894*a9fa9459Szrj       if (coff_is_function)
2895*a9fa9459Szrj 	{
2896*a9fa9459Szrj 	  last_func_type_info = coff_type;
2897*a9fa9459Szrj 	  last_func_sym_value = coff_sym_value;
2898*a9fa9459Szrj 	  return;
2899*a9fa9459Szrj 	}
2900*a9fa9459Szrj 
2901*a9fa9459Szrj       indx = add_aux_sym_tir (&coff_type,
2902*a9fa9459Szrj 			      hash_yes,
2903*a9fa9459Szrj 			      &cur_file_ptr->thash_head[0]);
2904*a9fa9459Szrj     }
2905*a9fa9459Szrj 
2906*a9fa9459Szrj   /* Do any last minute adjustments that are necessary.  */
2907*a9fa9459Szrj   switch (coff_symbol_typ)
2908*a9fa9459Szrj     {
2909*a9fa9459Szrj     default:
2910*a9fa9459Szrj       break;
2911*a9fa9459Szrj 
2912*a9fa9459Szrj       /* For the beginning of structs, unions, and enumerations, the
2913*a9fa9459Szrj          size info needs to be passed in the value field.  */
2914*a9fa9459Szrj     case st_Block:
2915*a9fa9459Szrj       if (coff_type.num_sizes - coff_type.num_dims - coff_type.extra_sizes
2916*a9fa9459Szrj 	  != 1)
2917*a9fa9459Szrj 	{
2918*a9fa9459Szrj 	  as_warn (_("bad COFF debugging information"));
2919*a9fa9459Szrj 	  return;
2920*a9fa9459Szrj 	}
2921*a9fa9459Szrj       else
2922*a9fa9459Szrj 	coff_value = coff_type.sizes[0];
2923*a9fa9459Szrj 
2924*a9fa9459Szrj       coff_inside_enumeration = (coff_type.orig_type == T_ENUM);
2925*a9fa9459Szrj       break;
2926*a9fa9459Szrj 
2927*a9fa9459Szrj       /* For the end of structs, unions, and enumerations, omit the
2928*a9fa9459Szrj          name which is always ".eos".  This needs to be done last, so
2929*a9fa9459Szrj          that any error reporting above gives the correct name.  */
2930*a9fa9459Szrj     case st_End:
2931*a9fa9459Szrj       free (name);
2932*a9fa9459Szrj       name = (char *) NULL;
2933*a9fa9459Szrj       coff_value = 0;
2934*a9fa9459Szrj       coff_inside_enumeration = 0;
2935*a9fa9459Szrj       break;
2936*a9fa9459Szrj 
2937*a9fa9459Szrj       /* Members of structures and unions that aren't bitfields, need
2938*a9fa9459Szrj          to adjust the value from a byte offset to a bit offset.
2939*a9fa9459Szrj          Members of enumerations do not have the value adjusted, and
2940*a9fa9459Szrj          can be distinguished by indx == indexNil.  For enumerations,
2941*a9fa9459Szrj          update the maximum enumeration value.  */
2942*a9fa9459Szrj     case st_Member:
2943*a9fa9459Szrj       if (! coff_type.bitfield && ! coff_inside_enumeration)
2944*a9fa9459Szrj 	coff_value *= 8;
2945*a9fa9459Szrj 
2946*a9fa9459Szrj       break;
2947*a9fa9459Szrj     }
2948*a9fa9459Szrj 
2949*a9fa9459Szrj   /* Add the symbol.  */
2950*a9fa9459Szrj   sym = add_ecoff_symbol (name,
2951*a9fa9459Szrj 			  coff_symbol_typ,
2952*a9fa9459Szrj 			  coff_storage_class,
2953*a9fa9459Szrj 			  coff_sym_value,
2954*a9fa9459Szrj 			  coff_sym_addend,
2955*a9fa9459Szrj 			  (symint_t) coff_value,
2956*a9fa9459Szrj 			  indx);
2957*a9fa9459Szrj 
2958*a9fa9459Szrj   /* deal with struct, union, and enum tags.  */
2959*a9fa9459Szrj   if (coff_symbol_typ == st_Block)
2960*a9fa9459Szrj     {
2961*a9fa9459Szrj       /* Create or update the tag information.  */
2962*a9fa9459Szrj       tag_t *tag_ptr = get_tag (name,
2963*a9fa9459Szrj 				sym,
2964*a9fa9459Szrj 				coff_type.basic_type);
2965*a9fa9459Szrj       forward_t **pf;
2966*a9fa9459Szrj 
2967*a9fa9459Szrj       /* Remember any forward references.  */
2968*a9fa9459Szrj       for (pf = &sym->forward_ref;
2969*a9fa9459Szrj 	   *pf != (forward_t *) NULL;
2970*a9fa9459Szrj 	   pf = &(*pf)->next)
2971*a9fa9459Szrj 	;
2972*a9fa9459Szrj       *pf = tag_ptr->forward_ref;
2973*a9fa9459Szrj       tag_ptr->forward_ref = (forward_t *) NULL;
2974*a9fa9459Szrj     }
2975*a9fa9459Szrj }
2976*a9fa9459Szrj 
2977*a9fa9459Szrj /* Parse .end directives.  */
2978*a9fa9459Szrj 
2979*a9fa9459Szrj void
ecoff_directive_end(int ignore ATTRIBUTE_UNUSED)2980*a9fa9459Szrj ecoff_directive_end (int ignore ATTRIBUTE_UNUSED)
2981*a9fa9459Szrj {
2982*a9fa9459Szrj   char *name;
2983*a9fa9459Szrj   char name_end;
2984*a9fa9459Szrj   symbolS *ent;
2985*a9fa9459Szrj 
2986*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
2987*a9fa9459Szrj     {
2988*a9fa9459Szrj       as_warn (_(".end directive without a preceding .file directive"));
2989*a9fa9459Szrj       demand_empty_rest_of_line ();
2990*a9fa9459Szrj       return;
2991*a9fa9459Szrj     }
2992*a9fa9459Szrj 
2993*a9fa9459Szrj   if (cur_proc_ptr == (proc_t *) NULL)
2994*a9fa9459Szrj     {
2995*a9fa9459Szrj       as_warn (_(".end directive without a preceding .ent directive"));
2996*a9fa9459Szrj       demand_empty_rest_of_line ();
2997*a9fa9459Szrj       return;
2998*a9fa9459Szrj     }
2999*a9fa9459Szrj 
3000*a9fa9459Szrj   name_end = get_symbol_name (&name);
3001*a9fa9459Szrj 
3002*a9fa9459Szrj   if (name == input_line_pointer)
3003*a9fa9459Szrj     {
3004*a9fa9459Szrj       as_warn (_(".end directive has no name"));
3005*a9fa9459Szrj       (void) restore_line_pointer (name_end);
3006*a9fa9459Szrj       demand_empty_rest_of_line ();
3007*a9fa9459Szrj       return;
3008*a9fa9459Szrj     }
3009*a9fa9459Szrj 
3010*a9fa9459Szrj   /* The value is the distance between the .end directive and the
3011*a9fa9459Szrj      corresponding symbol.  We create a fake symbol to hold the
3012*a9fa9459Szrj      current location, and put in the offset when we write out the
3013*a9fa9459Szrj      symbol.  */
3014*a9fa9459Szrj   ent = symbol_find (name);
3015*a9fa9459Szrj   if (ent == (symbolS *) NULL)
3016*a9fa9459Szrj     as_warn (_(".end directive names unknown symbol"));
3017*a9fa9459Szrj   else
3018*a9fa9459Szrj     (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text,
3019*a9fa9459Szrj 			     symbol_new ("L0\001", now_seg,
3020*a9fa9459Szrj 					 (valueT) frag_now_fix (),
3021*a9fa9459Szrj 					 frag_now),
3022*a9fa9459Szrj 			     (bfd_vma) 0, (symint_t) 0, (symint_t) 0);
3023*a9fa9459Szrj 
3024*a9fa9459Szrj   cur_proc_ptr = (proc_t *) NULL;
3025*a9fa9459Szrj 
3026*a9fa9459Szrj   (void) restore_line_pointer (name_end);
3027*a9fa9459Szrj   demand_empty_rest_of_line ();
3028*a9fa9459Szrj }
3029*a9fa9459Szrj 
3030*a9fa9459Szrj /* Parse .ent directives.  */
3031*a9fa9459Szrj 
3032*a9fa9459Szrj void
ecoff_directive_ent(int ignore ATTRIBUTE_UNUSED)3033*a9fa9459Szrj ecoff_directive_ent (int ignore ATTRIBUTE_UNUSED)
3034*a9fa9459Szrj {
3035*a9fa9459Szrj   char *name;
3036*a9fa9459Szrj   char name_end;
3037*a9fa9459Szrj 
3038*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
3039*a9fa9459Szrj     add_file ((const char *) NULL, 0, 1);
3040*a9fa9459Szrj 
3041*a9fa9459Szrj   if (cur_proc_ptr != (proc_t *) NULL)
3042*a9fa9459Szrj     {
3043*a9fa9459Szrj       as_warn (_("second .ent directive found before .end directive"));
3044*a9fa9459Szrj       demand_empty_rest_of_line ();
3045*a9fa9459Szrj       return;
3046*a9fa9459Szrj     }
3047*a9fa9459Szrj 
3048*a9fa9459Szrj   name_end = get_symbol_name (&name);
3049*a9fa9459Szrj 
3050*a9fa9459Szrj   if (name == input_line_pointer)
3051*a9fa9459Szrj     {
3052*a9fa9459Szrj       as_warn (_(".ent directive has no name"));
3053*a9fa9459Szrj       (void) restore_line_pointer (name_end);
3054*a9fa9459Szrj       demand_empty_rest_of_line ();
3055*a9fa9459Szrj       return;
3056*a9fa9459Szrj     }
3057*a9fa9459Szrj 
3058*a9fa9459Szrj   add_procedure (name);
3059*a9fa9459Szrj 
3060*a9fa9459Szrj   (void) restore_line_pointer (name_end);
3061*a9fa9459Szrj 
3062*a9fa9459Szrj   /* The .ent directive is sometimes followed by a number.  I'm not
3063*a9fa9459Szrj      really sure what the number means.  I don't see any way to store
3064*a9fa9459Szrj      the information in the PDR.  The Irix 4 assembler seems to ignore
3065*a9fa9459Szrj      the information.  */
3066*a9fa9459Szrj   SKIP_WHITESPACE ();
3067*a9fa9459Szrj   if (*input_line_pointer == ',')
3068*a9fa9459Szrj     {
3069*a9fa9459Szrj       ++input_line_pointer;
3070*a9fa9459Szrj       SKIP_WHITESPACE ();
3071*a9fa9459Szrj     }
3072*a9fa9459Szrj   if (ISDIGIT (*input_line_pointer)
3073*a9fa9459Szrj       || *input_line_pointer == '-')
3074*a9fa9459Szrj     (void) get_absolute_expression ();
3075*a9fa9459Szrj 
3076*a9fa9459Szrj   demand_empty_rest_of_line ();
3077*a9fa9459Szrj }
3078*a9fa9459Szrj 
3079*a9fa9459Szrj /* Parse .extern directives.  */
3080*a9fa9459Szrj 
3081*a9fa9459Szrj void
ecoff_directive_extern(int ignore ATTRIBUTE_UNUSED)3082*a9fa9459Szrj ecoff_directive_extern (int ignore ATTRIBUTE_UNUSED)
3083*a9fa9459Szrj {
3084*a9fa9459Szrj   char *name;
3085*a9fa9459Szrj   int c;
3086*a9fa9459Szrj   symbolS *symbolp;
3087*a9fa9459Szrj   valueT size;
3088*a9fa9459Szrj 
3089*a9fa9459Szrj   c = get_symbol_name (&name);
3090*a9fa9459Szrj   symbolp = symbol_find_or_make (name);
3091*a9fa9459Szrj   (void) restore_line_pointer (c);
3092*a9fa9459Szrj 
3093*a9fa9459Szrj   S_SET_EXTERNAL (symbolp);
3094*a9fa9459Szrj 
3095*a9fa9459Szrj   if (*input_line_pointer == ',')
3096*a9fa9459Szrj     ++input_line_pointer;
3097*a9fa9459Szrj   size = get_absolute_expression ();
3098*a9fa9459Szrj 
3099*a9fa9459Szrj   symbol_get_obj (symbolp)->ecoff_extern_size = size;
3100*a9fa9459Szrj }
3101*a9fa9459Szrj 
3102*a9fa9459Szrj /* Parse .file directives.  */
3103*a9fa9459Szrj 
3104*a9fa9459Szrj void
ecoff_directive_file(int ignore ATTRIBUTE_UNUSED)3105*a9fa9459Szrj ecoff_directive_file (int ignore ATTRIBUTE_UNUSED)
3106*a9fa9459Szrj {
3107*a9fa9459Szrj   int indx;
3108*a9fa9459Szrj   char *name;
3109*a9fa9459Szrj   int len;
3110*a9fa9459Szrj 
3111*a9fa9459Szrj   if (cur_proc_ptr != (proc_t *) NULL)
3112*a9fa9459Szrj     {
3113*a9fa9459Szrj       as_warn (_("no way to handle .file within .ent/.end section"));
3114*a9fa9459Szrj       demand_empty_rest_of_line ();
3115*a9fa9459Szrj       return;
3116*a9fa9459Szrj     }
3117*a9fa9459Szrj 
3118*a9fa9459Szrj   indx = (int) get_absolute_expression ();
3119*a9fa9459Szrj 
3120*a9fa9459Szrj   /* FIXME: we don't have to save the name here.  */
3121*a9fa9459Szrj   name = demand_copy_C_string (&len);
3122*a9fa9459Szrj 
3123*a9fa9459Szrj   add_file (name, indx - 1, 0);
3124*a9fa9459Szrj 
3125*a9fa9459Szrj   demand_empty_rest_of_line ();
3126*a9fa9459Szrj }
3127*a9fa9459Szrj 
3128*a9fa9459Szrj /* Parse .fmask directives.  */
3129*a9fa9459Szrj 
3130*a9fa9459Szrj void
ecoff_directive_fmask(int ignore ATTRIBUTE_UNUSED)3131*a9fa9459Szrj ecoff_directive_fmask (int ignore ATTRIBUTE_UNUSED)
3132*a9fa9459Szrj {
3133*a9fa9459Szrj   long val;
3134*a9fa9459Szrj 
3135*a9fa9459Szrj   if (cur_proc_ptr == (proc_t *) NULL)
3136*a9fa9459Szrj     {
3137*a9fa9459Szrj       as_warn (_(".fmask outside of .ent"));
3138*a9fa9459Szrj       demand_empty_rest_of_line ();
3139*a9fa9459Szrj       return;
3140*a9fa9459Szrj     }
3141*a9fa9459Szrj 
3142*a9fa9459Szrj   if (get_absolute_expression_and_terminator (&val) != ',')
3143*a9fa9459Szrj     {
3144*a9fa9459Szrj       as_warn (_("bad .fmask directive"));
3145*a9fa9459Szrj       --input_line_pointer;
3146*a9fa9459Szrj       demand_empty_rest_of_line ();
3147*a9fa9459Szrj       return;
3148*a9fa9459Szrj     }
3149*a9fa9459Szrj 
3150*a9fa9459Szrj   cur_proc_ptr->pdr.fregmask = val;
3151*a9fa9459Szrj   cur_proc_ptr->pdr.fregoffset = get_absolute_expression ();
3152*a9fa9459Szrj 
3153*a9fa9459Szrj   demand_empty_rest_of_line ();
3154*a9fa9459Szrj }
3155*a9fa9459Szrj 
3156*a9fa9459Szrj /* Parse .frame directives.  */
3157*a9fa9459Szrj 
3158*a9fa9459Szrj void
ecoff_directive_frame(int ignore ATTRIBUTE_UNUSED)3159*a9fa9459Szrj ecoff_directive_frame (int ignore ATTRIBUTE_UNUSED)
3160*a9fa9459Szrj {
3161*a9fa9459Szrj   long val;
3162*a9fa9459Szrj 
3163*a9fa9459Szrj   if (cur_proc_ptr == (proc_t *) NULL)
3164*a9fa9459Szrj     {
3165*a9fa9459Szrj       as_warn (_(".frame outside of .ent"));
3166*a9fa9459Szrj       demand_empty_rest_of_line ();
3167*a9fa9459Szrj       return;
3168*a9fa9459Szrj     }
3169*a9fa9459Szrj 
3170*a9fa9459Szrj   cur_proc_ptr->pdr.framereg = tc_get_register (1);
3171*a9fa9459Szrj 
3172*a9fa9459Szrj   SKIP_WHITESPACE ();
3173*a9fa9459Szrj   if (*input_line_pointer++ != ','
3174*a9fa9459Szrj       || get_absolute_expression_and_terminator (&val) != ',')
3175*a9fa9459Szrj     {
3176*a9fa9459Szrj       as_warn (_("bad .frame directive"));
3177*a9fa9459Szrj       --input_line_pointer;
3178*a9fa9459Szrj       demand_empty_rest_of_line ();
3179*a9fa9459Szrj       return;
3180*a9fa9459Szrj     }
3181*a9fa9459Szrj 
3182*a9fa9459Szrj   cur_proc_ptr->pdr.frameoffset = val;
3183*a9fa9459Szrj 
3184*a9fa9459Szrj   cur_proc_ptr->pdr.pcreg = tc_get_register (0);
3185*a9fa9459Szrj 
3186*a9fa9459Szrj   /* Alpha-OSF1 adds "the offset of saved $a0 from $sp", according to
3187*a9fa9459Szrj      Sandro.  I don't yet know where this value should be stored, if
3188*a9fa9459Szrj      anywhere.  Don't call demand_empty_rest_of_line ().  */
3189*a9fa9459Szrj   s_ignore (42);
3190*a9fa9459Szrj }
3191*a9fa9459Szrj 
3192*a9fa9459Szrj /* Parse .mask directives.  */
3193*a9fa9459Szrj 
3194*a9fa9459Szrj void
ecoff_directive_mask(int ignore ATTRIBUTE_UNUSED)3195*a9fa9459Szrj ecoff_directive_mask (int ignore ATTRIBUTE_UNUSED)
3196*a9fa9459Szrj {
3197*a9fa9459Szrj   long val;
3198*a9fa9459Szrj 
3199*a9fa9459Szrj   if (cur_proc_ptr == (proc_t *) NULL)
3200*a9fa9459Szrj     {
3201*a9fa9459Szrj       as_warn (_(".mask outside of .ent"));
3202*a9fa9459Szrj       demand_empty_rest_of_line ();
3203*a9fa9459Szrj       return;
3204*a9fa9459Szrj     }
3205*a9fa9459Szrj 
3206*a9fa9459Szrj   if (get_absolute_expression_and_terminator (&val) != ',')
3207*a9fa9459Szrj     {
3208*a9fa9459Szrj       as_warn (_("bad .mask directive"));
3209*a9fa9459Szrj       --input_line_pointer;
3210*a9fa9459Szrj       demand_empty_rest_of_line ();
3211*a9fa9459Szrj       return;
3212*a9fa9459Szrj     }
3213*a9fa9459Szrj 
3214*a9fa9459Szrj   cur_proc_ptr->pdr.regmask = val;
3215*a9fa9459Szrj   cur_proc_ptr->pdr.regoffset = get_absolute_expression ();
3216*a9fa9459Szrj 
3217*a9fa9459Szrj   demand_empty_rest_of_line ();
3218*a9fa9459Szrj }
3219*a9fa9459Szrj 
3220*a9fa9459Szrj /* Parse .loc directives.  */
3221*a9fa9459Szrj 
3222*a9fa9459Szrj void
ecoff_directive_loc(int ignore ATTRIBUTE_UNUSED)3223*a9fa9459Szrj ecoff_directive_loc (int ignore ATTRIBUTE_UNUSED)
3224*a9fa9459Szrj {
3225*a9fa9459Szrj   lineno_list_t *list;
3226*a9fa9459Szrj   symint_t lineno;
3227*a9fa9459Szrj 
3228*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
3229*a9fa9459Szrj     {
3230*a9fa9459Szrj       as_warn (_(".loc before .file"));
3231*a9fa9459Szrj       demand_empty_rest_of_line ();
3232*a9fa9459Szrj       return;
3233*a9fa9459Szrj     }
3234*a9fa9459Szrj 
3235*a9fa9459Szrj   if (now_seg != text_section)
3236*a9fa9459Szrj     {
3237*a9fa9459Szrj       as_warn (_(".loc outside of .text"));
3238*a9fa9459Szrj       demand_empty_rest_of_line ();
3239*a9fa9459Szrj       return;
3240*a9fa9459Szrj     }
3241*a9fa9459Szrj 
3242*a9fa9459Szrj   /* Skip the file number.  */
3243*a9fa9459Szrj   SKIP_WHITESPACE ();
3244*a9fa9459Szrj   get_absolute_expression ();
3245*a9fa9459Szrj   SKIP_WHITESPACE ();
3246*a9fa9459Szrj 
3247*a9fa9459Szrj   lineno = get_absolute_expression ();
3248*a9fa9459Szrj 
3249*a9fa9459Szrj #ifndef NO_LISTING
3250*a9fa9459Szrj   if (listing)
3251*a9fa9459Szrj     listing_source_line (lineno);
3252*a9fa9459Szrj #endif
3253*a9fa9459Szrj 
3254*a9fa9459Szrj   /* If we're building stabs, then output a special label rather than
3255*a9fa9459Szrj      ECOFF line number info.  */
3256*a9fa9459Szrj   if (stabs_seen)
3257*a9fa9459Szrj     {
3258*a9fa9459Szrj       (void) add_ecoff_symbol ((char *) NULL, st_Label, sc_Text,
3259*a9fa9459Szrj 			       symbol_new ("L0\001", now_seg,
3260*a9fa9459Szrj 					   (valueT) frag_now_fix (),
3261*a9fa9459Szrj 					   frag_now),
3262*a9fa9459Szrj 			       (bfd_vma) 0, 0, lineno);
3263*a9fa9459Szrj       return;
3264*a9fa9459Szrj     }
3265*a9fa9459Szrj 
3266*a9fa9459Szrj   list = allocate_lineno_list ();
3267*a9fa9459Szrj 
3268*a9fa9459Szrj   list->next = (lineno_list_t *) NULL;
3269*a9fa9459Szrj   list->file = cur_file_ptr;
3270*a9fa9459Szrj   list->proc = cur_proc_ptr;
3271*a9fa9459Szrj   list->frag = frag_now;
3272*a9fa9459Szrj   list->paddr = frag_now_fix ();
3273*a9fa9459Szrj   list->lineno = lineno;
3274*a9fa9459Szrj 
3275*a9fa9459Szrj   /* We don't want to merge files which have line numbers.  */
3276*a9fa9459Szrj   cur_file_ptr->fdr.fMerge = 0;
3277*a9fa9459Szrj 
3278*a9fa9459Szrj   /* A .loc directive will sometimes appear before a .ent directive,
3279*a9fa9459Szrj      which means that cur_proc_ptr will be NULL here.  Arrange to
3280*a9fa9459Szrj      patch this up.  */
3281*a9fa9459Szrj   if (cur_proc_ptr == (proc_t *) NULL)
3282*a9fa9459Szrj     {
3283*a9fa9459Szrj       lineno_list_t **pl;
3284*a9fa9459Szrj 
3285*a9fa9459Szrj       pl = &noproc_lineno;
3286*a9fa9459Szrj       while (*pl != (lineno_list_t *) NULL)
3287*a9fa9459Szrj 	pl = &(*pl)->next;
3288*a9fa9459Szrj       *pl = list;
3289*a9fa9459Szrj     }
3290*a9fa9459Szrj   else
3291*a9fa9459Szrj     {
3292*a9fa9459Szrj       last_lineno = list;
3293*a9fa9459Szrj       *last_lineno_ptr = list;
3294*a9fa9459Szrj       last_lineno_ptr = &list->next;
3295*a9fa9459Szrj     }
3296*a9fa9459Szrj }
3297*a9fa9459Szrj 
3298*a9fa9459Szrj /* The MIPS assembler sometimes inserts nop instructions in the
3299*a9fa9459Szrj    instruction stream.  When this happens, we must patch up the .loc
3300*a9fa9459Szrj    information so that it points to the instruction after the nop.  */
3301*a9fa9459Szrj 
3302*a9fa9459Szrj void
ecoff_fix_loc(fragS * old_frag,unsigned long old_frag_offset)3303*a9fa9459Szrj ecoff_fix_loc (fragS *old_frag, unsigned long old_frag_offset)
3304*a9fa9459Szrj {
3305*a9fa9459Szrj   if (last_lineno != NULL
3306*a9fa9459Szrj       && last_lineno->frag == old_frag
3307*a9fa9459Szrj       && last_lineno->paddr == old_frag_offset)
3308*a9fa9459Szrj     {
3309*a9fa9459Szrj       last_lineno->frag = frag_now;
3310*a9fa9459Szrj       last_lineno->paddr = frag_now_fix ();
3311*a9fa9459Szrj     }
3312*a9fa9459Szrj }
3313*a9fa9459Szrj 
3314*a9fa9459Szrj /* Make sure the @stabs symbol is emitted.  */
3315*a9fa9459Szrj 
3316*a9fa9459Szrj static void
mark_stabs(int ignore ATTRIBUTE_UNUSED)3317*a9fa9459Szrj mark_stabs (int ignore ATTRIBUTE_UNUSED)
3318*a9fa9459Szrj {
3319*a9fa9459Szrj   if (! stabs_seen)
3320*a9fa9459Szrj     {
3321*a9fa9459Szrj       /* Add a dummy @stabs dymbol.  */
3322*a9fa9459Szrj       stabs_seen = 1;
3323*a9fa9459Szrj       (void) add_ecoff_symbol (stabs_symbol, st_Nil, sc_Info,
3324*a9fa9459Szrj 			       (symbolS *) NULL,
3325*a9fa9459Szrj 			       (bfd_vma) 0, (symint_t) -1,
3326*a9fa9459Szrj 			       ECOFF_MARK_STAB (0));
3327*a9fa9459Szrj     }
3328*a9fa9459Szrj }
3329*a9fa9459Szrj 
3330*a9fa9459Szrj /* Parse .weakext directives.  */
3331*a9fa9459Szrj #ifndef TC_MIPS
3332*a9fa9459Szrj /* For TC_MIPS use the version in tc-mips.c.  */
3333*a9fa9459Szrj void
ecoff_directive_weakext(int ignore ATTRIBUTE_UNUSED)3334*a9fa9459Szrj ecoff_directive_weakext (int ignore ATTRIBUTE_UNUSED)
3335*a9fa9459Szrj {
3336*a9fa9459Szrj   char *name;
3337*a9fa9459Szrj   int c;
3338*a9fa9459Szrj   symbolS *symbolP;
3339*a9fa9459Szrj   expressionS exp;
3340*a9fa9459Szrj 
3341*a9fa9459Szrj   c = get_symbol_name (&name);
3342*a9fa9459Szrj   symbolP = symbol_find_or_make (name);
3343*a9fa9459Szrj   (void) restore_line_pointer (c);
3344*a9fa9459Szrj 
3345*a9fa9459Szrj   SKIP_WHITESPACE ();
3346*a9fa9459Szrj 
3347*a9fa9459Szrj   if (*input_line_pointer == ',')
3348*a9fa9459Szrj     {
3349*a9fa9459Szrj       if (S_IS_DEFINED (symbolP))
3350*a9fa9459Szrj 	{
3351*a9fa9459Szrj 	  as_bad (_("symbol `%s' is already defined"),
3352*a9fa9459Szrj 		  S_GET_NAME (symbolP));
3353*a9fa9459Szrj 	  ignore_rest_of_line ();
3354*a9fa9459Szrj 	  return;
3355*a9fa9459Szrj 	}
3356*a9fa9459Szrj 
3357*a9fa9459Szrj       ++input_line_pointer;
3358*a9fa9459Szrj       SKIP_WHITESPACE ();
3359*a9fa9459Szrj       if (! is_end_of_line[(unsigned char) *input_line_pointer])
3360*a9fa9459Szrj 	{
3361*a9fa9459Szrj 	  expression (&exp);
3362*a9fa9459Szrj 	  if (exp.X_op != O_symbol)
3363*a9fa9459Szrj 	    {
3364*a9fa9459Szrj 	      as_bad (_("bad .weakext directive"));
3365*a9fa9459Szrj 	      ignore_rest_of_line ();
3366*a9fa9459Szrj 	      return;
3367*a9fa9459Szrj 	    }
3368*a9fa9459Szrj 	  symbol_set_value_expression (symbolP, &exp);
3369*a9fa9459Szrj 	}
3370*a9fa9459Szrj     }
3371*a9fa9459Szrj 
3372*a9fa9459Szrj   S_SET_WEAK (symbolP);
3373*a9fa9459Szrj 
3374*a9fa9459Szrj   demand_empty_rest_of_line ();
3375*a9fa9459Szrj }
3376*a9fa9459Szrj #endif /* not TC_MIPS */
3377*a9fa9459Szrj 
3378*a9fa9459Szrj /* Handle .stabs directives.  The actual parsing routine is done by a
3379*a9fa9459Szrj    generic routine.  This routine is called via OBJ_PROCESS_STAB.
3380*a9fa9459Szrj    When this is called, input_line_pointer will be pointing at the
3381*a9fa9459Szrj    value field of the stab.
3382*a9fa9459Szrj 
3383*a9fa9459Szrj    .stabs directives have five fields:
3384*a9fa9459Szrj 	"string"	a string, encoding the type information.
3385*a9fa9459Szrj 	code		a numeric code, defined in <stab.h>
3386*a9fa9459Szrj 	0		a zero
3387*a9fa9459Szrj 	desc		a zero or line number
3388*a9fa9459Szrj 	value		a numeric value or an address.
3389*a9fa9459Szrj 
3390*a9fa9459Szrj     If the value is relocatable, we transform this into:
3391*a9fa9459Szrj 	iss		points as an index into string space
3392*a9fa9459Szrj 	value		value from lookup of the name
3393*a9fa9459Szrj 	st		st from lookup of the name
3394*a9fa9459Szrj 	sc		sc from lookup of the name
3395*a9fa9459Szrj 	index		code|CODE_MASK
3396*a9fa9459Szrj 
3397*a9fa9459Szrj     If the value is not relocatable, we transform this into:
3398*a9fa9459Szrj 	iss		points as an index into string space
3399*a9fa9459Szrj 	value		value
3400*a9fa9459Szrj 	st		st_Nil
3401*a9fa9459Szrj 	sc		sc_Nil
3402*a9fa9459Szrj 	index		code|CODE_MASK
3403*a9fa9459Szrj 
3404*a9fa9459Szrj     .stabn directives have four fields (string is null):
3405*a9fa9459Szrj 	code		a numeric code, defined in <stab.h>
3406*a9fa9459Szrj 	0		a zero
3407*a9fa9459Szrj 	desc		a zero or a line number
3408*a9fa9459Szrj 	value		a numeric value or an address.  */
3409*a9fa9459Szrj 
3410*a9fa9459Szrj void
ecoff_stab(segT sec ATTRIBUTE_UNUSED,int what,const char * string,int type,int other,int desc)3411*a9fa9459Szrj ecoff_stab (segT sec ATTRIBUTE_UNUSED,
3412*a9fa9459Szrj 	    int what,
3413*a9fa9459Szrj 	    const char *string,
3414*a9fa9459Szrj 	    int type,
3415*a9fa9459Szrj 	    int other,
3416*a9fa9459Szrj 	    int desc)
3417*a9fa9459Szrj {
3418*a9fa9459Szrj   efdr_t *save_file_ptr = cur_file_ptr;
3419*a9fa9459Szrj   symbolS *sym;
3420*a9fa9459Szrj   symint_t value;
3421*a9fa9459Szrj   bfd_vma addend;
3422*a9fa9459Szrj   st_t st;
3423*a9fa9459Szrj   sc_t sc;
3424*a9fa9459Szrj   symint_t indx;
3425*a9fa9459Szrj   localsym_t *hold = NULL;
3426*a9fa9459Szrj 
3427*a9fa9459Szrj   ecoff_debugging_seen = 1;
3428*a9fa9459Szrj 
3429*a9fa9459Szrj   /* We don't handle .stabd.  */
3430*a9fa9459Szrj   if (what != 's' && what != 'n')
3431*a9fa9459Szrj     {
3432*a9fa9459Szrj       as_bad (_(".stab%c is not supported"), what);
3433*a9fa9459Szrj       return;
3434*a9fa9459Szrj     }
3435*a9fa9459Szrj 
3436*a9fa9459Szrj   /* A .stabn uses a null name, not an empty string.  */
3437*a9fa9459Szrj   if (what == 'n')
3438*a9fa9459Szrj     string = NULL;
3439*a9fa9459Szrj 
3440*a9fa9459Szrj   /* We ignore the other field.  */
3441*a9fa9459Szrj   if (other != 0)
3442*a9fa9459Szrj     as_warn (_(".stab%c: ignoring non-zero other field"), what);
3443*a9fa9459Szrj 
3444*a9fa9459Szrj   /* Make sure we have a current file.  */
3445*a9fa9459Szrj   if (cur_file_ptr == (efdr_t *) NULL)
3446*a9fa9459Szrj     {
3447*a9fa9459Szrj       add_file ((const char *) NULL, 0, 1);
3448*a9fa9459Szrj       save_file_ptr = cur_file_ptr;
3449*a9fa9459Szrj     }
3450*a9fa9459Szrj 
3451*a9fa9459Szrj   /* For stabs in ECOFF, the first symbol must be @stabs.  This is a
3452*a9fa9459Szrj      signal to gdb.  */
3453*a9fa9459Szrj   if (stabs_seen == 0)
3454*a9fa9459Szrj     mark_stabs (0);
3455*a9fa9459Szrj 
3456*a9fa9459Szrj   /* Line number stabs are handled differently, since they have two
3457*a9fa9459Szrj      values, the line number and the address of the label.  We use the
3458*a9fa9459Szrj      index field (aka desc) to hold the line number, and the value
3459*a9fa9459Szrj      field to hold the address.  The symbol type is st_Label, which
3460*a9fa9459Szrj      should be different from the other stabs, so that gdb can
3461*a9fa9459Szrj      recognize it.  */
3462*a9fa9459Szrj   if (type == N_SLINE)
3463*a9fa9459Szrj     {
3464*a9fa9459Szrj       SYMR dummy_symr;
3465*a9fa9459Szrj       char *name;
3466*a9fa9459Szrj       char name_end;
3467*a9fa9459Szrj 
3468*a9fa9459Szrj #ifndef NO_LISTING
3469*a9fa9459Szrj       if (listing)
3470*a9fa9459Szrj 	listing_source_line ((unsigned int) desc);
3471*a9fa9459Szrj #endif
3472*a9fa9459Szrj 
3473*a9fa9459Szrj       dummy_symr.index = desc;
3474*a9fa9459Szrj       if (dummy_symr.index != desc)
3475*a9fa9459Szrj 	{
3476*a9fa9459Szrj 	  as_warn (_("line number (%d) for .stab%c directive cannot fit in index field (20 bits)"),
3477*a9fa9459Szrj 		   desc, what);
3478*a9fa9459Szrj 	  return;
3479*a9fa9459Szrj 	}
3480*a9fa9459Szrj 
3481*a9fa9459Szrj       name_end = get_symbol_name (&name);
3482*a9fa9459Szrj       sym = symbol_find_or_make (name);
3483*a9fa9459Szrj       (void) restore_line_pointer (name_end);
3484*a9fa9459Szrj 
3485*a9fa9459Szrj       value = 0;
3486*a9fa9459Szrj       addend = 0;
3487*a9fa9459Szrj       st = st_Label;
3488*a9fa9459Szrj       sc = sc_Text;
3489*a9fa9459Szrj       indx = desc;
3490*a9fa9459Szrj     }
3491*a9fa9459Szrj   else
3492*a9fa9459Szrj     {
3493*a9fa9459Szrj #ifndef NO_LISTING
3494*a9fa9459Szrj       if (listing && (type == N_SO || type == N_SOL))
3495*a9fa9459Szrj 	listing_source_file (string);
3496*a9fa9459Szrj #endif
3497*a9fa9459Szrj 
3498*a9fa9459Szrj       if (ISDIGIT (*input_line_pointer)
3499*a9fa9459Szrj 	  || *input_line_pointer == '-'
3500*a9fa9459Szrj 	  || *input_line_pointer == '+')
3501*a9fa9459Szrj 	{
3502*a9fa9459Szrj 	  st = st_Nil;
3503*a9fa9459Szrj 	  sc = sc_Nil;
3504*a9fa9459Szrj 	  sym = (symbolS *) NULL;
3505*a9fa9459Szrj 	  value = get_absolute_expression ();
3506*a9fa9459Szrj 	  addend = 0;
3507*a9fa9459Szrj 	}
3508*a9fa9459Szrj       else if (! is_name_beginner ((unsigned char) *input_line_pointer))
3509*a9fa9459Szrj 	{
3510*a9fa9459Szrj 	  as_warn (_("illegal .stab%c directive, bad character"), what);
3511*a9fa9459Szrj 	  return;
3512*a9fa9459Szrj 	}
3513*a9fa9459Szrj       else
3514*a9fa9459Szrj 	{
3515*a9fa9459Szrj 	  expressionS exp;
3516*a9fa9459Szrj 
3517*a9fa9459Szrj 	  sc = sc_Nil;
3518*a9fa9459Szrj 	  st = st_Nil;
3519*a9fa9459Szrj 
3520*a9fa9459Szrj 	  expression (&exp);
3521*a9fa9459Szrj 	  if (exp.X_op == O_constant)
3522*a9fa9459Szrj 	    {
3523*a9fa9459Szrj 	      sym = NULL;
3524*a9fa9459Szrj 	      value = exp.X_add_number;
3525*a9fa9459Szrj 	      addend = 0;
3526*a9fa9459Szrj 	    }
3527*a9fa9459Szrj 	  else if (exp.X_op == O_symbol)
3528*a9fa9459Szrj 	    {
3529*a9fa9459Szrj 	      sym = exp.X_add_symbol;
3530*a9fa9459Szrj 	      value = 0;
3531*a9fa9459Szrj 	      addend = exp.X_add_number;
3532*a9fa9459Szrj 	    }
3533*a9fa9459Szrj 	  else
3534*a9fa9459Szrj 	    {
3535*a9fa9459Szrj 	      sym = make_expr_symbol (&exp);
3536*a9fa9459Szrj 	      value = 0;
3537*a9fa9459Szrj 	      addend = 0;
3538*a9fa9459Szrj 	    }
3539*a9fa9459Szrj 	}
3540*a9fa9459Szrj 
3541*a9fa9459Szrj       indx = ECOFF_MARK_STAB (type);
3542*a9fa9459Szrj     }
3543*a9fa9459Szrj 
3544*a9fa9459Szrj   /* Don't store the stabs symbol we are creating as the type of the
3545*a9fa9459Szrj      ECOFF symbol.  We want to compute the type of the ECOFF symbol
3546*a9fa9459Szrj      independently.  */
3547*a9fa9459Szrj   if (sym != (symbolS *) NULL)
3548*a9fa9459Szrj     hold = symbol_get_obj (sym)->ecoff_symbol;
3549*a9fa9459Szrj 
3550*a9fa9459Szrj   (void) add_ecoff_symbol (string, st, sc, sym, addend, value, indx);
3551*a9fa9459Szrj 
3552*a9fa9459Szrj   if (sym != (symbolS *) NULL)
3553*a9fa9459Szrj     symbol_get_obj (sym)->ecoff_symbol = hold;
3554*a9fa9459Szrj 
3555*a9fa9459Szrj   /* Restore normal file type.  */
3556*a9fa9459Szrj   cur_file_ptr = save_file_ptr;
3557*a9fa9459Szrj }
3558*a9fa9459Szrj 
3559*a9fa9459Szrj /* Frob an ECOFF symbol.  Small common symbols go into a special
3560*a9fa9459Szrj    .scommon section rather than bfd_com_section.  */
3561*a9fa9459Szrj 
3562*a9fa9459Szrj void
ecoff_frob_symbol(symbolS * sym)3563*a9fa9459Szrj ecoff_frob_symbol (symbolS *sym)
3564*a9fa9459Szrj {
3565*a9fa9459Szrj   if (S_IS_COMMON (sym)
3566*a9fa9459Szrj       && S_GET_VALUE (sym) > 0
3567*a9fa9459Szrj       && S_GET_VALUE (sym) <= bfd_get_gp_size (stdoutput))
3568*a9fa9459Szrj     {
3569*a9fa9459Szrj       static asection scom_section;
3570*a9fa9459Szrj       static asymbol scom_symbol;
3571*a9fa9459Szrj 
3572*a9fa9459Szrj       /* We must construct a fake section similar to bfd_com_section
3573*a9fa9459Szrj          but with the name .scommon.  */
3574*a9fa9459Szrj       if (scom_section.name == NULL)
3575*a9fa9459Szrj 	{
3576*a9fa9459Szrj 	  scom_section = *bfd_com_section_ptr;
3577*a9fa9459Szrj 	  scom_section.name = ".scommon";
3578*a9fa9459Szrj 	  scom_section.output_section = &scom_section;
3579*a9fa9459Szrj 	  scom_section.symbol = &scom_symbol;
3580*a9fa9459Szrj 	  scom_section.symbol_ptr_ptr = &scom_section.symbol;
3581*a9fa9459Szrj 	  scom_symbol = *bfd_com_section_ptr->symbol;
3582*a9fa9459Szrj 	  scom_symbol.name = ".scommon";
3583*a9fa9459Szrj 	  scom_symbol.section = &scom_section;
3584*a9fa9459Szrj 	}
3585*a9fa9459Szrj       S_SET_SEGMENT (sym, &scom_section);
3586*a9fa9459Szrj     }
3587*a9fa9459Szrj 
3588*a9fa9459Szrj   /* Double check weak symbols.  */
3589*a9fa9459Szrj   if (S_IS_WEAK (sym))
3590*a9fa9459Szrj     {
3591*a9fa9459Szrj       if (S_IS_COMMON (sym))
3592*a9fa9459Szrj 	as_bad (_("symbol `%s' can not be both weak and common"),
3593*a9fa9459Szrj 		S_GET_NAME (sym));
3594*a9fa9459Szrj     }
3595*a9fa9459Szrj }
3596*a9fa9459Szrj 
3597*a9fa9459Szrj /* Add bytes to the symbolic information buffer.  */
3598*a9fa9459Szrj 
3599*a9fa9459Szrj static char *
ecoff_add_bytes(char ** buf,char ** bufend,char * bufptr,unsigned long need)3600*a9fa9459Szrj ecoff_add_bytes (char **buf,
3601*a9fa9459Szrj 		 char **bufend,
3602*a9fa9459Szrj 		 char *bufptr,
3603*a9fa9459Szrj 		 unsigned long need)
3604*a9fa9459Szrj {
3605*a9fa9459Szrj   unsigned long at;
3606*a9fa9459Szrj   unsigned long want;
3607*a9fa9459Szrj 
3608*a9fa9459Szrj   at = bufptr - *buf;
3609*a9fa9459Szrj   need -= *bufend - bufptr;
3610*a9fa9459Szrj   if (need < PAGE_SIZE)
3611*a9fa9459Szrj     need = PAGE_SIZE;
3612*a9fa9459Szrj   want = (*bufend - *buf) + need;
3613*a9fa9459Szrj   *buf = XRESIZEVEC (char, *buf, want);
3614*a9fa9459Szrj   *bufend = *buf + want;
3615*a9fa9459Szrj   return *buf + at;
3616*a9fa9459Szrj }
3617*a9fa9459Szrj 
3618*a9fa9459Szrj /* Adjust the symbolic information buffer to the alignment required
3619*a9fa9459Szrj    for the ECOFF target debugging information.  */
3620*a9fa9459Szrj 
3621*a9fa9459Szrj static unsigned long
ecoff_padding_adjust(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset,char ** bufptrptr)3622*a9fa9459Szrj ecoff_padding_adjust (const struct ecoff_debug_swap *backend,
3623*a9fa9459Szrj 		      char **buf,
3624*a9fa9459Szrj 		      char **bufend,
3625*a9fa9459Szrj 		      unsigned long offset,
3626*a9fa9459Szrj 		      char **bufptrptr)
3627*a9fa9459Szrj {
3628*a9fa9459Szrj   bfd_size_type align;
3629*a9fa9459Szrj 
3630*a9fa9459Szrj   align = backend->debug_align;
3631*a9fa9459Szrj   if ((offset & (align - 1)) != 0)
3632*a9fa9459Szrj     {
3633*a9fa9459Szrj       unsigned long add;
3634*a9fa9459Szrj 
3635*a9fa9459Szrj       add = align - (offset & (align - 1));
3636*a9fa9459Szrj       if ((unsigned long) (*bufend - (*buf + offset)) < add)
3637*a9fa9459Szrj 	(void) ecoff_add_bytes (buf, bufend, *buf + offset, add);
3638*a9fa9459Szrj       memset (*buf + offset, 0, add);
3639*a9fa9459Szrj       offset += add;
3640*a9fa9459Szrj       if (bufptrptr != (char **) NULL)
3641*a9fa9459Szrj 	*bufptrptr = *buf + offset;
3642*a9fa9459Szrj     }
3643*a9fa9459Szrj 
3644*a9fa9459Szrj   return offset;
3645*a9fa9459Szrj }
3646*a9fa9459Szrj 
3647*a9fa9459Szrj /* Build the line number information.  */
3648*a9fa9459Szrj 
3649*a9fa9459Szrj static unsigned long
ecoff_build_lineno(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset,long * linecntptr)3650*a9fa9459Szrj ecoff_build_lineno (const struct ecoff_debug_swap *backend,
3651*a9fa9459Szrj 		    char **buf,
3652*a9fa9459Szrj 		    char **bufend,
3653*a9fa9459Szrj 		    unsigned long offset,
3654*a9fa9459Szrj 		    long *linecntptr)
3655*a9fa9459Szrj {
3656*a9fa9459Szrj   char *bufptr;
3657*a9fa9459Szrj   lineno_list_t *l;
3658*a9fa9459Szrj   lineno_list_t *last;
3659*a9fa9459Szrj   efdr_t *file;
3660*a9fa9459Szrj   proc_t *proc;
3661*a9fa9459Szrj   unsigned long c;
3662*a9fa9459Szrj   long iline;
3663*a9fa9459Szrj   long totcount;
3664*a9fa9459Szrj   lineno_list_t first;
3665*a9fa9459Szrj   lineno_list_t *local_first_lineno = first_lineno;
3666*a9fa9459Szrj 
3667*a9fa9459Szrj   if (linecntptr != (long *) NULL)
3668*a9fa9459Szrj     *linecntptr = 0;
3669*a9fa9459Szrj 
3670*a9fa9459Szrj   bufptr = *buf + offset;
3671*a9fa9459Szrj 
3672*a9fa9459Szrj   file = (efdr_t *) NULL;
3673*a9fa9459Szrj   proc = (proc_t *) NULL;
3674*a9fa9459Szrj   last = (lineno_list_t *) NULL;
3675*a9fa9459Szrj   c = offset;
3676*a9fa9459Szrj   iline = 0;
3677*a9fa9459Szrj   totcount = 0;
3678*a9fa9459Szrj 
3679*a9fa9459Szrj   /* FIXME?  Now that MIPS embedded-PIC is gone, it may be safe to
3680*a9fa9459Szrj      remove this code.  */
3681*a9fa9459Szrj   /* For some reason the address of the first procedure is ignored
3682*a9fa9459Szrj      when reading line numbers.  This doesn't matter if the address of
3683*a9fa9459Szrj      the first procedure is 0, but when gcc is generating MIPS
3684*a9fa9459Szrj      embedded PIC code, it will put strings in the .text section
3685*a9fa9459Szrj      before the first procedure.  We cope by inserting a dummy line if
3686*a9fa9459Szrj      the address of the first procedure is not 0.  Hopefully this
3687*a9fa9459Szrj      won't screw things up too badly.
3688*a9fa9459Szrj 
3689*a9fa9459Szrj      Don't do this for ECOFF assembly source line numbers.  They work
3690*a9fa9459Szrj      without this extra attention.  */
3691*a9fa9459Szrj   if (debug_type != DEBUG_ECOFF
3692*a9fa9459Szrj       && first_proc_ptr != (proc_t *) NULL
3693*a9fa9459Szrj       && local_first_lineno != (lineno_list_t *) NULL
3694*a9fa9459Szrj       && ((S_GET_VALUE (first_proc_ptr->sym->as_sym)
3695*a9fa9459Szrj 	   + bfd_get_section_vma (stdoutput,
3696*a9fa9459Szrj 				  S_GET_SEGMENT (first_proc_ptr->sym->as_sym)))
3697*a9fa9459Szrj 	  != 0))
3698*a9fa9459Szrj     {
3699*a9fa9459Szrj       first.file = local_first_lineno->file;
3700*a9fa9459Szrj       first.proc = local_first_lineno->proc;
3701*a9fa9459Szrj       first.frag = &zero_address_frag;
3702*a9fa9459Szrj       first.paddr = 0;
3703*a9fa9459Szrj       first.lineno = 0;
3704*a9fa9459Szrj 
3705*a9fa9459Szrj       first.next = local_first_lineno;
3706*a9fa9459Szrj       local_first_lineno = &first;
3707*a9fa9459Szrj     }
3708*a9fa9459Szrj 
3709*a9fa9459Szrj   for (l = local_first_lineno; l != (lineno_list_t *) NULL; l = l->next)
3710*a9fa9459Szrj     {
3711*a9fa9459Szrj       long count;
3712*a9fa9459Szrj       long delta;
3713*a9fa9459Szrj 
3714*a9fa9459Szrj       /* Get the offset to the memory address of the next line number
3715*a9fa9459Szrj          (in words).  Do this first, so that we can skip ahead to the
3716*a9fa9459Szrj          next useful line number entry.  */
3717*a9fa9459Szrj       if (l->next == (lineno_list_t *) NULL)
3718*a9fa9459Szrj 	{
3719*a9fa9459Szrj 	  /* We want a count of zero, but it will be decremented
3720*a9fa9459Szrj 	     before it is used.  */
3721*a9fa9459Szrj 	  count = 1;
3722*a9fa9459Szrj 	}
3723*a9fa9459Szrj       else if (l->next->frag->fr_address + l->next->paddr
3724*a9fa9459Szrj 	       > l->frag->fr_address + l->paddr)
3725*a9fa9459Szrj 	{
3726*a9fa9459Szrj 	  count = ((l->next->frag->fr_address + l->next->paddr
3727*a9fa9459Szrj 		    - (l->frag->fr_address + l->paddr))
3728*a9fa9459Szrj 		   >> 2);
3729*a9fa9459Szrj 	}
3730*a9fa9459Szrj       else
3731*a9fa9459Szrj 	{
3732*a9fa9459Szrj 	  /* Don't change last, so we still get the right delta.  */
3733*a9fa9459Szrj 	  continue;
3734*a9fa9459Szrj 	}
3735*a9fa9459Szrj 
3736*a9fa9459Szrj       if (l->file != file || l->proc != proc)
3737*a9fa9459Szrj 	{
3738*a9fa9459Szrj 	  if (l->proc != proc && proc != (proc_t *) NULL)
3739*a9fa9459Szrj 	    proc->pdr.lnHigh = last->lineno;
3740*a9fa9459Szrj 	  if (l->file != file && file != (efdr_t *) NULL)
3741*a9fa9459Szrj 	    {
3742*a9fa9459Szrj 	      file->fdr.cbLine = c - file->fdr.cbLineOffset;
3743*a9fa9459Szrj 	      file->fdr.cline = totcount + count;
3744*a9fa9459Szrj 	      if (linecntptr != (long *) NULL)
3745*a9fa9459Szrj 		*linecntptr += totcount + count;
3746*a9fa9459Szrj 	      totcount = 0;
3747*a9fa9459Szrj 	    }
3748*a9fa9459Szrj 
3749*a9fa9459Szrj 	  if (l->file != file)
3750*a9fa9459Szrj 	    {
3751*a9fa9459Szrj 	      efdr_t *last_file = file;
3752*a9fa9459Szrj 
3753*a9fa9459Szrj 	      file = l->file;
3754*a9fa9459Szrj 	      if (last_file != (efdr_t *) NULL)
3755*a9fa9459Szrj 		file->fdr.ilineBase
3756*a9fa9459Szrj 		  = last_file->fdr.ilineBase + last_file->fdr.cline;
3757*a9fa9459Szrj 	      else
3758*a9fa9459Szrj 		file->fdr.ilineBase = 0;
3759*a9fa9459Szrj 	      file->fdr.cbLineOffset = c;
3760*a9fa9459Szrj 	    }
3761*a9fa9459Szrj 	  if (l->proc != proc)
3762*a9fa9459Szrj 	    {
3763*a9fa9459Szrj 	      proc = l->proc;
3764*a9fa9459Szrj 	      if (proc != (proc_t *) NULL)
3765*a9fa9459Szrj 		{
3766*a9fa9459Szrj 		  proc->pdr.lnLow = l->lineno;
3767*a9fa9459Szrj 		  proc->pdr.cbLineOffset = c - file->fdr.cbLineOffset;
3768*a9fa9459Szrj 		  proc->pdr.iline = totcount;
3769*a9fa9459Szrj 		}
3770*a9fa9459Szrj 	    }
3771*a9fa9459Szrj 
3772*a9fa9459Szrj 	  last = (lineno_list_t *) NULL;
3773*a9fa9459Szrj 	}
3774*a9fa9459Szrj 
3775*a9fa9459Szrj       totcount += count;
3776*a9fa9459Szrj 
3777*a9fa9459Szrj       /* Get the offset to this line number.  */
3778*a9fa9459Szrj       if (last == (lineno_list_t *) NULL)
3779*a9fa9459Szrj 	delta = 0;
3780*a9fa9459Szrj       else
3781*a9fa9459Szrj 	delta = l->lineno - last->lineno;
3782*a9fa9459Szrj 
3783*a9fa9459Szrj       /* Put in the offset to this line number.  */
3784*a9fa9459Szrj       while (delta != 0)
3785*a9fa9459Szrj 	{
3786*a9fa9459Szrj 	  int setcount;
3787*a9fa9459Szrj 
3788*a9fa9459Szrj 	  /* 1 is added to each count read.  */
3789*a9fa9459Szrj 	  --count;
3790*a9fa9459Szrj 	  /* We can only adjust the word count by up to 15 words at a
3791*a9fa9459Szrj 	     time.  */
3792*a9fa9459Szrj 	  if (count <= 0x0f)
3793*a9fa9459Szrj 	    {
3794*a9fa9459Szrj 	      setcount = count;
3795*a9fa9459Szrj 	      count = 0;
3796*a9fa9459Szrj 	    }
3797*a9fa9459Szrj 	  else
3798*a9fa9459Szrj 	    {
3799*a9fa9459Szrj 	      setcount = 0x0f;
3800*a9fa9459Szrj 	      count -= 0x0f;
3801*a9fa9459Szrj 	    }
3802*a9fa9459Szrj 	  if (delta >= -7 && delta <= 7)
3803*a9fa9459Szrj 	    {
3804*a9fa9459Szrj 	      if (bufptr >= *bufend)
3805*a9fa9459Szrj 		bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
3806*a9fa9459Szrj 	      *bufptr++ = setcount + (delta << 4);
3807*a9fa9459Szrj 	      delta = 0;
3808*a9fa9459Szrj 	      ++c;
3809*a9fa9459Szrj 	    }
3810*a9fa9459Szrj 	  else
3811*a9fa9459Szrj 	    {
3812*a9fa9459Szrj 	      int set;
3813*a9fa9459Szrj 
3814*a9fa9459Szrj 	      if (*bufend - bufptr < 3)
3815*a9fa9459Szrj 		bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 3);
3816*a9fa9459Szrj 	      *bufptr++ = setcount + (8 << 4);
3817*a9fa9459Szrj 	      if (delta < -0x8000)
3818*a9fa9459Szrj 		{
3819*a9fa9459Szrj 		  set = -0x8000;
3820*a9fa9459Szrj 		  delta += 0x8000;
3821*a9fa9459Szrj 		}
3822*a9fa9459Szrj 	      else if (delta > 0x7fff)
3823*a9fa9459Szrj 		{
3824*a9fa9459Szrj 		  set = 0x7fff;
3825*a9fa9459Szrj 		  delta -= 0x7fff;
3826*a9fa9459Szrj 		}
3827*a9fa9459Szrj 	      else
3828*a9fa9459Szrj 		{
3829*a9fa9459Szrj 		  set = delta;
3830*a9fa9459Szrj 		  delta = 0;
3831*a9fa9459Szrj 		}
3832*a9fa9459Szrj 	      *bufptr++ = set >> 8;
3833*a9fa9459Szrj 	      *bufptr++ = set & 0xffff;
3834*a9fa9459Szrj 	      c += 3;
3835*a9fa9459Szrj 	    }
3836*a9fa9459Szrj 	}
3837*a9fa9459Szrj 
3838*a9fa9459Szrj       /* Finish adjusting the count.  */
3839*a9fa9459Szrj       while (count > 0)
3840*a9fa9459Szrj 	{
3841*a9fa9459Szrj 	  if (bufptr >= *bufend)
3842*a9fa9459Szrj 	    bufptr = ecoff_add_bytes (buf, bufend, bufptr, (long) 1);
3843*a9fa9459Szrj 	  /* 1 is added to each count read.  */
3844*a9fa9459Szrj 	  --count;
3845*a9fa9459Szrj 	  if (count > 0x0f)
3846*a9fa9459Szrj 	    {
3847*a9fa9459Szrj 	      *bufptr++ = 0x0f;
3848*a9fa9459Szrj 	      count -= 0x0f;
3849*a9fa9459Szrj 	    }
3850*a9fa9459Szrj 	  else
3851*a9fa9459Szrj 	    {
3852*a9fa9459Szrj 	      *bufptr++ = count;
3853*a9fa9459Szrj 	      count = 0;
3854*a9fa9459Szrj 	    }
3855*a9fa9459Szrj 	  ++c;
3856*a9fa9459Szrj 	}
3857*a9fa9459Szrj 
3858*a9fa9459Szrj       ++iline;
3859*a9fa9459Szrj       last = l;
3860*a9fa9459Szrj     }
3861*a9fa9459Szrj 
3862*a9fa9459Szrj   if (proc != (proc_t *) NULL)
3863*a9fa9459Szrj     proc->pdr.lnHigh = last->lineno;
3864*a9fa9459Szrj   if (file != (efdr_t *) NULL)
3865*a9fa9459Szrj     {
3866*a9fa9459Szrj       file->fdr.cbLine = c - file->fdr.cbLineOffset;
3867*a9fa9459Szrj       file->fdr.cline = totcount;
3868*a9fa9459Szrj     }
3869*a9fa9459Szrj 
3870*a9fa9459Szrj   if (linecntptr != (long *) NULL)
3871*a9fa9459Szrj     *linecntptr += totcount;
3872*a9fa9459Szrj 
3873*a9fa9459Szrj   c = ecoff_padding_adjust (backend, buf, bufend, c, &bufptr);
3874*a9fa9459Szrj 
3875*a9fa9459Szrj   return c;
3876*a9fa9459Szrj }
3877*a9fa9459Szrj 
3878*a9fa9459Szrj /* Build and swap out the symbols.  */
3879*a9fa9459Szrj 
3880*a9fa9459Szrj static unsigned long
ecoff_build_symbols(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)3881*a9fa9459Szrj ecoff_build_symbols (const struct ecoff_debug_swap *backend,
3882*a9fa9459Szrj 		     char **buf,
3883*a9fa9459Szrj 		     char **bufend,
3884*a9fa9459Szrj 		     unsigned long offset)
3885*a9fa9459Szrj {
3886*a9fa9459Szrj   const bfd_size_type external_sym_size = backend->external_sym_size;
3887*a9fa9459Szrj   void (* const swap_sym_out) (bfd *, const SYMR *, void *)
3888*a9fa9459Szrj     = backend->swap_sym_out;
3889*a9fa9459Szrj   char *sym_out;
3890*a9fa9459Szrj   long isym;
3891*a9fa9459Szrj   vlinks_t *file_link;
3892*a9fa9459Szrj 
3893*a9fa9459Szrj   sym_out = *buf + offset;
3894*a9fa9459Szrj 
3895*a9fa9459Szrj   isym = 0;
3896*a9fa9459Szrj 
3897*a9fa9459Szrj   /* The symbols are stored by file.  */
3898*a9fa9459Szrj   for (file_link = file_desc.first;
3899*a9fa9459Szrj        file_link != (vlinks_t *) NULL;
3900*a9fa9459Szrj        file_link = file_link->next)
3901*a9fa9459Szrj     {
3902*a9fa9459Szrj       int ifilesym;
3903*a9fa9459Szrj       int fil_cnt;
3904*a9fa9459Szrj       efdr_t *fil_ptr;
3905*a9fa9459Szrj       efdr_t *fil_end;
3906*a9fa9459Szrj 
3907*a9fa9459Szrj       if (file_link->next == (vlinks_t *) NULL)
3908*a9fa9459Szrj 	fil_cnt = file_desc.objects_last_page;
3909*a9fa9459Szrj       else
3910*a9fa9459Szrj 	fil_cnt = file_desc.objects_per_page;
3911*a9fa9459Szrj       fil_ptr = file_link->datum->file;
3912*a9fa9459Szrj       fil_end = fil_ptr + fil_cnt;
3913*a9fa9459Szrj       for (; fil_ptr < fil_end; fil_ptr++)
3914*a9fa9459Szrj 	{
3915*a9fa9459Szrj 	  vlinks_t *sym_link;
3916*a9fa9459Szrj 
3917*a9fa9459Szrj 	  fil_ptr->fdr.isymBase = isym;
3918*a9fa9459Szrj 	  ifilesym = isym;
3919*a9fa9459Szrj 	  for (sym_link = fil_ptr->symbols.first;
3920*a9fa9459Szrj 	       sym_link != (vlinks_t *) NULL;
3921*a9fa9459Szrj 	       sym_link = sym_link->next)
3922*a9fa9459Szrj 	    {
3923*a9fa9459Szrj 	      int sym_cnt;
3924*a9fa9459Szrj 	      localsym_t *sym_ptr;
3925*a9fa9459Szrj 	      localsym_t *sym_end;
3926*a9fa9459Szrj 
3927*a9fa9459Szrj 	      if (sym_link->next == (vlinks_t *) NULL)
3928*a9fa9459Szrj 		sym_cnt = fil_ptr->symbols.objects_last_page;
3929*a9fa9459Szrj 	      else
3930*a9fa9459Szrj 		sym_cnt = fil_ptr->symbols.objects_per_page;
3931*a9fa9459Szrj 	      sym_ptr = sym_link->datum->sym;
3932*a9fa9459Szrj 	      sym_end = sym_ptr + sym_cnt;
3933*a9fa9459Szrj 	      for (; sym_ptr < sym_end; sym_ptr++)
3934*a9fa9459Szrj 		{
3935*a9fa9459Szrj 		  int local;
3936*a9fa9459Szrj 		  symbolS *as_sym;
3937*a9fa9459Szrj 		  forward_t *f;
3938*a9fa9459Szrj 
3939*a9fa9459Szrj 		  know (sym_ptr->file_ptr == fil_ptr);
3940*a9fa9459Szrj 
3941*a9fa9459Szrj 		  /* If there is no associated gas symbol, then this
3942*a9fa9459Szrj 		     is a pure debugging symbol.  We have already
3943*a9fa9459Szrj 		     added the name (if any) to fil_ptr->strings.
3944*a9fa9459Szrj 		     Otherwise we must decide whether this is an
3945*a9fa9459Szrj 		     external or a local symbol (actually, it may be
3946*a9fa9459Szrj 		     both if the local provides additional debugging
3947*a9fa9459Szrj 		     information for the external).  */
3948*a9fa9459Szrj 		  local = 1;
3949*a9fa9459Szrj 		  as_sym = sym_ptr->as_sym;
3950*a9fa9459Szrj 		  if (as_sym != (symbolS *) NULL)
3951*a9fa9459Szrj 		    {
3952*a9fa9459Szrj 		      symint_t indx;
3953*a9fa9459Szrj 
3954*a9fa9459Szrj 		      /* The value of a block start symbol is the
3955*a9fa9459Szrj 		         offset from the start of the procedure.  For
3956*a9fa9459Szrj 		         other symbols we just use the gas value (but
3957*a9fa9459Szrj 		         we must offset it by the vma of the section,
3958*a9fa9459Szrj 		         just as BFD does, because BFD will not see
3959*a9fa9459Szrj 		         this value).  */
3960*a9fa9459Szrj 		      if (sym_ptr->ecoff_sym.asym.st == (int) st_Block
3961*a9fa9459Szrj 			  && sym_ptr->ecoff_sym.asym.sc == (int) sc_Text)
3962*a9fa9459Szrj 			{
3963*a9fa9459Szrj 			  symbolS *begin_sym;
3964*a9fa9459Szrj 
3965*a9fa9459Szrj 			  know (sym_ptr->proc_ptr != (proc_t *) NULL);
3966*a9fa9459Szrj 			  begin_sym = sym_ptr->proc_ptr->sym->as_sym;
3967*a9fa9459Szrj 			  if (S_GET_SEGMENT (as_sym)
3968*a9fa9459Szrj 			      != S_GET_SEGMENT (begin_sym))
3969*a9fa9459Szrj 			    as_warn (_(".begin/.bend in different segments"));
3970*a9fa9459Szrj 			  sym_ptr->ecoff_sym.asym.value =
3971*a9fa9459Szrj 			    S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
3972*a9fa9459Szrj 			}
3973*a9fa9459Szrj 		      else
3974*a9fa9459Szrj 			sym_ptr->ecoff_sym.asym.value =
3975*a9fa9459Szrj 			  (S_GET_VALUE (as_sym)
3976*a9fa9459Szrj 			   + bfd_get_section_vma (stdoutput,
3977*a9fa9459Szrj 						  S_GET_SEGMENT (as_sym))
3978*a9fa9459Szrj 			   + sym_ptr->addend);
3979*a9fa9459Szrj 
3980*a9fa9459Szrj 		      sym_ptr->ecoff_sym.weakext = S_IS_WEAK (as_sym);
3981*a9fa9459Szrj 
3982*a9fa9459Szrj 		      /* Set st_Proc to st_StaticProc for local
3983*a9fa9459Szrj 			 functions.  */
3984*a9fa9459Szrj 		      if (sym_ptr->ecoff_sym.asym.st == st_Proc
3985*a9fa9459Szrj 			  && S_IS_DEFINED (as_sym)
3986*a9fa9459Szrj 			  && ! S_IS_EXTERNAL (as_sym)
3987*a9fa9459Szrj 			  && ! S_IS_WEAK (as_sym))
3988*a9fa9459Szrj 			sym_ptr->ecoff_sym.asym.st = st_StaticProc;
3989*a9fa9459Szrj 
3990*a9fa9459Szrj 		      /* Get the type and storage class based on where
3991*a9fa9459Szrj 		         the symbol actually wound up.  Traditionally,
3992*a9fa9459Szrj 		         N_LBRAC and N_RBRAC are *not* relocated.  */
3993*a9fa9459Szrj 		      indx = sym_ptr->ecoff_sym.asym.index;
3994*a9fa9459Szrj 		      if (sym_ptr->ecoff_sym.asym.st == st_Nil
3995*a9fa9459Szrj 			  && sym_ptr->ecoff_sym.asym.sc == sc_Nil
3996*a9fa9459Szrj 			  && (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
3997*a9fa9459Szrj 			      || ((ECOFF_UNMARK_STAB (indx) != N_LBRAC)
3998*a9fa9459Szrj 				  && (ECOFF_UNMARK_STAB (indx) != N_RBRAC))))
3999*a9fa9459Szrj 			{
4000*a9fa9459Szrj 			  segT seg;
4001*a9fa9459Szrj 			  const char *segname;
4002*a9fa9459Szrj 			  st_t st;
4003*a9fa9459Szrj 			  sc_t sc;
4004*a9fa9459Szrj 
4005*a9fa9459Szrj 			  seg = S_GET_SEGMENT (as_sym);
4006*a9fa9459Szrj 			  segname = segment_name (seg);
4007*a9fa9459Szrj 
4008*a9fa9459Szrj 			  if (! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym)
4009*a9fa9459Szrj 			      && (S_IS_EXTERNAL (as_sym)
4010*a9fa9459Szrj 				  || S_IS_WEAK (as_sym)
4011*a9fa9459Szrj 				  || ! S_IS_DEFINED (as_sym)))
4012*a9fa9459Szrj 			    {
4013*a9fa9459Szrj 			      if ((symbol_get_bfdsym (as_sym)->flags
4014*a9fa9459Szrj 				   & BSF_FUNCTION) != 0)
4015*a9fa9459Szrj 				st = st_Proc;
4016*a9fa9459Szrj 			      else
4017*a9fa9459Szrj 				st = st_Global;
4018*a9fa9459Szrj 			    }
4019*a9fa9459Szrj 			  else if (seg == text_section)
4020*a9fa9459Szrj 			    st = st_Label;
4021*a9fa9459Szrj 			  else
4022*a9fa9459Szrj 			    st = st_Static;
4023*a9fa9459Szrj 
4024*a9fa9459Szrj 			  if (! S_IS_DEFINED (as_sym))
4025*a9fa9459Szrj 			    {
4026*a9fa9459Szrj 			      valueT s;
4027*a9fa9459Szrj 
4028*a9fa9459Szrj 			      s = symbol_get_obj (as_sym)->ecoff_extern_size;
4029*a9fa9459Szrj 			      if (s == 0
4030*a9fa9459Szrj 				  || s > bfd_get_gp_size (stdoutput))
4031*a9fa9459Szrj 				sc = sc_Undefined;
4032*a9fa9459Szrj 			      else
4033*a9fa9459Szrj 				{
4034*a9fa9459Szrj 				  sc = sc_SUndefined;
4035*a9fa9459Szrj 				  sym_ptr->ecoff_sym.asym.value = s;
4036*a9fa9459Szrj 				}
4037*a9fa9459Szrj #ifdef S_SET_SIZE
4038*a9fa9459Szrj 			      S_SET_SIZE (as_sym, s);
4039*a9fa9459Szrj #endif
4040*a9fa9459Szrj 			    }
4041*a9fa9459Szrj 			  else if (S_IS_COMMON (as_sym))
4042*a9fa9459Szrj 			    {
4043*a9fa9459Szrj 			      if (S_GET_VALUE (as_sym) > 0
4044*a9fa9459Szrj 				  && (S_GET_VALUE (as_sym)
4045*a9fa9459Szrj 				      <= bfd_get_gp_size (stdoutput)))
4046*a9fa9459Szrj 				sc = sc_SCommon;
4047*a9fa9459Szrj 			      else
4048*a9fa9459Szrj 				sc = sc_Common;
4049*a9fa9459Szrj 			    }
4050*a9fa9459Szrj 			  else if (seg == text_section)
4051*a9fa9459Szrj 			    sc = sc_Text;
4052*a9fa9459Szrj 			  else if (seg == data_section)
4053*a9fa9459Szrj 			    sc = sc_Data;
4054*a9fa9459Szrj 			  else if (strcmp (segname, ".rdata") == 0
4055*a9fa9459Szrj 				   || strcmp (segname, ".rodata") == 0)
4056*a9fa9459Szrj 			    sc = sc_RData;
4057*a9fa9459Szrj 			  else if (strcmp (segname, ".sdata") == 0)
4058*a9fa9459Szrj 			    sc = sc_SData;
4059*a9fa9459Szrj 			  else if (seg == bss_section)
4060*a9fa9459Szrj 			    sc = sc_Bss;
4061*a9fa9459Szrj 			  else if (strcmp (segname, ".sbss") == 0)
4062*a9fa9459Szrj 			    sc = sc_SBss;
4063*a9fa9459Szrj 			  else if (seg == bfd_abs_section_ptr)
4064*a9fa9459Szrj 			    sc = sc_Abs;
4065*a9fa9459Szrj 			  else
4066*a9fa9459Szrj 			    {
4067*a9fa9459Szrj 			      /* This must be a user named section.
4068*a9fa9459Szrj 			         This is not possible in ECOFF, but it
4069*a9fa9459Szrj 			         is in ELF.  */
4070*a9fa9459Szrj 			      sc = sc_Data;
4071*a9fa9459Szrj 			    }
4072*a9fa9459Szrj 
4073*a9fa9459Szrj 			  sym_ptr->ecoff_sym.asym.st = (int) st;
4074*a9fa9459Szrj 			  sym_ptr->ecoff_sym.asym.sc = (int) sc;
4075*a9fa9459Szrj 			}
4076*a9fa9459Szrj 
4077*a9fa9459Szrj 		      /* This is just an external symbol if it is
4078*a9fa9459Szrj 		         outside a procedure and it has a type.
4079*a9fa9459Szrj 		         FIXME: g++ will generate symbols which have
4080*a9fa9459Szrj 		         different names in the debugging information
4081*a9fa9459Szrj 		         than the actual symbol.  Should we handle
4082*a9fa9459Szrj 		         them here?  */
4083*a9fa9459Szrj 		      if ((S_IS_EXTERNAL (as_sym)
4084*a9fa9459Szrj 			   || S_IS_WEAK (as_sym)
4085*a9fa9459Szrj 			   || ! S_IS_DEFINED (as_sym))
4086*a9fa9459Szrj 			  && sym_ptr->proc_ptr == (proc_t *) NULL
4087*a9fa9459Szrj 			  && sym_ptr->ecoff_sym.asym.st != (int) st_Nil
4088*a9fa9459Szrj 			  && ! ECOFF_IS_STAB (&sym_ptr->ecoff_sym.asym))
4089*a9fa9459Szrj 			local = 0;
4090*a9fa9459Szrj 
4091*a9fa9459Szrj 		      /* This is just an external symbol if it is a
4092*a9fa9459Szrj 		         common symbol.  */
4093*a9fa9459Szrj 		      if (S_IS_COMMON (as_sym))
4094*a9fa9459Szrj 			local = 0;
4095*a9fa9459Szrj 
4096*a9fa9459Szrj 		      /* If an st_end symbol has an associated gas
4097*a9fa9459Szrj 		         symbol, then it is a local label created for
4098*a9fa9459Szrj 		         a .bend or .end directive.  Stabs line
4099*a9fa9459Szrj 		         numbers will have \001 in the names.  */
4100*a9fa9459Szrj 		      if (local
4101*a9fa9459Szrj 			  && sym_ptr->ecoff_sym.asym.st != st_End
4102*a9fa9459Szrj 			  && strchr (sym_ptr->name, '\001') == 0)
4103*a9fa9459Szrj 			sym_ptr->ecoff_sym.asym.iss =
4104*a9fa9459Szrj 			  add_string (&fil_ptr->strings,
4105*a9fa9459Szrj 				      fil_ptr->str_hash,
4106*a9fa9459Szrj 				      sym_ptr->name,
4107*a9fa9459Szrj 				      (shash_t **) NULL);
4108*a9fa9459Szrj 		    }
4109*a9fa9459Szrj 
4110*a9fa9459Szrj 		  /* We now know the index of this symbol; fill in
4111*a9fa9459Szrj 		     locations that have been waiting for that
4112*a9fa9459Szrj 		     information.  */
4113*a9fa9459Szrj 		  if (sym_ptr->begin_ptr != (localsym_t *) NULL)
4114*a9fa9459Szrj 		    {
4115*a9fa9459Szrj 		      localsym_t *begin_ptr;
4116*a9fa9459Szrj 		      st_t begin_type;
4117*a9fa9459Szrj 
4118*a9fa9459Szrj 		      know (local);
4119*a9fa9459Szrj 		      begin_ptr = sym_ptr->begin_ptr;
4120*a9fa9459Szrj 		      know (begin_ptr->sym_index != -1);
4121*a9fa9459Szrj 		      sym_ptr->ecoff_sym.asym.index = begin_ptr->sym_index;
4122*a9fa9459Szrj 		      if (sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
4123*a9fa9459Szrj 			sym_ptr->ecoff_sym.asym.iss =
4124*a9fa9459Szrj 			  begin_ptr->ecoff_sym.asym.iss;
4125*a9fa9459Szrj 
4126*a9fa9459Szrj 		      begin_type = (st_t) begin_ptr->ecoff_sym.asym.st;
4127*a9fa9459Szrj 		      if (begin_type == st_File
4128*a9fa9459Szrj 			  || begin_type == st_Block)
4129*a9fa9459Szrj 			{
4130*a9fa9459Szrj 			  begin_ptr->ecoff_sym.asym.index =
4131*a9fa9459Szrj 			    isym - ifilesym + 1;
4132*a9fa9459Szrj 			  (*swap_sym_out) (stdoutput,
4133*a9fa9459Szrj 					   &begin_ptr->ecoff_sym.asym,
4134*a9fa9459Szrj 					   (*buf
4135*a9fa9459Szrj 					    + offset
4136*a9fa9459Szrj 					    + (begin_ptr->sym_index
4137*a9fa9459Szrj 					       * external_sym_size)));
4138*a9fa9459Szrj 			}
4139*a9fa9459Szrj 		      else
4140*a9fa9459Szrj 			{
4141*a9fa9459Szrj 			  know (begin_ptr->index_ptr != (aux_t *) NULL);
4142*a9fa9459Szrj 			  begin_ptr->index_ptr->data.isym =
4143*a9fa9459Szrj 			    isym - ifilesym + 1;
4144*a9fa9459Szrj 			}
4145*a9fa9459Szrj 
4146*a9fa9459Szrj 		      /* The value of the symbol marking the end of a
4147*a9fa9459Szrj 		         procedure is the size of the procedure.  The
4148*a9fa9459Szrj 		         value of the symbol marking the end of a
4149*a9fa9459Szrj 		         block is the offset from the start of the
4150*a9fa9459Szrj 		         procedure to the block.  */
4151*a9fa9459Szrj 		      if (begin_type == st_Proc
4152*a9fa9459Szrj 			  || begin_type == st_StaticProc)
4153*a9fa9459Szrj 			{
4154*a9fa9459Szrj 			  know (as_sym != (symbolS *) NULL);
4155*a9fa9459Szrj 			  know (begin_ptr->as_sym != (symbolS *) NULL);
4156*a9fa9459Szrj 			  if (S_GET_SEGMENT (as_sym)
4157*a9fa9459Szrj 			      != S_GET_SEGMENT (begin_ptr->as_sym))
4158*a9fa9459Szrj 			    as_warn (_(".begin/.bend in different segments"));
4159*a9fa9459Szrj 			  sym_ptr->ecoff_sym.asym.value =
4160*a9fa9459Szrj 			    (S_GET_VALUE (as_sym)
4161*a9fa9459Szrj 			     - S_GET_VALUE (begin_ptr->as_sym));
4162*a9fa9459Szrj 
4163*a9fa9459Szrj 			  /* If the size is odd, this is probably a
4164*a9fa9459Szrj 			     mips16 function; force it to be even.  */
4165*a9fa9459Szrj 			  if ((sym_ptr->ecoff_sym.asym.value & 1) != 0)
4166*a9fa9459Szrj 			    ++sym_ptr->ecoff_sym.asym.value;
4167*a9fa9459Szrj 
4168*a9fa9459Szrj #ifdef S_SET_SIZE
4169*a9fa9459Szrj 			  S_SET_SIZE (begin_ptr->as_sym,
4170*a9fa9459Szrj 				      sym_ptr->ecoff_sym.asym.value);
4171*a9fa9459Szrj #endif
4172*a9fa9459Szrj 			}
4173*a9fa9459Szrj 		      else if (begin_type == st_Block
4174*a9fa9459Szrj 			       && sym_ptr->ecoff_sym.asym.sc != (int) sc_Info)
4175*a9fa9459Szrj 			{
4176*a9fa9459Szrj 			  symbolS *begin_sym;
4177*a9fa9459Szrj 
4178*a9fa9459Szrj 			  know (as_sym != (symbolS *) NULL);
4179*a9fa9459Szrj 			  know (sym_ptr->proc_ptr != (proc_t *) NULL);
4180*a9fa9459Szrj 			  begin_sym = sym_ptr->proc_ptr->sym->as_sym;
4181*a9fa9459Szrj 			  if (S_GET_SEGMENT (as_sym)
4182*a9fa9459Szrj 			      != S_GET_SEGMENT (begin_sym))
4183*a9fa9459Szrj 			    as_warn (_(".begin/.bend in different segments"));
4184*a9fa9459Szrj 			  sym_ptr->ecoff_sym.asym.value =
4185*a9fa9459Szrj 			    S_GET_VALUE (as_sym) - S_GET_VALUE (begin_sym);
4186*a9fa9459Szrj 			}
4187*a9fa9459Szrj 		    }
4188*a9fa9459Szrj 
4189*a9fa9459Szrj 		  for (f = sym_ptr->forward_ref;
4190*a9fa9459Szrj 		       f != (forward_t *) NULL;
4191*a9fa9459Szrj 		       f = f->next)
4192*a9fa9459Szrj 		    {
4193*a9fa9459Szrj 		      know (local);
4194*a9fa9459Szrj 		      f->ifd_ptr->data.isym = fil_ptr->file_index;
4195*a9fa9459Szrj 		      f->index_ptr->data.rndx.index = isym - ifilesym;
4196*a9fa9459Szrj 		    }
4197*a9fa9459Szrj 
4198*a9fa9459Szrj 		  if (local)
4199*a9fa9459Szrj 		    {
4200*a9fa9459Szrj 		      if ((bfd_size_type)(*bufend - sym_out) < external_sym_size)
4201*a9fa9459Szrj 			sym_out = ecoff_add_bytes (buf, bufend,
4202*a9fa9459Szrj 						   sym_out,
4203*a9fa9459Szrj 						   external_sym_size);
4204*a9fa9459Szrj 		      (*swap_sym_out) (stdoutput, &sym_ptr->ecoff_sym.asym,
4205*a9fa9459Szrj 				       sym_out);
4206*a9fa9459Szrj 		      sym_out += external_sym_size;
4207*a9fa9459Szrj 
4208*a9fa9459Szrj 		      sym_ptr->sym_index = isym;
4209*a9fa9459Szrj 
4210*a9fa9459Szrj 		      if (sym_ptr->proc_ptr != (proc_t *) NULL
4211*a9fa9459Szrj 			  && sym_ptr->proc_ptr->sym == sym_ptr)
4212*a9fa9459Szrj 			sym_ptr->proc_ptr->pdr.isym = isym - ifilesym;
4213*a9fa9459Szrj 
4214*a9fa9459Szrj 		      ++isym;
4215*a9fa9459Szrj 		    }
4216*a9fa9459Szrj 
4217*a9fa9459Szrj 		  /* Record the local symbol index and file number in
4218*a9fa9459Szrj 		     case this is an external symbol.  Note that this
4219*a9fa9459Szrj 		     destroys the asym.index field.  */
4220*a9fa9459Szrj 		  if (as_sym != (symbolS *) NULL
4221*a9fa9459Szrj 		      && symbol_get_obj (as_sym)->ecoff_symbol == sym_ptr)
4222*a9fa9459Szrj 		    {
4223*a9fa9459Szrj 		      if ((sym_ptr->ecoff_sym.asym.st == st_Proc
4224*a9fa9459Szrj 			   || sym_ptr->ecoff_sym.asym.st == st_StaticProc)
4225*a9fa9459Szrj 			  && local)
4226*a9fa9459Szrj 			sym_ptr->ecoff_sym.asym.index = isym - ifilesym - 1;
4227*a9fa9459Szrj 		      sym_ptr->ecoff_sym.ifd = fil_ptr->file_index;
4228*a9fa9459Szrj 
4229*a9fa9459Szrj 		      /* Don't try to merge an FDR which has an
4230*a9fa9459Szrj 		         external symbol attached to it.  */
4231*a9fa9459Szrj 		      if (S_IS_EXTERNAL (as_sym) || S_IS_WEAK (as_sym))
4232*a9fa9459Szrj 			fil_ptr->fdr.fMerge = 0;
4233*a9fa9459Szrj 		    }
4234*a9fa9459Szrj 		}
4235*a9fa9459Szrj 	    }
4236*a9fa9459Szrj 	  fil_ptr->fdr.csym = isym - fil_ptr->fdr.isymBase;
4237*a9fa9459Szrj 	}
4238*a9fa9459Szrj     }
4239*a9fa9459Szrj 
4240*a9fa9459Szrj   return offset + isym * external_sym_size;
4241*a9fa9459Szrj }
4242*a9fa9459Szrj 
4243*a9fa9459Szrj /* Swap out the procedure information.  */
4244*a9fa9459Szrj 
4245*a9fa9459Szrj static unsigned long
ecoff_build_procs(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)4246*a9fa9459Szrj ecoff_build_procs (const struct ecoff_debug_swap *backend,
4247*a9fa9459Szrj 		   char **buf,
4248*a9fa9459Szrj 		   char **bufend,
4249*a9fa9459Szrj 		   unsigned long offset)
4250*a9fa9459Szrj {
4251*a9fa9459Szrj   const bfd_size_type external_pdr_size = backend->external_pdr_size;
4252*a9fa9459Szrj   void (* const swap_pdr_out) (bfd *, const PDR *, void *)
4253*a9fa9459Szrj     = backend->swap_pdr_out;
4254*a9fa9459Szrj   char *pdr_out;
4255*a9fa9459Szrj   long iproc;
4256*a9fa9459Szrj   vlinks_t *file_link;
4257*a9fa9459Szrj 
4258*a9fa9459Szrj   pdr_out = *buf + offset;
4259*a9fa9459Szrj 
4260*a9fa9459Szrj   iproc = 0;
4261*a9fa9459Szrj 
4262*a9fa9459Szrj   /* The procedures are stored by file.  */
4263*a9fa9459Szrj   for (file_link = file_desc.first;
4264*a9fa9459Szrj        file_link != (vlinks_t *) NULL;
4265*a9fa9459Szrj        file_link = file_link->next)
4266*a9fa9459Szrj     {
4267*a9fa9459Szrj       int fil_cnt;
4268*a9fa9459Szrj       efdr_t *fil_ptr;
4269*a9fa9459Szrj       efdr_t *fil_end;
4270*a9fa9459Szrj 
4271*a9fa9459Szrj       if (file_link->next == (vlinks_t *) NULL)
4272*a9fa9459Szrj 	fil_cnt = file_desc.objects_last_page;
4273*a9fa9459Szrj       else
4274*a9fa9459Szrj 	fil_cnt = file_desc.objects_per_page;
4275*a9fa9459Szrj       fil_ptr = file_link->datum->file;
4276*a9fa9459Szrj       fil_end = fil_ptr + fil_cnt;
4277*a9fa9459Szrj       for (; fil_ptr < fil_end; fil_ptr++)
4278*a9fa9459Szrj 	{
4279*a9fa9459Szrj 	  vlinks_t *proc_link;
4280*a9fa9459Szrj 	  int first;
4281*a9fa9459Szrj 
4282*a9fa9459Szrj 	  fil_ptr->fdr.ipdFirst = iproc;
4283*a9fa9459Szrj 	  first = 1;
4284*a9fa9459Szrj 	  for (proc_link = fil_ptr->procs.first;
4285*a9fa9459Szrj 	       proc_link != (vlinks_t *) NULL;
4286*a9fa9459Szrj 	       proc_link = proc_link->next)
4287*a9fa9459Szrj 	    {
4288*a9fa9459Szrj 	      int prc_cnt;
4289*a9fa9459Szrj 	      proc_t *proc_ptr;
4290*a9fa9459Szrj 	      proc_t *proc_end;
4291*a9fa9459Szrj 
4292*a9fa9459Szrj 	      if (proc_link->next == (vlinks_t *) NULL)
4293*a9fa9459Szrj 		prc_cnt = fil_ptr->procs.objects_last_page;
4294*a9fa9459Szrj 	      else
4295*a9fa9459Szrj 		prc_cnt = fil_ptr->procs.objects_per_page;
4296*a9fa9459Szrj 	      proc_ptr = proc_link->datum->proc;
4297*a9fa9459Szrj 	      proc_end = proc_ptr + prc_cnt;
4298*a9fa9459Szrj 	      for (; proc_ptr < proc_end; proc_ptr++)
4299*a9fa9459Szrj 		{
4300*a9fa9459Szrj 		  symbolS *adr_sym;
4301*a9fa9459Szrj 		  unsigned long adr;
4302*a9fa9459Szrj 
4303*a9fa9459Szrj 		  adr_sym = proc_ptr->sym->as_sym;
4304*a9fa9459Szrj 		  adr = (S_GET_VALUE (adr_sym)
4305*a9fa9459Szrj 			 + bfd_get_section_vma (stdoutput,
4306*a9fa9459Szrj 						S_GET_SEGMENT (adr_sym)));
4307*a9fa9459Szrj 		  if (first)
4308*a9fa9459Szrj 		    {
4309*a9fa9459Szrj 		      /* This code used to force the adr of the very
4310*a9fa9459Szrj 		         first fdr to be 0.  However, the native tools
4311*a9fa9459Szrj 		         don't do that, and I can't remember why it
4312*a9fa9459Szrj 		         used to work that way, so I took it out.  */
4313*a9fa9459Szrj 		      fil_ptr->fdr.adr = adr;
4314*a9fa9459Szrj 		      first = 0;
4315*a9fa9459Szrj 		    }
4316*a9fa9459Szrj 		  proc_ptr->pdr.adr = adr - fil_ptr->fdr.adr;
4317*a9fa9459Szrj 		  if ((bfd_size_type)(*bufend - pdr_out) < external_pdr_size)
4318*a9fa9459Szrj 		    pdr_out = ecoff_add_bytes (buf, bufend,
4319*a9fa9459Szrj 					       pdr_out,
4320*a9fa9459Szrj 					       external_pdr_size);
4321*a9fa9459Szrj 		  (*swap_pdr_out) (stdoutput, &proc_ptr->pdr, pdr_out);
4322*a9fa9459Szrj 		  pdr_out += external_pdr_size;
4323*a9fa9459Szrj 		  ++iproc;
4324*a9fa9459Szrj 		}
4325*a9fa9459Szrj 	    }
4326*a9fa9459Szrj 	  fil_ptr->fdr.cpd = iproc - fil_ptr->fdr.ipdFirst;
4327*a9fa9459Szrj 	}
4328*a9fa9459Szrj     }
4329*a9fa9459Szrj 
4330*a9fa9459Szrj   return offset + iproc * external_pdr_size;
4331*a9fa9459Szrj }
4332*a9fa9459Szrj 
4333*a9fa9459Szrj /* Swap out the aux information.  */
4334*a9fa9459Szrj 
4335*a9fa9459Szrj static unsigned long
ecoff_build_aux(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)4336*a9fa9459Szrj ecoff_build_aux (const struct ecoff_debug_swap *backend,
4337*a9fa9459Szrj 		 char **buf,
4338*a9fa9459Szrj 		 char **bufend,
4339*a9fa9459Szrj 		 unsigned long offset)
4340*a9fa9459Szrj {
4341*a9fa9459Szrj   int bigendian;
4342*a9fa9459Szrj   union aux_ext *aux_out;
4343*a9fa9459Szrj   long iaux;
4344*a9fa9459Szrj   vlinks_t *file_link;
4345*a9fa9459Szrj 
4346*a9fa9459Szrj   bigendian = bfd_big_endian (stdoutput);
4347*a9fa9459Szrj 
4348*a9fa9459Szrj   aux_out = (union aux_ext *) (*buf + offset);
4349*a9fa9459Szrj 
4350*a9fa9459Szrj   iaux = 0;
4351*a9fa9459Szrj 
4352*a9fa9459Szrj   /* The aux entries are stored by file.  */
4353*a9fa9459Szrj   for (file_link = file_desc.first;
4354*a9fa9459Szrj        file_link != (vlinks_t *) NULL;
4355*a9fa9459Szrj        file_link = file_link->next)
4356*a9fa9459Szrj     {
4357*a9fa9459Szrj       int fil_cnt;
4358*a9fa9459Szrj       efdr_t *fil_ptr;
4359*a9fa9459Szrj       efdr_t *fil_end;
4360*a9fa9459Szrj 
4361*a9fa9459Szrj       if (file_link->next == (vlinks_t *) NULL)
4362*a9fa9459Szrj 	fil_cnt = file_desc.objects_last_page;
4363*a9fa9459Szrj       else
4364*a9fa9459Szrj 	fil_cnt = file_desc.objects_per_page;
4365*a9fa9459Szrj       fil_ptr = file_link->datum->file;
4366*a9fa9459Szrj       fil_end = fil_ptr + fil_cnt;
4367*a9fa9459Szrj       for (; fil_ptr < fil_end; fil_ptr++)
4368*a9fa9459Szrj 	{
4369*a9fa9459Szrj 	  vlinks_t *aux_link;
4370*a9fa9459Szrj 
4371*a9fa9459Szrj 	  fil_ptr->fdr.fBigendian = bigendian;
4372*a9fa9459Szrj 	  fil_ptr->fdr.iauxBase = iaux;
4373*a9fa9459Szrj 	  for (aux_link = fil_ptr->aux_syms.first;
4374*a9fa9459Szrj 	       aux_link != (vlinks_t *) NULL;
4375*a9fa9459Szrj 	       aux_link = aux_link->next)
4376*a9fa9459Szrj 	    {
4377*a9fa9459Szrj 	      int aux_cnt;
4378*a9fa9459Szrj 	      aux_t *aux_ptr;
4379*a9fa9459Szrj 	      aux_t *aux_end;
4380*a9fa9459Szrj 
4381*a9fa9459Szrj 	      if (aux_link->next == (vlinks_t *) NULL)
4382*a9fa9459Szrj 		aux_cnt = fil_ptr->aux_syms.objects_last_page;
4383*a9fa9459Szrj 	      else
4384*a9fa9459Szrj 		aux_cnt = fil_ptr->aux_syms.objects_per_page;
4385*a9fa9459Szrj 	      aux_ptr = aux_link->datum->aux;
4386*a9fa9459Szrj 	      aux_end = aux_ptr + aux_cnt;
4387*a9fa9459Szrj 	      for (; aux_ptr < aux_end; aux_ptr++)
4388*a9fa9459Szrj 		{
4389*a9fa9459Szrj 		  if ((unsigned long) (*bufend - (char *) aux_out)
4390*a9fa9459Szrj 		      < sizeof (union aux_ext))
4391*a9fa9459Szrj 		    aux_out = ((union aux_ext *)
4392*a9fa9459Szrj 			       ecoff_add_bytes (buf, bufend,
4393*a9fa9459Szrj 						(char *) aux_out,
4394*a9fa9459Szrj 						sizeof (union aux_ext)));
4395*a9fa9459Szrj 		  switch (aux_ptr->type)
4396*a9fa9459Szrj 		    {
4397*a9fa9459Szrj 		    case aux_tir:
4398*a9fa9459Szrj 		      (*backend->swap_tir_out) (bigendian,
4399*a9fa9459Szrj 						&aux_ptr->data.ti,
4400*a9fa9459Szrj 						&aux_out->a_ti);
4401*a9fa9459Szrj 		      break;
4402*a9fa9459Szrj 		    case aux_rndx:
4403*a9fa9459Szrj 		      (*backend->swap_rndx_out) (bigendian,
4404*a9fa9459Szrj 						 &aux_ptr->data.rndx,
4405*a9fa9459Szrj 						 &aux_out->a_rndx);
4406*a9fa9459Szrj 		      break;
4407*a9fa9459Szrj 		    case aux_dnLow:
4408*a9fa9459Szrj 		      AUX_PUT_DNLOW (bigendian, aux_ptr->data.dnLow,
4409*a9fa9459Szrj 				     aux_out);
4410*a9fa9459Szrj 		      break;
4411*a9fa9459Szrj 		    case aux_dnHigh:
4412*a9fa9459Szrj 		      AUX_PUT_DNHIGH (bigendian, aux_ptr->data.dnHigh,
4413*a9fa9459Szrj 				      aux_out);
4414*a9fa9459Szrj 		      break;
4415*a9fa9459Szrj 		    case aux_isym:
4416*a9fa9459Szrj 		      AUX_PUT_ISYM (bigendian, aux_ptr->data.isym,
4417*a9fa9459Szrj 				    aux_out);
4418*a9fa9459Szrj 		      break;
4419*a9fa9459Szrj 		    case aux_iss:
4420*a9fa9459Szrj 		      AUX_PUT_ISS (bigendian, aux_ptr->data.iss,
4421*a9fa9459Szrj 				   aux_out);
4422*a9fa9459Szrj 		      break;
4423*a9fa9459Szrj 		    case aux_width:
4424*a9fa9459Szrj 		      AUX_PUT_WIDTH (bigendian, aux_ptr->data.width,
4425*a9fa9459Szrj 				     aux_out);
4426*a9fa9459Szrj 		      break;
4427*a9fa9459Szrj 		    case aux_count:
4428*a9fa9459Szrj 		      AUX_PUT_COUNT (bigendian, aux_ptr->data.count,
4429*a9fa9459Szrj 				     aux_out);
4430*a9fa9459Szrj 		      break;
4431*a9fa9459Szrj 		    }
4432*a9fa9459Szrj 
4433*a9fa9459Szrj 		  ++aux_out;
4434*a9fa9459Szrj 		  ++iaux;
4435*a9fa9459Szrj 		}
4436*a9fa9459Szrj 	    }
4437*a9fa9459Szrj 	  fil_ptr->fdr.caux = iaux - fil_ptr->fdr.iauxBase;
4438*a9fa9459Szrj 	}
4439*a9fa9459Szrj     }
4440*a9fa9459Szrj 
4441*a9fa9459Szrj   return ecoff_padding_adjust (backend, buf, bufend,
4442*a9fa9459Szrj 			       offset + iaux * sizeof (union aux_ext),
4443*a9fa9459Szrj 			       (char **) NULL);
4444*a9fa9459Szrj }
4445*a9fa9459Szrj 
4446*a9fa9459Szrj /* Copy out the strings from a varray_t.  This returns the number of
4447*a9fa9459Szrj    bytes copied, rather than the new offset.  */
4448*a9fa9459Szrj 
4449*a9fa9459Szrj static unsigned long
ecoff_build_strings(char ** buf,char ** bufend,unsigned long offset,varray_t * vp)4450*a9fa9459Szrj ecoff_build_strings (char **buf,
4451*a9fa9459Szrj 		     char **bufend,
4452*a9fa9459Szrj 		     unsigned long offset,
4453*a9fa9459Szrj 		     varray_t *vp)
4454*a9fa9459Szrj {
4455*a9fa9459Szrj   unsigned long istr;
4456*a9fa9459Szrj   char *str_out;
4457*a9fa9459Szrj   vlinks_t *str_link;
4458*a9fa9459Szrj 
4459*a9fa9459Szrj   str_out = *buf + offset;
4460*a9fa9459Szrj 
4461*a9fa9459Szrj   istr = 0;
4462*a9fa9459Szrj 
4463*a9fa9459Szrj   for (str_link = vp->first;
4464*a9fa9459Szrj        str_link != (vlinks_t *) NULL;
4465*a9fa9459Szrj        str_link = str_link->next)
4466*a9fa9459Szrj     {
4467*a9fa9459Szrj       unsigned long str_cnt;
4468*a9fa9459Szrj 
4469*a9fa9459Szrj       if (str_link->next == (vlinks_t *) NULL)
4470*a9fa9459Szrj 	str_cnt = vp->objects_last_page;
4471*a9fa9459Szrj       else
4472*a9fa9459Szrj 	str_cnt = vp->objects_per_page;
4473*a9fa9459Szrj 
4474*a9fa9459Szrj       if ((unsigned long)(*bufend - str_out) < str_cnt)
4475*a9fa9459Szrj 	str_out = ecoff_add_bytes (buf, bufend, str_out, str_cnt);
4476*a9fa9459Szrj 
4477*a9fa9459Szrj       memcpy (str_out, str_link->datum->byte, str_cnt);
4478*a9fa9459Szrj       str_out += str_cnt;
4479*a9fa9459Szrj       istr += str_cnt;
4480*a9fa9459Szrj     }
4481*a9fa9459Szrj 
4482*a9fa9459Szrj   return istr;
4483*a9fa9459Szrj }
4484*a9fa9459Szrj 
4485*a9fa9459Szrj /* Dump out the local strings.  */
4486*a9fa9459Szrj 
4487*a9fa9459Szrj static unsigned long
ecoff_build_ss(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)4488*a9fa9459Szrj ecoff_build_ss (const struct ecoff_debug_swap *backend,
4489*a9fa9459Szrj 		char **buf,
4490*a9fa9459Szrj 		char **bufend,
4491*a9fa9459Szrj 		unsigned long offset)
4492*a9fa9459Szrj {
4493*a9fa9459Szrj   long iss;
4494*a9fa9459Szrj   vlinks_t *file_link;
4495*a9fa9459Szrj 
4496*a9fa9459Szrj   iss = 0;
4497*a9fa9459Szrj 
4498*a9fa9459Szrj   for (file_link = file_desc.first;
4499*a9fa9459Szrj        file_link != (vlinks_t *) NULL;
4500*a9fa9459Szrj        file_link = file_link->next)
4501*a9fa9459Szrj     {
4502*a9fa9459Szrj       int fil_cnt;
4503*a9fa9459Szrj       efdr_t *fil_ptr;
4504*a9fa9459Szrj       efdr_t *fil_end;
4505*a9fa9459Szrj 
4506*a9fa9459Szrj       if (file_link->next == (vlinks_t *) NULL)
4507*a9fa9459Szrj 	fil_cnt = file_desc.objects_last_page;
4508*a9fa9459Szrj       else
4509*a9fa9459Szrj 	fil_cnt = file_desc.objects_per_page;
4510*a9fa9459Szrj       fil_ptr = file_link->datum->file;
4511*a9fa9459Szrj       fil_end = fil_ptr + fil_cnt;
4512*a9fa9459Szrj       for (; fil_ptr < fil_end; fil_ptr++)
4513*a9fa9459Szrj 	{
4514*a9fa9459Szrj 	  long ss_cnt;
4515*a9fa9459Szrj 
4516*a9fa9459Szrj 	  fil_ptr->fdr.issBase = iss;
4517*a9fa9459Szrj 	  ss_cnt = ecoff_build_strings (buf, bufend, offset + iss,
4518*a9fa9459Szrj 					&fil_ptr->strings);
4519*a9fa9459Szrj 	  fil_ptr->fdr.cbSs = ss_cnt;
4520*a9fa9459Szrj 	  iss += ss_cnt;
4521*a9fa9459Szrj 	}
4522*a9fa9459Szrj     }
4523*a9fa9459Szrj 
4524*a9fa9459Szrj   return ecoff_padding_adjust (backend, buf, bufend, offset + iss,
4525*a9fa9459Szrj 			       (char **) NULL);
4526*a9fa9459Szrj }
4527*a9fa9459Szrj 
4528*a9fa9459Szrj /* Swap out the file descriptors.  */
4529*a9fa9459Szrj 
4530*a9fa9459Szrj static unsigned long
ecoff_build_fdr(const struct ecoff_debug_swap * backend,char ** buf,char ** bufend,unsigned long offset)4531*a9fa9459Szrj ecoff_build_fdr (const struct ecoff_debug_swap *backend,
4532*a9fa9459Szrj 		 char **buf,
4533*a9fa9459Szrj 		 char **bufend,
4534*a9fa9459Szrj 		 unsigned long offset)
4535*a9fa9459Szrj {
4536*a9fa9459Szrj   const bfd_size_type external_fdr_size = backend->external_fdr_size;
4537*a9fa9459Szrj   void (* const swap_fdr_out) (bfd *, const FDR *, void *)
4538*a9fa9459Szrj     = backend->swap_fdr_out;
4539*a9fa9459Szrj   long ifile;
4540*a9fa9459Szrj   char *fdr_out;
4541*a9fa9459Szrj   vlinks_t *file_link;
4542*a9fa9459Szrj 
4543*a9fa9459Szrj   ifile = 0;
4544*a9fa9459Szrj 
4545*a9fa9459Szrj   fdr_out = *buf + offset;
4546*a9fa9459Szrj 
4547*a9fa9459Szrj   for (file_link = file_desc.first;
4548*a9fa9459Szrj        file_link != (vlinks_t *) NULL;
4549*a9fa9459Szrj        file_link = file_link->next)
4550*a9fa9459Szrj     {
4551*a9fa9459Szrj       int fil_cnt;
4552*a9fa9459Szrj       efdr_t *fil_ptr;
4553*a9fa9459Szrj       efdr_t *fil_end;
4554*a9fa9459Szrj 
4555*a9fa9459Szrj       if (file_link->next == (vlinks_t *) NULL)
4556*a9fa9459Szrj 	fil_cnt = file_desc.objects_last_page;
4557*a9fa9459Szrj       else
4558*a9fa9459Szrj 	fil_cnt = file_desc.objects_per_page;
4559*a9fa9459Szrj       fil_ptr = file_link->datum->file;
4560*a9fa9459Szrj       fil_end = fil_ptr + fil_cnt;
4561*a9fa9459Szrj       for (; fil_ptr < fil_end; fil_ptr++)
4562*a9fa9459Szrj 	{
4563*a9fa9459Szrj 	  if ((bfd_size_type)(*bufend - fdr_out) < external_fdr_size)
4564*a9fa9459Szrj 	    fdr_out = ecoff_add_bytes (buf, bufend, fdr_out,
4565*a9fa9459Szrj 				       external_fdr_size);
4566*a9fa9459Szrj 	  (*swap_fdr_out) (stdoutput, &fil_ptr->fdr, fdr_out);
4567*a9fa9459Szrj 	  fdr_out += external_fdr_size;
4568*a9fa9459Szrj 	  ++ifile;
4569*a9fa9459Szrj 	}
4570*a9fa9459Szrj     }
4571*a9fa9459Szrj 
4572*a9fa9459Szrj   return offset + ifile * external_fdr_size;
4573*a9fa9459Szrj }
4574*a9fa9459Szrj 
4575*a9fa9459Szrj /* Set up the external symbols.  These are supposed to be handled by
4576*a9fa9459Szrj    the backend.  This routine just gets the right information and
4577*a9fa9459Szrj    calls a backend function to deal with it.  */
4578*a9fa9459Szrj 
4579*a9fa9459Szrj static void
ecoff_setup_ext(void)4580*a9fa9459Szrj ecoff_setup_ext (void)
4581*a9fa9459Szrj {
4582*a9fa9459Szrj   symbolS *sym;
4583*a9fa9459Szrj 
4584*a9fa9459Szrj   for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
4585*a9fa9459Szrj     {
4586*a9fa9459Szrj       if (symbol_get_obj (sym)->ecoff_symbol == NULL)
4587*a9fa9459Szrj 	continue;
4588*a9fa9459Szrj 
4589*a9fa9459Szrj       /* If this is a local symbol, then force the fields to zero.  */
4590*a9fa9459Szrj       if (! S_IS_EXTERNAL (sym)
4591*a9fa9459Szrj 	  && ! S_IS_WEAK (sym)
4592*a9fa9459Szrj 	  && S_IS_DEFINED (sym))
4593*a9fa9459Szrj 	{
4594*a9fa9459Szrj 	  struct localsym *lsym;
4595*a9fa9459Szrj 
4596*a9fa9459Szrj 	  lsym = symbol_get_obj (sym)->ecoff_symbol;
4597*a9fa9459Szrj 	  lsym->ecoff_sym.asym.value = 0;
4598*a9fa9459Szrj 	  lsym->ecoff_sym.asym.st = (int) st_Nil;
4599*a9fa9459Szrj 	  lsym->ecoff_sym.asym.sc = (int) sc_Nil;
4600*a9fa9459Szrj 	  lsym->ecoff_sym.asym.index = indexNil;
4601*a9fa9459Szrj 	}
4602*a9fa9459Szrj 
4603*a9fa9459Szrj       obj_ecoff_set_ext (sym, &symbol_get_obj (sym)->ecoff_symbol->ecoff_sym);
4604*a9fa9459Szrj     }
4605*a9fa9459Szrj }
4606*a9fa9459Szrj 
4607*a9fa9459Szrj /* Build the ECOFF debugging information.  */
4608*a9fa9459Szrj 
4609*a9fa9459Szrj unsigned long
ecoff_build_debug(HDRR * hdr,char ** bufp,const struct ecoff_debug_swap * backend)4610*a9fa9459Szrj ecoff_build_debug (HDRR *hdr,
4611*a9fa9459Szrj 		   char **bufp,
4612*a9fa9459Szrj 		   const struct ecoff_debug_swap *backend)
4613*a9fa9459Szrj {
4614*a9fa9459Szrj   const bfd_size_type external_pdr_size = backend->external_pdr_size;
4615*a9fa9459Szrj   tag_t *ptag;
4616*a9fa9459Szrj   tag_t *ptag_next;
4617*a9fa9459Szrj   efdr_t *fil_ptr;
4618*a9fa9459Szrj   int end_warning;
4619*a9fa9459Szrj   efdr_t *hold_file_ptr;
4620*a9fa9459Szrj   proc_t *hold_proc_ptr;
4621*a9fa9459Szrj   symbolS *sym;
4622*a9fa9459Szrj   char *buf;
4623*a9fa9459Szrj   char *bufend;
4624*a9fa9459Szrj   unsigned long offset;
4625*a9fa9459Szrj 
4626*a9fa9459Szrj   /* Make sure we have a file.  */
4627*a9fa9459Szrj   if (first_file == (efdr_t *) NULL)
4628*a9fa9459Szrj     add_file ((const char *) NULL, 0, 1);
4629*a9fa9459Szrj 
4630*a9fa9459Szrj   /* Handle any top level tags.  */
4631*a9fa9459Szrj   for (ptag = top_tag_head->first_tag;
4632*a9fa9459Szrj        ptag != (tag_t *) NULL;
4633*a9fa9459Szrj        ptag = ptag_next)
4634*a9fa9459Szrj     {
4635*a9fa9459Szrj       if (ptag->forward_ref != (forward_t *) NULL)
4636*a9fa9459Szrj 	add_unknown_tag (ptag);
4637*a9fa9459Szrj 
4638*a9fa9459Szrj       ptag_next = ptag->same_block;
4639*a9fa9459Szrj       ptag->hash_ptr->tag_ptr = ptag->same_name;
4640*a9fa9459Szrj       free_tag (ptag);
4641*a9fa9459Szrj     }
4642*a9fa9459Szrj 
4643*a9fa9459Szrj   free_thead (top_tag_head);
4644*a9fa9459Szrj 
4645*a9fa9459Szrj   /* Look through the symbols.  Add debugging information for each
4646*a9fa9459Szrj      symbol that has not already received it.  */
4647*a9fa9459Szrj   hold_file_ptr = cur_file_ptr;
4648*a9fa9459Szrj   hold_proc_ptr = cur_proc_ptr;
4649*a9fa9459Szrj   cur_proc_ptr = (proc_t *) NULL;
4650*a9fa9459Szrj   for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
4651*a9fa9459Szrj     {
4652*a9fa9459Szrj       if (symbol_get_obj (sym)->ecoff_symbol != NULL
4653*a9fa9459Szrj 	  || symbol_get_obj (sym)->ecoff_file == (efdr_t *) NULL
4654*a9fa9459Szrj 	  || (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM) != 0)
4655*a9fa9459Szrj 	continue;
4656*a9fa9459Szrj 
4657*a9fa9459Szrj       cur_file_ptr = symbol_get_obj (sym)->ecoff_file;
4658*a9fa9459Szrj       add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym,
4659*a9fa9459Szrj 			(bfd_vma) 0, S_GET_VALUE (sym), indexNil);
4660*a9fa9459Szrj     }
4661*a9fa9459Szrj   cur_proc_ptr = hold_proc_ptr;
4662*a9fa9459Szrj   cur_file_ptr = hold_file_ptr;
4663*a9fa9459Szrj 
4664*a9fa9459Szrj   /* Output an ending symbol for all the files.  We have to do this
4665*a9fa9459Szrj      here for the last file, so we may as well do it for all of the
4666*a9fa9459Szrj      files.  */
4667*a9fa9459Szrj   end_warning = 0;
4668*a9fa9459Szrj   for (fil_ptr = first_file;
4669*a9fa9459Szrj        fil_ptr != (efdr_t *) NULL;
4670*a9fa9459Szrj        fil_ptr = fil_ptr->next_file)
4671*a9fa9459Szrj     {
4672*a9fa9459Szrj       cur_file_ptr = fil_ptr;
4673*a9fa9459Szrj       while (cur_file_ptr->cur_scope != (scope_t *) NULL
4674*a9fa9459Szrj 	     && cur_file_ptr->cur_scope->prev != (scope_t *) NULL)
4675*a9fa9459Szrj 	{
4676*a9fa9459Szrj 	  cur_file_ptr->cur_scope = cur_file_ptr->cur_scope->prev;
4677*a9fa9459Szrj 	  if (! end_warning && ! cur_file_ptr->fake)
4678*a9fa9459Szrj 	    {
4679*a9fa9459Szrj 	      as_warn (_("missing .end or .bend at end of file"));
4680*a9fa9459Szrj 	      end_warning = 1;
4681*a9fa9459Szrj 	    }
4682*a9fa9459Szrj 	}
4683*a9fa9459Szrj       if (cur_file_ptr->cur_scope != (scope_t *) NULL)
4684*a9fa9459Szrj 	(void) add_ecoff_symbol ((const char *) NULL,
4685*a9fa9459Szrj 				 st_End, sc_Text,
4686*a9fa9459Szrj 				 (symbolS *) NULL,
4687*a9fa9459Szrj 				 (bfd_vma) 0,
4688*a9fa9459Szrj 				 (symint_t) 0,
4689*a9fa9459Szrj 				 (symint_t) 0);
4690*a9fa9459Szrj     }
4691*a9fa9459Szrj 
4692*a9fa9459Szrj   /* Build the symbolic information.  */
4693*a9fa9459Szrj   offset = 0;
4694*a9fa9459Szrj   buf = XNEWVEC (char, PAGE_SIZE);
4695*a9fa9459Szrj   bufend = buf + PAGE_SIZE;
4696*a9fa9459Szrj 
4697*a9fa9459Szrj   /* Build the line number information.  */
4698*a9fa9459Szrj   hdr->cbLineOffset = offset;
4699*a9fa9459Szrj   offset = ecoff_build_lineno (backend, &buf, &bufend, offset,
4700*a9fa9459Szrj 			       &hdr->ilineMax);
4701*a9fa9459Szrj   hdr->cbLine = offset - hdr->cbLineOffset;
4702*a9fa9459Szrj 
4703*a9fa9459Szrj   /* We don't use dense numbers at all.  */
4704*a9fa9459Szrj   hdr->idnMax = 0;
4705*a9fa9459Szrj   hdr->cbDnOffset = 0;
4706*a9fa9459Szrj 
4707*a9fa9459Szrj   /* We can't build the PDR table until we have built the symbols,
4708*a9fa9459Szrj      because a PDR contains a symbol index.  However, we set aside
4709*a9fa9459Szrj      space at this point.  */
4710*a9fa9459Szrj   hdr->ipdMax = proc_cnt;
4711*a9fa9459Szrj   hdr->cbPdOffset = offset;
4712*a9fa9459Szrj   if ((bfd_size_type)(bufend - (buf + offset)) < proc_cnt * external_pdr_size)
4713*a9fa9459Szrj     (void) ecoff_add_bytes (&buf, &bufend, buf + offset,
4714*a9fa9459Szrj 			    proc_cnt * external_pdr_size);
4715*a9fa9459Szrj   offset += proc_cnt * external_pdr_size;
4716*a9fa9459Szrj 
4717*a9fa9459Szrj   /* Build the local symbols.  */
4718*a9fa9459Szrj   hdr->cbSymOffset = offset;
4719*a9fa9459Szrj   offset = ecoff_build_symbols (backend, &buf, &bufend, offset);
4720*a9fa9459Szrj   hdr->isymMax = (offset - hdr->cbSymOffset) / backend->external_sym_size;
4721*a9fa9459Szrj 
4722*a9fa9459Szrj   /* Building the symbols initializes the symbol index in the PDR's.
4723*a9fa9459Szrj      Now we can swap out the PDR's.  */
4724*a9fa9459Szrj   (void) ecoff_build_procs (backend, &buf, &bufend, hdr->cbPdOffset);
4725*a9fa9459Szrj 
4726*a9fa9459Szrj   /* We don't use optimization symbols.  */
4727*a9fa9459Szrj   hdr->ioptMax = 0;
4728*a9fa9459Szrj   hdr->cbOptOffset = 0;
4729*a9fa9459Szrj 
4730*a9fa9459Szrj   /* Swap out the auxiliary type information.  */
4731*a9fa9459Szrj   hdr->cbAuxOffset = offset;
4732*a9fa9459Szrj   offset = ecoff_build_aux (backend, &buf, &bufend, offset);
4733*a9fa9459Szrj   hdr->iauxMax = (offset - hdr->cbAuxOffset) / sizeof (union aux_ext);
4734*a9fa9459Szrj 
4735*a9fa9459Szrj   /* Copy out the local strings.  */
4736*a9fa9459Szrj   hdr->cbSsOffset = offset;
4737*a9fa9459Szrj   offset = ecoff_build_ss (backend, &buf, &bufend, offset);
4738*a9fa9459Szrj   hdr->issMax = offset - hdr->cbSsOffset;
4739*a9fa9459Szrj 
4740*a9fa9459Szrj   /* We don't use relative file descriptors.  */
4741*a9fa9459Szrj   hdr->crfd = 0;
4742*a9fa9459Szrj   hdr->cbRfdOffset = 0;
4743*a9fa9459Szrj 
4744*a9fa9459Szrj   /* Swap out the file descriptors.  */
4745*a9fa9459Szrj   hdr->cbFdOffset = offset;
4746*a9fa9459Szrj   offset = ecoff_build_fdr (backend, &buf, &bufend, offset);
4747*a9fa9459Szrj   hdr->ifdMax = (offset - hdr->cbFdOffset) / backend->external_fdr_size;
4748*a9fa9459Szrj 
4749*a9fa9459Szrj   /* Set up the external symbols, which are handled by the BFD back
4750*a9fa9459Szrj      end.  */
4751*a9fa9459Szrj   hdr->issExtMax = 0;
4752*a9fa9459Szrj   hdr->cbSsExtOffset = 0;
4753*a9fa9459Szrj   hdr->iextMax = 0;
4754*a9fa9459Szrj   hdr->cbExtOffset = 0;
4755*a9fa9459Szrj   ecoff_setup_ext ();
4756*a9fa9459Szrj 
4757*a9fa9459Szrj   know ((offset & (backend->debug_align - 1)) == 0);
4758*a9fa9459Szrj 
4759*a9fa9459Szrj   /* FIXME: This value should be determined from the .verstamp directive,
4760*a9fa9459Szrj      with reasonable defaults in config files.  */
4761*a9fa9459Szrj #ifdef TC_ALPHA
4762*a9fa9459Szrj   hdr->vstamp = 0x030b;
4763*a9fa9459Szrj #else
4764*a9fa9459Szrj   hdr->vstamp = 0x020b;
4765*a9fa9459Szrj #endif
4766*a9fa9459Szrj 
4767*a9fa9459Szrj   *bufp = buf;
4768*a9fa9459Szrj   return offset;
4769*a9fa9459Szrj }
4770*a9fa9459Szrj 
4771*a9fa9459Szrj /* Allocate a cluster of pages.  */
4772*a9fa9459Szrj 
4773*a9fa9459Szrj #ifndef MALLOC_CHECK
4774*a9fa9459Szrj 
4775*a9fa9459Szrj static page_type *
allocate_cluster(unsigned long npages)4776*a9fa9459Szrj allocate_cluster (unsigned long npages)
4777*a9fa9459Szrj {
4778*a9fa9459Szrj   page_type *value = (page_type *) xmalloc (npages * PAGE_USIZE);
4779*a9fa9459Szrj 
4780*a9fa9459Szrj #ifdef ECOFF_DEBUG
4781*a9fa9459Szrj   if (debug > 3)
4782*a9fa9459Szrj     fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
4783*a9fa9459Szrj #endif
4784*a9fa9459Szrj 
4785*a9fa9459Szrj   memset (value, 0, npages * PAGE_USIZE);
4786*a9fa9459Szrj 
4787*a9fa9459Szrj   return value;
4788*a9fa9459Szrj }
4789*a9fa9459Szrj 
4790*a9fa9459Szrj static page_type *cluster_ptr = NULL;
4791*a9fa9459Szrj static unsigned long pages_left = 0;
4792*a9fa9459Szrj 
4793*a9fa9459Szrj #endif /* MALLOC_CHECK */
4794*a9fa9459Szrj 
4795*a9fa9459Szrj /* Allocate one page (which is initialized to 0).  */
4796*a9fa9459Szrj 
4797*a9fa9459Szrj static page_type *
allocate_page(void)4798*a9fa9459Szrj allocate_page (void)
4799*a9fa9459Szrj {
4800*a9fa9459Szrj #ifndef MALLOC_CHECK
4801*a9fa9459Szrj 
4802*a9fa9459Szrj   if (pages_left == 0)
4803*a9fa9459Szrj     {
4804*a9fa9459Szrj       pages_left = MAX_CLUSTER_PAGES;
4805*a9fa9459Szrj       cluster_ptr = allocate_cluster (pages_left);
4806*a9fa9459Szrj     }
4807*a9fa9459Szrj 
4808*a9fa9459Szrj   pages_left--;
4809*a9fa9459Szrj   return cluster_ptr++;
4810*a9fa9459Szrj 
4811*a9fa9459Szrj #else /* MALLOC_CHECK */
4812*a9fa9459Szrj 
4813*a9fa9459Szrj   page_type *ptr;
4814*a9fa9459Szrj 
4815*a9fa9459Szrj   ptr = xmalloc (PAGE_USIZE);
4816*a9fa9459Szrj   memset (ptr, 0, PAGE_USIZE);
4817*a9fa9459Szrj   return ptr;
4818*a9fa9459Szrj 
4819*a9fa9459Szrj #endif /* MALLOC_CHECK */
4820*a9fa9459Szrj }
4821*a9fa9459Szrj 
4822*a9fa9459Szrj /* Allocate scoping information.  */
4823*a9fa9459Szrj 
4824*a9fa9459Szrj static scope_t *
allocate_scope(void)4825*a9fa9459Szrj allocate_scope (void)
4826*a9fa9459Szrj {
4827*a9fa9459Szrj   scope_t *ptr;
4828*a9fa9459Szrj   static scope_t initial_scope;
4829*a9fa9459Szrj 
4830*a9fa9459Szrj #ifndef MALLOC_CHECK
4831*a9fa9459Szrj 
4832*a9fa9459Szrj   ptr = alloc_counts[(int) alloc_type_scope].free_list.f_scope;
4833*a9fa9459Szrj   if (ptr != (scope_t *) NULL)
4834*a9fa9459Szrj     alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr->free;
4835*a9fa9459Szrj   else
4836*a9fa9459Szrj     {
4837*a9fa9459Szrj       int unallocated	= alloc_counts[(int) alloc_type_scope].unallocated;
4838*a9fa9459Szrj       page_type *cur_page	= alloc_counts[(int) alloc_type_scope].cur_page;
4839*a9fa9459Szrj 
4840*a9fa9459Szrj       if (unallocated == 0)
4841*a9fa9459Szrj 	{
4842*a9fa9459Szrj 	  unallocated = PAGE_SIZE / sizeof (scope_t);
4843*a9fa9459Szrj 	  alloc_counts[(int) alloc_type_scope].cur_page = cur_page = allocate_page ();
4844*a9fa9459Szrj 	  alloc_counts[(int) alloc_type_scope].total_pages++;
4845*a9fa9459Szrj 	}
4846*a9fa9459Szrj 
4847*a9fa9459Szrj       ptr = &cur_page->scope[--unallocated];
4848*a9fa9459Szrj       alloc_counts[(int) alloc_type_scope].unallocated = unallocated;
4849*a9fa9459Szrj     }
4850*a9fa9459Szrj 
4851*a9fa9459Szrj #else
4852*a9fa9459Szrj 
4853*a9fa9459Szrj   ptr = XNEW (scope_t);
4854*a9fa9459Szrj 
4855*a9fa9459Szrj #endif
4856*a9fa9459Szrj 
4857*a9fa9459Szrj   alloc_counts[(int) alloc_type_scope].total_alloc++;
4858*a9fa9459Szrj   *ptr = initial_scope;
4859*a9fa9459Szrj   return ptr;
4860*a9fa9459Szrj }
4861*a9fa9459Szrj 
4862*a9fa9459Szrj /* Free scoping information.  */
4863*a9fa9459Szrj 
4864*a9fa9459Szrj static void
free_scope(scope_t * ptr)4865*a9fa9459Szrj free_scope (scope_t *ptr)
4866*a9fa9459Szrj {
4867*a9fa9459Szrj   alloc_counts[(int) alloc_type_scope].total_free++;
4868*a9fa9459Szrj 
4869*a9fa9459Szrj #ifndef MALLOC_CHECK
4870*a9fa9459Szrj   ptr->free = alloc_counts[(int) alloc_type_scope].free_list.f_scope;
4871*a9fa9459Szrj   alloc_counts[(int) alloc_type_scope].free_list.f_scope = ptr;
4872*a9fa9459Szrj #else
4873*a9fa9459Szrj   free ((void *) ptr);
4874*a9fa9459Szrj #endif
4875*a9fa9459Szrj }
4876*a9fa9459Szrj 
4877*a9fa9459Szrj /* Allocate links for pages in a virtual array.  */
4878*a9fa9459Szrj 
4879*a9fa9459Szrj static vlinks_t *
allocate_vlinks(void)4880*a9fa9459Szrj allocate_vlinks (void)
4881*a9fa9459Szrj {
4882*a9fa9459Szrj   vlinks_t *ptr;
4883*a9fa9459Szrj   static vlinks_t initial_vlinks;
4884*a9fa9459Szrj 
4885*a9fa9459Szrj #ifndef MALLOC_CHECK
4886*a9fa9459Szrj 
4887*a9fa9459Szrj   int unallocated = alloc_counts[(int) alloc_type_vlinks].unallocated;
4888*a9fa9459Szrj   page_type *cur_page = alloc_counts[(int) alloc_type_vlinks].cur_page;
4889*a9fa9459Szrj 
4890*a9fa9459Szrj   if (unallocated == 0)
4891*a9fa9459Szrj     {
4892*a9fa9459Szrj       unallocated = PAGE_SIZE / sizeof (vlinks_t);
4893*a9fa9459Szrj       alloc_counts[(int) alloc_type_vlinks].cur_page = cur_page = allocate_page ();
4894*a9fa9459Szrj       alloc_counts[(int) alloc_type_vlinks].total_pages++;
4895*a9fa9459Szrj     }
4896*a9fa9459Szrj 
4897*a9fa9459Szrj   ptr = &cur_page->vlinks[--unallocated];
4898*a9fa9459Szrj   alloc_counts[(int) alloc_type_vlinks].unallocated = unallocated;
4899*a9fa9459Szrj 
4900*a9fa9459Szrj #else
4901*a9fa9459Szrj 
4902*a9fa9459Szrj   ptr = XNEW (vlinks_t);
4903*a9fa9459Szrj 
4904*a9fa9459Szrj #endif
4905*a9fa9459Szrj 
4906*a9fa9459Szrj   alloc_counts[(int) alloc_type_vlinks].total_alloc++;
4907*a9fa9459Szrj   *ptr = initial_vlinks;
4908*a9fa9459Szrj   return ptr;
4909*a9fa9459Szrj }
4910*a9fa9459Szrj 
4911*a9fa9459Szrj /* Allocate string hash buckets.  */
4912*a9fa9459Szrj 
4913*a9fa9459Szrj static shash_t *
allocate_shash(void)4914*a9fa9459Szrj allocate_shash (void)
4915*a9fa9459Szrj {
4916*a9fa9459Szrj   shash_t *ptr;
4917*a9fa9459Szrj   static shash_t initial_shash;
4918*a9fa9459Szrj 
4919*a9fa9459Szrj #ifndef MALLOC_CHECK
4920*a9fa9459Szrj 
4921*a9fa9459Szrj   int unallocated = alloc_counts[(int) alloc_type_shash].unallocated;
4922*a9fa9459Szrj   page_type *cur_page = alloc_counts[(int) alloc_type_shash].cur_page;
4923*a9fa9459Szrj 
4924*a9fa9459Szrj   if (unallocated == 0)
4925*a9fa9459Szrj     {
4926*a9fa9459Szrj       unallocated = PAGE_SIZE / sizeof (shash_t);
4927*a9fa9459Szrj       alloc_counts[(int) alloc_type_shash].cur_page = cur_page = allocate_page ();
4928*a9fa9459Szrj       alloc_counts[(int) alloc_type_shash].total_pages++;
4929*a9fa9459Szrj     }
4930*a9fa9459Szrj 
4931*a9fa9459Szrj   ptr = &cur_page->shash[--unallocated];
4932*a9fa9459Szrj   alloc_counts[(int) alloc_type_shash].unallocated = unallocated;
4933*a9fa9459Szrj 
4934*a9fa9459Szrj #else
4935*a9fa9459Szrj 
4936*a9fa9459Szrj   ptr = XNEW (shash_t);
4937*a9fa9459Szrj 
4938*a9fa9459Szrj #endif
4939*a9fa9459Szrj 
4940*a9fa9459Szrj   alloc_counts[(int) alloc_type_shash].total_alloc++;
4941*a9fa9459Szrj   *ptr = initial_shash;
4942*a9fa9459Szrj   return ptr;
4943*a9fa9459Szrj }
4944*a9fa9459Szrj 
4945*a9fa9459Szrj /* Allocate type hash buckets.  */
4946*a9fa9459Szrj 
4947*a9fa9459Szrj static thash_t *
allocate_thash(void)4948*a9fa9459Szrj allocate_thash (void)
4949*a9fa9459Szrj {
4950*a9fa9459Szrj   thash_t *ptr;
4951*a9fa9459Szrj   static thash_t initial_thash;
4952*a9fa9459Szrj 
4953*a9fa9459Szrj #ifndef MALLOC_CHECK
4954*a9fa9459Szrj 
4955*a9fa9459Szrj   int unallocated = alloc_counts[(int) alloc_type_thash].unallocated;
4956*a9fa9459Szrj   page_type *cur_page = alloc_counts[(int) alloc_type_thash].cur_page;
4957*a9fa9459Szrj 
4958*a9fa9459Szrj   if (unallocated == 0)
4959*a9fa9459Szrj     {
4960*a9fa9459Szrj       unallocated = PAGE_SIZE / sizeof (thash_t);
4961*a9fa9459Szrj       alloc_counts[(int) alloc_type_thash].cur_page = cur_page = allocate_page ();
4962*a9fa9459Szrj       alloc_counts[(int) alloc_type_thash].total_pages++;
4963*a9fa9459Szrj     }
4964*a9fa9459Szrj 
4965*a9fa9459Szrj   ptr = &cur_page->thash[--unallocated];
4966*a9fa9459Szrj   alloc_counts[(int) alloc_type_thash].unallocated = unallocated;
4967*a9fa9459Szrj 
4968*a9fa9459Szrj #else
4969*a9fa9459Szrj 
4970*a9fa9459Szrj   ptr = XNEW (thash_t);
4971*a9fa9459Szrj 
4972*a9fa9459Szrj #endif
4973*a9fa9459Szrj 
4974*a9fa9459Szrj   alloc_counts[(int) alloc_type_thash].total_alloc++;
4975*a9fa9459Szrj   *ptr = initial_thash;
4976*a9fa9459Szrj   return ptr;
4977*a9fa9459Szrj }
4978*a9fa9459Szrj 
4979*a9fa9459Szrj /* Allocate structure, union, or enum tag information.  */
4980*a9fa9459Szrj 
4981*a9fa9459Szrj static tag_t *
allocate_tag(void)4982*a9fa9459Szrj allocate_tag (void)
4983*a9fa9459Szrj {
4984*a9fa9459Szrj   tag_t *ptr;
4985*a9fa9459Szrj   static tag_t initial_tag;
4986*a9fa9459Szrj 
4987*a9fa9459Szrj #ifndef MALLOC_CHECK
4988*a9fa9459Szrj 
4989*a9fa9459Szrj   ptr = alloc_counts[(int) alloc_type_tag].free_list.f_tag;
4990*a9fa9459Szrj   if (ptr != (tag_t *) NULL)
4991*a9fa9459Szrj     alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr->free;
4992*a9fa9459Szrj   else
4993*a9fa9459Szrj     {
4994*a9fa9459Szrj       int unallocated = alloc_counts[(int) alloc_type_tag].unallocated;
4995*a9fa9459Szrj       page_type *cur_page = alloc_counts[(int) alloc_type_tag].cur_page;
4996*a9fa9459Szrj 
4997*a9fa9459Szrj       if (unallocated == 0)
4998*a9fa9459Szrj 	{
4999*a9fa9459Szrj 	  unallocated = PAGE_SIZE / sizeof (tag_t);
5000*a9fa9459Szrj 	  alloc_counts[(int) alloc_type_tag].cur_page = cur_page = allocate_page ();
5001*a9fa9459Szrj 	  alloc_counts[(int) alloc_type_tag].total_pages++;
5002*a9fa9459Szrj 	}
5003*a9fa9459Szrj 
5004*a9fa9459Szrj       ptr = &cur_page->tag[--unallocated];
5005*a9fa9459Szrj       alloc_counts[(int) alloc_type_tag].unallocated = unallocated;
5006*a9fa9459Szrj     }
5007*a9fa9459Szrj 
5008*a9fa9459Szrj #else
5009*a9fa9459Szrj 
5010*a9fa9459Szrj   ptr = XNEW (tag_t);
5011*a9fa9459Szrj 
5012*a9fa9459Szrj #endif
5013*a9fa9459Szrj 
5014*a9fa9459Szrj   alloc_counts[(int) alloc_type_tag].total_alloc++;
5015*a9fa9459Szrj   *ptr = initial_tag;
5016*a9fa9459Szrj   return ptr;
5017*a9fa9459Szrj }
5018*a9fa9459Szrj 
5019*a9fa9459Szrj /* Free scoping information.  */
5020*a9fa9459Szrj 
5021*a9fa9459Szrj static void
free_tag(tag_t * ptr)5022*a9fa9459Szrj free_tag (tag_t *ptr)
5023*a9fa9459Szrj {
5024*a9fa9459Szrj   alloc_counts[(int) alloc_type_tag].total_free++;
5025*a9fa9459Szrj 
5026*a9fa9459Szrj #ifndef MALLOC_CHECK
5027*a9fa9459Szrj   ptr->free = alloc_counts[(int) alloc_type_tag].free_list.f_tag;
5028*a9fa9459Szrj   alloc_counts[(int) alloc_type_tag].free_list.f_tag = ptr;
5029*a9fa9459Szrj #else
5030*a9fa9459Szrj   free ((PTR_T) ptr);
5031*a9fa9459Szrj #endif
5032*a9fa9459Szrj }
5033*a9fa9459Szrj 
5034*a9fa9459Szrj /* Allocate forward reference to a yet unknown tag.  */
5035*a9fa9459Szrj 
5036*a9fa9459Szrj static forward_t *
allocate_forward(void)5037*a9fa9459Szrj allocate_forward (void)
5038*a9fa9459Szrj {
5039*a9fa9459Szrj   forward_t *ptr;
5040*a9fa9459Szrj   static forward_t initial_forward;
5041*a9fa9459Szrj 
5042*a9fa9459Szrj #ifndef MALLOC_CHECK
5043*a9fa9459Szrj 
5044*a9fa9459Szrj   int unallocated = alloc_counts[(int) alloc_type_forward].unallocated;
5045*a9fa9459Szrj   page_type *cur_page = alloc_counts[(int) alloc_type_forward].cur_page;
5046*a9fa9459Szrj 
5047*a9fa9459Szrj   if (unallocated == 0)
5048*a9fa9459Szrj     {
5049*a9fa9459Szrj       unallocated = PAGE_SIZE / sizeof (forward_t);
5050*a9fa9459Szrj       alloc_counts[(int) alloc_type_forward].cur_page = cur_page = allocate_page ();
5051*a9fa9459Szrj       alloc_counts[(int) alloc_type_forward].total_pages++;
5052*a9fa9459Szrj     }
5053*a9fa9459Szrj 
5054*a9fa9459Szrj   ptr = &cur_page->forward[--unallocated];
5055*a9fa9459Szrj   alloc_counts[(int) alloc_type_forward].unallocated = unallocated;
5056*a9fa9459Szrj 
5057*a9fa9459Szrj #else
5058*a9fa9459Szrj 
5059*a9fa9459Szrj   ptr = XNEW (forward_t);
5060*a9fa9459Szrj 
5061*a9fa9459Szrj #endif
5062*a9fa9459Szrj 
5063*a9fa9459Szrj   alloc_counts[(int) alloc_type_forward].total_alloc++;
5064*a9fa9459Szrj   *ptr = initial_forward;
5065*a9fa9459Szrj   return ptr;
5066*a9fa9459Szrj }
5067*a9fa9459Szrj 
5068*a9fa9459Szrj /* Allocate head of type hash list.  */
5069*a9fa9459Szrj 
5070*a9fa9459Szrj static thead_t *
allocate_thead(void)5071*a9fa9459Szrj allocate_thead (void)
5072*a9fa9459Szrj {
5073*a9fa9459Szrj   thead_t *ptr;
5074*a9fa9459Szrj   static thead_t initial_thead;
5075*a9fa9459Szrj 
5076*a9fa9459Szrj #ifndef MALLOC_CHECK
5077*a9fa9459Szrj 
5078*a9fa9459Szrj   ptr = alloc_counts[(int) alloc_type_thead].free_list.f_thead;
5079*a9fa9459Szrj   if (ptr != (thead_t *) NULL)
5080*a9fa9459Szrj     alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr->free;
5081*a9fa9459Szrj   else
5082*a9fa9459Szrj     {
5083*a9fa9459Szrj       int unallocated = alloc_counts[(int) alloc_type_thead].unallocated;
5084*a9fa9459Szrj       page_type *cur_page = alloc_counts[(int) alloc_type_thead].cur_page;
5085*a9fa9459Szrj 
5086*a9fa9459Szrj       if (unallocated == 0)
5087*a9fa9459Szrj 	{
5088*a9fa9459Szrj 	  unallocated = PAGE_SIZE / sizeof (thead_t);
5089*a9fa9459Szrj 	  alloc_counts[(int) alloc_type_thead].cur_page = cur_page = allocate_page ();
5090*a9fa9459Szrj 	  alloc_counts[(int) alloc_type_thead].total_pages++;
5091*a9fa9459Szrj 	}
5092*a9fa9459Szrj 
5093*a9fa9459Szrj       ptr = &cur_page->thead[--unallocated];
5094*a9fa9459Szrj       alloc_counts[(int) alloc_type_thead].unallocated = unallocated;
5095*a9fa9459Szrj     }
5096*a9fa9459Szrj 
5097*a9fa9459Szrj #else
5098*a9fa9459Szrj 
5099*a9fa9459Szrj   ptr = XNEW (thead_t);
5100*a9fa9459Szrj 
5101*a9fa9459Szrj #endif
5102*a9fa9459Szrj 
5103*a9fa9459Szrj   alloc_counts[(int) alloc_type_thead].total_alloc++;
5104*a9fa9459Szrj   *ptr = initial_thead;
5105*a9fa9459Szrj   return ptr;
5106*a9fa9459Szrj }
5107*a9fa9459Szrj 
5108*a9fa9459Szrj /* Free scoping information.  */
5109*a9fa9459Szrj 
5110*a9fa9459Szrj static void
free_thead(thead_t * ptr)5111*a9fa9459Szrj free_thead (thead_t *ptr)
5112*a9fa9459Szrj {
5113*a9fa9459Szrj   alloc_counts[(int) alloc_type_thead].total_free++;
5114*a9fa9459Szrj 
5115*a9fa9459Szrj #ifndef MALLOC_CHECK
5116*a9fa9459Szrj   ptr->free = (thead_t *) alloc_counts[(int) alloc_type_thead].free_list.f_thead;
5117*a9fa9459Szrj   alloc_counts[(int) alloc_type_thead].free_list.f_thead = ptr;
5118*a9fa9459Szrj #else
5119*a9fa9459Szrj   free ((PTR_T) ptr);
5120*a9fa9459Szrj #endif
5121*a9fa9459Szrj }
5122*a9fa9459Szrj 
5123*a9fa9459Szrj static lineno_list_t *
allocate_lineno_list(void)5124*a9fa9459Szrj allocate_lineno_list (void)
5125*a9fa9459Szrj {
5126*a9fa9459Szrj   lineno_list_t *ptr;
5127*a9fa9459Szrj   static lineno_list_t initial_lineno_list;
5128*a9fa9459Szrj 
5129*a9fa9459Szrj #ifndef MALLOC_CHECK
5130*a9fa9459Szrj 
5131*a9fa9459Szrj   int unallocated = alloc_counts[(int) alloc_type_lineno].unallocated;
5132*a9fa9459Szrj   page_type *cur_page = alloc_counts[(int) alloc_type_lineno].cur_page;
5133*a9fa9459Szrj 
5134*a9fa9459Szrj   if (unallocated == 0)
5135*a9fa9459Szrj     {
5136*a9fa9459Szrj       unallocated = PAGE_SIZE / sizeof (lineno_list_t);
5137*a9fa9459Szrj       alloc_counts[(int) alloc_type_lineno].cur_page = cur_page = allocate_page ();
5138*a9fa9459Szrj       alloc_counts[(int) alloc_type_lineno].total_pages++;
5139*a9fa9459Szrj     }
5140*a9fa9459Szrj 
5141*a9fa9459Szrj   ptr = &cur_page->lineno[--unallocated];
5142*a9fa9459Szrj   alloc_counts[(int) alloc_type_lineno].unallocated = unallocated;
5143*a9fa9459Szrj 
5144*a9fa9459Szrj #else
5145*a9fa9459Szrj 
5146*a9fa9459Szrj   ptr = XNEW (lineno_list_t);
5147*a9fa9459Szrj 
5148*a9fa9459Szrj #endif
5149*a9fa9459Szrj 
5150*a9fa9459Szrj   alloc_counts[(int) alloc_type_lineno].total_alloc++;
5151*a9fa9459Szrj   *ptr = initial_lineno_list;
5152*a9fa9459Szrj   return ptr;
5153*a9fa9459Szrj }
5154*a9fa9459Szrj 
5155*a9fa9459Szrj void
ecoff_set_gp_prolog_size(int sz)5156*a9fa9459Szrj ecoff_set_gp_prolog_size (int sz)
5157*a9fa9459Szrj {
5158*a9fa9459Szrj   if (cur_proc_ptr == 0)
5159*a9fa9459Szrj     return;
5160*a9fa9459Szrj 
5161*a9fa9459Szrj   cur_proc_ptr->pdr.gp_prologue = sz;
5162*a9fa9459Szrj   if (cur_proc_ptr->pdr.gp_prologue != sz)
5163*a9fa9459Szrj     {
5164*a9fa9459Szrj       as_warn (_("GP prologue size exceeds field size, using 0 instead"));
5165*a9fa9459Szrj       cur_proc_ptr->pdr.gp_prologue = 0;
5166*a9fa9459Szrj     }
5167*a9fa9459Szrj 
5168*a9fa9459Szrj   cur_proc_ptr->pdr.gp_used = 1;
5169*a9fa9459Szrj }
5170*a9fa9459Szrj 
5171*a9fa9459Szrj int
ecoff_no_current_file(void)5172*a9fa9459Szrj ecoff_no_current_file (void)
5173*a9fa9459Szrj {
5174*a9fa9459Szrj   return cur_file_ptr == (efdr_t *) NULL;
5175*a9fa9459Szrj }
5176*a9fa9459Szrj 
5177*a9fa9459Szrj void
ecoff_generate_asm_lineno(void)5178*a9fa9459Szrj ecoff_generate_asm_lineno (void)
5179*a9fa9459Szrj {
5180*a9fa9459Szrj   unsigned int lineno;
5181*a9fa9459Szrj   const char *filename;
5182*a9fa9459Szrj   lineno_list_t *list;
5183*a9fa9459Szrj 
5184*a9fa9459Szrj   filename = as_where (&lineno);
5185*a9fa9459Szrj 
5186*a9fa9459Szrj   if (current_stabs_filename == (char *) NULL
5187*a9fa9459Szrj       || filename_cmp (current_stabs_filename, filename))
5188*a9fa9459Szrj     add_file (filename, 0, 1);
5189*a9fa9459Szrj 
5190*a9fa9459Szrj   list = allocate_lineno_list ();
5191*a9fa9459Szrj 
5192*a9fa9459Szrj   list->next = (lineno_list_t *) NULL;
5193*a9fa9459Szrj   list->file = cur_file_ptr;
5194*a9fa9459Szrj   list->proc = cur_proc_ptr;
5195*a9fa9459Szrj   list->frag = frag_now;
5196*a9fa9459Szrj   list->paddr = frag_now_fix ();
5197*a9fa9459Szrj   list->lineno = lineno;
5198*a9fa9459Szrj 
5199*a9fa9459Szrj   /* We don't want to merge files which have line numbers.  */
5200*a9fa9459Szrj   cur_file_ptr->fdr.fMerge = 0;
5201*a9fa9459Szrj 
5202*a9fa9459Szrj   /* A .loc directive will sometimes appear before a .ent directive,
5203*a9fa9459Szrj      which means that cur_proc_ptr will be NULL here.  Arrange to
5204*a9fa9459Szrj      patch this up.  */
5205*a9fa9459Szrj   if (cur_proc_ptr == (proc_t *) NULL)
5206*a9fa9459Szrj     {
5207*a9fa9459Szrj       lineno_list_t **pl;
5208*a9fa9459Szrj 
5209*a9fa9459Szrj       pl = &noproc_lineno;
5210*a9fa9459Szrj       while (*pl != (lineno_list_t *) NULL)
5211*a9fa9459Szrj 	pl = &(*pl)->next;
5212*a9fa9459Szrj       *pl = list;
5213*a9fa9459Szrj     }
5214*a9fa9459Szrj   else
5215*a9fa9459Szrj     {
5216*a9fa9459Szrj       last_lineno = list;
5217*a9fa9459Szrj       *last_lineno_ptr = list;
5218*a9fa9459Szrj       last_lineno_ptr = &list->next;
5219*a9fa9459Szrj     }
5220*a9fa9459Szrj }
5221*a9fa9459Szrj 
5222*a9fa9459Szrj #else
5223*a9fa9459Szrj 
5224*a9fa9459Szrj void
ecoff_generate_asm_lineno(void)5225*a9fa9459Szrj ecoff_generate_asm_lineno (void)
5226*a9fa9459Szrj {
5227*a9fa9459Szrj }
5228*a9fa9459Szrj 
5229*a9fa9459Szrj #endif /* ECOFF_DEBUGGING */
5230