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