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