Replace "GNU CC" with "GCC"
[official-gcc.git] / gcc / mips-tfile.c
blobb29a7da223480f73e22be5188358e797fdc6ec43
1 /* Update the symbol table (the .T file) in a MIPS object to
2 contain debugging information specified by the GNU compiler
3 in the form of comments (the mips assembler does not support
4 assembly access to debug information).
5 Copyright (C) 1991, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
6 2002, 2003 Free Software Foundation, Inc.
7 Contributed by Michael Meissner (meissner@cygnus.com).
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
14 version.
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 02111-1307, USA. */
27 /* Here is a brief description of the MIPS ECOFF symbol table. The
28 MIPS symbol table has the following pieces:
30 Symbolic Header
32 +-- Auxiliary Symbols
34 +-- Dense number table
36 +-- Optimizer Symbols
38 +-- External Strings
40 +-- External Symbols
42 +-- Relative file descriptors
44 +-- File table
46 +-- Procedure table
48 +-- Line number table
50 +-- Local Strings
52 +-- Local Symbols
54 The symbolic header points to each of the other tables, and also
55 contains the number of entries. It also contains a magic number
56 and MIPS compiler version number, such as 2.0.
58 The auxiliary table is a series of 32 bit integers, that are
59 referenced as needed from the local symbol table. Unlike standard
60 COFF, the aux. information does not follow the symbol that uses
61 it, but rather is a separate table. In theory, this would allow
62 the MIPS compilers to collapse duplicate aux. entries, but I've not
63 noticed this happening with the 1.31 compiler suite. The different
64 types of aux. entries are:
66 1) dnLow: Low bound on array dimension.
68 2) dnHigh: High bound on array dimension.
70 3) isym: Index to the local symbol which is the start of the
71 function for the end of function first aux. entry.
73 4) width: Width of structures and bitfields.
75 5) count: Count of ranges for variant part.
77 6) rndx: A relative index into the symbol table. The relative
78 index field has two parts: rfd which is a pointer into the
79 relative file index table or ST_RFDESCAPE which says the next
80 aux. entry is the file number, and index: which is the pointer
81 into the local symbol within a given file table. This is for
82 things like references to types defined in another file.
84 7) Type information: This is like the COFF type bits, except it
85 is 32 bits instead of 16; they still have room to add new
86 basic types; and they can handle more than 6 levels of array,
87 pointer, function, etc. Each type information field contains
88 the following structure members:
90 a) fBitfield: a bit that says this is a bitfield, and the
91 size in bits follows as the next aux. entry.
93 b) continued: a bit that says the next aux. entry is a
94 continuation of the current type information (in case
95 there are more than 6 levels of array/ptr/function).
97 c) bt: an integer containing the base type before adding
98 array, pointer, function, etc. qualifiers. The
99 current base types that I have documentation for are:
101 btNil -- undefined
102 btAdr -- address - integer same size as ptr
103 btChar -- character
104 btUChar -- unsigned character
105 btShort -- short
106 btUShort -- unsigned short
107 btInt -- int
108 btUInt -- unsigned int
109 btLong -- long
110 btULong -- unsigned long
111 btFloat -- float (real)
112 btDouble -- Double (real)
113 btStruct -- Structure (Record)
114 btUnion -- Union (variant)
115 btEnum -- Enumerated
116 btTypedef -- defined via a typedef isymRef
117 btRange -- subrange of int
118 btSet -- pascal sets
119 btComplex -- fortran complex
120 btDComplex -- fortran double complex
121 btIndirect -- forward or unnamed typedef
122 btFixedDec -- Fixed Decimal
123 btFloatDec -- Float Decimal
124 btString -- Varying Length Character String
125 btBit -- Aligned Bit String
126 btPicture -- Picture
127 btVoid -- Void (MIPS cc revision >= 2.00)
129 d) tq0 - tq5: type qualifier fields as needed. The
130 current type qualifier fields I have documentation for
131 are:
133 tqNil -- no more qualifiers
134 tqPtr -- pointer
135 tqProc -- procedure
136 tqArray -- array
137 tqFar -- 8086 far pointers
138 tqVol -- volatile
141 The dense number table is used in the front ends, and disappears by
142 the time the .o is created.
144 With the 1.31 compiler suite, the optimization symbols don't seem
145 to be used as far as I can tell.
147 The linker is the first entity that creates the relative file
148 descriptor table, and I believe it is used so that the individual
149 file table pointers don't have to be rewritten when the objects are
150 merged together into the program file.
152 Unlike COFF, the basic symbol & string tables are split into
153 external and local symbols/strings. The relocation information
154 only goes off of the external symbol table, and the debug
155 information only goes off of the internal symbol table. The
156 external symbols can have links to an appropriate file index and
157 symbol within the file to give it the appropriate type information.
158 Because of this, the external symbols are actually larger than the
159 internal symbols (to contain the link information), and contain the
160 local symbol structure as a member, though this member is not the
161 first member of the external symbol structure (!). I suspect this
162 split is to make strip easier to deal with.
164 Each file table has offsets for where the line numbers, local
165 strings, local symbols, and procedure table starts from within the
166 global tables, and the indexs are reset to 0 for each of those
167 tables for the file.
169 The procedure table contains the binary equivalents of the .ent
170 (start of the function address), .frame (what register is the
171 virtual frame pointer, constant offset from the register to obtain
172 the VFP, and what register holds the return address), .mask/.fmask
173 (bitmask of saved registers, and where the first register is stored
174 relative to the VFP) assembler directives. It also contains the
175 low and high bounds of the line numbers if debugging is turned on.
177 The line number table is a compressed form of the normal COFF line
178 table. Each line number entry is either 1 or 3 bytes long, and
179 contains a signed delta from the previous line, and an unsigned
180 count of the number of instructions this statement takes.
182 The local symbol table contains the following fields:
184 1) iss: index to the local string table giving the name of the
185 symbol.
187 2) value: value of the symbol (address, register number, etc.).
189 3) st: symbol type. The current symbol types are:
191 stNil -- Nuthin' special
192 stGlobal -- external symbol
193 stStatic -- static
194 stParam -- procedure argument
195 stLocal -- local variable
196 stLabel -- label
197 stProc -- External Procedure
198 stBlock -- beginning of block
199 stEnd -- end (of anything)
200 stMember -- member (of anything)
201 stTypedef -- type definition
202 stFile -- file name
203 stRegReloc -- register relocation
204 stForward -- forwarding address
205 stStaticProc -- Static procedure
206 stConstant -- const
208 4) sc: storage class. The current storage classes are:
210 scText -- text symbol
211 scData -- initialized data symbol
212 scBss -- un-initialized data symbol
213 scRegister -- value of symbol is register number
214 scAbs -- value of symbol is absolute
215 scUndefined -- who knows?
216 scCdbLocal -- variable's value is IN se->va.??
217 scBits -- this is a bit field
218 scCdbSystem -- value is IN debugger's address space
219 scRegImage -- register value saved on stack
220 scInfo -- symbol contains debugger information
221 scUserStruct -- addr in struct user for current process
222 scSData -- load time only small data
223 scSBss -- load time only small common
224 scRData -- load time only read only data
225 scVar -- Var parameter (fortranpascal)
226 scCommon -- common variable
227 scSCommon -- small common
228 scVarRegister -- Var parameter in a register
229 scVariant -- Variant record
230 scSUndefined -- small undefined(external) data
231 scInit -- .init section symbol
233 5) index: pointer to a local symbol or aux. entry.
237 For the following program:
239 #include <stdio.h>
241 main(){
242 printf("Hello World!\n");
243 return 0;
246 Mips-tdump produces the following information:
248 Global file header:
249 magic number 0x162
250 # sections 2
251 timestamp 645311799, Wed Jun 13 17:16:39 1990
252 symbolic header offset 284
253 symbolic header size 96
254 optional header 56
255 flags 0x0
257 Symbolic header, magic number = 0x7009, vstamp = 1.31:
259 Info Offset Number Bytes
260 ==== ====== ====== =====
262 Line numbers 380 4 4 [13]
263 Dense numbers 0 0 0
264 Procedures Tables 384 1 52
265 Local Symbols 436 16 192
266 Optimization Symbols 0 0 0
267 Auxiliary Symbols 628 39 156
268 Local Strings 784 80 80
269 External Strings 864 144 144
270 File Tables 1008 2 144
271 Relative Files 0 0 0
272 External Symbols 1152 20 320
274 File #0, "hello2.c"
276 Name index = 1 Readin = No
277 Merge = No Endian = LITTLE
278 Debug level = G2 Language = C
279 Adr = 0x00000000
281 Info Start Number Size Offset
282 ==== ===== ====== ==== ======
283 Local strings 0 15 15 784
284 Local symbols 0 6 72 436
285 Line numbers 0 13 13 380
286 Optimization symbols 0 0 0 0
287 Procedures 0 1 52 384
288 Auxiliary symbols 0 14 56 628
289 Relative Files 0 0 0 0
291 There are 6 local symbols, starting at 436
293 Symbol# 0: "hello2.c"
294 End+1 symbol = 6
295 String index = 1
296 Storage class = Text Index = 6
297 Symbol type = File Value = 0
299 Symbol# 1: "main"
300 End+1 symbol = 5
301 Type = int
302 String index = 10
303 Storage class = Text Index = 12
304 Symbol type = Proc Value = 0
306 Symbol# 2: ""
307 End+1 symbol = 4
308 String index = 0
309 Storage class = Text Index = 4
310 Symbol type = Block Value = 8
312 Symbol# 3: ""
313 First symbol = 2
314 String index = 0
315 Storage class = Text Index = 2
316 Symbol type = End Value = 28
318 Symbol# 4: "main"
319 First symbol = 1
320 String index = 10
321 Storage class = Text Index = 1
322 Symbol type = End Value = 52
324 Symbol# 5: "hello2.c"
325 First symbol = 0
326 String index = 1
327 Storage class = Text Index = 0
328 Symbol type = End Value = 0
330 There are 14 auxiliary table entries, starting at 628.
332 * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
333 * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
334 * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0]
335 * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0]
336 * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
337 * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0]
338 * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0]
339 * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0]
340 * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0]
341 * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0]
342 * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0]
343 * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0]
344 #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0]
345 #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
347 There are 1 procedure descriptor entries, starting at 0.
349 Procedure descriptor 0:
350 Name index = 10 Name = "main"
351 .mask 0x80000000,-4 .fmask 0x00000000,0
352 .frame $29,24,$31
353 Opt. start = -1 Symbols start = 1
354 First line # = 3 Last line # = 6
355 Line Offset = 0 Address = 0x00000000
357 There are 4 bytes holding line numbers, starting at 380.
358 Line 3, delta 0, count 2
359 Line 4, delta 1, count 3
360 Line 5, delta 1, count 2
361 Line 6, delta 1, count 6
363 File #1, "/usr/include/stdio.h"
365 Name index = 1 Readin = No
366 Merge = Yes Endian = LITTLE
367 Debug level = G2 Language = C
368 Adr = 0x00000000
370 Info Start Number Size Offset
371 ==== ===== ====== ==== ======
372 Local strings 15 65 65 799
373 Local symbols 6 10 120 508
374 Line numbers 0 0 0 380
375 Optimization symbols 0 0 0 0
376 Procedures 1 0 0 436
377 Auxiliary symbols 14 25 100 684
378 Relative Files 0 0 0 0
380 There are 10 local symbols, starting at 442
382 Symbol# 0: "/usr/include/stdio.h"
383 End+1 symbol = 10
384 String index = 1
385 Storage class = Text Index = 10
386 Symbol type = File Value = 0
388 Symbol# 1: "_iobuf"
389 End+1 symbol = 9
390 String index = 22
391 Storage class = Info Index = 9
392 Symbol type = Block Value = 20
394 Symbol# 2: "_cnt"
395 Type = int
396 String index = 29
397 Storage class = Info Index = 4
398 Symbol type = Member Value = 0
400 Symbol# 3: "_ptr"
401 Type = ptr to char
402 String index = 34
403 Storage class = Info Index = 15
404 Symbol type = Member Value = 32
406 Symbol# 4: "_base"
407 Type = ptr to char
408 String index = 39
409 Storage class = Info Index = 16
410 Symbol type = Member Value = 64
412 Symbol# 5: "_bufsiz"
413 Type = int
414 String index = 45
415 Storage class = Info Index = 4
416 Symbol type = Member Value = 96
418 Symbol# 6: "_flag"
419 Type = short
420 String index = 53
421 Storage class = Info Index = 3
422 Symbol type = Member Value = 128
424 Symbol# 7: "_file"
425 Type = char
426 String index = 59
427 Storage class = Info Index = 2
428 Symbol type = Member Value = 144
430 Symbol# 8: ""
431 First symbol = 1
432 String index = 0
433 Storage class = Info Index = 1
434 Symbol type = End Value = 0
436 Symbol# 9: "/usr/include/stdio.h"
437 First symbol = 0
438 String index = 1
439 Storage class = Text Index = 0
440 Symbol type = End Value = 0
442 There are 25 auxiliary table entries, starting at 642.
444 * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
445 #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
446 #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
447 * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0]
448 * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1]
449 * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
450 * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4]
451 * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
452 * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
453 * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0]
454 * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0]
455 * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
456 * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
457 * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
458 * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
459 * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
460 * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
461 * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
462 * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
463 * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
464 * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
465 * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
466 * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
467 * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
468 * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
470 There are 0 procedure descriptor entries, starting at 1.
472 There are 20 external symbols, starting at 1152
474 Symbol# 0: "_iob"
475 Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
476 String index = 0 Ifd = 1
477 Storage class = Nil Index = 17
478 Symbol type = Global Value = 60
480 Symbol# 1: "fopen"
481 String index = 5 Ifd = 1
482 Storage class = Nil Index = 1048575
483 Symbol type = Proc Value = 0
485 Symbol# 2: "fdopen"
486 String index = 11 Ifd = 1
487 Storage class = Nil Index = 1048575
488 Symbol type = Proc Value = 0
490 Symbol# 3: "freopen"
491 String index = 18 Ifd = 1
492 Storage class = Nil Index = 1048575
493 Symbol type = Proc Value = 0
495 Symbol# 4: "popen"
496 String index = 26 Ifd = 1
497 Storage class = Nil Index = 1048575
498 Symbol type = Proc Value = 0
500 Symbol# 5: "tmpfile"
501 String index = 32 Ifd = 1
502 Storage class = Nil Index = 1048575
503 Symbol type = Proc Value = 0
505 Symbol# 6: "ftell"
506 String index = 40 Ifd = 1
507 Storage class = Nil Index = 1048575
508 Symbol type = Proc Value = 0
510 Symbol# 7: "rewind"
511 String index = 46 Ifd = 1
512 Storage class = Nil Index = 1048575
513 Symbol type = Proc Value = 0
515 Symbol# 8: "setbuf"
516 String index = 53 Ifd = 1
517 Storage class = Nil Index = 1048575
518 Symbol type = Proc Value = 0
520 Symbol# 9: "setbuffer"
521 String index = 60 Ifd = 1
522 Storage class = Nil Index = 1048575
523 Symbol type = Proc Value = 0
525 Symbol# 10: "setlinebuf"
526 String index = 70 Ifd = 1
527 Storage class = Nil Index = 1048575
528 Symbol type = Proc Value = 0
530 Symbol# 11: "fgets"
531 String index = 81 Ifd = 1
532 Storage class = Nil Index = 1048575
533 Symbol type = Proc Value = 0
535 Symbol# 12: "gets"
536 String index = 87 Ifd = 1
537 Storage class = Nil Index = 1048575
538 Symbol type = Proc Value = 0
540 Symbol# 13: "ctermid"
541 String index = 92 Ifd = 1
542 Storage class = Nil Index = 1048575
543 Symbol type = Proc Value = 0
545 Symbol# 14: "cuserid"
546 String index = 100 Ifd = 1
547 Storage class = Nil Index = 1048575
548 Symbol type = Proc Value = 0
550 Symbol# 15: "tempnam"
551 String index = 108 Ifd = 1
552 Storage class = Nil Index = 1048575
553 Symbol type = Proc Value = 0
555 Symbol# 16: "tmpnam"
556 String index = 116 Ifd = 1
557 Storage class = Nil Index = 1048575
558 Symbol type = Proc Value = 0
560 Symbol# 17: "sprintf"
561 String index = 123 Ifd = 1
562 Storage class = Nil Index = 1048575
563 Symbol type = Proc Value = 0
565 Symbol# 18: "main"
566 Type = int
567 String index = 131 Ifd = 0
568 Storage class = Text Index = 1
569 Symbol type = Proc Value = 0
571 Symbol# 19: "printf"
572 String index = 136 Ifd = 0
573 Storage class = Undefined Index = 1048575
574 Symbol type = Proc Value = 0
576 The following auxiliary table entries were unused:
578 #0 0 0x00000000 void
579 #2 8 0x00000008 char
580 #3 16 0x00000010 short
581 #4 24 0x00000018 int
582 #5 32 0x00000020 long
583 #6 40 0x00000028 float
584 #7 44 0x0000002c double
585 #8 12 0x0000000c unsigned char
586 #9 20 0x00000014 unsigned short
587 #10 28 0x0000001c unsigned int
588 #11 36 0x00000024 unsigned long
589 #14 0 0x00000000 void
590 #15 24 0x00000018 int
591 #19 32 0x00000020 long
592 #20 40 0x00000028 float
593 #21 44 0x0000002c double
594 #22 12 0x0000000c unsigned char
595 #23 20 0x00000014 unsigned short
596 #24 28 0x0000001c unsigned int
597 #25 36 0x00000024 unsigned long
598 #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 }
603 #include "config.h"
604 #include "system.h"
605 #include "coretypes.h"
606 #include "tm.h"
607 #include "version.h"
608 #include "intl.h"
610 #ifndef __SABER__
611 #define saber_stop()
612 #endif
614 #ifndef __LINE__
615 #define __LINE__ 0
616 #endif
618 /* Due to size_t being defined in sys/types.h and different
619 in stddef.h, we have to do this by hand..... Note, these
620 types are correct for MIPS based systems, and may not be
621 correct for other systems. Ultrix 4.0 and Silicon Graphics
622 have this fixed, but since the following is correct, and
623 the fact that including stddef.h gets you GCC's version
624 instead of the standard one it's not worth it to fix it. */
626 #if defined(__OSF1__) || defined(__OSF__) || defined(__osf__)
627 #define Size_t long unsigned int
628 #else
629 #define Size_t unsigned int
630 #endif
631 #define Ptrdiff_t long
633 /* The following might be called from obstack or malloc,
634 so they can't be static. */
636 extern void pfatal_with_name
637 PARAMS ((const char *)) ATTRIBUTE_NORETURN;
638 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
639 void botch PARAMS ((const char *)) ATTRIBUTE_NORETURN;
641 extern void fatal PARAMS ((const char *format, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
642 extern void error PARAMS ((const char *format, ...)) ATTRIBUTE_PRINTF_1;
644 #ifndef MIPS_DEBUGGING_INFO
646 static int line_number;
647 static int cur_line_start;
648 static int debug;
649 static int had_errors;
650 static const char *progname;
651 static const char *input_name;
654 main ()
656 fprintf (stderr, "Mips-tfile should only be run on a MIPS computer!\n");
657 exit (1);
660 #else /* MIPS_DEBUGGING defined */
662 /* The local and global symbols have a field index, so undo any defines
663 of index -> strchr. */
665 #undef index
667 #include <signal.h>
669 #ifndef CROSS_COMPILE
670 #include <a.out.h>
671 #else
672 #include "mips/a.out.h"
673 #endif /* CROSS_COMPILE */
675 #include "gstab.h"
677 #define STAB_CODE_TYPE enum __stab_debug_code
679 #ifndef MALLOC_CHECK
680 #ifdef __SABER__
681 #define MALLOC_CHECK
682 #endif
683 #endif
685 #define IS_ASM_IDENT(ch) \
686 (ISIDNUM (ch) || (ch) == '.' || (ch) == '$')
689 /* Redefinition of storage classes as an enumeration for better
690 debugging. */
692 typedef enum sc {
693 sc_Nil = scNil, /* no storage class */
694 sc_Text = scText, /* text symbol */
695 sc_Data = scData, /* initialized data symbol */
696 sc_Bss = scBss, /* un-initialized data symbol */
697 sc_Register = scRegister, /* value of symbol is register number */
698 sc_Abs = scAbs, /* value of symbol is absolute */
699 sc_Undefined = scUndefined, /* who knows? */
700 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
701 sc_Bits = scBits, /* this is a bit field */
702 sc_CdbSystem = scCdbSystem, /* value is IN CDB's address space */
703 sc_RegImage = scRegImage, /* register value saved on stack */
704 sc_Info = scInfo, /* symbol contains debugger information */
705 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
706 sc_SData = scSData, /* load time only small data */
707 sc_SBss = scSBss, /* load time only small common */
708 sc_RData = scRData, /* load time only read only data */
709 sc_Var = scVar, /* Var parameter (fortran,pascal) */
710 sc_Common = scCommon, /* common variable */
711 sc_SCommon = scSCommon, /* small common */
712 sc_VarRegister = scVarRegister, /* Var parameter in a register */
713 sc_Variant = scVariant, /* Variant record */
714 sc_SUndefined = scSUndefined, /* small undefined(external) data */
715 sc_Init = scInit, /* .init section symbol */
716 sc_Max = scMax /* Max storage class+1 */
717 } sc_t;
719 /* Redefinition of symbol type. */
721 typedef enum st {
722 st_Nil = stNil, /* Nuthin' special */
723 st_Global = stGlobal, /* external symbol */
724 st_Static = stStatic, /* static */
725 st_Param = stParam, /* procedure argument */
726 st_Local = stLocal, /* local variable */
727 st_Label = stLabel, /* label */
728 st_Proc = stProc, /* " " Procedure */
729 st_Block = stBlock, /* beginning of block */
730 st_End = stEnd, /* end (of anything) */
731 st_Member = stMember, /* member (of anything - struct/union/enum */
732 st_Typedef = stTypedef, /* type definition */
733 st_File = stFile, /* file name */
734 st_RegReloc = stRegReloc, /* register relocation */
735 st_Forward = stForward, /* forwarding address */
736 st_StaticProc = stStaticProc, /* load time only static procs */
737 st_Constant = stConstant, /* const */
738 st_Str = stStr, /* string */
739 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
740 st_Expr = stExpr, /* 2+2 vs. 4 */
741 st_Type = stType, /* post-coercion SER */
742 st_Max = stMax /* max type+1 */
743 } st_t;
745 /* Redefinition of type qualifiers. */
747 typedef enum tq {
748 tq_Nil = tqNil, /* bt is what you see */
749 tq_Ptr = tqPtr, /* pointer */
750 tq_Proc = tqProc, /* procedure */
751 tq_Array = tqArray, /* duh */
752 tq_Far = tqFar, /* longer addressing - 8086/8 land */
753 tq_Vol = tqVol, /* volatile */
754 tq_Max = tqMax /* Max type qualifier+1 */
755 } tq_t;
757 /* Redefinition of basic types. */
759 typedef enum bt {
760 bt_Nil = btNil, /* undefined */
761 bt_Adr = btAdr, /* address - integer same size as pointer */
762 bt_Char = btChar, /* character */
763 bt_UChar = btUChar, /* unsigned character */
764 bt_Short = btShort, /* short */
765 bt_UShort = btUShort, /* unsigned short */
766 bt_Int = btInt, /* int */
767 bt_UInt = btUInt, /* unsigned int */
768 bt_Long = btLong, /* long */
769 bt_ULong = btULong, /* unsigned long */
770 bt_Float = btFloat, /* float (real) */
771 bt_Double = btDouble, /* Double (real) */
772 bt_Struct = btStruct, /* Structure (Record) */
773 bt_Union = btUnion, /* Union (variant) */
774 bt_Enum = btEnum, /* Enumerated */
775 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
776 bt_Range = btRange, /* subrange of int */
777 bt_Set = btSet, /* pascal sets */
778 bt_Complex = btComplex, /* fortran complex */
779 bt_DComplex = btDComplex, /* fortran double complex */
780 bt_Indirect = btIndirect, /* forward or unnamed typedef */
781 bt_FixedDec = btFixedDec, /* Fixed Decimal */
782 bt_FloatDec = btFloatDec, /* Float Decimal */
783 bt_String = btString, /* Varying Length Character String */
784 bt_Bit = btBit, /* Aligned Bit String */
785 bt_Picture = btPicture, /* Picture */
787 #ifdef btVoid
788 bt_Void = btVoid, /* Void */
789 #else
790 #define bt_Void bt_Nil
791 #endif
793 bt_Max = btMax /* Max basic type+1 */
794 } bt_t;
798 /* Basic COFF storage classes. */
799 enum coff_storage {
800 C_EFCN = -1,
801 C_NULL = 0,
802 C_AUTO = 1,
803 C_EXT = 2,
804 C_STAT = 3,
805 C_REG = 4,
806 C_EXTDEF = 5,
807 C_LABEL = 6,
808 C_ULABEL = 7,
809 C_MOS = 8,
810 C_ARG = 9,
811 C_STRTAG = 10,
812 C_MOU = 11,
813 C_UNTAG = 12,
814 C_TPDEF = 13,
815 C_USTATIC = 14,
816 C_ENTAG = 15,
817 C_MOE = 16,
818 C_REGPARM = 17,
819 C_FIELD = 18,
820 C_BLOCK = 100,
821 C_FCN = 101,
822 C_EOS = 102,
823 C_FILE = 103,
824 C_LINE = 104,
825 C_ALIAS = 105,
826 C_HIDDEN = 106,
827 C_MAX = 107
828 } coff_storage_t;
830 /* Regular COFF fundamental type. */
831 typedef enum coff_type {
832 T_NULL = 0,
833 T_ARG = 1,
834 T_CHAR = 2,
835 T_SHORT = 3,
836 T_INT = 4,
837 T_LONG = 5,
838 T_FLOAT = 6,
839 T_DOUBLE = 7,
840 T_STRUCT = 8,
841 T_UNION = 9,
842 T_ENUM = 10,
843 T_MOE = 11,
844 T_UCHAR = 12,
845 T_USHORT = 13,
846 T_UINT = 14,
847 T_ULONG = 15,
848 T_MAX = 16
849 } coff_type_t;
851 /* Regular COFF derived types. */
852 typedef enum coff_dt {
853 DT_NON = 0,
854 DT_PTR = 1,
855 DT_FCN = 2,
856 DT_ARY = 3,
857 DT_MAX = 4
858 } coff_dt_t;
860 #define N_BTMASK 017 /* bitmask to isolate basic type */
861 #define N_TMASK 003 /* bitmask to isolate derived type */
862 #define N_BT_SHIFT 4 /* # bits to shift past basic type */
863 #define N_TQ_SHIFT 2 /* # bits to shift derived types */
864 #define N_TQ 6 /* # of type qualifiers */
866 /* States for whether to hash type or not. */
867 typedef enum hash_state {
868 hash_no = 0, /* don't hash type */
869 hash_yes = 1, /* ok to hash type, or use previous hash */
870 hash_record = 2 /* ok to record hash, but don't use prev. */
871 } hash_state_t;
874 /* Types of different sized allocation requests. */
875 enum alloc_type {
876 alloc_type_none, /* dummy value */
877 alloc_type_scope, /* nested scopes linked list */
878 alloc_type_vlinks, /* glue linking pages in varray */
879 alloc_type_shash, /* string hash element */
880 alloc_type_thash, /* type hash element */
881 alloc_type_tag, /* struct/union/tag element */
882 alloc_type_forward, /* element to hold unknown tag */
883 alloc_type_thead, /* head of type hash list */
884 alloc_type_varray, /* general varray allocation */
885 alloc_type_last /* last+1 element for array bounds */
889 #define WORD_ALIGN(x) (((x) + (sizeof (long) - 1)) & ~ (sizeof (long) - 1))
890 #define DWORD_ALIGN(x) (((x) + 7) & ~7)
893 /* Structures to provide n-number of virtual arrays, each of which can
894 grow linearly, and which are written in the object file as sequential
895 pages. On systems with a BSD malloc that define USE_MALLOC, the
896 MAX_CLUSTER_PAGES should be 1 less than a power of two, since malloc
897 adds its overhead, and rounds up to the next power of 2. Pages are
898 linked together via a linked list.
900 If PAGE_SIZE is > 4096, the string length in the shash_t structure
901 can't be represented (assuming there are strings > 4096 bytes). */
903 #ifndef PAGE_SIZE
904 #define PAGE_SIZE 4096 /* size of varray pages */
905 #endif
907 #define PAGE_USIZE ((Size_t) PAGE_SIZE)
910 #ifndef MAX_CLUSTER_PAGES /* # pages to get from system */
911 #ifndef USE_MALLOC /* in one memory request */
912 #define MAX_CLUSTER_PAGES 64
913 #else
914 #define MAX_CLUSTER_PAGES 63
915 #endif
916 #endif
919 /* Linked list connecting separate page allocations. */
920 typedef struct vlinks {
921 struct vlinks *prev; /* previous set of pages */
922 struct vlinks *next; /* next set of pages */
923 union page *datum; /* start of page */
924 unsigned long start_index; /* starting index # of page */
925 } vlinks_t;
928 /* Virtual array header. */
929 typedef struct varray {
930 vlinks_t *first; /* first page link */
931 vlinks_t *last; /* last page link */
932 unsigned long num_allocated; /* # objects allocated */
933 unsigned short object_size; /* size in bytes of each object */
934 unsigned short objects_per_page; /* # objects that can fit on a page */
935 unsigned short objects_last_page; /* # objects allocated on last page */
936 } varray_t;
938 #ifndef MALLOC_CHECK
939 #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
940 #else
941 #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
942 #endif
944 #define INIT_VARRAY(type) { /* macro to initialize a varray */ \
945 (vlinks_t *) 0, /* first */ \
946 (vlinks_t *) 0, /* last */ \
947 0, /* num_allocated */ \
948 sizeof (type), /* object_size */ \
949 OBJECTS_PER_PAGE (type), /* objects_per_page */ \
950 OBJECTS_PER_PAGE (type), /* objects_last_page */ \
953 #define INITIALIZE_VARRAY(x,type) \
954 do { \
955 (x)->object_size = sizeof (type); \
956 (x)->objects_per_page = OBJECTS_PER_PAGE (type); \
957 (x)->objects_last_page = OBJECTS_PER_PAGE (type); \
958 } while (0)
960 /* Master type for indexes within the symbol table. */
961 typedef unsigned long symint_t;
964 /* Linked list support for nested scopes (file, block, structure, etc.). */
965 typedef struct scope {
966 struct scope *prev; /* previous scope level */
967 struct scope *free; /* free list pointer */
968 SYMR *lsym; /* pointer to local symbol node */
969 symint_t lnumber; /* lsym index */
970 st_t type; /* type of the node */
971 } scope_t;
974 /* Forward reference list for tags referenced, but not yet defined. */
975 typedef struct forward {
976 struct forward *next; /* next forward reference */
977 struct forward *free; /* free list pointer */
978 AUXU *ifd_ptr; /* pointer to store file index */
979 AUXU *index_ptr; /* pointer to store symbol index */
980 AUXU *type_ptr; /* pointer to munge type info */
981 } forward_t;
984 /* Linked list support for tags. The first tag in the list is always
985 the current tag for that block. */
986 typedef struct tag {
987 struct tag *free; /* free list pointer */
988 struct shash *hash_ptr; /* pointer to the hash table head */
989 struct tag *same_name; /* tag with same name in outer scope */
990 struct tag *same_block; /* next tag defined in the same block. */
991 struct forward *forward_ref; /* list of forward references */
992 bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
993 symint_t ifd; /* file # tag defined in */
994 symint_t indx; /* index within file's local symbols */
995 } tag_t;
998 /* Head of a block's linked list of tags. */
999 typedef struct thead {
1000 struct thead *prev; /* previous block */
1001 struct thead *free; /* free list pointer */
1002 struct tag *first_tag; /* first tag in block defined */
1003 } thead_t;
1006 /* Union containing pointers to each the small structures which are freed up. */
1007 typedef union small_free {
1008 scope_t *f_scope; /* scope structure */
1009 thead_t *f_thead; /* tag head structure */
1010 tag_t *f_tag; /* tag element structure */
1011 forward_t *f_forward; /* forward tag reference */
1012 } small_free_t;
1015 /* String hash table support. The size of the hash table must fit
1016 within a page. */
1018 #ifndef SHASH_SIZE
1019 #define SHASH_SIZE 1009
1020 #endif
1022 #define HASH_LEN_MAX ((1 << 12) - 1) /* Max length we can store */
1024 typedef struct shash {
1025 struct shash *next; /* next hash value */
1026 char *string; /* string we are hashing */
1027 symint_t len; /* string length */
1028 symint_t indx; /* index within string table */
1029 EXTR *esym_ptr; /* global symbol pointer */
1030 SYMR *sym_ptr; /* local symbol pointer */
1031 SYMR *end_ptr; /* symbol pointer to end block */
1032 tag_t *tag_ptr; /* tag pointer */
1033 PDR *proc_ptr; /* procedure descriptor pointer */
1034 } shash_t;
1037 /* Type hash table support. The size of the hash table must fit
1038 within a page with the other extended file descriptor information.
1039 Because unique types which are hashed are fewer in number than
1040 strings, we use a smaller hash value. */
1042 #ifndef THASH_SIZE
1043 #define THASH_SIZE 113
1044 #endif
1046 typedef struct thash {
1047 struct thash *next; /* next hash value */
1048 AUXU type; /* type we are hashing */
1049 symint_t indx; /* index within string table */
1050 } thash_t;
1053 /* Extended file descriptor that contains all of the support necessary
1054 to add things to each file separately. */
1055 typedef struct efdr {
1056 FDR fdr; /* File header to be written out */
1057 FDR *orig_fdr; /* original file header */
1058 char *name; /* filename */
1059 int name_len; /* length of the filename */
1060 symint_t void_type; /* aux. pointer to 'void' type */
1061 symint_t int_type; /* aux. pointer to 'int' type */
1062 scope_t *cur_scope; /* current nested scopes */
1063 symint_t file_index; /* current file number */
1064 int nested_scopes; /* # nested scopes */
1065 varray_t strings; /* local strings */
1066 varray_t symbols; /* local symbols */
1067 varray_t procs; /* procedures */
1068 varray_t aux_syms; /* auxiliary symbols */
1069 struct efdr *next_file; /* next file descriptor */
1070 /* string/type hash tables */
1071 shash_t **shash_head; /* string hash table */
1072 thash_t *thash_head[THASH_SIZE];
1073 } efdr_t;
1075 /* Pre-initialized extended file structure. */
1076 static int init_file_initialized = 0;
1077 static efdr_t init_file;
1079 static efdr_t *first_file; /* first file descriptor */
1080 static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */
1083 /* Union of various things that are held in pages. */
1084 typedef union page {
1085 char byte [ PAGE_SIZE ];
1086 unsigned char ubyte [ PAGE_SIZE ];
1087 efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
1088 FDR ofile [ PAGE_SIZE / sizeof (FDR) ];
1089 PDR proc [ PAGE_SIZE / sizeof (PDR) ];
1090 SYMR sym [ PAGE_SIZE / sizeof (SYMR) ];
1091 EXTR esym [ PAGE_SIZE / sizeof (EXTR) ];
1092 AUXU aux [ PAGE_SIZE / sizeof (AUXU) ];
1093 DNR dense [ PAGE_SIZE / sizeof (DNR) ];
1094 scope_t scope [ PAGE_SIZE / sizeof (scope_t) ];
1095 vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ];
1096 shash_t shash [ PAGE_SIZE / sizeof (shash_t) ];
1097 thash_t thash [ PAGE_SIZE / sizeof (thash_t) ];
1098 tag_t tag [ PAGE_SIZE / sizeof (tag_t) ];
1099 forward_t forward [ PAGE_SIZE / sizeof (forward_t) ];
1100 thead_t thead [ PAGE_SIZE / sizeof (thead_t) ];
1101 } page_t;
1104 /* Structure holding allocation information for small sized structures. */
1105 typedef struct alloc_info {
1106 const char *alloc_name; /* name of this allocation type (must be first) */
1107 page_t *cur_page; /* current page being allocated from */
1108 small_free_t free_list; /* current free list if any */
1109 int unallocated; /* number of elements unallocated on page */
1110 int total_alloc; /* total number of allocations */
1111 int total_free; /* total number of frees */
1112 int total_pages; /* total number of pages allocated */
1113 } alloc_info_t;
1115 /* Type information collected together. */
1116 typedef struct type_info {
1117 bt_t basic_type; /* basic type */
1118 coff_type_t orig_type; /* original COFF-based type */
1119 int num_tq; /* # type qualifiers */
1120 int num_dims; /* # dimensions */
1121 int num_sizes; /* # sizes */
1122 int extra_sizes; /* # extra sizes not tied with dims */
1123 tag_t * tag_ptr; /* tag pointer */
1124 int bitfield; /* symbol is a bitfield */
1125 int unknown_tag; /* this is an unknown tag */
1126 tq_t type_qualifiers[N_TQ]; /* type qualifiers (ptr, func, array)*/
1127 symint_t dimensions [N_TQ]; /* dimensions for each array */
1128 symint_t sizes [N_TQ+2]; /* sizes of each array slice + size of
1129 struct/union/enum + bitfield size */
1130 } type_info_t;
1132 /* Pre-initialized type_info struct. */
1133 static type_info_t type_info_init = {
1134 bt_Nil, /* basic type */
1135 T_NULL, /* original COFF-based type */
1136 0, /* # type qualifiers */
1137 0, /* # dimensions */
1138 0, /* # sizes */
1139 0, /* sizes not tied with dims */
1140 NULL, /* ptr to tag */
1141 0, /* bitfield */
1142 0, /* unknown tag */
1143 { /* type qualifiers */
1144 tq_Nil,
1145 tq_Nil,
1146 tq_Nil,
1147 tq_Nil,
1148 tq_Nil,
1149 tq_Nil,
1151 { /* dimensions */
1159 { /* sizes */
1172 /* Global virtual arrays & hash table for external strings as well as
1173 for the tags table and global tables for file descriptors, and
1174 dense numbers. */
1176 static varray_t file_desc = INIT_VARRAY (efdr_t);
1177 static varray_t dense_num = INIT_VARRAY (DNR);
1178 static varray_t tag_strings = INIT_VARRAY (char);
1179 static varray_t ext_strings = INIT_VARRAY (char);
1180 static varray_t ext_symbols = INIT_VARRAY (EXTR);
1182 static shash_t *orig_str_hash[SHASH_SIZE];
1183 static shash_t *ext_str_hash [SHASH_SIZE];
1184 static shash_t *tag_hash [SHASH_SIZE];
1186 /* Static types for int and void. Also, remember the last function's
1187 type (which is set up when we encounter the declaration for the
1188 function, and used when the end block for the function is emitted. */
1190 static type_info_t int_type_info;
1191 static type_info_t void_type_info;
1192 static type_info_t last_func_type_info;
1193 static EXTR *last_func_eptr;
1196 /* Convert COFF basic type to ECOFF basic type. The T_NULL type
1197 really should use bt_Void, but this causes the current ecoff GDB to
1198 issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
1199 2.0) doesn't understand it, even though the compiler generates it.
1200 Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
1201 suite, but for now go with what works. */
1203 static const bt_t map_coff_types[ (int) T_MAX ] = {
1204 bt_Nil, /* T_NULL */
1205 bt_Nil, /* T_ARG */
1206 bt_Char, /* T_CHAR */
1207 bt_Short, /* T_SHORT */
1208 bt_Int, /* T_INT */
1209 bt_Long, /* T_LONG */
1210 bt_Float, /* T_FLOAT */
1211 bt_Double, /* T_DOUBLE */
1212 bt_Struct, /* T_STRUCT */
1213 bt_Union, /* T_UNION */
1214 bt_Enum, /* T_ENUM */
1215 bt_Enum, /* T_MOE */
1216 bt_UChar, /* T_UCHAR */
1217 bt_UShort, /* T_USHORT */
1218 bt_UInt, /* T_UINT */
1219 bt_ULong /* T_ULONG */
1222 /* Convert COFF storage class to ECOFF storage class. */
1223 static const sc_t map_coff_storage[ (int) C_MAX ] = {
1224 sc_Nil, /* 0: C_NULL */
1225 sc_Abs, /* 1: C_AUTO auto var */
1226 sc_Undefined, /* 2: C_EXT external */
1227 sc_Data, /* 3: C_STAT static */
1228 sc_Register, /* 4: C_REG register */
1229 sc_Undefined, /* 5: C_EXTDEF ??? */
1230 sc_Text, /* 6: C_LABEL label */
1231 sc_Text, /* 7: C_ULABEL user label */
1232 sc_Info, /* 8: C_MOS member of struct */
1233 sc_Abs, /* 9: C_ARG argument */
1234 sc_Info, /* 10: C_STRTAG struct tag */
1235 sc_Info, /* 11: C_MOU member of union */
1236 sc_Info, /* 12: C_UNTAG union tag */
1237 sc_Info, /* 13: C_TPDEF typedef */
1238 sc_Data, /* 14: C_USTATIC ??? */
1239 sc_Info, /* 15: C_ENTAG enum tag */
1240 sc_Info, /* 16: C_MOE member of enum */
1241 sc_Register, /* 17: C_REGPARM register parameter */
1242 sc_Bits, /* 18; C_FIELD bitfield */
1243 sc_Nil, /* 19 */
1244 sc_Nil, /* 20 */
1245 sc_Nil, /* 21 */
1246 sc_Nil, /* 22 */
1247 sc_Nil, /* 23 */
1248 sc_Nil, /* 24 */
1249 sc_Nil, /* 25 */
1250 sc_Nil, /* 26 */
1251 sc_Nil, /* 27 */
1252 sc_Nil, /* 28 */
1253 sc_Nil, /* 29 */
1254 sc_Nil, /* 30 */
1255 sc_Nil, /* 31 */
1256 sc_Nil, /* 32 */
1257 sc_Nil, /* 33 */
1258 sc_Nil, /* 34 */
1259 sc_Nil, /* 35 */
1260 sc_Nil, /* 36 */
1261 sc_Nil, /* 37 */
1262 sc_Nil, /* 38 */
1263 sc_Nil, /* 39 */
1264 sc_Nil, /* 40 */
1265 sc_Nil, /* 41 */
1266 sc_Nil, /* 42 */
1267 sc_Nil, /* 43 */
1268 sc_Nil, /* 44 */
1269 sc_Nil, /* 45 */
1270 sc_Nil, /* 46 */
1271 sc_Nil, /* 47 */
1272 sc_Nil, /* 48 */
1273 sc_Nil, /* 49 */
1274 sc_Nil, /* 50 */
1275 sc_Nil, /* 51 */
1276 sc_Nil, /* 52 */
1277 sc_Nil, /* 53 */
1278 sc_Nil, /* 54 */
1279 sc_Nil, /* 55 */
1280 sc_Nil, /* 56 */
1281 sc_Nil, /* 57 */
1282 sc_Nil, /* 58 */
1283 sc_Nil, /* 59 */
1284 sc_Nil, /* 60 */
1285 sc_Nil, /* 61 */
1286 sc_Nil, /* 62 */
1287 sc_Nil, /* 63 */
1288 sc_Nil, /* 64 */
1289 sc_Nil, /* 65 */
1290 sc_Nil, /* 66 */
1291 sc_Nil, /* 67 */
1292 sc_Nil, /* 68 */
1293 sc_Nil, /* 69 */
1294 sc_Nil, /* 70 */
1295 sc_Nil, /* 71 */
1296 sc_Nil, /* 72 */
1297 sc_Nil, /* 73 */
1298 sc_Nil, /* 74 */
1299 sc_Nil, /* 75 */
1300 sc_Nil, /* 76 */
1301 sc_Nil, /* 77 */
1302 sc_Nil, /* 78 */
1303 sc_Nil, /* 79 */
1304 sc_Nil, /* 80 */
1305 sc_Nil, /* 81 */
1306 sc_Nil, /* 82 */
1307 sc_Nil, /* 83 */
1308 sc_Nil, /* 84 */
1309 sc_Nil, /* 85 */
1310 sc_Nil, /* 86 */
1311 sc_Nil, /* 87 */
1312 sc_Nil, /* 88 */
1313 sc_Nil, /* 89 */
1314 sc_Nil, /* 90 */
1315 sc_Nil, /* 91 */
1316 sc_Nil, /* 92 */
1317 sc_Nil, /* 93 */
1318 sc_Nil, /* 94 */
1319 sc_Nil, /* 95 */
1320 sc_Nil, /* 96 */
1321 sc_Nil, /* 97 */
1322 sc_Nil, /* 98 */
1323 sc_Nil, /* 99 */
1324 sc_Text, /* 100: C_BLOCK block start/end */
1325 sc_Text, /* 101: C_FCN function start/end */
1326 sc_Info, /* 102: C_EOS end of struct/union/enum */
1327 sc_Nil, /* 103: C_FILE file start */
1328 sc_Nil, /* 104: C_LINE line number */
1329 sc_Nil, /* 105: C_ALIAS combined type info */
1330 sc_Nil, /* 106: C_HIDDEN ??? */
1333 /* Convert COFF storage class to ECOFF symbol type. */
1334 static const st_t map_coff_sym_type[ (int) C_MAX ] = {
1335 st_Nil, /* 0: C_NULL */
1336 st_Local, /* 1: C_AUTO auto var */
1337 st_Global, /* 2: C_EXT external */
1338 st_Static, /* 3: C_STAT static */
1339 st_Local, /* 4: C_REG register */
1340 st_Global, /* 5: C_EXTDEF ??? */
1341 st_Label, /* 6: C_LABEL label */
1342 st_Label, /* 7: C_ULABEL user label */
1343 st_Member, /* 8: C_MOS member of struct */
1344 st_Param, /* 9: C_ARG argument */
1345 st_Block, /* 10: C_STRTAG struct tag */
1346 st_Member, /* 11: C_MOU member of union */
1347 st_Block, /* 12: C_UNTAG union tag */
1348 st_Typedef, /* 13: C_TPDEF typedef */
1349 st_Static, /* 14: C_USTATIC ??? */
1350 st_Block, /* 15: C_ENTAG enum tag */
1351 st_Member, /* 16: C_MOE member of enum */
1352 st_Param, /* 17: C_REGPARM register parameter */
1353 st_Member, /* 18; C_FIELD bitfield */
1354 st_Nil, /* 19 */
1355 st_Nil, /* 20 */
1356 st_Nil, /* 21 */
1357 st_Nil, /* 22 */
1358 st_Nil, /* 23 */
1359 st_Nil, /* 24 */
1360 st_Nil, /* 25 */
1361 st_Nil, /* 26 */
1362 st_Nil, /* 27 */
1363 st_Nil, /* 28 */
1364 st_Nil, /* 29 */
1365 st_Nil, /* 30 */
1366 st_Nil, /* 31 */
1367 st_Nil, /* 32 */
1368 st_Nil, /* 33 */
1369 st_Nil, /* 34 */
1370 st_Nil, /* 35 */
1371 st_Nil, /* 36 */
1372 st_Nil, /* 37 */
1373 st_Nil, /* 38 */
1374 st_Nil, /* 39 */
1375 st_Nil, /* 40 */
1376 st_Nil, /* 41 */
1377 st_Nil, /* 42 */
1378 st_Nil, /* 43 */
1379 st_Nil, /* 44 */
1380 st_Nil, /* 45 */
1381 st_Nil, /* 46 */
1382 st_Nil, /* 47 */
1383 st_Nil, /* 48 */
1384 st_Nil, /* 49 */
1385 st_Nil, /* 50 */
1386 st_Nil, /* 51 */
1387 st_Nil, /* 52 */
1388 st_Nil, /* 53 */
1389 st_Nil, /* 54 */
1390 st_Nil, /* 55 */
1391 st_Nil, /* 56 */
1392 st_Nil, /* 57 */
1393 st_Nil, /* 58 */
1394 st_Nil, /* 59 */
1395 st_Nil, /* 60 */
1396 st_Nil, /* 61 */
1397 st_Nil, /* 62 */
1398 st_Nil, /* 63 */
1399 st_Nil, /* 64 */
1400 st_Nil, /* 65 */
1401 st_Nil, /* 66 */
1402 st_Nil, /* 67 */
1403 st_Nil, /* 68 */
1404 st_Nil, /* 69 */
1405 st_Nil, /* 70 */
1406 st_Nil, /* 71 */
1407 st_Nil, /* 72 */
1408 st_Nil, /* 73 */
1409 st_Nil, /* 74 */
1410 st_Nil, /* 75 */
1411 st_Nil, /* 76 */
1412 st_Nil, /* 77 */
1413 st_Nil, /* 78 */
1414 st_Nil, /* 79 */
1415 st_Nil, /* 80 */
1416 st_Nil, /* 81 */
1417 st_Nil, /* 82 */
1418 st_Nil, /* 83 */
1419 st_Nil, /* 84 */
1420 st_Nil, /* 85 */
1421 st_Nil, /* 86 */
1422 st_Nil, /* 87 */
1423 st_Nil, /* 88 */
1424 st_Nil, /* 89 */
1425 st_Nil, /* 90 */
1426 st_Nil, /* 91 */
1427 st_Nil, /* 92 */
1428 st_Nil, /* 93 */
1429 st_Nil, /* 94 */
1430 st_Nil, /* 95 */
1431 st_Nil, /* 96 */
1432 st_Nil, /* 97 */
1433 st_Nil, /* 98 */
1434 st_Nil, /* 99 */
1435 st_Block, /* 100: C_BLOCK block start/end */
1436 st_Proc, /* 101: C_FCN function start/end */
1437 st_End, /* 102: C_EOS end of struct/union/enum */
1438 st_File, /* 103: C_FILE file start */
1439 st_Nil, /* 104: C_LINE line number */
1440 st_Nil, /* 105: C_ALIAS combined type info */
1441 st_Nil, /* 106: C_HIDDEN ??? */
1444 /* Map COFF derived types to ECOFF type qualifiers. */
1445 static const tq_t map_coff_derived_type[ (int) DT_MAX ] = {
1446 tq_Nil, /* 0: DT_NON no more qualifiers */
1447 tq_Ptr, /* 1: DT_PTR pointer */
1448 tq_Proc, /* 2: DT_FCN function */
1449 tq_Array, /* 3: DT_ARY array */
1453 /* Keep track of different sized allocation requests. */
1454 static alloc_info_t alloc_counts[ (int) alloc_type_last ];
1457 /* Pointers and such to the original symbol table that is read in. */
1458 static struct filehdr orig_file_header; /* global object file header */
1460 static HDRR orig_sym_hdr; /* symbolic header on input */
1461 static char *orig_linenum; /* line numbers */
1462 static DNR *orig_dense; /* dense numbers */
1463 static PDR *orig_procs; /* procedures */
1464 static SYMR *orig_local_syms; /* local symbols */
1465 static OPTR *orig_opt_syms; /* optimization symbols */
1466 static AUXU *orig_aux_syms; /* auxiliary symbols */
1467 static char *orig_local_strs; /* local strings */
1468 static char *orig_ext_strs; /* external strings */
1469 static FDR *orig_files; /* file descriptors */
1470 static symint_t *orig_rfds; /* relative file desc's */
1471 static EXTR *orig_ext_syms; /* external symbols */
1473 /* Macros to convert an index into a given object within the original
1474 symbol table. */
1475 #define CHECK(num,max,str) \
1476 (((unsigned long) num > (unsigned long) max) ? out_of_bounds (num, max, str, __LINE__) : 0)
1478 #define ORIG_LINENUM(indx) (CHECK ((indx), orig_sym_hdr.cbLine, "line#"), (indx) + orig_linenum)
1479 #define ORIG_DENSE(indx) (CHECK ((indx), orig_sym_hdr.idnMax, "dense"), (indx) + orig_dense)
1480 #define ORIG_PROCS(indx) (CHECK ((indx), orig_sym_hdr.ipdMax, "procs"), (indx) + orig_procs)
1481 #define ORIG_FILES(indx) (CHECK ((indx), orig_sym_hdr.ifdMax, "funcs"), (indx) + orig_files)
1482 #define ORIG_LSYMS(indx) (CHECK ((indx), orig_sym_hdr.isymMax, "lsyms"), (indx) + orig_local_syms)
1483 #define ORIG_LSTRS(indx) (CHECK ((indx), orig_sym_hdr.issMax, "lstrs"), (indx) + orig_local_strs)
1484 #define ORIG_ESYMS(indx) (CHECK ((indx), orig_sym_hdr.iextMax, "esyms"), (indx) + orig_ext_syms)
1485 #define ORIG_ESTRS(indx) (CHECK ((indx), orig_sym_hdr.issExtMax, "estrs"), (indx) + orig_ext_strs)
1486 #define ORIG_OPT(indx) (CHECK ((indx), orig_sym_hdr.ioptMax, "opt"), (indx) + orig_opt_syms)
1487 #define ORIG_AUX(indx) (CHECK ((indx), orig_sym_hdr.iauxMax, "aux"), (indx) + orig_aux_syms)
1488 #define ORIG_RFDS(indx) (CHECK ((indx), orig_sym_hdr.crfd, "rfds"), (indx) + orig_rfds)
1490 /* Various other statics. */
1491 static HDRR symbolic_header; /* symbolic header */
1492 static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */
1493 static PDR *cur_proc_ptr = (PDR *) 0; /* current procedure header */
1494 static SYMR *cur_oproc_begin = (SYMR *) 0; /* original proc. sym begin info */
1495 static SYMR *cur_oproc_end = (SYMR *) 0; /* original proc. sym end info */
1496 static PDR *cur_oproc_ptr = (PDR *) 0; /* current original procedure*/
1497 static thead_t *cur_tag_head = (thead_t *) 0;/* current tag head */
1498 static unsigned long file_offset = 0; /* current file offset */
1499 static unsigned long max_file_offset = 0; /* maximum file offset */
1500 static FILE *object_stream = (FILE *) 0; /* file desc. to output .o */
1501 static FILE *obj_in_stream = (FILE *) 0; /* file desc. to input .o */
1502 static char *progname = (char *) 0; /* program name for errors */
1503 static const char *input_name = "stdin"; /* name of input file */
1504 static char *object_name = (char *) 0; /* tmp. name of object file */
1505 static char *obj_in_name = (char *) 0; /* name of input object file */
1506 static char *cur_line_start = (char *) 0; /* current line read in */
1507 static char *cur_line_ptr = (char *) 0; /* ptr within current line */
1508 static unsigned cur_line_nbytes = 0; /* # bytes for current line */
1509 static unsigned cur_line_alloc = 0; /* # bytes total in buffer */
1510 static long line_number = 0; /* current input line number */
1511 static int debug = 0; /* trace functions */
1512 static int version = 0; /* print version # */
1513 static int had_errors = 0; /* != 0 if errors were found */
1514 static int rename_output = 0; /* != 0 if rename output file*/
1515 static int delete_input = 0; /* != 0 if delete input after done */
1516 static int stabs_seen = 0; /* != 0 if stabs have been seen */
1519 /* Pseudo symbol to use when putting stabs into the symbol table. */
1520 #ifndef STABS_SYMBOL
1521 #define STABS_SYMBOL "@stabs"
1522 #endif
1524 static const char stabs_symbol[] = STABS_SYMBOL;
1527 /* Forward reference for functions. See the definition for more details. */
1529 #ifndef STATIC
1530 #define STATIC static
1531 #endif
1533 STATIC int out_of_bounds PARAMS ((symint_t, symint_t, const char *, int));
1535 STATIC shash_t *hash_string PARAMS ((const char *,
1536 Ptrdiff_t,
1537 shash_t **,
1538 symint_t *));
1540 STATIC symint_t add_string PARAMS ((varray_t *,
1541 shash_t **,
1542 const char *,
1543 const char *,
1544 shash_t **));
1546 STATIC symint_t add_local_symbol
1547 PARAMS ((const char *,
1548 const char *,
1549 st_t,
1550 sc_t,
1551 symint_t,
1552 symint_t));
1554 STATIC symint_t add_ext_symbol PARAMS ((EXTR *,
1555 int));
1557 STATIC symint_t add_aux_sym_symint
1558 PARAMS ((symint_t));
1560 STATIC symint_t add_aux_sym_rndx
1561 PARAMS ((int, symint_t));
1563 STATIC symint_t add_aux_sym_tir PARAMS ((type_info_t *,
1564 hash_state_t,
1565 thash_t **));
1567 STATIC tag_t * get_tag PARAMS ((const char *,
1568 const char *,
1569 symint_t,
1570 bt_t));
1572 STATIC void add_unknown_tag PARAMS ((tag_t *));
1574 STATIC void add_procedure PARAMS ((const char *,
1575 const char *));
1577 STATIC void initialize_init_file PARAMS ((void));
1579 STATIC void add_file PARAMS ((const char *,
1580 const char *));
1582 STATIC void add_bytes PARAMS ((varray_t *,
1583 char *,
1584 Size_t));
1586 STATIC void add_varray_page PARAMS ((varray_t *));
1588 STATIC void update_headers PARAMS ((void));
1590 STATIC void write_varray PARAMS ((varray_t *, off_t, const char *));
1591 STATIC void write_object PARAMS ((void));
1592 STATIC const char *st_to_string PARAMS ((st_t));
1593 STATIC const char *sc_to_string PARAMS ((sc_t));
1594 STATIC char *read_line PARAMS ((void));
1595 STATIC void parse_input PARAMS ((void));
1596 STATIC void mark_stabs PARAMS ((const char *));
1597 STATIC void parse_begin PARAMS ((const char *));
1598 STATIC void parse_bend PARAMS ((const char *));
1599 STATIC void parse_def PARAMS ((const char *));
1600 STATIC void parse_end PARAMS ((const char *));
1601 STATIC void parse_ent PARAMS ((const char *));
1602 STATIC void parse_file PARAMS ((const char *));
1603 STATIC void parse_stabs_common
1604 PARAMS ((const char *, const char *, const char *));
1605 STATIC void parse_stabs PARAMS ((const char *));
1606 STATIC void parse_stabn PARAMS ((const char *));
1607 STATIC page_t *read_seek PARAMS ((Size_t, off_t, const char *));
1608 STATIC void copy_object PARAMS ((void));
1610 STATIC void catch_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
1611 STATIC page_t *allocate_page PARAMS ((void));
1613 STATIC page_t *allocate_multiple_pages
1614 PARAMS ((Size_t));
1616 STATIC void free_multiple_pages
1617 PARAMS ((page_t *, Size_t));
1619 #ifndef MALLOC_CHECK
1620 STATIC page_t *allocate_cluster
1621 PARAMS ((Size_t));
1622 #endif
1624 STATIC forward_t *allocate_forward PARAMS ((void));
1625 STATIC scope_t *allocate_scope PARAMS ((void));
1626 STATIC shash_t *allocate_shash PARAMS ((void));
1627 STATIC tag_t *allocate_tag PARAMS ((void));
1628 STATIC thash_t *allocate_thash PARAMS ((void));
1629 STATIC thead_t *allocate_thead PARAMS ((void));
1630 STATIC vlinks_t *allocate_vlinks PARAMS ((void));
1632 STATIC void free_forward PARAMS ((forward_t *));
1633 STATIC void free_scope PARAMS ((scope_t *));
1634 STATIC void free_tag PARAMS ((tag_t *));
1635 STATIC void free_thead PARAMS ((thead_t *));
1637 extern char *optarg;
1638 extern int optind;
1639 extern int opterr;
1641 /* List of assembler pseudo ops and beginning sequences that need
1642 special actions. Someday, this should be a hash table, and such,
1643 but for now a linear list of names and calls to memcmp will
1644 do...... */
1646 typedef struct _pseudo_ops {
1647 const char *const name; /* pseudo-op in ascii */
1648 const int len; /* length of name to compare */
1649 void (*const func) PARAMS ((const char *)); /* function to handle line */
1650 } pseudo_ops_t;
1652 static const pseudo_ops_t pseudo_ops[] = {
1653 { "#.def", sizeof("#.def")-1, parse_def },
1654 { "#.begin", sizeof("#.begin")-1, parse_begin },
1655 { "#.bend", sizeof("#.bend")-1, parse_bend },
1656 { ".end", sizeof(".end")-1, parse_end },
1657 { ".ent", sizeof(".ent")-1, parse_ent },
1658 { ".file", sizeof(".file")-1, parse_file },
1659 { "#.stabs", sizeof("#.stabs")-1, parse_stabs },
1660 { "#.stabn", sizeof("#.stabn")-1, parse_stabn },
1661 { ".stabs", sizeof(".stabs")-1, parse_stabs },
1662 { ".stabn", sizeof(".stabn")-1, parse_stabn },
1663 { "#@stabs", sizeof("#@stabs")-1, mark_stabs },
1667 /* Add a page to a varray object. */
1669 STATIC void
1670 add_varray_page (vp)
1671 varray_t *vp; /* varray to add page to */
1673 vlinks_t *new_links = allocate_vlinks ();
1675 #ifdef MALLOC_CHECK
1676 if (vp->object_size > 1)
1677 new_links->datum = (page_t *) xcalloc (1, vp->object_size);
1678 else
1679 #endif
1680 new_links->datum = allocate_page ();
1682 alloc_counts[ (int) alloc_type_varray ].total_alloc++;
1683 alloc_counts[ (int) alloc_type_varray ].total_pages++;
1685 new_links->start_index = vp->num_allocated;
1686 vp->objects_last_page = 0;
1688 if (vp->first == (vlinks_t *) 0) /* first allocation? */
1689 vp->first = vp->last = new_links;
1690 else
1691 { /* 2nd or greater allocation */
1692 new_links->prev = vp->last;
1693 vp->last->next = new_links;
1694 vp->last = new_links;
1699 /* Compute hash code (from tree.c) */
1701 #define HASHBITS 30
1703 STATIC shash_t *
1704 hash_string (text, hash_len, hash_tbl, ret_hash_index)
1705 const char *text; /* ptr to text to hash */
1706 Ptrdiff_t hash_len; /* length of the text */
1707 shash_t **hash_tbl; /* hash table */
1708 symint_t *ret_hash_index; /* ptr to store hash index */
1710 unsigned long hi;
1711 Ptrdiff_t i;
1712 shash_t *ptr;
1713 int first_ch = *text;
1715 hi = hash_len;
1716 for (i = 0; i < hash_len; i++)
1717 hi = ((hi & 0x003fffff) * 613) + (text[i] & 0xff);
1719 hi &= (1 << HASHBITS) - 1;
1720 hi %= SHASH_SIZE;
1722 if (ret_hash_index != (symint_t *) 0)
1723 *ret_hash_index = hi;
1725 for (ptr = hash_tbl[hi]; ptr != (shash_t *) 0; ptr = ptr->next)
1726 if ((symint_t) hash_len == ptr->len
1727 && first_ch == ptr->string[0]
1728 && memcmp (text, ptr->string, hash_len) == 0)
1729 break;
1731 return ptr;
1735 /* Add a string (and null pad) to one of the string tables. A
1736 consequence of hashing strings, is that we don't let strings
1737 cross page boundaries. The extra nulls will be ignored. */
1739 STATIC symint_t
1740 add_string (vp, hash_tbl, start, end_p1, ret_hash)
1741 varray_t *vp; /* string virtual array */
1742 shash_t **hash_tbl; /* ptr to hash table */
1743 const char *start; /* 1st byte in string */
1744 const char *end_p1; /* 1st byte after string */
1745 shash_t **ret_hash; /* return hash pointer */
1747 Ptrdiff_t len = end_p1 - start;
1748 shash_t *hash_ptr;
1749 symint_t hi;
1751 if (len >= (Ptrdiff_t) PAGE_USIZE)
1752 fatal ("string too big (%ld bytes)", (long) len);
1754 hash_ptr = hash_string (start, len, hash_tbl, &hi);
1755 if (hash_ptr == (shash_t *) 0)
1757 char *p;
1759 if (vp->objects_last_page + len >= (long) PAGE_USIZE)
1761 vp->num_allocated
1762 = ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
1763 add_varray_page (vp);
1766 hash_ptr = allocate_shash ();
1767 hash_ptr->next = hash_tbl[hi];
1768 hash_tbl[hi] = hash_ptr;
1770 hash_ptr->len = len;
1771 hash_ptr->indx = vp->num_allocated;
1772 hash_ptr->string = p = & vp->last->datum->byte[ vp->objects_last_page ];
1774 vp->objects_last_page += len+1;
1775 vp->num_allocated += len+1;
1777 while (len-- > 0)
1778 *p++ = *start++;
1780 *p = '\0';
1783 if (ret_hash != (shash_t **) 0)
1784 *ret_hash = hash_ptr;
1786 return hash_ptr->indx;
1790 /* Add a local symbol. */
1792 STATIC symint_t
1793 add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
1794 const char *str_start; /* first byte in string */
1795 const char *str_end_p1; /* first byte after string */
1796 st_t type; /* symbol type */
1797 sc_t storage; /* storage class */
1798 symint_t value; /* value of symbol */
1799 symint_t indx; /* index to local/aux. syms */
1801 symint_t ret;
1802 SYMR *psym;
1803 scope_t *pscope;
1804 thead_t *ptag_head;
1805 tag_t *ptag;
1806 tag_t *ptag_next;
1807 varray_t *vp = &cur_file_ptr->symbols;
1808 int scope_delta = 0;
1809 shash_t *hash_ptr = (shash_t *) 0;
1811 if (vp->objects_last_page == vp->objects_per_page)
1812 add_varray_page (vp);
1814 psym = &vp->last->datum->sym[ vp->objects_last_page++ ];
1816 psym->value = value;
1817 psym->st = (unsigned) type;
1818 psym->sc = (unsigned) storage;
1819 psym->index = indx;
1820 psym->iss = (str_start == (const char *) 0)
1822 : add_string (&cur_file_ptr->strings,
1823 &cur_file_ptr->shash_head[0],
1824 str_start,
1825 str_end_p1,
1826 &hash_ptr);
1828 ret = vp->num_allocated++;
1830 if (MIPS_IS_STAB (psym))
1831 return ret;
1833 /* Save the symbol within the hash table if this is a static
1834 item, and it has a name. */
1835 if (hash_ptr != (shash_t *) 0
1836 && (type == st_Global || type == st_Static || type == st_Label
1837 || type == st_Proc || type == st_StaticProc))
1838 hash_ptr->sym_ptr = psym;
1840 /* push or pop a scope if appropriate. */
1841 switch (type)
1843 default:
1844 break;
1846 case st_File: /* beginning of file */
1847 case st_Proc: /* procedure */
1848 case st_StaticProc: /* static procedure */
1849 case st_Block: /* begin scope */
1850 pscope = allocate_scope ();
1851 pscope->prev = cur_file_ptr->cur_scope;
1852 pscope->lsym = psym;
1853 pscope->lnumber = ret;
1854 pscope->type = type;
1855 cur_file_ptr->cur_scope = pscope;
1857 if (type != st_File)
1858 scope_delta = 1;
1860 /* For every block type except file, struct, union, or
1861 enumeration blocks, push a level on the tag stack. We omit
1862 file types, so that tags can span file boundaries. */
1863 if (type != st_File && storage != sc_Info)
1865 ptag_head = allocate_thead ();
1866 ptag_head->first_tag = 0;
1867 ptag_head->prev = cur_tag_head;
1868 cur_tag_head = ptag_head;
1870 break;
1872 case st_End:
1873 pscope = cur_file_ptr->cur_scope;
1874 if (pscope == (scope_t *) 0)
1875 error ("internal error, too many st_End's");
1877 else
1879 st_t begin_type = (st_t) pscope->lsym->st;
1881 if (begin_type != st_File)
1882 scope_delta = -1;
1884 /* Except for file, structure, union, or enumeration end
1885 blocks remove all tags created within this scope. */
1886 if (begin_type != st_File && storage != sc_Info)
1888 ptag_head = cur_tag_head;
1889 cur_tag_head = ptag_head->prev;
1891 for (ptag = ptag_head->first_tag;
1892 ptag != (tag_t *) 0;
1893 ptag = ptag_next)
1895 if (ptag->forward_ref != (forward_t *) 0)
1896 add_unknown_tag (ptag);
1898 ptag_next = ptag->same_block;
1899 ptag->hash_ptr->tag_ptr = ptag->same_name;
1900 free_tag (ptag);
1903 free_thead (ptag_head);
1906 cur_file_ptr->cur_scope = pscope->prev;
1907 psym->index = pscope->lnumber; /* blk end gets begin sym # */
1909 if (storage != sc_Info)
1910 psym->iss = pscope->lsym->iss; /* blk end gets same name */
1912 if (begin_type == st_File || begin_type == st_Block)
1913 pscope->lsym->index = ret+1; /* block begin gets next sym # */
1915 /* Functions push two or more aux words as follows:
1916 1st word: index+1 of the end symbol
1917 2nd word: type of the function (plus any aux words needed).
1918 Also, tie the external pointer back to the function begin symbol. */
1919 else
1921 symint_t type;
1922 pscope->lsym->index = add_aux_sym_symint (ret+1);
1923 type = add_aux_sym_tir (&last_func_type_info,
1924 hash_no,
1925 &cur_file_ptr->thash_head[0]);
1926 if (last_func_eptr)
1928 last_func_eptr->ifd = cur_file_ptr->file_index;
1930 /* The index for an external st_Proc symbol is the index
1931 of the st_Proc symbol in the local symbol table. */
1932 last_func_eptr->asym.index = psym->index;
1936 free_scope (pscope);
1940 cur_file_ptr->nested_scopes += scope_delta;
1942 if (debug && type != st_File
1943 && (debug > 2 || type == st_Block || type == st_End
1944 || type == st_Proc || type == st_StaticProc))
1946 const char *sc_str = sc_to_string (storage);
1947 const char *st_str = st_to_string (type);
1948 int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
1950 fprintf (stderr,
1951 "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
1952 value, depth, sc_str);
1954 if (str_start && str_end_p1 - str_start > 0)
1955 fprintf (stderr, " st= %-11s name= %.*s\n",
1956 st_str, (int) (str_end_p1 - str_start), str_start);
1957 else
1959 Size_t len = strlen (st_str);
1960 fprintf (stderr, " st= %.*s\n", (int) (len-1), st_str);
1964 return ret;
1968 /* Add an external symbol. */
1970 STATIC symint_t
1971 add_ext_symbol (esym, ifd)
1972 EXTR *esym; /* symbol pointer */
1973 int ifd; /* file index */
1975 const char *str_start; /* first byte in string */
1976 const char *str_end_p1; /* first byte after string */
1977 EXTR *psym;
1978 varray_t *vp = &ext_symbols;
1979 shash_t *hash_ptr = (shash_t *) 0;
1981 str_start = ORIG_ESTRS (esym->asym.iss);
1982 str_end_p1 = str_start + strlen (str_start);
1984 if (debug > 1)
1986 long value = esym->asym.value;
1987 const char *sc_str = sc_to_string (esym->asym.sc);
1988 const char *st_str = st_to_string (esym->asym.st);
1990 fprintf (stderr,
1991 "\tesym\tv= %10ld, ifd= %2d, sc= %-12s",
1992 value, ifd, sc_str);
1994 if (str_start && str_end_p1 - str_start > 0)
1995 fprintf (stderr, " st= %-11s name= %.*s\n",
1996 st_str, (int) (str_end_p1 - str_start), str_start);
1997 else
1998 fprintf (stderr, " st= %s\n", st_str);
2001 if (vp->objects_last_page == vp->objects_per_page)
2002 add_varray_page (vp);
2004 psym = &vp->last->datum->esym[ vp->objects_last_page++ ];
2006 *psym = *esym;
2007 psym->ifd = ifd;
2008 psym->asym.index = indexNil;
2009 psym->asym.iss = (str_start == (const char *) 0)
2011 : add_string (&ext_strings,
2012 &ext_str_hash[0],
2013 str_start,
2014 str_end_p1,
2015 &hash_ptr);
2017 hash_ptr->esym_ptr = psym;
2018 return vp->num_allocated++;
2022 /* Add an auxiliary symbol (passing a symint). */
2024 STATIC symint_t
2025 add_aux_sym_symint (aux_word)
2026 symint_t aux_word; /* auxiliary information word */
2028 AUXU *aux_ptr;
2029 efdr_t *file_ptr = cur_file_ptr;
2030 varray_t *vp = &file_ptr->aux_syms;
2032 if (vp->objects_last_page == vp->objects_per_page)
2033 add_varray_page (vp);
2035 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2036 aux_ptr->isym = aux_word;
2038 return vp->num_allocated++;
2042 /* Add an auxiliary symbol (passing a file/symbol index combo). */
2044 STATIC symint_t
2045 add_aux_sym_rndx (file_index, sym_index)
2046 int file_index;
2047 symint_t sym_index;
2049 AUXU *aux_ptr;
2050 efdr_t *file_ptr = cur_file_ptr;
2051 varray_t *vp = &file_ptr->aux_syms;
2053 if (vp->objects_last_page == vp->objects_per_page)
2054 add_varray_page (vp);
2056 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2057 aux_ptr->rndx.rfd = file_index;
2058 aux_ptr->rndx.index = sym_index;
2060 return vp->num_allocated++;
2064 /* Add an auxiliary symbol (passing the basic type and possibly
2065 type qualifiers). */
2067 STATIC symint_t
2068 add_aux_sym_tir (t, state, hash_tbl)
2069 type_info_t *t; /* current type information */
2070 hash_state_t state; /* whether to hash type or not */
2071 thash_t **hash_tbl; /* pointer to hash table to use */
2073 AUXU *aux_ptr;
2074 efdr_t *file_ptr = cur_file_ptr;
2075 varray_t *vp = &file_ptr->aux_syms;
2076 static AUXU init_aux;
2077 symint_t ret;
2078 int i;
2079 AUXU aux;
2081 aux = init_aux;
2082 aux.ti.bt = (int) t->basic_type;
2083 aux.ti.continued = 0;
2084 aux.ti.fBitfield = t->bitfield;
2086 aux.ti.tq0 = (int) t->type_qualifiers[0];
2087 aux.ti.tq1 = (int) t->type_qualifiers[1];
2088 aux.ti.tq2 = (int) t->type_qualifiers[2];
2089 aux.ti.tq3 = (int) t->type_qualifiers[3];
2090 aux.ti.tq4 = (int) t->type_qualifiers[4];
2091 aux.ti.tq5 = (int) t->type_qualifiers[5];
2094 /* For anything that adds additional information, we must not hash,
2095 so check here, and reset our state. */
2097 if (state != hash_no
2098 && (t->type_qualifiers[0] == tq_Array
2099 || t->type_qualifiers[1] == tq_Array
2100 || t->type_qualifiers[2] == tq_Array
2101 || t->type_qualifiers[3] == tq_Array
2102 || t->type_qualifiers[4] == tq_Array
2103 || t->type_qualifiers[5] == tq_Array
2104 || t->basic_type == bt_Struct
2105 || t->basic_type == bt_Union
2106 || t->basic_type == bt_Enum
2107 || t->bitfield
2108 || t->num_dims > 0))
2109 state = hash_no;
2111 /* See if we can hash this type, and save some space, but some types
2112 can't be hashed (because they contain arrays or continuations),
2113 and others can be put into the hash list, but cannot use existing
2114 types because other aux entries precede this one. */
2116 if (state != hash_no)
2118 thash_t *hash_ptr;
2119 symint_t hi;
2121 hi = aux.isym & ((1 << HASHBITS) - 1);
2122 hi %= THASH_SIZE;
2124 for (hash_ptr = hash_tbl[hi];
2125 hash_ptr != (thash_t *) 0;
2126 hash_ptr = hash_ptr->next)
2128 if (aux.isym == hash_ptr->type.isym)
2129 break;
2132 if (hash_ptr != (thash_t *) 0 && state == hash_yes)
2133 return hash_ptr->indx;
2135 if (hash_ptr == (thash_t *) 0)
2137 hash_ptr = allocate_thash ();
2138 hash_ptr->next = hash_tbl[hi];
2139 hash_ptr->type = aux;
2140 hash_ptr->indx = vp->num_allocated;
2141 hash_tbl[hi] = hash_ptr;
2145 /* Everything is set up, add the aux symbol. */
2146 if (vp->objects_last_page == vp->objects_per_page)
2147 add_varray_page (vp);
2149 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2150 *aux_ptr = aux;
2152 ret = vp->num_allocated++;
2154 /* Add bitfield length if it exists.
2156 NOTE: Mips documentation claims bitfield goes at the end of the
2157 AUX record, but the DECstation compiler emits it here.
2158 (This would only make a difference for enum bitfields.)
2160 Also note: We use the last size given since gcc may emit 2
2161 for an enum bitfield. */
2163 if (t->bitfield)
2164 (void) add_aux_sym_symint ((symint_t) t->sizes[t->num_sizes-1]);
2167 /* Add tag information if needed. Structure, union, and enum
2168 references add 2 aux symbols: a [file index, symbol index]
2169 pointer to the structure type, and the current file index. */
2171 if (t->basic_type == bt_Struct
2172 || t->basic_type == bt_Union
2173 || t->basic_type == bt_Enum)
2175 symint_t file_index = t->tag_ptr->ifd;
2176 symint_t sym_index = t->tag_ptr->indx;
2178 if (t->unknown_tag)
2180 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2181 (void) add_aux_sym_symint ((symint_t)-1);
2183 else if (sym_index != indexNil)
2185 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2186 (void) add_aux_sym_symint (file_index);
2188 else
2190 forward_t *forward_ref = allocate_forward ();
2192 forward_ref->type_ptr = aux_ptr;
2193 forward_ref->next = t->tag_ptr->forward_ref;
2194 t->tag_ptr->forward_ref = forward_ref;
2196 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2197 forward_ref->index_ptr
2198 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2200 (void) add_aux_sym_symint (file_index);
2201 forward_ref->ifd_ptr
2202 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2206 /* Add information about array bounds if they exist. */
2207 for (i = 0; i < t->num_dims; i++)
2209 (void) add_aux_sym_rndx (ST_RFDESCAPE,
2210 cur_file_ptr->int_type);
2212 (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/
2213 (void) add_aux_sym_symint ((symint_t) 0); /* low bound */
2214 (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/
2215 (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */
2217 : (t->sizes[i] * 8) / t->dimensions[i]);
2220 /* NOTE: Mips documentation claims that the bitfield width goes here.
2221 But it needs to be emitted earlier. */
2223 return ret;
2227 /* Add a tag to the tag table (unless it already exists). */
2229 STATIC tag_t *
2230 get_tag (tag_start, tag_end_p1, indx, basic_type)
2231 const char *tag_start; /* 1st byte of tag name */
2232 const char *tag_end_p1; /* 1st byte after tag name */
2233 symint_t indx; /* index of tag start block */
2234 bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
2236 shash_t *hash_ptr;
2237 tag_t *tag_ptr;
2238 hash_ptr = hash_string (tag_start,
2239 tag_end_p1 - tag_start,
2240 &tag_hash[0],
2241 (symint_t *) 0);
2243 if (hash_ptr != (shash_t *) 0
2244 && hash_ptr->tag_ptr != (tag_t *) 0)
2246 tag_ptr = hash_ptr->tag_ptr;
2247 if (indx != indexNil)
2249 tag_ptr->basic_type = basic_type;
2250 tag_ptr->ifd = cur_file_ptr->file_index;
2251 tag_ptr->indx = indx;
2253 return tag_ptr;
2256 (void) add_string (&tag_strings,
2257 &tag_hash[0],
2258 tag_start,
2259 tag_end_p1,
2260 &hash_ptr);
2262 tag_ptr = allocate_tag ();
2263 tag_ptr->forward_ref = (forward_t *) 0;
2264 tag_ptr->hash_ptr = hash_ptr;
2265 tag_ptr->same_name = hash_ptr->tag_ptr;
2266 tag_ptr->basic_type = basic_type;
2267 tag_ptr->indx = indx;
2268 tag_ptr->ifd = (indx == indexNil
2269 ? (symint_t) -1 : cur_file_ptr->file_index);
2270 tag_ptr->same_block = cur_tag_head->first_tag;
2272 cur_tag_head->first_tag = tag_ptr;
2273 hash_ptr->tag_ptr = tag_ptr;
2275 return tag_ptr;
2279 /* Add an unknown {struct, union, enum} tag. */
2281 STATIC void
2282 add_unknown_tag (ptag)
2283 tag_t *ptag; /* pointer to tag information */
2285 shash_t *hash_ptr = ptag->hash_ptr;
2286 char *name_start = hash_ptr->string;
2287 char *name_end_p1 = name_start + hash_ptr->len;
2288 forward_t *f_next = ptag->forward_ref;
2289 forward_t *f_cur;
2290 int sym_index;
2291 int file_index = cur_file_ptr->file_index;
2293 if (debug > 1)
2295 const char *agg_type = "{unknown aggregate type}";
2296 switch (ptag->basic_type)
2298 case bt_Struct: agg_type = "struct"; break;
2299 case bt_Union: agg_type = "union"; break;
2300 case bt_Enum: agg_type = "enum"; break;
2301 default: break;
2304 fprintf (stderr, "unknown %s %.*s found\n",
2305 agg_type, (int) hash_ptr->len, name_start);
2308 sym_index = add_local_symbol (name_start,
2309 name_end_p1,
2310 st_Block,
2311 sc_Info,
2312 (symint_t) 0,
2313 (symint_t) 0);
2315 (void) add_local_symbol (name_start,
2316 name_end_p1,
2317 st_End,
2318 sc_Info,
2319 (symint_t) 0,
2320 (symint_t) 0);
2322 while (f_next != (forward_t *) 0)
2324 f_cur = f_next;
2325 f_next = f_next->next;
2327 f_cur->ifd_ptr->isym = file_index;
2328 f_cur->index_ptr->rndx.index = sym_index;
2330 free_forward (f_cur);
2333 return;
2337 /* Add a procedure to the current file's list of procedures, and record
2338 this is the current procedure. If the assembler created a PDR for
2339 this procedure, use that to initialize the current PDR. */
2341 STATIC void
2342 add_procedure (func_start, func_end_p1)
2343 const char *func_start; /* 1st byte of func name */
2344 const char *func_end_p1; /* 1st byte after func name */
2346 PDR *new_proc_ptr;
2347 efdr_t *file_ptr = cur_file_ptr;
2348 varray_t *vp = &file_ptr->procs;
2349 symint_t value = 0;
2350 st_t proc_type = st_Proc;
2351 shash_t *shash_ptr = hash_string (func_start,
2352 func_end_p1 - func_start,
2353 &orig_str_hash[0],
2354 (symint_t *) 0);
2356 if (debug)
2357 fputc ('\n', stderr);
2359 if (vp->objects_last_page == vp->objects_per_page)
2360 add_varray_page (vp);
2362 cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[ vp->objects_last_page++ ];
2364 vp->num_allocated++;
2367 /* Did the assembler create this procedure? If so, get the PDR information. */
2368 cur_oproc_ptr = (PDR *) 0;
2369 if (shash_ptr != (shash_t *) 0)
2371 PDR *old_proc_ptr = shash_ptr->proc_ptr;
2372 SYMR *sym_ptr = shash_ptr->sym_ptr;
2374 if (old_proc_ptr != (PDR *) 0
2375 && sym_ptr != (SYMR *) 0
2376 && ((st_t) sym_ptr->st == st_Proc || (st_t) sym_ptr->st == st_StaticProc))
2378 cur_oproc_begin = sym_ptr;
2379 cur_oproc_end = shash_ptr->end_ptr;
2380 value = sym_ptr->value;
2382 cur_oproc_ptr = old_proc_ptr;
2383 proc_type = (st_t) sym_ptr->st;
2384 *new_proc_ptr = *old_proc_ptr; /* initialize */
2388 if (cur_oproc_ptr == (PDR *) 0)
2389 error ("did not find a PDR block for %.*s",
2390 (int) (func_end_p1 - func_start), func_start);
2392 /* Determine the start of symbols. */
2393 new_proc_ptr->isym = file_ptr->symbols.num_allocated;
2395 /* Push the start of the function. */
2396 (void) add_local_symbol (func_start, func_end_p1,
2397 proc_type, sc_Text,
2398 value,
2399 (symint_t) 0);
2403 /* Initialize the init_file structure. */
2405 STATIC void
2406 initialize_init_file ()
2408 memset ((void*) &init_file, 0, sizeof (init_file));
2410 init_file.fdr.lang = langC;
2411 init_file.fdr.fMerge = 1;
2412 init_file.fdr.glevel = GLEVEL_2;
2414 #ifdef HOST_WORDS_BIG_ENDIAN
2415 init_file.fdr.fBigendian = 1;
2416 #endif
2418 INITIALIZE_VARRAY (&init_file.strings, char);
2419 INITIALIZE_VARRAY (&init_file.symbols, SYMR);
2420 INITIALIZE_VARRAY (&init_file.procs, PDR);
2421 INITIALIZE_VARRAY (&init_file.aux_syms, AUXU);
2423 init_file_initialized = 1;
2426 /* Add a new filename, and set up all of the file relative
2427 virtual arrays (strings, symbols, aux syms, etc.). Record
2428 where the current file structure lives. */
2430 STATIC void
2431 add_file (file_start, file_end_p1)
2432 const char *file_start; /* first byte in string */
2433 const char *file_end_p1; /* first byte after string */
2435 static char zero_bytes[2] = { '\0', '\0' };
2437 Ptrdiff_t len = file_end_p1 - file_start;
2438 int first_ch = *file_start;
2439 efdr_t *file_ptr;
2441 if (debug)
2442 fprintf (stderr, "\tfile\t%.*s\n", (int) len, file_start);
2444 /* See if the file has already been created. */
2445 for (file_ptr = first_file;
2446 file_ptr != (efdr_t *) 0;
2447 file_ptr = file_ptr->next_file)
2449 if (first_ch == file_ptr->name[0]
2450 && file_ptr->name[len] == '\0'
2451 && memcmp (file_start, file_ptr->name, len) == 0)
2453 cur_file_ptr = file_ptr;
2454 break;
2458 /* If this is a new file, create it. */
2459 if (file_ptr == (efdr_t *) 0)
2461 if (file_desc.objects_last_page == file_desc.objects_per_page)
2462 add_varray_page (&file_desc);
2464 if (! init_file_initialized)
2465 initialize_init_file ();
2467 file_ptr = cur_file_ptr
2468 = &file_desc.last->datum->file[ file_desc.objects_last_page++ ];
2469 *file_ptr = init_file;
2471 file_ptr->file_index = file_desc.num_allocated++;
2473 /* Allocate the string hash table. */
2474 file_ptr->shash_head = (shash_t **) allocate_page ();
2476 /* Make sure 0 byte in string table is null */
2477 add_string (&file_ptr->strings,
2478 &file_ptr->shash_head[0],
2479 &zero_bytes[0],
2480 &zero_bytes[0],
2481 (shash_t **) 0);
2483 if (file_end_p1 - file_start > (long) PAGE_USIZE-2)
2484 fatal ("filename goes over one page boundary");
2486 /* Push the start of the filename. We assume that the filename
2487 will be stored at string offset 1. */
2488 (void) add_local_symbol (file_start, file_end_p1, st_File, sc_Text,
2489 (symint_t) 0, (symint_t) 0);
2490 file_ptr->fdr.rss = 1;
2491 file_ptr->name = &file_ptr->strings.last->datum->byte[1];
2492 file_ptr->name_len = file_end_p1 - file_start;
2494 /* Update the linked list of file descriptors. */
2495 *last_file_ptr = file_ptr;
2496 last_file_ptr = &file_ptr->next_file;
2498 /* Add void & int types to the file (void should be first to catch
2499 errant 0's within the index fields). */
2500 file_ptr->void_type = add_aux_sym_tir (&void_type_info,
2501 hash_yes,
2502 &cur_file_ptr->thash_head[0]);
2504 file_ptr->int_type = add_aux_sym_tir (&int_type_info,
2505 hash_yes,
2506 &cur_file_ptr->thash_head[0]);
2511 /* Add a stream of random bytes to a varray. */
2513 STATIC void
2514 add_bytes (vp, input_ptr, nitems)
2515 varray_t *vp; /* virtual array to add too */
2516 char *input_ptr; /* start of the bytes */
2517 Size_t nitems; /* # items to move */
2519 Size_t move_items;
2520 Size_t move_bytes;
2521 char *ptr;
2523 while (nitems > 0)
2525 if (vp->objects_last_page >= vp->objects_per_page)
2526 add_varray_page (vp);
2528 ptr = &vp->last->datum->byte[ vp->objects_last_page * vp->object_size ];
2529 move_items = vp->objects_per_page - vp->objects_last_page;
2530 if (move_items > nitems)
2531 move_items = nitems;
2533 move_bytes = move_items * vp->object_size;
2534 nitems -= move_items;
2536 if (move_bytes >= 32)
2538 (void) memcpy (ptr, input_ptr, move_bytes);
2539 input_ptr += move_bytes;
2541 else
2543 while (move_bytes-- > 0)
2544 *ptr++ = *input_ptr++;
2550 /* Convert storage class to string. */
2552 STATIC const char *
2553 sc_to_string (storage_class)
2554 sc_t storage_class;
2556 switch (storage_class)
2558 case sc_Nil: return "Nil,";
2559 case sc_Text: return "Text,";
2560 case sc_Data: return "Data,";
2561 case sc_Bss: return "Bss,";
2562 case sc_Register: return "Register,";
2563 case sc_Abs: return "Abs,";
2564 case sc_Undefined: return "Undefined,";
2565 case sc_CdbLocal: return "CdbLocal,";
2566 case sc_Bits: return "Bits,";
2567 case sc_CdbSystem: return "CdbSystem,";
2568 case sc_RegImage: return "RegImage,";
2569 case sc_Info: return "Info,";
2570 case sc_UserStruct: return "UserStruct,";
2571 case sc_SData: return "SData,";
2572 case sc_SBss: return "SBss,";
2573 case sc_RData: return "RData,";
2574 case sc_Var: return "Var,";
2575 case sc_Common: return "Common,";
2576 case sc_SCommon: return "SCommon,";
2577 case sc_VarRegister: return "VarRegister,";
2578 case sc_Variant: return "Variant,";
2579 case sc_SUndefined: return "SUndefined,";
2580 case sc_Init: return "Init,";
2581 case sc_Max: return "Max,";
2584 return "???,";
2588 /* Convert symbol type to string. */
2590 STATIC const char *
2591 st_to_string (symbol_type)
2592 st_t symbol_type;
2594 switch (symbol_type)
2596 case st_Nil: return "Nil,";
2597 case st_Global: return "Global,";
2598 case st_Static: return "Static,";
2599 case st_Param: return "Param,";
2600 case st_Local: return "Local,";
2601 case st_Label: return "Label,";
2602 case st_Proc: return "Proc,";
2603 case st_Block: return "Block,";
2604 case st_End: return "End,";
2605 case st_Member: return "Member,";
2606 case st_Typedef: return "Typedef,";
2607 case st_File: return "File,";
2608 case st_RegReloc: return "RegReloc,";
2609 case st_Forward: return "Forward,";
2610 case st_StaticProc: return "StaticProc,";
2611 case st_Constant: return "Constant,";
2612 case st_Str: return "String,";
2613 case st_Number: return "Number,";
2614 case st_Expr: return "Expr,";
2615 case st_Type: return "Type,";
2616 case st_Max: return "Max,";
2619 return "???,";
2623 /* Read a line from standard input, and return the start of the buffer
2624 (which is grows if the line is too big). We split lines at the
2625 semi-colon, and return each logical line independently. */
2627 STATIC char *
2628 read_line ()
2630 static int line_split_p = 0;
2631 int string_p = 0;
2632 int comment_p = 0;
2633 int ch;
2634 char *ptr;
2636 if (cur_line_start == (char *) 0)
2637 { /* allocate initial page */
2638 cur_line_start = (char *) allocate_page ();
2639 cur_line_alloc = PAGE_SIZE;
2642 if (!line_split_p)
2643 line_number++;
2645 line_split_p = 0;
2646 cur_line_nbytes = 0;
2648 for (ptr = cur_line_start; (ch = getchar ()) != EOF; *ptr++ = ch)
2650 if (++cur_line_nbytes >= cur_line_alloc-1)
2652 int num_pages = cur_line_alloc / PAGE_SIZE;
2653 char *old_buffer = cur_line_start;
2655 cur_line_alloc += PAGE_SIZE;
2656 cur_line_start = (char *) allocate_multiple_pages (num_pages+1);
2657 memcpy (cur_line_start, old_buffer, num_pages * PAGE_SIZE);
2659 ptr = cur_line_start + cur_line_nbytes - 1;
2662 if (ch == '\n')
2664 *ptr++ = '\n';
2665 *ptr = '\0';
2666 cur_line_ptr = cur_line_start;
2667 return cur_line_ptr;
2670 else if (ch == '\0')
2671 error ("null character found in input");
2673 else if (!comment_p)
2675 if (ch == '"')
2676 string_p = !string_p;
2678 else if (ch == '#')
2679 comment_p++;
2681 else if (ch == ';' && !string_p)
2683 line_split_p = 1;
2684 *ptr++ = '\n';
2685 *ptr = '\0';
2686 cur_line_ptr = cur_line_start;
2687 return cur_line_ptr;
2692 if (ferror (stdin))
2693 pfatal_with_name (input_name);
2695 cur_line_ptr = (char *) 0;
2696 return (char *) 0;
2700 /* Parse #.begin directives which have a label as the first argument
2701 which gives the location of the start of the block. */
2703 STATIC void
2704 parse_begin (start)
2705 const char *start; /* start of directive */
2707 const char *end_p1; /* end of label */
2708 int ch;
2709 shash_t *hash_ptr; /* hash pointer to lookup label */
2711 if (cur_file_ptr == (efdr_t *) 0)
2713 error ("#.begin directive without a preceding .file directive");
2714 return;
2717 if (cur_proc_ptr == (PDR *) 0)
2719 error ("#.begin directive without a preceding .ent directive");
2720 return;
2723 for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++)
2726 hash_ptr = hash_string (start,
2727 end_p1 - start,
2728 &orig_str_hash[0],
2729 (symint_t *) 0);
2731 if (hash_ptr == (shash_t *) 0)
2733 error ("label %.*s not found for #.begin",
2734 (int) (end_p1 - start), start);
2735 return;
2738 if (cur_oproc_begin == (SYMR *) 0)
2740 error ("procedure table %.*s not found for #.begin",
2741 (int) (end_p1 - start), start);
2742 return;
2745 (void) add_local_symbol ((const char *) 0, (const char *) 0,
2746 st_Block, sc_Text,
2747 (symint_t) hash_ptr->sym_ptr->value - cur_oproc_begin->value,
2748 (symint_t) 0);
2752 /* Parse #.bend directives which have a label as the first argument
2753 which gives the location of the end of the block. */
2755 STATIC void
2756 parse_bend (start)
2757 const char *start; /* start of directive */
2759 const char *end_p1; /* end of label */
2760 int ch;
2761 shash_t *hash_ptr; /* hash pointer to lookup label */
2763 if (cur_file_ptr == (efdr_t *) 0)
2765 error ("#.begin directive without a preceding .file directive");
2766 return;
2769 if (cur_proc_ptr == (PDR *) 0)
2771 error ("#.bend directive without a preceding .ent directive");
2772 return;
2775 for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++)
2778 hash_ptr = hash_string (start,
2779 end_p1 - start,
2780 &orig_str_hash[0],
2781 (symint_t *) 0);
2783 if (hash_ptr == (shash_t *) 0)
2785 error ("label %.*s not found for #.bend", (int) (end_p1 - start), start);
2786 return;
2789 if (cur_oproc_begin == (SYMR *) 0)
2791 error ("procedure table %.*s not found for #.bend",
2792 (int) (end_p1 - start), start);
2793 return;
2796 (void) add_local_symbol ((const char *) 0, (const char *) 0,
2797 st_End, sc_Text,
2798 (symint_t) hash_ptr->sym_ptr->value - cur_oproc_begin->value,
2799 (symint_t) 0);
2803 /* Parse #.def directives, which are contain standard COFF subdirectives
2804 to describe the debugging format. These subdirectives include:
2806 .scl specify storage class
2807 .val specify a value
2808 .endef specify end of COFF directives
2809 .type specify the type
2810 .size specify the size of an array
2811 .dim specify an array dimension
2812 .tag specify a tag for a struct, union, or enum. */
2814 STATIC void
2815 parse_def (name_start)
2816 const char *name_start; /* start of directive */
2818 const char *dir_start; /* start of current directive*/
2819 const char *dir_end_p1; /* end+1 of current directive*/
2820 const char *arg_start; /* start of current argument */
2821 const char *arg_end_p1; /* end+1 of current argument */
2822 const char *name_end_p1; /* end+1 of label */
2823 const char *tag_start = 0; /* start of tag name */
2824 const char *tag_end_p1 = 0; /* end+1 of tag name */
2825 sc_t storage_class = sc_Nil;
2826 st_t symbol_type = st_Nil;
2827 type_info_t t;
2828 EXTR *eptr = (EXTR *) 0; /* ext. sym equivalent to def*/
2829 int is_function = 0; /* != 0 if function */
2830 symint_t value = 0;
2831 symint_t indx = cur_file_ptr->void_type;
2832 int error_line = 0;
2833 symint_t arg_number;
2834 symint_t temp_array[ N_TQ ];
2835 int arg_was_number;
2836 int ch, i;
2837 Ptrdiff_t len;
2839 static int inside_enumeration = 0; /* is this an enumeration? */
2842 /* Initialize the type information. */
2843 t = type_info_init;
2846 /* Search for the end of the name being defined. */
2847 /* Allow spaces and such in names for G++ templates, which produce stabs
2848 that look like:
2850 #.def SMANIP<long unsigned int>; .scl 10; .type 0x8; .size 8; .endef */
2852 for (name_end_p1 = name_start; (ch = *name_end_p1) != ';' && ch != '\0'; name_end_p1++)
2855 if (ch == '\0')
2857 error_line = __LINE__;
2858 saber_stop ();
2859 goto bomb_out;
2862 /* Parse the remaining subdirectives now. */
2863 dir_start = name_end_p1+1;
2864 for (;;)
2866 while ((ch = *dir_start) == ' ' || ch == '\t')
2867 ++dir_start;
2869 if (ch != '.')
2871 error_line = __LINE__;
2872 saber_stop ();
2873 goto bomb_out;
2876 /* Are we done? */
2877 if (dir_start[1] == 'e'
2878 && memcmp (dir_start, ".endef", sizeof (".endef")-1) == 0)
2879 break;
2881 /* Pick up the subdirective now */
2882 for (dir_end_p1 = dir_start+1;
2883 (ch = *dir_end_p1) != ' ' && ch != '\t';
2884 dir_end_p1++)
2886 if (ch == '\0' || ISSPACE (ch))
2888 error_line = __LINE__;
2889 saber_stop ();
2890 goto bomb_out;
2894 /* Pick up the subdirective argument now. */
2895 arg_was_number = arg_number = 0;
2896 arg_end_p1 = 0;
2897 arg_start = dir_end_p1+1;
2898 ch = *arg_start;
2899 while (ch == ' ' || ch == '\t')
2900 ch = *++arg_start;
2902 if (ISDIGIT (ch) || ch == '-' || ch == '+')
2904 int ch2;
2905 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
2906 if (arg_end_p1 != arg_start || ((ch2 = *arg_end_p1) != ';') || ch2 != ',')
2907 arg_was_number++;
2910 else if (ch == '\0' || ISSPACE (ch))
2912 error_line = __LINE__;
2913 saber_stop ();
2914 goto bomb_out;
2917 if (!arg_was_number)
2919 /* Allow spaces and such in names for G++ templates. */
2920 for (arg_end_p1 = arg_start+1;
2921 (ch = *arg_end_p1) != ';' && ch != '\0';
2922 arg_end_p1++)
2925 if (ch == '\0')
2927 error_line = __LINE__;
2928 saber_stop ();
2929 goto bomb_out;
2933 /* Classify the directives now. */
2934 len = dir_end_p1 - dir_start;
2935 switch (dir_start[1])
2937 default:
2938 error_line = __LINE__;
2939 saber_stop ();
2940 goto bomb_out;
2942 case 'd':
2943 if (len == sizeof (".dim")-1
2944 && memcmp (dir_start, ".dim", sizeof (".dim")-1) == 0
2945 && arg_was_number)
2947 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
2949 *t_ptr = arg_number;
2950 while (*arg_end_p1 == ',' && arg_was_number)
2952 arg_start = arg_end_p1+1;
2953 ch = *arg_start;
2954 while (ch == ' ' || ch == '\t')
2955 ch = *++arg_start;
2957 arg_was_number = 0;
2958 if (ISDIGIT (ch) || ch == '-' || ch == '+')
2960 int ch2;
2961 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
2962 if (arg_end_p1 != arg_start || ((ch2 = *arg_end_p1) != ';') || ch2 != ',')
2963 arg_was_number++;
2965 if (t_ptr == &temp_array[0])
2967 error_line = __LINE__;
2968 saber_stop ();
2969 goto bomb_out;
2972 *--t_ptr = arg_number;
2976 /* Reverse order of dimensions. */
2977 while (t_ptr <= &temp_array[ N_TQ-1 ])
2979 if (t.num_dims >= N_TQ-1)
2981 error_line = __LINE__;
2982 saber_stop ();
2983 goto bomb_out;
2986 t.dimensions[ t.num_dims++ ] = *t_ptr++;
2988 break;
2990 else
2992 error_line = __LINE__;
2993 saber_stop ();
2994 goto bomb_out;
2998 case 's':
2999 if (len == sizeof (".scl")-1
3000 && memcmp (dir_start, ".scl", sizeof (".scl")-1) == 0
3001 && arg_was_number
3002 && arg_number < ((symint_t) C_MAX))
3004 /* If the symbol is a static or external, we have
3005 already gotten the appropriate type and class, so
3006 make sure we don't override those values. This is
3007 needed because there are some type and classes that
3008 are not in COFF, such as short data, etc. */
3009 if (symbol_type == st_Nil)
3011 symbol_type = map_coff_sym_type[arg_number];
3012 storage_class = map_coff_storage [arg_number];
3014 break;
3017 else if (len == sizeof (".size")-1
3018 && memcmp (dir_start, ".size", sizeof (".size")-1) == 0
3019 && arg_was_number)
3021 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
3023 *t_ptr = arg_number;
3024 while (*arg_end_p1 == ',' && arg_was_number)
3026 arg_start = arg_end_p1+1;
3027 ch = *arg_start;
3028 while (ch == ' ' || ch == '\t')
3029 ch = *++arg_start;
3031 arg_was_number = 0;
3032 if (ISDIGIT (ch) || ch == '-' || ch == '+')
3034 int ch2;
3035 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
3036 if (arg_end_p1 != arg_start || ((ch2 = *arg_end_p1) != ';') || ch2 != ',')
3037 arg_was_number++;
3039 if (t_ptr == &temp_array[0])
3041 error_line = __LINE__;
3042 saber_stop ();
3043 goto bomb_out;
3046 *--t_ptr = arg_number;
3050 /* Reverse order of sizes. */
3051 while (t_ptr <= &temp_array[ N_TQ-1 ])
3053 if (t.num_sizes >= N_TQ-1)
3055 error_line = __LINE__;
3056 saber_stop ();
3057 goto bomb_out;
3060 t.sizes[ t.num_sizes++ ] = *t_ptr++;
3062 break;
3065 else
3067 error_line = __LINE__;
3068 saber_stop ();
3069 goto bomb_out;
3073 case 't':
3074 if (len == sizeof (".type")-1
3075 && memcmp (dir_start, ".type", sizeof (".type")-1) == 0
3076 && arg_was_number)
3078 tq_t *tq_ptr = &t.type_qualifiers[0];
3080 t.orig_type = (coff_type_t) (arg_number & N_BTMASK);
3081 t.basic_type = map_coff_types [(int) t.orig_type];
3082 for (i = N_TQ-1; i >= 0; i--)
3084 int dt = (arg_number >> ((i * N_TQ_SHIFT) + N_BT_SHIFT)
3085 & N_TMASK);
3087 if (dt != (int) DT_NON)
3088 *tq_ptr++ = map_coff_derived_type [dt];
3091 /* If this is a function, ignore it, so that we don't get
3092 two entries (one from the .ent, and one for the .def
3093 that precedes it). Save the type information so that
3094 the end block can properly add it after the begin block
3095 index. For MIPS knows what reason, we must strip off
3096 the function type at this point. */
3097 if (tq_ptr != &t.type_qualifiers[0] && tq_ptr[-1] == tq_Proc)
3099 is_function = 1;
3100 tq_ptr[-1] = tq_Nil;
3103 break;
3106 else if (len == sizeof (".tag")-1
3107 && memcmp (dir_start, ".tag", sizeof (".tag")-1) == 0)
3109 tag_start = arg_start;
3110 tag_end_p1 = arg_end_p1;
3111 break;
3114 else
3116 error_line = __LINE__;
3117 saber_stop ();
3118 goto bomb_out;
3122 case 'v':
3123 if (len == sizeof (".val")-1
3124 && memcmp (dir_start, ".val", sizeof (".val")-1) == 0)
3126 if (arg_was_number)
3127 value = arg_number;
3129 /* If the value is not an integer value, it must be the
3130 name of a static or global item. Look up the name in
3131 the original symbol table to pick up the storage
3132 class, symbol type, etc. */
3133 else
3135 shash_t *orig_hash_ptr; /* hash within orig sym table*/
3136 shash_t *ext_hash_ptr; /* hash within ext. sym table*/
3138 ext_hash_ptr = hash_string (arg_start,
3139 arg_end_p1 - arg_start,
3140 &ext_str_hash[0],
3141 (symint_t *) 0);
3143 if (ext_hash_ptr != (shash_t *) 0
3144 && ext_hash_ptr->esym_ptr != (EXTR *) 0)
3145 eptr = ext_hash_ptr->esym_ptr;
3147 orig_hash_ptr = hash_string (arg_start,
3148 arg_end_p1 - arg_start,
3149 &orig_str_hash[0],
3150 (symint_t *) 0);
3152 if ((orig_hash_ptr == (shash_t *) 0
3153 || orig_hash_ptr->sym_ptr == (SYMR *) 0)
3154 && eptr == (EXTR *) 0)
3156 fprintf (stderr, "warning, %.*s not found in original or external symbol tables, value defaults to 0\n",
3157 (int) (arg_end_p1 - arg_start),
3158 arg_start);
3159 value = 0;
3161 else
3163 SYMR *ptr = (orig_hash_ptr != (shash_t *) 0
3164 && orig_hash_ptr->sym_ptr != (SYMR *) 0)
3165 ? orig_hash_ptr->sym_ptr
3166 : &eptr->asym;
3168 symbol_type = (st_t) ptr->st;
3169 storage_class = (sc_t) ptr->sc;
3170 value = ptr->value;
3173 break;
3175 else
3177 error_line = __LINE__;
3178 saber_stop ();
3179 goto bomb_out;
3183 /* Set up to find next directive. */
3184 dir_start = arg_end_p1 + 1;
3188 if (storage_class == sc_Bits)
3190 t.bitfield = 1;
3191 t.extra_sizes = 1;
3193 else
3194 t.extra_sizes = 0;
3196 if (t.num_dims > 0)
3198 int num_real_sizes = t.num_sizes - t.extra_sizes;
3199 int diff = t.num_dims - num_real_sizes;
3200 int i = t.num_dims - 1;
3201 int j;
3203 if (num_real_sizes != 1 || diff < 0)
3205 error_line = __LINE__;
3206 saber_stop ();
3207 goto bomb_out;
3210 /* If this is an array, make sure the same number of dimensions
3211 and sizes were passed, creating extra sizes for multiply
3212 dimensioned arrays if not passed. */
3214 if (diff)
3216 for (j = ARRAY_SIZE (t.sizes) - 1; j >= 0; j--)
3217 t.sizes[ j ] = ((j-diff) >= 0) ? t.sizes[ j-diff ] : 0;
3219 t.num_sizes = i + 1;
3220 for ( i--; i >= 0; i-- )
3222 if (t.dimensions[ i+1 ])
3223 t.sizes[ i ] = t.sizes[ i+1 ] / t.dimensions[ i+1 ];
3224 else
3225 t.sizes[ i ] = t.sizes[ i+1 ];
3230 /* Except for enumeration members & begin/ending of scopes, put the
3231 type word in the aux. symbol table. */
3233 if (symbol_type == st_Block || symbol_type == st_End)
3234 indx = 0;
3236 else if (inside_enumeration)
3237 indx = cur_file_ptr->void_type;
3239 else
3241 if (t.basic_type == bt_Struct
3242 || t.basic_type == bt_Union
3243 || t.basic_type == bt_Enum)
3245 if (tag_start == (char *) 0)
3247 error ("no tag specified for %.*s",
3248 (int) (name_end_p1 - name_start),
3249 name_start);
3250 return;
3253 t.tag_ptr = get_tag (tag_start, tag_end_p1, (symint_t) indexNil,
3254 t.basic_type);
3257 if (is_function)
3259 last_func_type_info = t;
3260 last_func_eptr = eptr;
3261 return;
3264 indx = add_aux_sym_tir (&t,
3265 hash_yes,
3266 &cur_file_ptr->thash_head[0]);
3270 /* If this is an external or static symbol, update the appropriate
3271 external symbol. */
3273 if (eptr != (EXTR *) 0
3274 && (eptr->asym.index == indexNil || cur_proc_ptr == (PDR *) 0))
3276 eptr->ifd = cur_file_ptr->file_index;
3277 eptr->asym.index = indx;
3281 /* Do any last minute adjustments that are necessary. */
3282 switch (symbol_type)
3284 default:
3285 break;
3288 /* For the beginning of structs, unions, and enumerations, the
3289 size info needs to be passed in the value field. */
3291 case st_Block:
3292 if (t.num_sizes - t.num_dims - t.extra_sizes != 1)
3294 error_line = __LINE__;
3295 saber_stop ();
3296 goto bomb_out;
3299 else
3300 value = t.sizes[0];
3302 inside_enumeration = (t.orig_type == T_ENUM);
3303 break;
3306 /* For the end of structs, unions, and enumerations, omit the
3307 name which is always ".eos". This needs to be done last, so
3308 that any error reporting above gives the correct name. */
3310 case st_End:
3311 name_start = name_end_p1 = 0;
3312 value = inside_enumeration = 0;
3313 break;
3316 /* Members of structures and unions that aren't bitfields, need
3317 to adjust the value from a byte offset to a bit offset.
3318 Members of enumerations do not have the value adjusted, and
3319 can be distinguished by indx == indexNil. For enumerations,
3320 update the maximum enumeration value. */
3322 case st_Member:
3323 if (!t.bitfield && !inside_enumeration)
3324 value *= 8;
3326 break;
3330 /* Add the symbol, except for global symbols outside of functions,
3331 for which the external symbol table is fine enough. */
3333 if (eptr == (EXTR *) 0
3334 || eptr->asym.st == (int) st_Nil
3335 || cur_proc_ptr != (PDR *) 0)
3337 symint_t isym = add_local_symbol (name_start, name_end_p1,
3338 symbol_type, storage_class,
3339 value,
3340 indx);
3342 /* deal with struct, union, and enum tags. */
3343 if (symbol_type == st_Block)
3345 /* Create or update the tag information. */
3346 tag_t *tag_ptr = get_tag (name_start,
3347 name_end_p1,
3348 isym,
3349 t.basic_type);
3351 /* If there are any forward references, fill in the appropriate
3352 file and symbol indexes. */
3354 symint_t file_index = cur_file_ptr->file_index;
3355 forward_t *f_next = tag_ptr->forward_ref;
3356 forward_t *f_cur;
3358 while (f_next != (forward_t *) 0)
3360 f_cur = f_next;
3361 f_next = f_next->next;
3363 f_cur->ifd_ptr->isym = file_index;
3364 f_cur->index_ptr->rndx.index = isym;
3366 free_forward (f_cur);
3369 tag_ptr->forward_ref = (forward_t *) 0;
3373 /* Normal return */
3374 return;
3376 /* Error return, issue message. */
3377 bomb_out:
3378 if (error_line)
3379 error ("compiler error, badly formed #.def (internal line # = %d)", error_line);
3380 else
3381 error ("compiler error, badly formed #.def");
3383 return;
3387 /* Parse .end directives. */
3389 STATIC void
3390 parse_end (start)
3391 const char *start; /* start of directive */
3393 const char *start_func, *end_func_p1;
3394 int ch;
3395 symint_t value;
3396 FDR *orig_fdr;
3398 if (cur_file_ptr == (efdr_t *) 0)
3400 error (".end directive without a preceding .file directive");
3401 return;
3404 if (cur_proc_ptr == (PDR *) 0)
3406 error (".end directive without a preceding .ent directive");
3407 return;
3410 /* Get the function name, skipping whitespace. */
3411 for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++)
3414 ch = *start_func;
3415 if (!IS_ASM_IDENT (ch))
3417 error (".end directive has no name");
3418 return;
3421 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
3425 /* Get the value field for creating the end from the original object
3426 file (which we find by locating the procedure start, and using the
3427 pointer to the end+1 block and backing up. The index points to a
3428 two word aux. symbol, whose first word is the index of the end
3429 symbol, and the second word is the type of the function return
3430 value. */
3432 orig_fdr = cur_file_ptr->orig_fdr;
3433 value = 0;
3434 if (orig_fdr != (FDR *) 0 && cur_oproc_end != (SYMR *) 0)
3435 value = cur_oproc_end->value;
3437 else
3438 error ("cannot find .end block for %.*s",
3439 (int) (end_func_p1 - start_func), start_func);
3441 (void) add_local_symbol (start_func, end_func_p1,
3442 st_End, sc_Text,
3443 value,
3444 (symint_t) 0);
3446 cur_proc_ptr = cur_oproc_ptr = (PDR *) 0;
3450 /* Parse .ent directives. */
3452 STATIC void
3453 parse_ent (start)
3454 const char *start; /* start of directive */
3456 const char *start_func, *end_func_p1;
3457 int ch;
3459 if (cur_file_ptr == (efdr_t *) 0)
3461 error (".ent directive without a preceding .file directive");
3462 return;
3465 if (cur_proc_ptr != (PDR *) 0)
3467 error ("second .ent directive found before .end directive");
3468 return;
3471 for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++)
3474 ch = *start_func;
3475 if (!IS_ASM_IDENT (ch))
3477 error (".ent directive has no name");
3478 return;
3481 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
3484 (void) add_procedure (start_func, end_func_p1);
3488 /* Parse .file directives. */
3490 STATIC void
3491 parse_file (start)
3492 const char *start; /* start of directive */
3494 char *p;
3495 char *start_name, *end_name_p1;
3497 (void) strtol (start, &p, 0);
3498 if (start == p
3499 || (start_name = strchr (p, '"')) == (char *) 0
3500 || (end_name_p1 = strrchr (++start_name, '"')) == (char *) 0)
3502 error ("invalid .file directive");
3503 return;
3506 if (cur_proc_ptr != (PDR *) 0)
3508 error ("no way to handle .file within .ent/.end section");
3509 return;
3512 add_file (start_name, end_name_p1);
3516 /* Make sure the @stabs symbol is emitted. */
3518 static void
3519 mark_stabs (start)
3520 const char *start ATTRIBUTE_UNUSED; /* Start of directive (ignored) */
3522 if (!stabs_seen)
3524 /* Add a dummy @stabs symbol. */
3525 stabs_seen = 1;
3526 (void) add_local_symbol (stabs_symbol,
3527 stabs_symbol + sizeof (stabs_symbol),
3528 stNil, scInfo, -1, MIPS_MARK_STAB (0));
3534 /* Parse .stabs directives.
3536 .stabs directives have five fields:
3537 "string" a string, encoding the type information.
3538 code a numeric code, defined in <stab.h>
3539 0 a zero
3540 0 a zero or line number
3541 value a numeric value or an address.
3543 If the value is relocatable, we transform this into:
3544 iss points as an index into string space
3545 value value from lookup of the name
3546 st st from lookup of the name
3547 sc sc from lookup of the name
3548 index code|CODE_MASK
3550 If the value is not relocatable, we transform this into:
3551 iss points as an index into string space
3552 value value
3553 st st_Nil
3554 sc sc_Nil
3555 index code|CODE_MASK
3557 .stabn directives have four fields (string is null):
3558 code a numeric code, defined in <stab.h>
3559 0 a zero
3560 0 a zero or a line number
3561 value a numeric value or an address. */
3563 STATIC void
3564 parse_stabs_common (string_start, string_end, rest)
3565 const char *string_start; /* start of string or NULL */
3566 const char *string_end; /* end+1 of string or NULL */
3567 const char *rest; /* rest of the directive. */
3569 efdr_t *save_file_ptr = cur_file_ptr;
3570 symint_t code;
3571 symint_t value;
3572 char *p;
3573 st_t st;
3574 sc_t sc;
3575 int ch;
3577 if (stabs_seen == 0)
3578 mark_stabs ("");
3580 /* Read code from stabs. */
3581 if (!ISDIGIT (*rest))
3583 error ("invalid .stabs/.stabn directive, code is non-numeric");
3584 return;
3587 code = strtol (rest, &p, 0);
3589 /* Line number stabs are handled differently, since they have two values,
3590 the line number and the address of the label. We use the index field
3591 (aka code) to hold the line number, and the value field to hold the
3592 address. The symbol type is st_Label, which should be different from
3593 the other stabs, so that gdb can recognize it. */
3595 if (code == (int) N_SLINE)
3597 SYMR *sym_ptr, dummy_symr;
3598 shash_t *shash_ptr;
3600 /* Skip ,0, */
3601 if (p[0] != ',' || p[1] != '0' || p[2] != ',' || !ISDIGIT (p[3]))
3603 error ("invalid line number .stabs/.stabn directive");
3604 return;
3607 code = strtol (p+3, &p, 0);
3608 ch = *++p;
3609 if (p[-1] != ',' || ISDIGIT (ch) || !IS_ASM_IDENT (ch))
3611 error ("invalid line number .stabs/.stabn directive");
3612 return;
3615 dummy_symr.index = code;
3616 if (dummy_symr.index != code)
3618 error ("line number (%lu) for .stabs/.stabn directive cannot fit in index field (20 bits)",
3619 code);
3621 return;
3624 shash_ptr = hash_string (p,
3625 strlen (p) - 1,
3626 &orig_str_hash[0],
3627 (symint_t *) 0);
3629 if (shash_ptr == (shash_t *) 0
3630 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0)
3632 error ("invalid .stabs/.stabn directive, value not found");
3633 return;
3636 if ((st_t) sym_ptr->st != st_Label)
3638 error ("invalid line number .stabs/.stabn directive");
3639 return;
3642 st = st_Label;
3643 sc = (sc_t) sym_ptr->sc;
3644 value = sym_ptr->value;
3646 else
3648 /* Skip ,<num>,<num>, */
3649 if (*p++ != ',')
3650 goto failure;
3651 for (; ISDIGIT (*p); p++)
3653 if (*p++ != ',')
3654 goto failure;
3655 for (; ISDIGIT (*p); p++)
3657 if (*p++ != ',')
3658 goto failure;
3659 ch = *p;
3660 if (!IS_ASM_IDENT (ch) && ch != '-')
3662 failure:
3663 error ("invalid .stabs/.stabn directive, bad character");
3664 return;
3667 if (ISDIGIT (ch) || ch == '-')
3669 st = st_Nil;
3670 sc = sc_Nil;
3671 value = strtol (p, &p, 0);
3672 if (*p != '\n')
3674 error ("invalid .stabs/.stabn directive, stuff after numeric value");
3675 return;
3678 else if (!IS_ASM_IDENT (ch))
3680 error ("invalid .stabs/.stabn directive, bad character");
3681 return;
3683 else
3685 SYMR *sym_ptr;
3686 shash_t *shash_ptr;
3687 const char *start, *end_p1;
3689 start = p;
3690 if ((end_p1 = strchr (start, '+')) == (char *) 0)
3692 if ((end_p1 = strchr (start, '-')) == (char *) 0)
3693 end_p1 = start + strlen (start) - 1;
3696 shash_ptr = hash_string (start,
3697 end_p1 - start,
3698 &orig_str_hash[0],
3699 (symint_t *) 0);
3701 if (shash_ptr == (shash_t *) 0
3702 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0)
3704 shash_ptr = hash_string (start,
3705 end_p1 - start,
3706 &ext_str_hash[0],
3707 (symint_t *) 0);
3709 if (shash_ptr == (shash_t *) 0
3710 || shash_ptr->esym_ptr == (EXTR *) 0)
3712 error ("invalid .stabs/.stabn directive, value not found");
3713 return;
3715 else
3716 sym_ptr = &(shash_ptr->esym_ptr->asym);
3719 /* Traditionally, N_LBRAC and N_RBRAC are *not* relocated. */
3720 if (code == (int) N_LBRAC || code == (int) N_RBRAC)
3722 sc = scNil;
3723 st = stNil;
3725 else
3727 sc = (sc_t) sym_ptr->sc;
3728 st = (st_t) sym_ptr->st;
3730 value = sym_ptr->value;
3732 ch = *end_p1++;
3733 if (ch != '\n')
3735 if (((!ISDIGIT (*end_p1)) && (*end_p1 != '-'))
3736 || ((ch != '+') && (ch != '-')))
3738 error ("invalid .stabs/.stabn directive, badly formed value");
3739 return;
3741 if (ch == '+')
3742 value += strtol (end_p1, &p, 0);
3743 else if (ch == '-')
3744 value -= strtol (end_p1, &p, 0);
3746 if (*p != '\n')
3748 error ("invalid .stabs/.stabn directive, stuff after numeric value");
3749 return;
3753 code = MIPS_MARK_STAB (code);
3756 (void) add_local_symbol (string_start, string_end, st, sc, value, code);
3757 /* Restore normal file type. */
3758 cur_file_ptr = save_file_ptr;
3762 STATIC void
3763 parse_stabs (start)
3764 const char *start; /* start of directive */
3766 const char *end = strchr (start+1, '"');
3768 if (*start != '"' || end == (const char *) 0 || end[1] != ',')
3770 error ("invalid .stabs directive, no string");
3771 return;
3774 parse_stabs_common (start+1, end, end+2);
3778 STATIC void
3779 parse_stabn (start)
3780 const char *start; /* start of directive */
3782 parse_stabs_common ((const char *) 0, (const char *) 0, start);
3786 /* Parse the input file, and write the lines to the output file
3787 if needed. */
3789 STATIC void
3790 parse_input ()
3792 char *p;
3793 Size_t i;
3794 thead_t *ptag_head;
3795 tag_t *ptag;
3796 tag_t *ptag_next;
3798 if (debug)
3799 fprintf (stderr, "\tinput\n");
3801 /* Add a dummy scope block around the entire compilation unit for
3802 structures defined outside of blocks. */
3803 ptag_head = allocate_thead ();
3804 ptag_head->first_tag = 0;
3805 ptag_head->prev = cur_tag_head;
3806 cur_tag_head = ptag_head;
3808 while ((p = read_line ()) != (char *) 0)
3810 /* Skip leading blanks */
3811 while (ISSPACE ((unsigned char)*p))
3812 p++;
3814 /* See if it's a directive we handle. If so, dispatch handler. */
3815 for (i = 0; i < ARRAY_SIZE (pseudo_ops); i++)
3816 if (memcmp (p, pseudo_ops[i].name, pseudo_ops[i].len) == 0
3817 && ISSPACE ((unsigned char)(p[pseudo_ops[i].len])))
3819 p += pseudo_ops[i].len; /* skip to first argument */
3820 while (ISSPACE ((unsigned char)*p))
3821 p++;
3823 (*pseudo_ops[i].func)( p );
3824 break;
3828 /* Process any tags at global level. */
3829 ptag_head = cur_tag_head;
3830 cur_tag_head = ptag_head->prev;
3832 for (ptag = ptag_head->first_tag;
3833 ptag != (tag_t *) 0;
3834 ptag = ptag_next)
3836 if (ptag->forward_ref != (forward_t *) 0)
3837 add_unknown_tag (ptag);
3839 ptag_next = ptag->same_block;
3840 ptag->hash_ptr->tag_ptr = ptag->same_name;
3841 free_tag (ptag);
3844 free_thead (ptag_head);
3849 /* Update the global headers with the final offsets in preparation
3850 to write out the .T file. */
3852 STATIC void
3853 update_headers ()
3855 symint_t i;
3856 efdr_t *file_ptr;
3858 /* Set up the symbolic header. */
3859 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
3860 symbolic_header.magic = orig_sym_hdr.magic;
3861 symbolic_header.vstamp = orig_sym_hdr.vstamp;
3863 /* Set up global counts. */
3864 symbolic_header.issExtMax = ext_strings.num_allocated;
3865 symbolic_header.idnMax = dense_num.num_allocated;
3866 symbolic_header.ifdMax = file_desc.num_allocated;
3867 symbolic_header.iextMax = ext_symbols.num_allocated;
3868 symbolic_header.ilineMax = orig_sym_hdr.ilineMax;
3869 symbolic_header.ioptMax = orig_sym_hdr.ioptMax;
3870 symbolic_header.cbLine = orig_sym_hdr.cbLine;
3871 symbolic_header.crfd = orig_sym_hdr.crfd;
3874 /* Loop through each file, figuring out how many local syms,
3875 line numbers, etc. there are. Also, put out end symbol
3876 for the filename. */
3878 for (file_ptr = first_file;
3879 file_ptr != (efdr_t *) 0;
3880 file_ptr = file_ptr->next_file)
3882 SYMR *sym_start;
3883 SYMR *sym;
3884 SYMR *sym_end_p1;
3885 FDR *fd_ptr = file_ptr->orig_fdr;
3887 cur_file_ptr = file_ptr;
3889 /* Copy st_Static symbols from the original local symbol table if
3890 they did not get added to the new local symbol table.
3891 This happens with stabs-in-ecoff or if the source file is
3892 compiled without debugging. */
3893 sym_start = ORIG_LSYMS (fd_ptr->isymBase);
3894 sym_end_p1 = sym_start + fd_ptr->csym;
3895 for (sym = sym_start; sym < sym_end_p1; sym++)
3897 if ((st_t) sym->st == st_Static)
3899 char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
3900 Size_t len = strlen (str);
3901 shash_t *hash_ptr;
3903 /* Ignore internal labels. */
3904 if (str[0] == '$' && str[1] == 'L')
3905 continue;
3906 hash_ptr = hash_string (str,
3907 (Ptrdiff_t) len,
3908 &file_ptr->shash_head[0],
3909 (symint_t *) 0);
3910 if (hash_ptr == (shash_t *) 0)
3912 (void) add_local_symbol (str, str + len,
3913 (st_t) sym->st, (sc_t) sym->sc,
3914 (symint_t) sym->value,
3915 (symint_t) indexNil);
3919 (void) add_local_symbol ((const char *) 0, (const char *) 0,
3920 st_End, sc_Text,
3921 (symint_t) 0,
3922 (symint_t) 0);
3924 file_ptr->fdr.cpd = file_ptr->procs.num_allocated;
3925 file_ptr->fdr.ipdFirst = symbolic_header.ipdMax;
3926 symbolic_header.ipdMax += file_ptr->fdr.cpd;
3928 file_ptr->fdr.csym = file_ptr->symbols.num_allocated;
3929 file_ptr->fdr.isymBase = symbolic_header.isymMax;
3930 symbolic_header.isymMax += file_ptr->fdr.csym;
3932 file_ptr->fdr.caux = file_ptr->aux_syms.num_allocated;
3933 file_ptr->fdr.iauxBase = symbolic_header.iauxMax;
3934 symbolic_header.iauxMax += file_ptr->fdr.caux;
3936 file_ptr->fdr.cbSs = file_ptr->strings.num_allocated;
3937 file_ptr->fdr.issBase = symbolic_header.issMax;
3938 symbolic_header.issMax += file_ptr->fdr.cbSs;
3941 #ifndef ALIGN_SYMTABLE_OFFSET
3942 #define ALIGN_SYMTABLE_OFFSET(OFFSET) (OFFSET)
3943 #endif
3945 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
3946 i = WORD_ALIGN (symbolic_header.cbLine); /* line numbers */
3947 if (i > 0)
3949 symbolic_header.cbLineOffset = file_offset;
3950 file_offset += i;
3951 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
3954 i = symbolic_header.ioptMax; /* optimization symbols */
3955 if (((long) i) > 0)
3957 symbolic_header.cbOptOffset = file_offset;
3958 file_offset += i * sizeof (OPTR);
3959 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
3962 i = symbolic_header.idnMax; /* dense numbers */
3963 if (i > 0)
3965 symbolic_header.cbDnOffset = file_offset;
3966 file_offset += i * sizeof (DNR);
3967 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
3970 i = symbolic_header.ipdMax; /* procedure tables */
3971 if (i > 0)
3973 symbolic_header.cbPdOffset = file_offset;
3974 file_offset += i * sizeof (PDR);
3975 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
3978 i = symbolic_header.isymMax; /* local symbols */
3979 if (i > 0)
3981 symbolic_header.cbSymOffset = file_offset;
3982 file_offset += i * sizeof (SYMR);
3983 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
3986 i = symbolic_header.iauxMax; /* aux syms. */
3987 if (i > 0)
3989 symbolic_header.cbAuxOffset = file_offset;
3990 file_offset += i * sizeof (TIR);
3991 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
3994 i = WORD_ALIGN (symbolic_header.issMax); /* local strings */
3995 if (i > 0)
3997 symbolic_header.cbSsOffset = file_offset;
3998 file_offset += i;
3999 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4002 i = WORD_ALIGN (symbolic_header.issExtMax); /* external strings */
4003 if (i > 0)
4005 symbolic_header.cbSsExtOffset = file_offset;
4006 file_offset += i;
4007 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4010 i = symbolic_header.ifdMax; /* file tables */
4011 if (i > 0)
4013 symbolic_header.cbFdOffset = file_offset;
4014 file_offset += i * sizeof (FDR);
4015 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4018 i = symbolic_header.crfd; /* relative file descriptors */
4019 if (i > 0)
4021 symbolic_header.cbRfdOffset = file_offset;
4022 file_offset += i * sizeof (symint_t);
4023 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4026 i = symbolic_header.iextMax; /* external symbols */
4027 if (i > 0)
4029 symbolic_header.cbExtOffset = file_offset;
4030 file_offset += i * sizeof (EXTR);
4031 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4036 /* Write out a varray at a given location. */
4038 STATIC void
4039 write_varray (vp, offset, str)
4040 varray_t *vp; /* virtual array */
4041 off_t offset; /* offset to write varray to */
4042 const char *str; /* string to print out when tracing */
4044 int num_write, sys_write;
4045 vlinks_t *ptr;
4047 if (vp->num_allocated == 0)
4048 return;
4050 if (debug)
4052 fputs ("\twarray\tvp = ", stderr);
4053 fprintf (stderr, HOST_PTR_PRINTF, (PTR) vp);
4054 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4055 (unsigned long) offset, vp->num_allocated * vp->object_size, str);
4058 if (file_offset != (unsigned long) offset
4059 && fseek (object_stream, (long) offset, SEEK_SET) < 0)
4060 pfatal_with_name (object_name);
4062 for (ptr = vp->first; ptr != (vlinks_t *) 0; ptr = ptr->next)
4064 num_write = (ptr->next == (vlinks_t *) 0)
4065 ? vp->objects_last_page * vp->object_size
4066 : vp->objects_per_page * vp->object_size;
4068 sys_write = fwrite ((PTR) ptr->datum, 1, num_write, object_stream);
4069 if (sys_write <= 0)
4070 pfatal_with_name (object_name);
4072 else if (sys_write != num_write)
4073 fatal ("wrote %d bytes to %s, system returned %d",
4074 num_write,
4075 object_name,
4076 sys_write);
4078 file_offset += num_write;
4083 /* Write out the symbol table in the object file. */
4085 STATIC void
4086 write_object ()
4088 int sys_write;
4089 efdr_t *file_ptr;
4090 off_t offset;
4092 if (debug)
4094 fputs ("\n\twrite\tvp = ", stderr);
4095 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &symbolic_header);
4096 fprintf (stderr, ", offset = %7u, size = %7lu, %s\n",
4097 0, (unsigned long) sizeof (symbolic_header), "symbolic header");
4100 sys_write = fwrite ((PTR) &symbolic_header,
4102 sizeof (symbolic_header),
4103 object_stream);
4105 if (sys_write < 0)
4106 pfatal_with_name (object_name);
4108 else if (sys_write != sizeof (symbolic_header))
4109 fatal ("wrote %d bytes to %s, system returned %d",
4110 (int) sizeof (symbolic_header),
4111 object_name,
4112 sys_write);
4115 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
4117 if (symbolic_header.cbLine > 0) /* line numbers */
4119 long sys_write;
4121 if (file_offset != (unsigned long) symbolic_header.cbLineOffset
4122 && fseek (object_stream, symbolic_header.cbLineOffset, SEEK_SET) != 0)
4123 pfatal_with_name (object_name);
4125 if (debug)
4127 fputs ("\twrite\tvp = ", stderr);
4128 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &orig_linenum);
4129 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4130 (long) symbolic_header.cbLineOffset,
4131 (long) symbolic_header.cbLine, "Line numbers");
4134 sys_write = fwrite ((PTR) orig_linenum,
4136 symbolic_header.cbLine,
4137 object_stream);
4139 if (sys_write <= 0)
4140 pfatal_with_name (object_name);
4142 else if (sys_write != symbolic_header.cbLine)
4143 fatal ("wrote %ld bytes to %s, system returned %ld",
4144 (long) symbolic_header.cbLine,
4145 object_name,
4146 sys_write);
4148 file_offset = symbolic_header.cbLineOffset + symbolic_header.cbLine;
4151 if (symbolic_header.ioptMax > 0) /* optimization symbols */
4153 long sys_write;
4154 long num_write = symbolic_header.ioptMax * sizeof (OPTR);
4156 if (file_offset != (unsigned long) symbolic_header.cbOptOffset
4157 && fseek (object_stream, symbolic_header.cbOptOffset, SEEK_SET) != 0)
4158 pfatal_with_name (object_name);
4160 if (debug)
4162 fputs ("\twrite\tvp = ", stderr);
4163 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &orig_opt_syms);
4164 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4165 (long) symbolic_header.cbOptOffset,
4166 num_write, "Optimizer symbols");
4169 sys_write = fwrite ((PTR) orig_opt_syms,
4171 num_write,
4172 object_stream);
4174 if (sys_write <= 0)
4175 pfatal_with_name (object_name);
4177 else if (sys_write != num_write)
4178 fatal ("wrote %ld bytes to %s, system returned %ld",
4179 num_write,
4180 object_name,
4181 sys_write);
4183 file_offset = symbolic_header.cbOptOffset + num_write;
4186 if (symbolic_header.idnMax > 0) /* dense numbers */
4187 write_varray (&dense_num, (off_t) symbolic_header.cbDnOffset, "Dense numbers");
4189 if (symbolic_header.ipdMax > 0) /* procedure tables */
4191 offset = symbolic_header.cbPdOffset;
4192 for (file_ptr = first_file;
4193 file_ptr != (efdr_t *) 0;
4194 file_ptr = file_ptr->next_file)
4196 write_varray (&file_ptr->procs, offset, "Procedure tables");
4197 offset = file_offset;
4201 if (symbolic_header.isymMax > 0) /* local symbols */
4203 offset = symbolic_header.cbSymOffset;
4204 for (file_ptr = first_file;
4205 file_ptr != (efdr_t *) 0;
4206 file_ptr = file_ptr->next_file)
4208 write_varray (&file_ptr->symbols, offset, "Local symbols");
4209 offset = file_offset;
4213 if (symbolic_header.iauxMax > 0) /* aux symbols */
4215 offset = symbolic_header.cbAuxOffset;
4216 for (file_ptr = first_file;
4217 file_ptr != (efdr_t *) 0;
4218 file_ptr = file_ptr->next_file)
4220 write_varray (&file_ptr->aux_syms, offset, "Aux. symbols");
4221 offset = file_offset;
4225 if (symbolic_header.issMax > 0) /* local strings */
4227 offset = symbolic_header.cbSsOffset;
4228 for (file_ptr = first_file;
4229 file_ptr != (efdr_t *) 0;
4230 file_ptr = file_ptr->next_file)
4232 write_varray (&file_ptr->strings, offset, "Local strings");
4233 offset = file_offset;
4237 if (symbolic_header.issExtMax > 0) /* external strings */
4238 write_varray (&ext_strings, symbolic_header.cbSsExtOffset, "External strings");
4240 if (symbolic_header.ifdMax > 0) /* file tables */
4242 offset = symbolic_header.cbFdOffset;
4243 if (file_offset != (unsigned long) offset
4244 && fseek (object_stream, (long) offset, SEEK_SET) < 0)
4245 pfatal_with_name (object_name);
4247 file_offset = offset;
4248 for (file_ptr = first_file;
4249 file_ptr != (efdr_t *) 0;
4250 file_ptr = file_ptr->next_file)
4252 if (debug)
4254 fputs ("\twrite\tvp = ", stderr);
4255 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &file_ptr->fdr);
4256 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4257 file_offset, (unsigned long) sizeof (FDR),
4258 "File header");
4261 sys_write = fwrite (&file_ptr->fdr,
4263 sizeof (FDR),
4264 object_stream);
4266 if (sys_write < 0)
4267 pfatal_with_name (object_name);
4269 else if (sys_write != sizeof (FDR))
4270 fatal ("wrote %d bytes to %s, system returned %d",
4271 (int) sizeof (FDR),
4272 object_name,
4273 sys_write);
4275 file_offset = offset += sizeof (FDR);
4279 if (symbolic_header.crfd > 0) /* relative file descriptors */
4281 long sys_write;
4282 symint_t num_write = symbolic_header.crfd * sizeof (symint_t);
4284 if (file_offset != (unsigned long) symbolic_header.cbRfdOffset
4285 && fseek (object_stream, symbolic_header.cbRfdOffset, SEEK_SET) != 0)
4286 pfatal_with_name (object_name);
4288 if (debug)
4290 fputs ("\twrite\tvp = ", stderr);
4291 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &orig_rfds);
4292 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4293 (long) symbolic_header.cbRfdOffset,
4294 num_write, "Relative file descriptors");
4297 sys_write = fwrite (orig_rfds,
4299 num_write,
4300 object_stream);
4302 if (sys_write <= 0)
4303 pfatal_with_name (object_name);
4305 else if (sys_write != (long) num_write)
4306 fatal ("wrote %lu bytes to %s, system returned %ld",
4307 num_write,
4308 object_name,
4309 sys_write);
4311 file_offset = symbolic_header.cbRfdOffset + num_write;
4314 if (symbolic_header.issExtMax > 0) /* external symbols */
4315 write_varray (&ext_symbols, (off_t) symbolic_header.cbExtOffset, "External symbols");
4317 if (fclose (object_stream) != 0)
4318 pfatal_with_name (object_name);
4322 /* Read some bytes at a specified location, and return a pointer. */
4324 STATIC page_t *
4325 read_seek (size, offset, str)
4326 Size_t size; /* # bytes to read */
4327 off_t offset; /* offset to read at */
4328 const char *str; /* name for tracing */
4330 page_t *ptr;
4331 long sys_read = 0;
4333 if (size == 0) /* nothing to read */
4334 return (page_t *) 0;
4336 if (debug)
4337 fprintf (stderr,
4338 "\trseek\tsize = %7lu, offset = %7lu, currently at %7lu, %s\n",
4339 (unsigned long) size, (unsigned long) offset, file_offset, str);
4341 #ifndef MALLOC_CHECK
4342 ptr = allocate_multiple_pages ((size + PAGE_USIZE - 1) / PAGE_USIZE);
4343 #else
4344 ptr = (page_t *) xcalloc (1, size);
4345 #endif
4347 /* If we need to seek, and the distance is nearby, just do some reads,
4348 to speed things up. */
4349 if (file_offset != (unsigned long) offset)
4351 symint_t difference = offset - file_offset;
4353 if (difference < 8)
4355 char small_buffer[8];
4357 sys_read = fread (small_buffer, 1, difference, obj_in_stream);
4358 if (sys_read <= 0)
4359 pfatal_with_name (obj_in_name);
4361 if ((symint_t) sys_read != difference)
4362 fatal ("wanted to read %lu bytes from %s, system returned %ld",
4363 (unsigned long) size,
4364 obj_in_name,
4365 sys_read);
4367 else if (fseek (obj_in_stream, offset, SEEK_SET) < 0)
4368 pfatal_with_name (obj_in_name);
4371 sys_read = fread ((PTR) ptr, 1, size, obj_in_stream);
4372 if (sys_read <= 0)
4373 pfatal_with_name (obj_in_name);
4375 if (sys_read != (long) size)
4376 fatal ("wanted to read %lu bytes from %s, system returned %ld",
4377 (unsigned long) size,
4378 obj_in_name,
4379 sys_read);
4381 file_offset = offset + size;
4383 if (file_offset > max_file_offset)
4384 max_file_offset = file_offset;
4386 return ptr;
4390 /* Read the existing object file (and copy to the output object file
4391 if it is different from the input object file), and remove the old
4392 symbol table. */
4394 STATIC void
4395 copy_object ()
4397 char buffer[ PAGE_SIZE ];
4398 int sys_read;
4399 int remaining;
4400 int num_write;
4401 int sys_write;
4402 int fd, es;
4403 int delete_ifd = 0;
4404 int *remap_file_number;
4405 struct stat stat_buf;
4407 if (debug)
4408 fprintf (stderr, "\tcopy\n");
4410 if (fstat (fileno (obj_in_stream), &stat_buf) != 0
4411 || fseek (obj_in_stream, 0L, SEEK_SET) != 0)
4412 pfatal_with_name (obj_in_name);
4414 sys_read = fread ((PTR) &orig_file_header,
4416 sizeof (struct filehdr),
4417 obj_in_stream);
4419 if (sys_read < 0)
4420 pfatal_with_name (obj_in_name);
4422 else if (sys_read == 0 && feof (obj_in_stream))
4423 return; /* create a .T file sans file header */
4425 else if (sys_read < (int) sizeof (struct filehdr))
4426 fatal ("wanted to read %d bytes from %s, system returned %d",
4427 (int) sizeof (struct filehdr),
4428 obj_in_name,
4429 sys_read);
4432 if (orig_file_header.f_nsyms != sizeof (HDRR))
4433 fatal ("%s symbolic header wrong size (%ld bytes, should be %ld)",
4434 input_name, (long) orig_file_header.f_nsyms, (long) sizeof (HDRR));
4437 /* Read in the current symbolic header. */
4438 if (fseek (obj_in_stream, (long) orig_file_header.f_symptr, SEEK_SET) != 0)
4439 pfatal_with_name (input_name);
4441 sys_read = fread ((PTR) &orig_sym_hdr,
4443 sizeof (orig_sym_hdr),
4444 obj_in_stream);
4446 if (sys_read < 0)
4447 pfatal_with_name (object_name);
4449 else if (sys_read < (int) sizeof (struct filehdr))
4450 fatal ("wanted to read %d bytes from %s, system returned %d",
4451 (int) sizeof (struct filehdr),
4452 obj_in_name,
4453 sys_read);
4456 /* Read in each of the sections if they exist in the object file.
4457 We read things in in the order the mips assembler creates the
4458 sections, so in theory no extra seeks are done.
4460 For simplicity sake, round each read up to a page boundary,
4461 we may want to revisit this later.... */
4463 file_offset = orig_file_header.f_symptr + sizeof (struct filehdr);
4465 if (orig_sym_hdr.cbLine > 0) /* line numbers */
4466 orig_linenum = (char *) read_seek ((Size_t) orig_sym_hdr.cbLine,
4467 orig_sym_hdr.cbLineOffset,
4468 "Line numbers");
4470 if (orig_sym_hdr.ipdMax > 0) /* procedure tables */
4471 orig_procs = (PDR *) read_seek ((Size_t) orig_sym_hdr.ipdMax * sizeof (PDR),
4472 orig_sym_hdr.cbPdOffset,
4473 "Procedure tables");
4475 if (orig_sym_hdr.isymMax > 0) /* local symbols */
4476 orig_local_syms = (SYMR *) read_seek ((Size_t) orig_sym_hdr.isymMax * sizeof (SYMR),
4477 orig_sym_hdr.cbSymOffset,
4478 "Local symbols");
4480 if (orig_sym_hdr.iauxMax > 0) /* aux symbols */
4481 orig_aux_syms = (AUXU *) read_seek ((Size_t) orig_sym_hdr.iauxMax * sizeof (AUXU),
4482 orig_sym_hdr.cbAuxOffset,
4483 "Aux. symbols");
4485 if (orig_sym_hdr.issMax > 0) /* local strings */
4486 orig_local_strs = (char *) read_seek ((Size_t) orig_sym_hdr.issMax,
4487 orig_sym_hdr.cbSsOffset,
4488 "Local strings");
4490 if (orig_sym_hdr.issExtMax > 0) /* external strings */
4491 orig_ext_strs = (char *) read_seek ((Size_t) orig_sym_hdr.issExtMax,
4492 orig_sym_hdr.cbSsExtOffset,
4493 "External strings");
4495 if (orig_sym_hdr.ifdMax > 0) /* file tables */
4496 orig_files = (FDR *) read_seek ((Size_t) orig_sym_hdr.ifdMax * sizeof (FDR),
4497 orig_sym_hdr.cbFdOffset,
4498 "File tables");
4500 if (orig_sym_hdr.crfd > 0) /* relative file descriptors */
4501 orig_rfds = (symint_t *) read_seek ((Size_t) orig_sym_hdr.crfd * sizeof (symint_t),
4502 orig_sym_hdr.cbRfdOffset,
4503 "Relative file descriptors");
4505 if (orig_sym_hdr.issExtMax > 0) /* external symbols */
4506 orig_ext_syms = (EXTR *) read_seek ((Size_t) orig_sym_hdr.iextMax * sizeof (EXTR),
4507 orig_sym_hdr.cbExtOffset,
4508 "External symbols");
4510 if (orig_sym_hdr.idnMax > 0) /* dense numbers */
4512 orig_dense = (DNR *) read_seek ((Size_t) orig_sym_hdr.idnMax * sizeof (DNR),
4513 orig_sym_hdr.cbDnOffset,
4514 "Dense numbers");
4516 add_bytes (&dense_num, (char *) orig_dense, (Size_t) orig_sym_hdr.idnMax);
4519 if (orig_sym_hdr.ioptMax > 0) /* opt symbols */
4520 orig_opt_syms = (OPTR *) read_seek ((Size_t) orig_sym_hdr.ioptMax * sizeof (OPTR),
4521 orig_sym_hdr.cbOptOffset,
4522 "Optimizer symbols");
4526 /* Abort if the symbol table is not last. */
4527 if (max_file_offset != (unsigned long) stat_buf.st_size)
4528 fatal ("symbol table is not last (symbol table ends at %ld, .o ends at %ld",
4529 max_file_offset,
4530 (long) stat_buf.st_size);
4533 /* If the first original file descriptor is a dummy which the assembler
4534 put out, but there are no symbols in it, skip it now. */
4535 if (orig_sym_hdr.ifdMax > 1
4536 && orig_files->csym == 2
4537 && orig_files->caux == 0)
4539 char *filename = orig_local_strs + (orig_files->issBase + orig_files->rss);
4540 char *suffix = strrchr (filename, '.');
4542 if (suffix != (char *) 0 && strcmp (suffix, ".s") == 0)
4543 delete_ifd = 1;
4547 /* Create array to map original file numbers to the new file numbers
4548 (in case there are duplicate filenames, we collapse them into one
4549 file section, the MIPS assembler may or may not collapse them). */
4551 remap_file_number = (int *) alloca (sizeof (int) * orig_sym_hdr.ifdMax);
4553 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
4555 FDR *fd_ptr = ORIG_FILES (fd);
4556 char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
4558 /* file support itself. */
4559 add_file (filename, filename + strlen (filename));
4560 remap_file_number[fd] = cur_file_ptr->file_index;
4563 if (delete_ifd > 0) /* just in case */
4564 remap_file_number[0] = remap_file_number[1];
4567 /* Loop, adding each of the external symbols. These must be in
4568 order or otherwise we would have to change the relocation
4569 entries. We don't just call add_bytes, because we need to have
4570 the names put into the external hash table. We set the type to
4571 'void' for now, and parse_def will fill in the correct type if it
4572 is in the symbol table. We must add the external symbols before
4573 the locals, since the locals do lookups against the externals. */
4575 if (debug)
4576 fprintf (stderr, "\tehash\n");
4578 for (es = 0; es < orig_sym_hdr.iextMax; es++)
4580 EXTR *eptr = orig_ext_syms + es;
4581 int ifd = eptr->ifd;
4583 (void) add_ext_symbol (eptr, ((long) ifd < orig_sym_hdr.ifdMax)
4584 ? remap_file_number[ ifd ] : ifd );
4588 /* For each of the files in the object file, copy the symbols, and such
4589 into the varrays for the new object file. */
4591 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
4593 FDR *fd_ptr = ORIG_FILES (fd);
4594 char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
4595 SYMR *sym_start;
4596 SYMR *sym;
4597 SYMR *sym_end_p1;
4598 PDR *proc_start;
4599 PDR *proc;
4600 PDR *proc_end_p1;
4602 /* file support itself. */
4603 add_file (filename, filename + strlen (filename));
4604 cur_file_ptr->orig_fdr = fd_ptr;
4606 /* Copy stuff that's just passed through (such as line #'s) */
4607 cur_file_ptr->fdr.adr = fd_ptr->adr;
4608 cur_file_ptr->fdr.ilineBase = fd_ptr->ilineBase;
4609 cur_file_ptr->fdr.cline = fd_ptr->cline;
4610 cur_file_ptr->fdr.rfdBase = fd_ptr->rfdBase;
4611 cur_file_ptr->fdr.crfd = fd_ptr->crfd;
4612 cur_file_ptr->fdr.cbLineOffset = fd_ptr->cbLineOffset;
4613 cur_file_ptr->fdr.cbLine = fd_ptr->cbLine;
4614 cur_file_ptr->fdr.fMerge = fd_ptr->fMerge;
4615 cur_file_ptr->fdr.fReadin = fd_ptr->fReadin;
4616 cur_file_ptr->fdr.glevel = fd_ptr->glevel;
4618 if (debug)
4619 fprintf (stderr, "\thash\tstart, filename %s\n", filename);
4621 /* For each of the static and global symbols defined, add them
4622 to the hash table of original symbols, so we can look up
4623 their values. */
4625 sym_start = ORIG_LSYMS (fd_ptr->isymBase);
4626 sym_end_p1 = sym_start + fd_ptr->csym;
4627 for (sym = sym_start; sym < sym_end_p1; sym++)
4629 switch ((st_t) sym->st)
4631 default:
4632 break;
4634 case st_Global:
4635 case st_Static:
4636 case st_Label:
4637 case st_Proc:
4638 case st_StaticProc:
4640 auto symint_t hash_index;
4641 char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
4642 Size_t len = strlen (str);
4643 shash_t *shash_ptr = hash_string (str,
4644 (Ptrdiff_t) len,
4645 &orig_str_hash[0],
4646 &hash_index);
4648 if (shash_ptr != (shash_t *) 0)
4649 error ("internal error, %s is already in original symbol table", str);
4651 else
4653 shash_ptr = allocate_shash ();
4654 shash_ptr->next = orig_str_hash[hash_index];
4655 orig_str_hash[hash_index] = shash_ptr;
4657 shash_ptr->len = len;
4658 shash_ptr->indx = indexNil;
4659 shash_ptr->string = str;
4660 shash_ptr->sym_ptr = sym;
4663 break;
4665 case st_End:
4666 if ((sc_t) sym->sc == sc_Text)
4668 char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
4670 if (*str != '\0')
4672 Size_t len = strlen (str);
4673 shash_t *shash_ptr = hash_string (str,
4674 (Ptrdiff_t) len,
4675 &orig_str_hash[0],
4676 (symint_t *) 0);
4678 if (shash_ptr != (shash_t *) 0)
4679 shash_ptr->end_ptr = sym;
4682 break;
4687 if (debug)
4689 fprintf (stderr, "\thash\tdone, filename %s\n", filename);
4690 fprintf (stderr, "\tproc\tstart, filename %s\n", filename);
4693 /* Go through each of the procedures in this file, and add the
4694 procedure pointer to the hash entry for the given name. */
4696 proc_start = ORIG_PROCS (fd_ptr->ipdFirst);
4697 proc_end_p1 = proc_start + fd_ptr->cpd;
4698 for (proc = proc_start; proc < proc_end_p1; proc++)
4700 SYMR *proc_sym = ORIG_LSYMS (fd_ptr->isymBase + proc->isym);
4701 char *str = ORIG_LSTRS (fd_ptr->issBase + proc_sym->iss);
4702 Size_t len = strlen (str);
4703 shash_t *shash_ptr = hash_string (str,
4704 (Ptrdiff_t) len,
4705 &orig_str_hash[0],
4706 (symint_t *) 0);
4708 if (shash_ptr == (shash_t *) 0)
4709 error ("internal error, function %s is not in original symbol table", str);
4711 else
4712 shash_ptr->proc_ptr = proc;
4715 if (debug)
4716 fprintf (stderr, "\tproc\tdone, filename %s\n", filename);
4719 cur_file_ptr = first_file;
4722 /* Copy all of the object file up to the symbol table. Originally
4723 we were going to use ftruncate, but that doesn't seem to work
4724 on Ultrix 3.1.... */
4726 if (fseek (obj_in_stream, (long) 0, SEEK_SET) != 0)
4727 pfatal_with_name (obj_in_name);
4729 if (fseek (object_stream, (long) 0, SEEK_SET) != 0)
4730 pfatal_with_name (object_name);
4732 for (remaining = orig_file_header.f_symptr;
4733 remaining > 0;
4734 remaining -= num_write)
4736 num_write
4737 = (remaining <= (int) sizeof (buffer))
4738 ? remaining : (int) sizeof (buffer);
4739 sys_read = fread ((PTR) buffer, 1, num_write, obj_in_stream);
4740 if (sys_read <= 0)
4741 pfatal_with_name (obj_in_name);
4743 else if (sys_read != num_write)
4744 fatal ("wanted to read %d bytes from %s, system returned %d",
4745 num_write,
4746 obj_in_name,
4747 sys_read);
4749 sys_write = fwrite (buffer, 1, num_write, object_stream);
4750 if (sys_write <= 0)
4751 pfatal_with_name (object_name);
4753 else if (sys_write != num_write)
4754 fatal ("wrote %d bytes to %s, system returned %d",
4755 num_write,
4756 object_name,
4757 sys_write);
4762 /* Ye olde main program. */
4764 extern int main PARAMS ((int, char **));
4767 main (argc, argv)
4768 int argc;
4769 char **argv;
4771 int iflag = 0;
4772 char *p = strrchr (argv[0], '/');
4773 char *num_end;
4774 int option;
4775 int i;
4777 progname = (p != 0) ? p+1 : argv[0];
4779 (void) signal (SIGSEGV, catch_signal);
4780 (void) signal (SIGBUS, catch_signal);
4781 (void) signal (SIGABRT, catch_signal);
4783 #if !defined(__SABER__) && !defined(lint)
4784 if (sizeof (efdr_t) > PAGE_USIZE)
4785 fatal ("efdr_t has a sizeof %d bytes, when it should be less than %d",
4786 (int) sizeof (efdr_t),
4787 (int) PAGE_USIZE);
4789 if (sizeof (page_t) != PAGE_USIZE)
4790 fatal ("page_t has a sizeof %d bytes, when it should be %d",
4791 (int) sizeof (page_t),
4792 (int) PAGE_USIZE);
4794 #endif
4796 alloc_counts[ alloc_type_none ].alloc_name = "none";
4797 alloc_counts[ alloc_type_scope ].alloc_name = "scope";
4798 alloc_counts[ alloc_type_vlinks ].alloc_name = "vlinks";
4799 alloc_counts[ alloc_type_shash ].alloc_name = "shash";
4800 alloc_counts[ alloc_type_thash ].alloc_name = "thash";
4801 alloc_counts[ alloc_type_tag ].alloc_name = "tag";
4802 alloc_counts[ alloc_type_forward ].alloc_name = "forward";
4803 alloc_counts[ alloc_type_thead ].alloc_name = "thead";
4804 alloc_counts[ alloc_type_varray ].alloc_name = "varray";
4806 int_type_info = type_info_init;
4807 int_type_info.basic_type = bt_Int;
4809 void_type_info = type_info_init;
4810 void_type_info.basic_type = bt_Void;
4812 while ((option = getopt (argc, argv, "d:i:I:o:v")) != EOF)
4813 switch (option)
4815 default:
4816 had_errors++;
4817 break;
4819 case 'd':
4820 debug = strtol (optarg, &num_end, 0);
4821 if ((unsigned) debug > 4 || num_end == optarg)
4822 had_errors++;
4824 break;
4826 case 'I':
4827 if (rename_output || obj_in_name != (char *) 0)
4828 had_errors++;
4829 else
4830 rename_output = 1;
4832 /* fall through to 'i' case. */
4834 case 'i':
4835 if (obj_in_name == (char *) 0)
4837 obj_in_name = optarg;
4838 iflag++;
4840 else
4841 had_errors++;
4842 break;
4844 case 'o':
4845 if (object_name == (char *) 0)
4846 object_name = optarg;
4847 else
4848 had_errors++;
4849 break;
4851 case 'v':
4852 version++;
4853 break;
4856 if (obj_in_name == (char *) 0 && optind <= argc - 2)
4857 obj_in_name = argv[--argc];
4859 if (object_name == (char *) 0 && optind <= argc - 2)
4860 object_name = argv[--argc];
4862 /* If there is an output name, but no input name use
4863 the same file for both, deleting the name between
4864 opening it for input and opening it for output. */
4865 if (obj_in_name == (char *) 0 && object_name != (char *) 0)
4867 obj_in_name = object_name;
4868 delete_input = 1;
4871 if (object_name == (char *) 0 || had_errors || optind != argc - 1)
4873 fprintf (stderr, _("Calling Sequence:\n"));
4874 fprintf (stderr, _("\tmips-tfile [-d <num>] [-v] [-i <o-in-file>] -o <o-out-file> <s-file> (or)\n"));
4875 fprintf (stderr, _("\tmips-tfile [-d <num>] [-v] [-I <o-in-file>] -o <o-out-file> <s-file> (or)\n"));
4876 fprintf (stderr, _("\tmips-tfile [-d <num>] [-v] <s-file> <o-in-file> <o-out-file>\n"));
4877 fprintf (stderr, "\n");
4878 fprintf (stderr, _("Debug levels are:\n"));
4879 fprintf (stderr, _(" 1\tGeneral debug + trace functions/blocks.\n"));
4880 fprintf (stderr, _(" 2\tDebug level 1 + trace externals.\n"));
4881 fprintf (stderr, _(" 3\tDebug level 2 + trace all symbols.\n"));
4882 fprintf (stderr, _(" 4\tDebug level 3 + trace memory allocations.\n"));
4883 return 1;
4887 if (version)
4889 fprintf (stderr, _("mips-tfile version %s"), version_string);
4890 #ifdef TARGET_VERSION
4891 TARGET_VERSION;
4892 #endif
4893 fputc ('\n', stderr);
4896 if (obj_in_name == (char *) 0)
4897 obj_in_name = object_name;
4899 if (rename_output && rename (object_name, obj_in_name) != 0)
4901 char *buffer = (char *) allocate_multiple_pages (4);
4902 int len;
4903 int len2;
4904 int in_fd;
4905 int out_fd;
4907 /* Rename failed, copy input file */
4908 in_fd = open (object_name, O_RDONLY, 0666);
4909 if (in_fd < 0)
4910 pfatal_with_name (object_name);
4912 out_fd = open (obj_in_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
4913 if (out_fd < 0)
4914 pfatal_with_name (obj_in_name);
4916 while ((len = read (in_fd, buffer, 4*PAGE_SIZE)) > 0)
4918 len2 = write (out_fd, buffer, len);
4919 if (len2 < 0)
4920 pfatal_with_name (object_name);
4922 if (len != len2)
4923 fatal ("wrote %d bytes to %s, expected to write %d", len2, obj_in_name, len);
4926 free_multiple_pages ((page_t *) buffer, 4);
4928 if (len < 0)
4929 pfatal_with_name (object_name);
4931 if (close (in_fd) < 0)
4932 pfatal_with_name (object_name);
4934 if (close (out_fd) < 0)
4935 pfatal_with_name (obj_in_name);
4938 /* Must open input before output, since the output may be the same file, and
4939 we need to get the input handle before truncating it. */
4940 obj_in_stream = fopen (obj_in_name, "r");
4941 if (obj_in_stream == (FILE *) 0)
4942 pfatal_with_name (obj_in_name);
4944 if (delete_input && unlink (obj_in_name) != 0)
4945 pfatal_with_name (obj_in_name);
4947 object_stream = fopen (object_name, "w");
4948 if (object_stream == (FILE *) 0)
4949 pfatal_with_name (object_name);
4951 if (strcmp (argv[optind], "-") != 0)
4953 input_name = argv[optind];
4954 if (freopen (argv[optind], "r", stdin) != stdin)
4955 pfatal_with_name (argv[optind]);
4958 copy_object (); /* scan & copy object file */
4959 parse_input (); /* scan all of input */
4961 update_headers (); /* write out tfile */
4962 write_object ();
4964 if (debug)
4966 fprintf (stderr, "\n\tAllocation summary:\n\n");
4967 for (i = (int) alloc_type_none; i < (int) alloc_type_last; i++)
4968 if (alloc_counts[i].total_alloc)
4970 fprintf (stderr,
4971 "\t%s\t%5d allocation(s), %5d free(s), %2d page(s)\n",
4972 alloc_counts[i].alloc_name,
4973 alloc_counts[i].total_alloc,
4974 alloc_counts[i].total_free,
4975 alloc_counts[i].total_pages);
4979 return (had_errors) ? 1 : 0;
4983 /* Catch a signal and exit without dumping core. */
4985 STATIC void
4986 catch_signal (signum)
4987 int signum;
4989 (void) signal (signum, SIG_DFL); /* just in case... */
4990 fatal ("%s", strsignal (signum));
4993 /* Print a fatal error message. NAME is the text.
4994 Also include a system error message based on `errno'. */
4996 void
4997 pfatal_with_name (msg)
4998 const char *msg;
5000 int save_errno = errno; /* just in case.... */
5001 if (line_number > 0)
5002 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5003 else
5004 fprintf (stderr, "%s:", progname);
5006 errno = save_errno;
5007 if (errno == 0)
5008 fprintf (stderr, "[errno = 0] %s\n", msg);
5009 else
5010 perror (msg);
5012 exit (1);
5016 /* Procedure to abort with an out of bounds error message. It has
5017 type int, so it can be used with an ?: expression within the
5018 ORIG_xxx macros, but the function never returns. */
5020 static int
5021 out_of_bounds (indx, max, str, prog_line)
5022 symint_t indx; /* index that is out of bounds */
5023 symint_t max; /* maximum index */
5024 const char *str; /* string to print out */
5025 int prog_line; /* line number within mips-tfile.c */
5027 if (indx < max) /* just in case */
5028 return 0;
5030 fprintf (stderr, "%s, %s:%ld index %lu is out of bounds for %s, max is %lu, mips-tfile.c line# %d\n",
5031 progname, input_name, line_number, indx, str, max, prog_line);
5033 exit (1);
5034 return 0; /* turn off warning messages */
5038 /* Allocate a cluster of pages. USE_MALLOC says that malloc does not
5039 like sbrk's behind its back (or sbrk isn't available). If we use
5040 sbrk, we assume it gives us zeroed pages. */
5042 #ifndef MALLOC_CHECK
5043 #ifdef USE_MALLOC
5045 STATIC page_t *
5046 allocate_cluster (npages)
5047 Size_t npages;
5049 page_t *value = (page_t *) xcalloc (npages, PAGE_USIZE);
5051 if (debug > 3)
5052 fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
5054 return value;
5057 #else /* USE_MALLOC */
5059 STATIC page_t *
5060 allocate_cluster (npages)
5061 Size_t npages;
5063 page_t *ptr = (page_t *) sbrk (0); /* current sbreak */
5064 unsigned long offset = ((unsigned long) ptr) & (PAGE_SIZE - 1);
5066 if (offset != 0) /* align to a page boundary */
5068 if (sbrk (PAGE_USIZE - offset) == (char *)-1)
5069 pfatal_with_name ("allocate_cluster");
5071 ptr = (page_t *) (((char *) ptr) + PAGE_SIZE - offset);
5074 if (sbrk (npages * PAGE_USIZE) == (char *) -1)
5075 pfatal_with_name ("allocate_cluster");
5077 if (debug > 3)
5079 fprintf (stderr, "\talloc\tnpages = %lu, value = ",
5080 (unsigned long) npages);
5081 fprintf (stderr, HOST_PTR_PRINTF, (PTR) ptr);
5082 fputs ("\n", stderr);
5085 return ptr;
5088 #endif /* USE_MALLOC */
5091 static page_t *cluster_ptr = NULL;
5092 static unsigned pages_left = 0;
5094 #endif /* MALLOC_CHECK */
5097 /* Allocate some pages (which is initialized to 0). */
5099 STATIC page_t *
5100 allocate_multiple_pages (npages)
5101 Size_t npages;
5103 #ifndef MALLOC_CHECK
5104 if (pages_left == 0 && npages < MAX_CLUSTER_PAGES)
5106 pages_left = MAX_CLUSTER_PAGES;
5107 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
5110 if (npages <= pages_left)
5112 page_t *ptr = cluster_ptr;
5113 cluster_ptr += npages;
5114 pages_left -= npages;
5115 return ptr;
5118 return allocate_cluster (npages);
5120 #else /* MALLOC_CHECK */
5121 return (page_t *) xcalloc (npages, PAGE_SIZE);
5123 #endif /* MALLOC_CHECK */
5127 /* Release some pages. */
5129 STATIC void
5130 free_multiple_pages (page_ptr, npages)
5131 page_t *page_ptr;
5132 Size_t npages;
5134 #ifndef MALLOC_CHECK
5135 if (pages_left == 0)
5137 cluster_ptr = page_ptr;
5138 pages_left = npages;
5141 else if ((page_ptr + npages) == cluster_ptr)
5143 cluster_ptr -= npages;
5144 pages_left += npages;
5147 /* otherwise the page is not freed. If more than call is
5148 done, we probably should worry about it, but at present,
5149 the free pages is done right after an allocate. */
5151 #else /* MALLOC_CHECK */
5152 free ((char *) page_ptr);
5154 #endif /* MALLOC_CHECK */
5158 /* Allocate one page (which is initialized to 0). */
5160 STATIC page_t *
5161 allocate_page ()
5163 #ifndef MALLOC_CHECK
5164 if (pages_left == 0)
5166 pages_left = MAX_CLUSTER_PAGES;
5167 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
5170 pages_left--;
5171 return cluster_ptr++;
5173 #else /* MALLOC_CHECK */
5174 return (page_t *) xcalloc (1, PAGE_SIZE);
5176 #endif /* MALLOC_CHECK */
5180 /* Allocate scoping information. */
5182 STATIC scope_t *
5183 allocate_scope ()
5185 scope_t *ptr;
5186 static scope_t initial_scope;
5188 #ifndef MALLOC_CHECK
5189 ptr = alloc_counts[ (int) alloc_type_scope ].free_list.f_scope;
5190 if (ptr != (scope_t *) 0)
5191 alloc_counts[ (int) alloc_type_scope ].free_list.f_scope = ptr->free;
5193 else
5195 int unallocated = alloc_counts[ (int) alloc_type_scope ].unallocated;
5196 page_t *cur_page = alloc_counts[ (int) alloc_type_scope ].cur_page;
5198 if (unallocated == 0)
5200 unallocated = PAGE_SIZE / sizeof (scope_t);
5201 alloc_counts[ (int) alloc_type_scope ].cur_page = cur_page = allocate_page ();
5202 alloc_counts[ (int) alloc_type_scope ].total_pages++;
5205 ptr = &cur_page->scope[ --unallocated ];
5206 alloc_counts[ (int) alloc_type_scope ].unallocated = unallocated;
5209 #else
5210 ptr = (scope_t *) xmalloc (sizeof (scope_t));
5212 #endif
5214 alloc_counts[ (int) alloc_type_scope ].total_alloc++;
5215 *ptr = initial_scope;
5216 return ptr;
5219 /* Free scoping information. */
5221 STATIC void
5222 free_scope (ptr)
5223 scope_t *ptr;
5225 alloc_counts[ (int) alloc_type_scope ].total_free++;
5227 #ifndef MALLOC_CHECK
5228 ptr->free = alloc_counts[ (int) alloc_type_scope ].free_list.f_scope;
5229 alloc_counts[ (int) alloc_type_scope ].free_list.f_scope = ptr;
5231 #else
5232 free ((PTR) ptr);
5233 #endif
5238 /* Allocate links for pages in a virtual array. */
5240 STATIC vlinks_t *
5241 allocate_vlinks ()
5243 vlinks_t *ptr;
5244 static vlinks_t initial_vlinks;
5246 #ifndef MALLOC_CHECK
5247 int unallocated = alloc_counts[ (int) alloc_type_vlinks ].unallocated;
5248 page_t *cur_page = alloc_counts[ (int) alloc_type_vlinks ].cur_page;
5250 if (unallocated == 0)
5252 unallocated = PAGE_SIZE / sizeof (vlinks_t);
5253 alloc_counts[ (int) alloc_type_vlinks ].cur_page = cur_page = allocate_page ();
5254 alloc_counts[ (int) alloc_type_vlinks ].total_pages++;
5257 ptr = &cur_page->vlinks[ --unallocated ];
5258 alloc_counts[ (int) alloc_type_vlinks ].unallocated = unallocated;
5260 #else
5261 ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
5263 #endif
5265 alloc_counts[ (int) alloc_type_vlinks ].total_alloc++;
5266 *ptr = initial_vlinks;
5267 return ptr;
5271 /* Allocate string hash buckets. */
5273 STATIC shash_t *
5274 allocate_shash ()
5276 shash_t *ptr;
5277 static shash_t initial_shash;
5279 #ifndef MALLOC_CHECK
5280 int unallocated = alloc_counts[ (int) alloc_type_shash ].unallocated;
5281 page_t *cur_page = alloc_counts[ (int) alloc_type_shash ].cur_page;
5283 if (unallocated == 0)
5285 unallocated = PAGE_SIZE / sizeof (shash_t);
5286 alloc_counts[ (int) alloc_type_shash ].cur_page = cur_page = allocate_page ();
5287 alloc_counts[ (int) alloc_type_shash ].total_pages++;
5290 ptr = &cur_page->shash[ --unallocated ];
5291 alloc_counts[ (int) alloc_type_shash ].unallocated = unallocated;
5293 #else
5294 ptr = (shash_t *) xmalloc (sizeof (shash_t));
5296 #endif
5298 alloc_counts[ (int) alloc_type_shash ].total_alloc++;
5299 *ptr = initial_shash;
5300 return ptr;
5304 /* Allocate type hash buckets. */
5306 STATIC thash_t *
5307 allocate_thash ()
5309 thash_t *ptr;
5310 static thash_t initial_thash;
5312 #ifndef MALLOC_CHECK
5313 int unallocated = alloc_counts[ (int) alloc_type_thash ].unallocated;
5314 page_t *cur_page = alloc_counts[ (int) alloc_type_thash ].cur_page;
5316 if (unallocated == 0)
5318 unallocated = PAGE_SIZE / sizeof (thash_t);
5319 alloc_counts[ (int) alloc_type_thash ].cur_page = cur_page = allocate_page ();
5320 alloc_counts[ (int) alloc_type_thash ].total_pages++;
5323 ptr = &cur_page->thash[ --unallocated ];
5324 alloc_counts[ (int) alloc_type_thash ].unallocated = unallocated;
5326 #else
5327 ptr = (thash_t *) xmalloc (sizeof (thash_t));
5329 #endif
5331 alloc_counts[ (int) alloc_type_thash ].total_alloc++;
5332 *ptr = initial_thash;
5333 return ptr;
5337 /* Allocate structure, union, or enum tag information. */
5339 STATIC tag_t *
5340 allocate_tag ()
5342 tag_t *ptr;
5343 static tag_t initial_tag;
5345 #ifndef MALLOC_CHECK
5346 ptr = alloc_counts[ (int) alloc_type_tag ].free_list.f_tag;
5347 if (ptr != (tag_t *) 0)
5348 alloc_counts[ (int) alloc_type_tag ].free_list.f_tag = ptr->free;
5350 else
5352 int unallocated = alloc_counts[ (int) alloc_type_tag ].unallocated;
5353 page_t *cur_page = alloc_counts[ (int) alloc_type_tag ].cur_page;
5355 if (unallocated == 0)
5357 unallocated = PAGE_SIZE / sizeof (tag_t);
5358 alloc_counts[ (int) alloc_type_tag ].cur_page = cur_page = allocate_page ();
5359 alloc_counts[ (int) alloc_type_tag ].total_pages++;
5362 ptr = &cur_page->tag[ --unallocated ];
5363 alloc_counts[ (int) alloc_type_tag ].unallocated = unallocated;
5366 #else
5367 ptr = (tag_t *) xmalloc (sizeof (tag_t));
5369 #endif
5371 alloc_counts[ (int) alloc_type_tag ].total_alloc++;
5372 *ptr = initial_tag;
5373 return ptr;
5376 /* Free scoping information. */
5378 STATIC void
5379 free_tag (ptr)
5380 tag_t *ptr;
5382 alloc_counts[ (int) alloc_type_tag ].total_free++;
5384 #ifndef MALLOC_CHECK
5385 ptr->free = alloc_counts[ (int) alloc_type_tag ].free_list.f_tag;
5386 alloc_counts[ (int) alloc_type_tag ].free_list.f_tag = ptr;
5388 #else
5389 free ((PTR) ptr);
5390 #endif
5395 /* Allocate forward reference to a yet unknown tag. */
5397 STATIC forward_t *
5398 allocate_forward ()
5400 forward_t *ptr;
5401 static forward_t initial_forward;
5403 #ifndef MALLOC_CHECK
5404 ptr = alloc_counts[ (int) alloc_type_forward ].free_list.f_forward;
5405 if (ptr != (forward_t *) 0)
5406 alloc_counts[ (int) alloc_type_forward ].free_list.f_forward = ptr->free;
5408 else
5410 int unallocated = alloc_counts[ (int) alloc_type_forward ].unallocated;
5411 page_t *cur_page = alloc_counts[ (int) alloc_type_forward ].cur_page;
5413 if (unallocated == 0)
5415 unallocated = PAGE_SIZE / sizeof (forward_t);
5416 alloc_counts[ (int) alloc_type_forward ].cur_page = cur_page = allocate_page ();
5417 alloc_counts[ (int) alloc_type_forward ].total_pages++;
5420 ptr = &cur_page->forward[ --unallocated ];
5421 alloc_counts[ (int) alloc_type_forward ].unallocated = unallocated;
5424 #else
5425 ptr = (forward_t *) xmalloc (sizeof (forward_t));
5427 #endif
5429 alloc_counts[ (int) alloc_type_forward ].total_alloc++;
5430 *ptr = initial_forward;
5431 return ptr;
5434 /* Free scoping information. */
5436 STATIC void
5437 free_forward (ptr)
5438 forward_t *ptr;
5440 alloc_counts[ (int) alloc_type_forward ].total_free++;
5442 #ifndef MALLOC_CHECK
5443 ptr->free = alloc_counts[ (int) alloc_type_forward ].free_list.f_forward;
5444 alloc_counts[ (int) alloc_type_forward ].free_list.f_forward = ptr;
5446 #else
5447 free ((PTR) ptr);
5448 #endif
5453 /* Allocate head of type hash list. */
5455 STATIC thead_t *
5456 allocate_thead ()
5458 thead_t *ptr;
5459 static thead_t initial_thead;
5461 #ifndef MALLOC_CHECK
5462 ptr = alloc_counts[ (int) alloc_type_thead ].free_list.f_thead;
5463 if (ptr != (thead_t *) 0)
5464 alloc_counts[ (int) alloc_type_thead ].free_list.f_thead = ptr->free;
5466 else
5468 int unallocated = alloc_counts[ (int) alloc_type_thead ].unallocated;
5469 page_t *cur_page = alloc_counts[ (int) alloc_type_thead ].cur_page;
5471 if (unallocated == 0)
5473 unallocated = PAGE_SIZE / sizeof (thead_t);
5474 alloc_counts[ (int) alloc_type_thead ].cur_page = cur_page = allocate_page ();
5475 alloc_counts[ (int) alloc_type_thead ].total_pages++;
5478 ptr = &cur_page->thead[ --unallocated ];
5479 alloc_counts[ (int) alloc_type_thead ].unallocated = unallocated;
5482 #else
5483 ptr = (thead_t *) xmalloc (sizeof (thead_t));
5485 #endif
5487 alloc_counts[ (int) alloc_type_thead ].total_alloc++;
5488 *ptr = initial_thead;
5489 return ptr;
5492 /* Free scoping information. */
5494 STATIC void
5495 free_thead (ptr)
5496 thead_t *ptr;
5498 alloc_counts[ (int) alloc_type_thead ].total_free++;
5500 #ifndef MALLOC_CHECK
5501 ptr->free = (thead_t *) alloc_counts[ (int) alloc_type_thead ].free_list.f_thead;
5502 alloc_counts[ (int) alloc_type_thead ].free_list.f_thead = ptr;
5504 #else
5505 free ((PTR) ptr);
5506 #endif
5510 #endif /* MIPS_DEBUGGING_INFO */
5513 /* Output an error message and exit */
5515 /*VARARGS*/
5516 void
5517 fatal VPARAMS ((const char *format, ...))
5519 VA_OPEN (ap, format);
5520 VA_FIXEDARG (ap, const char *, format);
5522 if (line_number > 0)
5523 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5524 else
5525 fprintf (stderr, "%s:", progname);
5527 vfprintf (stderr, format, ap);
5528 VA_CLOSE (ap);
5529 fprintf (stderr, "\n");
5530 if (line_number > 0)
5531 fprintf (stderr, "line:\t%s\n", cur_line_start);
5533 saber_stop ();
5534 exit (1);
5537 /*VARARGS*/
5538 void
5539 error VPARAMS ((const char *format, ...))
5541 VA_OPEN (ap, format);
5542 VA_FIXEDARG (ap, char *, format);
5544 if (line_number > 0)
5545 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5546 else
5547 fprintf (stderr, "%s:", progname);
5549 vfprintf (stderr, format, ap);
5550 fprintf (stderr, "\n");
5551 if (line_number > 0)
5552 fprintf (stderr, "line:\t%s\n", cur_line_start);
5554 had_errors++;
5555 VA_CLOSE (ap);
5557 saber_stop ();
5560 /* More 'friendly' abort that prints the line and file.
5561 config.h can #define abort fancy_abort if you like that sort of thing. */
5563 void
5564 fancy_abort ()
5566 fatal ("internal abort");
5570 /* When `malloc.c' is compiled with `rcheck' defined,
5571 it calls this function to report clobberage. */
5573 void
5574 botch (s)
5575 const char *s;
5577 fatal ("%s", s);