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 Contributed by: Michael Meissner, meissner@osf.org
6 Copyright (C) 1991, 1993 Free Software Foundation, Inc.
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 /* Here is a brief description of the MIPS ECOFF symbol table. The
26 MIPS symbol table has the following pieces:
32 +-- Dense number table
40 +-- Relative file descriptors
52 The symbolic header points to each of the other tables, and also
53 contains the number of entries. It also contains a magic number
54 and MIPS compiler version number, such as 2.0.
56 The auxiliary table is a series of 32 bit integers, that are
57 referenced as needed from the local symbol table. Unlike standard
58 COFF, the aux. information does not follow the symbol that uses
59 it, but rather is a separate table. In theory, this would allow
60 the MIPS compilers to collapse duplicate aux. entries, but I've not
61 noticed this happening with the 1.31 compiler suite. The different
62 types of aux. entries are:
64 1) dnLow: Low bound on array dimension.
66 2) dnHigh: High bound on array dimension.
68 3) isym: Index to the local symbol which is the start of the
69 function for the end of function first aux. entry.
71 4) width: Width of structures and bitfields.
73 5) count: Count of ranges for variant part.
75 6) rndx: A relative index into the symbol table. The relative
76 index field has two parts: rfd which is a pointer into the
77 relative file index table or ST_RFDESCAPE which says the next
78 aux. entry is the file number, and index: which is the pointer
79 into the local symbol within a given file table. This is for
80 things like references to types defined in another file.
82 7) Type information: This is like the COFF type bits, except it
83 is 32 bits instead of 16; they still have room to add new
84 basic types; and they can handle more than 6 levels of array,
85 pointer, function, etc. Each type information field contains
86 the following structure members:
88 a) fBitfield: a bit that says this is a bitfield, and the
89 size in bits follows as the next aux. entry.
91 b) continued: a bit that says the next aux. entry is a
92 continuation of the current type information (in case
93 there are more than 6 levels of array/ptr/function).
95 c) bt: an integer containing the base type before adding
96 array, pointer, function, etc. qualifiers. The
97 current base types that I have documentation for are:
100 btAdr -- address - integer same size as ptr
102 btUChar -- unsigned character
104 btUShort -- unsigned short
106 btUInt -- unsigned int
108 btULong -- unsigned long
109 btFloat -- float (real)
110 btDouble -- Double (real)
111 btStruct -- Structure (Record)
112 btUnion -- Union (variant)
114 btTypedef -- defined via a typedef isymRef
115 btRange -- subrange of int
117 btComplex -- fortran complex
118 btDComplex -- fortran double complex
119 btIndirect -- forward or unnamed typedef
120 btFixedDec -- Fixed Decimal
121 btFloatDec -- Float Decimal
122 btString -- Varying Length Character String
123 btBit -- Aligned Bit String
125 btVoid -- Void (MIPS cc revision >= 2.00)
127 d) tq0 - tq5: type qualifier fields as needed. The
128 current type qualifier fields I have documentation for
131 tqNil -- no more qualifiers
135 tqFar -- 8086 far pointers
139 The dense number table is used in the front ends, and disappears by
140 the time the .o is created.
142 With the 1.31 compiler suite, the optimization symbols don't seem
143 to be used as far as I can tell.
145 The linker is the first entity that creates the relative file
146 descriptor table, and I believe it is used so that the individual
147 file table pointers don't have to be rewritten when the objects are
148 merged together into the program file.
150 Unlike COFF, the basic symbol & string tables are split into
151 external and local symbols/strings. The relocation information
152 only goes off of the external symbol table, and the debug
153 information only goes off of the internal symbol table. The
154 external symbols can have links to an appropriate file index and
155 symbol within the file to give it the appropriate type information.
156 Because of this, the external symbols are actually larger than the
157 internal symbols (to contain the link information), and contain the
158 local symbol structure as a member, though this member is not the
159 first member of the external symbol structure (!). I suspect this
160 split is to make strip easier to deal with.
162 Each file table has offsets for where the line numbers, local
163 strings, local symbols, and procedure table starts from within the
164 global tables, and the indexs are reset to 0 for each of those
167 The procedure table contains the binary equivalents of the .ent
168 (start of the function address), .frame (what register is the
169 virtual frame pointer, constant offset from the register to obtain
170 the VFP, and what register holds the return address), .mask/.fmask
171 (bitmask of saved registers, and where the first register is stored
172 relative to the VFP) assembler directives. It also contains the
173 low and high bounds of the line numbers if debugging is turned on.
175 The line number table is a compressed form of the normal COFF line
176 table. Each line number entry is either 1 or 3 bytes long, and
177 contains a signed delta from the previous line, and an unsigned
178 count of the number of instructions this statement takes.
180 The local symbol table contains the following fields:
182 1) iss: index to the local string table giving the name of the
185 2) value: value of the symbol (address, register number, etc.).
187 3) st: symbol type. The current symbol types are:
189 stNil -- Nuthin' special
190 stGlobal -- external symbol
192 stParam -- procedure argument
193 stLocal -- local variable
195 stProc -- External Procedure
196 stBlock -- beginning of block
197 stEnd -- end (of anything)
198 stMember -- member (of anything)
199 stTypedef -- type definition
201 stRegReloc -- register relocation
202 stForward -- forwarding address
203 stStaticProc -- Static procedure
206 4) sc: storage class. The current storage classes are:
208 scText -- text symbol
209 scData -- initialized data symbol
210 scBss -- un-initialized data symbol
211 scRegister -- value of symbol is register number
212 scAbs -- value of symbol is absolute
213 scUndefined -- who knows?
214 scCdbLocal -- variable's value is IN se->va.??
215 scBits -- this is a bit field
216 scCdbSystem -- value is IN debugger's address space
217 scRegImage -- register value saved on stack
218 scInfo -- symbol contains debugger information
219 scUserStruct -- addr in struct user for current process
220 scSData -- load time only small data
221 scSBss -- load time only small common
222 scRData -- load time only read only data
223 scVar -- Var parameter (fortranpascal)
224 scCommon -- common variable
225 scSCommon -- small common
226 scVarRegister -- Var parameter in a register
227 scVariant -- Variant record
228 scSUndefined -- small undefined(external) data
229 scInit -- .init section symbol
231 5) index: pointer to a local symbol or aux. entry.
235 For the following program:
240 printf("Hello World!\n");
244 Mips-tdump produces the following information:
249 timestamp 645311799, Wed Jun 13 17:16:39 1990
250 symbolic header offset 284
251 symbolic header size 96
255 Symbolic header, magic number = 0x7009, vstamp = 1.31:
257 Info Offset Number Bytes
258 ==== ====== ====== =====
260 Line numbers 380 4 4 [13]
262 Procedures Tables 384 1 52
263 Local Symbols 436 16 192
264 Optimization Symbols 0 0 0
265 Auxiliary Symbols 628 39 156
266 Local Strings 784 80 80
267 External Strings 864 144 144
268 File Tables 1008 2 144
270 External Symbols 1152 20 320
274 Name index = 1 Readin = No
275 Merge = No Endian = LITTLE
276 Debug level = G2 Language = C
279 Info Start Number Size Offset
280 ==== ===== ====== ==== ======
281 Local strings 0 15 15 784
282 Local symbols 0 6 72 436
283 Line numbers 0 13 13 380
284 Optimization symbols 0 0 0 0
285 Procedures 0 1 52 384
286 Auxiliary symbols 0 14 56 628
287 Relative Files 0 0 0 0
289 There are 6 local symbols, starting at 436
291 Symbol# 0: "hello2.c"
294 Storage class = Text Index = 6
295 Symbol type = File Value = 0
301 Storage class = Text Index = 12
302 Symbol type = Proc Value = 0
307 Storage class = Text Index = 4
308 Symbol type = Block Value = 8
313 Storage class = Text Index = 2
314 Symbol type = End Value = 28
319 Storage class = Text Index = 1
320 Symbol type = End Value = 52
322 Symbol# 5: "hello2.c"
325 Storage class = Text Index = 0
326 Symbol type = End Value = 0
328 There are 14 auxiliary table entries, starting at 628.
330 * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
331 * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
332 * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0]
333 * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0]
334 * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
335 * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0]
336 * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0]
337 * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0]
338 * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0]
339 * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0]
340 * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0]
341 * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0]
342 #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0]
343 #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
345 There are 1 procedure descriptor entries, starting at 0.
347 Procedure descriptor 0:
348 Name index = 10 Name = "main"
349 .mask 0x80000000,-4 .fmask 0x00000000,0
351 Opt. start = -1 Symbols start = 1
352 First line # = 3 Last line # = 6
353 Line Offset = 0 Address = 0x00000000
355 There are 4 bytes holding line numbers, starting at 380.
356 Line 3, delta 0, count 2
357 Line 4, delta 1, count 3
358 Line 5, delta 1, count 2
359 Line 6, delta 1, count 6
361 File #1, "/usr/include/stdio.h"
363 Name index = 1 Readin = No
364 Merge = Yes Endian = LITTLE
365 Debug level = G2 Language = C
368 Info Start Number Size Offset
369 ==== ===== ====== ==== ======
370 Local strings 15 65 65 799
371 Local symbols 6 10 120 508
372 Line numbers 0 0 0 380
373 Optimization symbols 0 0 0 0
375 Auxiliary symbols 14 25 100 684
376 Relative Files 0 0 0 0
378 There are 10 local symbols, starting at 442
380 Symbol# 0: "/usr/include/stdio.h"
383 Storage class = Text Index = 10
384 Symbol type = File Value = 0
389 Storage class = Info Index = 9
390 Symbol type = Block Value = 20
395 Storage class = Info Index = 4
396 Symbol type = Member Value = 0
401 Storage class = Info Index = 15
402 Symbol type = Member Value = 32
407 Storage class = Info Index = 16
408 Symbol type = Member Value = 64
413 Storage class = Info Index = 4
414 Symbol type = Member Value = 96
419 Storage class = Info Index = 3
420 Symbol type = Member Value = 128
425 Storage class = Info Index = 2
426 Symbol type = Member Value = 144
431 Storage class = Info Index = 1
432 Symbol type = End Value = 0
434 Symbol# 9: "/usr/include/stdio.h"
437 Storage class = Text Index = 0
438 Symbol type = End Value = 0
440 There are 25 auxiliary table entries, starting at 642.
442 * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
443 #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
444 #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
445 * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0]
446 * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1]
447 * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
448 * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4]
449 * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
450 * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
451 * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0]
452 * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0]
453 * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
454 * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
455 * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
456 * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
457 * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
458 * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
459 * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
460 * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
461 * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
462 * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
463 * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
464 * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
465 * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
466 * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
468 There are 0 procedure descriptor entries, starting at 1.
470 There are 20 external symbols, starting at 1152
473 Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
474 String index = 0 Ifd = 1
475 Storage class = Nil Index = 17
476 Symbol type = Global Value = 60
479 String index = 5 Ifd = 1
480 Storage class = Nil Index = 1048575
481 Symbol type = Proc Value = 0
484 String index = 11 Ifd = 1
485 Storage class = Nil Index = 1048575
486 Symbol type = Proc Value = 0
489 String index = 18 Ifd = 1
490 Storage class = Nil Index = 1048575
491 Symbol type = Proc Value = 0
494 String index = 26 Ifd = 1
495 Storage class = Nil Index = 1048575
496 Symbol type = Proc Value = 0
499 String index = 32 Ifd = 1
500 Storage class = Nil Index = 1048575
501 Symbol type = Proc Value = 0
504 String index = 40 Ifd = 1
505 Storage class = Nil Index = 1048575
506 Symbol type = Proc Value = 0
509 String index = 46 Ifd = 1
510 Storage class = Nil Index = 1048575
511 Symbol type = Proc Value = 0
514 String index = 53 Ifd = 1
515 Storage class = Nil Index = 1048575
516 Symbol type = Proc Value = 0
518 Symbol# 9: "setbuffer"
519 String index = 60 Ifd = 1
520 Storage class = Nil Index = 1048575
521 Symbol type = Proc Value = 0
523 Symbol# 10: "setlinebuf"
524 String index = 70 Ifd = 1
525 Storage class = Nil Index = 1048575
526 Symbol type = Proc Value = 0
529 String index = 81 Ifd = 1
530 Storage class = Nil Index = 1048575
531 Symbol type = Proc Value = 0
534 String index = 87 Ifd = 1
535 Storage class = Nil Index = 1048575
536 Symbol type = Proc Value = 0
538 Symbol# 13: "ctermid"
539 String index = 92 Ifd = 1
540 Storage class = Nil Index = 1048575
541 Symbol type = Proc Value = 0
543 Symbol# 14: "cuserid"
544 String index = 100 Ifd = 1
545 Storage class = Nil Index = 1048575
546 Symbol type = Proc Value = 0
548 Symbol# 15: "tempnam"
549 String index = 108 Ifd = 1
550 Storage class = Nil Index = 1048575
551 Symbol type = Proc Value = 0
554 String index = 116 Ifd = 1
555 Storage class = Nil Index = 1048575
556 Symbol type = Proc Value = 0
558 Symbol# 17: "sprintf"
559 String index = 123 Ifd = 1
560 Storage class = Nil Index = 1048575
561 Symbol type = Proc Value = 0
565 String index = 131 Ifd = 0
566 Storage class = Text Index = 1
567 Symbol type = Proc Value = 0
570 String index = 136 Ifd = 0
571 Storage class = Undefined Index = 1048575
572 Symbol type = Proc Value = 0
574 The following auxiliary table entries were unused:
578 #3 16 0x00000010 short
580 #5 32 0x00000020 long
581 #6 40 0x00000028 float
582 #7 44 0x0000002c double
583 #8 12 0x0000000c unsigned char
584 #9 20 0x00000014 unsigned short
585 #10 28 0x0000001c unsigned int
586 #11 36 0x00000024 unsigned long
587 #14 0 0x00000000 void
588 #15 24 0x00000018 int
589 #19 32 0x00000020 long
590 #20 40 0x00000028 float
591 #21 44 0x0000002c double
592 #22 12 0x0000000c unsigned char
593 #23 20 0x00000014 unsigned short
594 #24 28 0x0000001c unsigned int
595 #25 36 0x00000024 unsigned long
596 #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 }
601 #include "gvarargs.h"
615 typedef const void *CPTR_T;
619 #if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */
621 typedef void *CPTR_T;
624 typedef char *PTR_T; /* Ultrix 3.1 */
625 typedef char *CPTR_T;
628 #define __proto(x) ()
632 /* Do to size_t being defined in sys/types.h and different
633 in stddef.h, we have to do this by hand..... Note, these
634 types are correct for MIPS based systems, and may not be
635 correct for other systems. Ultrix 4.0 and Silicon Graphics
636 have this fixed, but since the following is correct, and
637 the fact that including stddef.h gets you GCC's version
638 instead of the standard one it's not worth it to fix it. */
640 #if defined(__OSF1__) || defined(__OSF__) || defined(__osf__)
641 #define Size_t long unsigned int
643 #define Size_t unsigned int
645 #define Ptrdiff_t long
647 /* The following might be called from obstack or malloc,
648 so they can't be static. */
650 extern void pfatal_with_name
652 extern void fancy_abort __proto((void));
653 void botch __proto((const char *));
654 extern PTR_T xmalloc __proto((Size_t));
655 extern PTR_T xcalloc __proto((Size_t, Size_t));
656 extern PTR_T xrealloc __proto((PTR_T, Size_t));
657 extern void xfree __proto((PTR_T));
659 extern void fatal(); /* can't use prototypes here */
663 #ifndef MIPS_DEBUGGING_INFO
665 static int line_number;
666 static int cur_line_start;
668 static int had_errors;
669 static char *progname;
670 static char *input_name;
675 fprintf (stderr, "Mips-tfile should only be run on a MIPS computer!\n");
679 #else /* MIPS_DEBUGGING defined */
681 /* The local and global symbols have a field index, so undo any defines
682 of index -> strchr and rindex -> strrchr. */
687 #include <sys/types.h>
693 #include <sys/stat.h>
695 #ifndef CROSS_COMPILE
698 #include "mips/a.out.h"
699 #endif /* CROSS_COMPILE */
701 #if defined (USG) || defined (NO_STAB_H)
702 #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */
704 #include <stab.h> /* On BSD, use the system's stab.h. */
708 #define STAB_CODE_TYPE enum __stab_debug_code
710 #define STAB_CODE_TYPE int
727 extern int errno; /* MIPS errno.h doesn't declare this */
736 #define IS_ASM_IDENT(ch) \
737 (isalnum (ch) || (ch) == '_' || (ch) == '.' || (ch) == '$')
740 /* Redefinition of of storage classes as an enumeration for better
744 sc_Nil = scNil, /* no storage class */
745 sc_Text = scText, /* text symbol */
746 sc_Data = scData, /* initialized data symbol */
747 sc_Bss = scBss, /* un-initialized data symbol */
748 sc_Register = scRegister, /* value of symbol is register number */
749 sc_Abs = scAbs, /* value of symbol is absolute */
750 sc_Undefined = scUndefined, /* who knows? */
751 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
752 sc_Bits = scBits, /* this is a bit field */
753 sc_CdbSystem = scCdbSystem, /* value is IN CDB's address space */
754 sc_RegImage = scRegImage, /* register value saved on stack */
755 sc_Info = scInfo, /* symbol contains debugger information */
756 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
757 sc_SData = scSData, /* load time only small data */
758 sc_SBss = scSBss, /* load time only small common */
759 sc_RData = scRData, /* load time only read only data */
760 sc_Var = scVar, /* Var parameter (fortran,pascal) */
761 sc_Common = scCommon, /* common variable */
762 sc_SCommon = scSCommon, /* small common */
763 sc_VarRegister = scVarRegister, /* Var parameter in a register */
764 sc_Variant = scVariant, /* Variant record */
765 sc_SUndefined = scSUndefined, /* small undefined(external) data */
766 sc_Init = scInit, /* .init section symbol */
767 sc_Max = scMax /* Max storage class+1 */
770 /* Redefinition of symbol type. */
773 st_Nil = stNil, /* Nuthin' special */
774 st_Global = stGlobal, /* external symbol */
775 st_Static = stStatic, /* static */
776 st_Param = stParam, /* procedure argument */
777 st_Local = stLocal, /* local variable */
778 st_Label = stLabel, /* label */
779 st_Proc = stProc, /* " " Procedure */
780 st_Block = stBlock, /* beginning of block */
781 st_End = stEnd, /* end (of anything) */
782 st_Member = stMember, /* member (of anything - struct/union/enum */
783 st_Typedef = stTypedef, /* type definition */
784 st_File = stFile, /* file name */
785 st_RegReloc = stRegReloc, /* register relocation */
786 st_Forward = stForward, /* forwarding address */
787 st_StaticProc = stStaticProc, /* load time only static procs */
788 st_Constant = stConstant, /* const */
789 st_Str = stStr, /* string */
790 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
791 st_Expr = stExpr, /* 2+2 vs. 4 */
792 st_Type = stType, /* post-coercion SER */
793 st_Max = stMax /* max type+1 */
796 /* Redefinition of type qualifiers. */
799 tq_Nil = tqNil, /* bt is what you see */
800 tq_Ptr = tqPtr, /* pointer */
801 tq_Proc = tqProc, /* procedure */
802 tq_Array = tqArray, /* duh */
803 tq_Far = tqFar, /* longer addressing - 8086/8 land */
804 tq_Vol = tqVol, /* volatile */
805 tq_Max = tqMax /* Max type qualifier+1 */
808 /* Redefinition of basic types. */
811 bt_Nil = btNil, /* undefined */
812 bt_Adr = btAdr, /* address - integer same size as pointer */
813 bt_Char = btChar, /* character */
814 bt_UChar = btUChar, /* unsigned character */
815 bt_Short = btShort, /* short */
816 bt_UShort = btUShort, /* unsigned short */
817 bt_Int = btInt, /* int */
818 bt_UInt = btUInt, /* unsigned int */
819 bt_Long = btLong, /* long */
820 bt_ULong = btULong, /* unsigned long */
821 bt_Float = btFloat, /* float (real) */
822 bt_Double = btDouble, /* Double (real) */
823 bt_Struct = btStruct, /* Structure (Record) */
824 bt_Union = btUnion, /* Union (variant) */
825 bt_Enum = btEnum, /* Enumerated */
826 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
827 bt_Range = btRange, /* subrange of int */
828 bt_Set = btSet, /* pascal sets */
829 bt_Complex = btComplex, /* fortran complex */
830 bt_DComplex = btDComplex, /* fortran double complex */
831 bt_Indirect = btIndirect, /* forward or unnamed typedef */
832 bt_FixedDec = btFixedDec, /* Fixed Decimal */
833 bt_FloatDec = btFloatDec, /* Float Decimal */
834 bt_String = btString, /* Varying Length Character String */
835 bt_Bit = btBit, /* Aligned Bit String */
836 bt_Picture = btPicture, /* Picture */
839 bt_Void = btVoid, /* Void */
841 #define bt_Void bt_Nil
844 bt_Max = btMax /* Max basic type+1 */
849 /* Basic COFF storage classes. */
881 /* Regular COFF fundamental type. */
882 typedef enum coff_type {
902 /* Regular COFF derived types. */
903 typedef enum coff_dt {
911 #define N_BTMASK 017 /* bitmask to isolate basic type */
912 #define N_TMASK 003 /* bitmask to isolate derived type */
913 #define N_BT_SHIFT 4 /* # bits to shift past basic type */
914 #define N_TQ_SHIFT 2 /* # bits to shift derived types */
915 #define N_TQ 6 /* # of type qualifiers */
917 /* States for whether to hash type or not. */
918 typedef enum hash_state {
919 hash_no = 0, /* don't hash type */
920 hash_yes = 1, /* ok to hash type, or use previous hash */
921 hash_record = 2 /* ok to record hash, but don't use prev. */
925 /* Types of different sized allocation requests. */
927 alloc_type_none, /* dummy value */
928 alloc_type_scope, /* nested scopes linked list */
929 alloc_type_vlinks, /* glue linking pages in varray */
930 alloc_type_shash, /* string hash element */
931 alloc_type_thash, /* type hash element */
932 alloc_type_tag, /* struct/union/tag element */
933 alloc_type_forward, /* element to hold unknown tag */
934 alloc_type_thead, /* head of type hash list */
935 alloc_type_varray, /* general varray allocation */
936 alloc_type_last /* last+1 element for array bounds */
940 #define WORD_ALIGN(x) (((x) + (sizeof (long) - 1)) & ~ (sizeof (long) - 1))
941 #define DWORD_ALIGN(x) (((x) + 7) & ~7)
944 /* Structures to provide n-number of virtual arrays, each of which can
945 grow linearly, and which are written in the object file as sequential
946 pages. On systems with a BSD malloc that define USE_MALLOC, the
947 MAX_CLUSTER_PAGES should be 1 less than a power of two, since malloc
948 adds it's overhead, and rounds up to the next power of 2. Pages are
949 linked together via a linked list.
951 If PAGE_SIZE is > 4096, the string length in the shash_t structure
952 can't be represented (assuming there are strings > 4096 bytes). */
955 #define PAGE_SIZE 4096 /* size of varray pages */
958 #define PAGE_USIZE ((Size_t)PAGE_SIZE)
961 #ifndef MAX_CLUSTER_PAGES /* # pages to get from system */
962 #ifndef USE_MALLOC /* in one memory request */
963 #define MAX_CLUSTER_PAGES 64
965 #define MAX_CLUSTER_PAGES 63
970 /* Linked list connecting separate page allocations. */
971 typedef struct vlinks {
972 struct vlinks *prev; /* previous set of pages */
973 struct vlinks *next; /* next set of pages */
974 union page *datum; /* start of page */
975 unsigned long start_index; /* starting index # of page */
979 /* Virtual array header. */
980 typedef struct varray {
981 vlinks_t *first; /* first page link */
982 vlinks_t *last; /* last page link */
983 unsigned long num_allocated; /* # objects allocated */
984 unsigned short object_size; /* size in bytes of each object */
985 unsigned short objects_per_page; /* # objects that can fit on a page */
986 unsigned short objects_last_page; /* # objects allocated on last page */
990 #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
992 #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
995 #define INIT_VARRAY(type) { /* macro to initialize a varray */ \
996 (vlinks_t *)0, /* first */ \
997 (vlinks_t *)0, /* last */ \
998 0, /* num_allocated */ \
999 sizeof (type), /* object_size */ \
1000 OBJECTS_PER_PAGE (type), /* objects_per_page */ \
1001 OBJECTS_PER_PAGE (type), /* objects_last_page */ \
1004 /* Master type for indexes within the symbol table. */
1005 typedef unsigned long symint_t;
1008 /* Linked list support for nested scopes (file, block, structure, etc.). */
1009 typedef struct scope {
1010 struct scope *prev; /* previous scope level */
1011 struct scope *free; /* free list pointer */
1012 SYMR *lsym; /* pointer to local symbol node */
1013 symint_t lnumber; /* lsym index */
1014 st_t type; /* type of the node */
1018 /* Forward reference list for tags referenced, but not yet defined. */
1019 typedef struct forward {
1020 struct forward *next; /* next forward reference */
1021 struct forward *free; /* free list pointer */
1022 AUXU *ifd_ptr; /* pointer to store file index */
1023 AUXU *index_ptr; /* pointer to store symbol index */
1024 AUXU *type_ptr; /* pointer to munge type info */
1028 /* Linked list support for tags. The first tag in the list is always
1029 the current tag for that block. */
1030 typedef struct tag {
1031 struct tag *free; /* free list pointer */
1032 struct shash *hash_ptr; /* pointer to the hash table head */
1033 struct tag *same_name; /* tag with same name in outer scope */
1034 struct tag *same_block; /* next tag defined in the same block. */
1035 struct forward *forward_ref; /* list of forward references */
1036 bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
1037 symint_t ifd; /* file # tag defined in */
1038 symint_t indx; /* index within file's local symbols */
1042 /* Head of a block's linked list of tags. */
1043 typedef struct thead {
1044 struct thead *prev; /* previous block */
1045 struct thead *free; /* free list pointer */
1046 struct tag *first_tag; /* first tag in block defined */
1050 /* Union containing pointers to each the small structures which are freed up. */
1051 typedef union small_free {
1052 scope_t *f_scope; /* scope structure */
1053 thead_t *f_thead; /* tag head structure */
1054 tag_t *f_tag; /* tag element structure */
1055 forward_t *f_forward; /* forward tag reference */
1059 /* String hash table support. The size of the hash table must fit
1063 #define SHASH_SIZE 1009
1066 #define HASH_LEN_MAX ((1 << 12) - 1) /* Max length we can store */
1068 typedef struct shash {
1069 struct shash *next; /* next hash value */
1070 char *string; /* string we are hashing */
1071 symint_t len; /* string length */
1072 symint_t indx; /* index within string table */
1073 EXTR *esym_ptr; /* global symbol pointer */
1074 SYMR *sym_ptr; /* local symbol pointer */
1075 SYMR *end_ptr; /* symbol pointer to end block */
1076 tag_t *tag_ptr; /* tag pointer */
1077 PDR *proc_ptr; /* procedure descriptor pointer */
1081 /* Type hash table support. The size of the hash table must fit
1082 within a page with the other extended file descriptor information.
1083 Because unique types which are hashed are fewer in number than
1084 strings, we use a smaller hash value. */
1087 #define THASH_SIZE 113
1090 typedef struct thash {
1091 struct thash *next; /* next hash value */
1092 AUXU type; /* type we are hashing */
1093 symint_t indx; /* index within string table */
1097 /* Extended file descriptor that contains all of the support necessary
1098 to add things to each file separately. */
1099 typedef struct efdr {
1100 FDR fdr; /* File header to be written out */
1101 FDR *orig_fdr; /* original file header */
1102 char *name; /* filename */
1103 int name_len; /* length of the filename */
1104 symint_t void_type; /* aux. pointer to 'void' type */
1105 symint_t int_type; /* aux. pointer to 'int' type */
1106 scope_t *cur_scope; /* current nested scopes */
1107 symint_t file_index; /* current file number */
1108 int nested_scopes; /* # nested scopes */
1109 varray_t strings; /* local strings */
1110 varray_t symbols; /* local symbols */
1111 varray_t procs; /* procedures */
1112 varray_t aux_syms; /* auxiliary symbols */
1113 struct efdr *next_file; /* next file descriptor */
1114 /* string/type hash tables */
1115 shash_t **shash_head; /* string hash table */
1116 thash_t *thash_head[THASH_SIZE];
1119 /* Pre-initialized extended file structure. */
1120 static efdr_t init_file =
1122 { /* FDR structure */
1123 0, /* adr: memory address of beginning of file */
1124 0, /* rss: file name (of source, if known) */
1125 0, /* issBase: file's string space */
1126 0, /* cbSs: number of bytes in the ss */
1127 0, /* isymBase: beginning of symbols */
1128 0, /* csym: count file's of symbols */
1129 0, /* ilineBase: file's line symbols */
1130 0, /* cline: count of file's line symbols */
1131 0, /* ioptBase: file's optimization entries */
1132 0, /* copt: count of file's optimization entries */
1133 0, /* ipdFirst: start of procedures for this file */
1134 0, /* cpd: count of procedures for this file */
1135 0, /* iauxBase: file's auxiliary entries */
1136 0, /* caux: count of file's auxiliary entries */
1137 0, /* rfdBase: index into the file indirect table */
1138 0, /* crfd: count file indirect entries */
1139 langC, /* lang: language for this file */
1140 1, /* fMerge: whether this file can be merged */
1141 0, /* fReadin: true if read in (not just created) */
1142 #if BYTES_BIG_ENDIAN
1143 1, /* fBigendian: if 1, compiled on big endian machine */
1145 0, /* fBigendian: if 1, compiled on big endian machine */
1147 GLEVEL_2, /* glevel: level this file was compiled with */
1148 0, /* reserved: reserved for future use */
1149 0, /* cbLineOffset: byte offset from header for this file ln's */
1150 0, /* cbLine: size of lines for this file */
1153 (FDR *)0, /* orig_fdr: original file header pointer */
1154 (char *)0, /* name: pointer to filename */
1155 0, /* name_len: length of filename */
1156 0, /* void_type: ptr to aux node for void type */
1157 0, /* int_type: ptr to aux node for int type */
1158 (scope_t *)0, /* cur_scope: current scope being processed */
1159 0, /* file_index: current file # */
1160 0, /* nested_scopes: # nested scopes */
1161 INIT_VARRAY (char), /* strings: local string varray */
1162 INIT_VARRAY (SYMR), /* symbols: local symbols varray */
1163 INIT_VARRAY (PDR), /* procs: procedure varray */
1164 INIT_VARRAY (AUXU), /* aux_syms: auxiliary symbols varray */
1166 (struct efdr *)0, /* next_file: next file structure */
1168 (shash_t **)0, /* shash_head: string hash table */
1169 { 0 }, /* thash_head: type hash table */
1173 static efdr_t *first_file; /* first file descriptor */
1174 static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */
1177 /* Union of various things that are held in pages. */
1178 typedef union page {
1179 char byte [ PAGE_SIZE ];
1180 unsigned char ubyte [ PAGE_SIZE ];
1181 efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
1182 FDR ofile [ PAGE_SIZE / sizeof (FDR) ];
1183 PDR proc [ PAGE_SIZE / sizeof (PDR) ];
1184 SYMR sym [ PAGE_SIZE / sizeof (SYMR) ];
1185 EXTR esym [ PAGE_SIZE / sizeof (EXTR) ];
1186 AUXU aux [ PAGE_SIZE / sizeof (AUXU) ];
1187 DNR dense [ PAGE_SIZE / sizeof (DNR) ];
1188 scope_t scope [ PAGE_SIZE / sizeof (scope_t) ];
1189 vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ];
1190 shash_t shash [ PAGE_SIZE / sizeof (shash_t) ];
1191 thash_t thash [ PAGE_SIZE / sizeof (thash_t) ];
1192 tag_t tag [ PAGE_SIZE / sizeof (tag_t) ];
1193 forward_t forward [ PAGE_SIZE / sizeof (forward_t) ];
1194 thead_t thead [ PAGE_SIZE / sizeof (thead_t) ];
1198 /* Structure holding allocation information for small sized structures. */
1199 typedef struct alloc_info {
1200 char *alloc_name; /* name of this allocation type (must be first) */
1201 page_t *cur_page; /* current page being allocated from */
1202 small_free_t free_list; /* current free list if any */
1203 int unallocated; /* number of elements unallocated on page */
1204 int total_alloc; /* total number of allocations */
1205 int total_free; /* total number of frees */
1206 int total_pages; /* total number of pages allocated */
1209 /* Type information collected together. */
1210 typedef struct type_info {
1211 bt_t basic_type; /* basic type */
1212 coff_type_t orig_type; /* original COFF-based type */
1213 int num_tq; /* # type qualifiers */
1214 int num_dims; /* # dimensions */
1215 int num_sizes; /* # sizes */
1216 int extra_sizes; /* # extra sizes not tied with dims */
1217 tag_t * tag_ptr; /* tag pointer */
1218 int bitfield; /* symbol is a bitfield */
1219 int unknown_tag; /* this is an unknown tag */
1220 tq_t type_qualifiers[N_TQ]; /* type qualifiers (ptr, func, array)*/
1221 symint_t dimensions [N_TQ]; /* dimensions for each array */
1222 symint_t sizes [N_TQ+2]; /* sizes of each array slice + size of
1223 struct/union/enum + bitfield size */
1226 /* Pre-initialized type_info struct. */
1227 static type_info_t type_info_init = {
1228 bt_Nil, /* basic type */
1229 T_NULL, /* original COFF-based type */
1230 0, /* # type qualifiers */
1231 0, /* # dimensions */
1233 0, /* sizes not tied with dims */
1234 NULL, /* ptr to tag */
1236 0, /* unknown tag */
1237 { /* type qualifiers */
1266 /* Global virtual arrays & hash table for external strings as well as
1267 for the tags table and global tables for file descriptors, and
1270 static varray_t file_desc = INIT_VARRAY (efdr_t);
1271 static varray_t dense_num = INIT_VARRAY (DNR);
1272 static varray_t tag_strings = INIT_VARRAY (char);
1273 static varray_t ext_strings = INIT_VARRAY (char);
1274 static varray_t ext_symbols = INIT_VARRAY (EXTR);
1276 static shash_t *orig_str_hash[SHASH_SIZE];
1277 static shash_t *ext_str_hash [SHASH_SIZE];
1278 static shash_t *tag_hash [SHASH_SIZE];
1280 /* Static types for int and void. Also, remember the last function's
1281 type (which is set up when we encounter the declaration for the
1282 function, and used when the end block for the function is emitted. */
1284 static type_info_t int_type_info;
1285 static type_info_t void_type_info;
1286 static type_info_t last_func_type_info;
1287 static EXTR *last_func_eptr;
1290 /* Convert COFF basic type to ECOFF basic type. The T_NULL type
1291 really should use bt_Void, but this causes the current ecoff GDB to
1292 issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
1293 2.0) doesn't understand it, even though the compiler generates it.
1294 Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
1295 suite, but for now go with what works. */
1297 static bt_t map_coff_types[ (int)T_MAX ] = {
1298 bt_Nil, /* T_NULL */
1300 bt_Char, /* T_CHAR */
1301 bt_Short, /* T_SHORT */
1303 bt_Long, /* T_LONG */
1304 bt_Float, /* T_FLOAT */
1305 bt_Double, /* T_DOUBLE */
1306 bt_Struct, /* T_STRUCT */
1307 bt_Union, /* T_UNION */
1308 bt_Enum, /* T_ENUM */
1309 bt_Enum, /* T_MOE */
1310 bt_UChar, /* T_UCHAR */
1311 bt_UShort, /* T_USHORT */
1312 bt_UInt, /* T_UINT */
1313 bt_ULong /* T_ULONG */
1316 /* Convert COFF storage class to ECOFF storage class. */
1317 static sc_t map_coff_storage[ (int)C_MAX ] = {
1318 sc_Nil, /* 0: C_NULL */
1319 sc_Abs, /* 1: C_AUTO auto var */
1320 sc_Undefined, /* 2: C_EXT external */
1321 sc_Data, /* 3: C_STAT static */
1322 sc_Register, /* 4: C_REG register */
1323 sc_Undefined, /* 5: C_EXTDEF ??? */
1324 sc_Text, /* 6: C_LABEL label */
1325 sc_Text, /* 7: C_ULABEL user label */
1326 sc_Info, /* 8: C_MOS member of struct */
1327 sc_Abs, /* 9: C_ARG argument */
1328 sc_Info, /* 10: C_STRTAG struct tag */
1329 sc_Info, /* 11: C_MOU member of union */
1330 sc_Info, /* 12: C_UNTAG union tag */
1331 sc_Info, /* 13: C_TPDEF typedef */
1332 sc_Data, /* 14: C_USTATIC ??? */
1333 sc_Info, /* 15: C_ENTAG enum tag */
1334 sc_Info, /* 16: C_MOE member of enum */
1335 sc_Register, /* 17: C_REGPARM register parameter */
1336 sc_Bits, /* 18; C_FIELD bitfield */
1418 sc_Text, /* 100: C_BLOCK block start/end */
1419 sc_Text, /* 101: C_FCN function start/end */
1420 sc_Info, /* 102: C_EOS end of struct/union/enum */
1421 sc_Nil, /* 103: C_FILE file start */
1422 sc_Nil, /* 104: C_LINE line number */
1423 sc_Nil, /* 105: C_ALIAS combined type info */
1424 sc_Nil, /* 106: C_HIDDEN ??? */
1427 /* Convert COFF storage class to ECOFF symbol type. */
1428 static st_t map_coff_sym_type[ (int)C_MAX ] = {
1429 st_Nil, /* 0: C_NULL */
1430 st_Local, /* 1: C_AUTO auto var */
1431 st_Global, /* 2: C_EXT external */
1432 st_Static, /* 3: C_STAT static */
1433 st_Local, /* 4: C_REG register */
1434 st_Global, /* 5: C_EXTDEF ??? */
1435 st_Label, /* 6: C_LABEL label */
1436 st_Label, /* 7: C_ULABEL user label */
1437 st_Member, /* 8: C_MOS member of struct */
1438 st_Param, /* 9: C_ARG argument */
1439 st_Block, /* 10: C_STRTAG struct tag */
1440 st_Member, /* 11: C_MOU member of union */
1441 st_Block, /* 12: C_UNTAG union tag */
1442 st_Typedef, /* 13: C_TPDEF typedef */
1443 st_Static, /* 14: C_USTATIC ??? */
1444 st_Block, /* 15: C_ENTAG enum tag */
1445 st_Member, /* 16: C_MOE member of enum */
1446 st_Param, /* 17: C_REGPARM register parameter */
1447 st_Member, /* 18; C_FIELD bitfield */
1529 st_Block, /* 100: C_BLOCK block start/end */
1530 st_Proc, /* 101: C_FCN function start/end */
1531 st_End, /* 102: C_EOS end of struct/union/enum */
1532 st_File, /* 103: C_FILE file start */
1533 st_Nil, /* 104: C_LINE line number */
1534 st_Nil, /* 105: C_ALIAS combined type info */
1535 st_Nil, /* 106: C_HIDDEN ??? */
1538 /* Map COFF derived types to ECOFF type qualifiers. */
1539 static tq_t map_coff_derived_type[ (int)DT_MAX ] = {
1540 tq_Nil, /* 0: DT_NON no more qualifiers */
1541 tq_Ptr, /* 1: DT_PTR pointer */
1542 tq_Proc, /* 2: DT_FCN function */
1543 tq_Array, /* 3: DT_ARY array */
1547 /* Keep track of different sized allocation requests. */
1548 static alloc_info_t alloc_counts[ (int)alloc_type_last ];
1551 /* Pointers and such to the original symbol table that is read in. */
1552 static struct filehdr orig_file_header; /* global object file header */
1554 static HDRR orig_sym_hdr; /* symbolic header on input */
1555 static char *orig_linenum; /* line numbers */
1556 static DNR *orig_dense; /* dense numbers */
1557 static PDR *orig_procs; /* procedures */
1558 static SYMR *orig_local_syms; /* local symbols */
1559 static OPTR *orig_opt_syms; /* optimization symbols */
1560 static AUXU *orig_aux_syms; /* auxiliary symbols */
1561 static char *orig_local_strs; /* local strings */
1562 static char *orig_ext_strs; /* external strings */
1563 static FDR *orig_files; /* file descriptors */
1564 static symint_t *orig_rfds; /* relative file desc's */
1565 static EXTR *orig_ext_syms; /* external symbols */
1567 /* Macros to convert an index into a given object within the original
1569 #define CHECK(num,max,str) \
1570 (((unsigned long)num > (unsigned long)max) ? out_of_bounds (num, max, str, __LINE__) : 0)
1572 #define ORIG_LINENUM(indx) (CHECK ((indx), orig_sym_hdr.cbLine, "line#"), (indx) + orig_linenum)
1573 #define ORIG_DENSE(indx) (CHECK ((indx), orig_sym_hdr.idnMax, "dense"), (indx) + orig_dense)
1574 #define ORIG_PROCS(indx) (CHECK ((indx), orig_sym_hdr.ipdMax, "procs"), (indx) + orig_procs)
1575 #define ORIG_FILES(indx) (CHECK ((indx), orig_sym_hdr.ifdMax, "funcs"), (indx) + orig_files)
1576 #define ORIG_LSYMS(indx) (CHECK ((indx), orig_sym_hdr.isymMax, "lsyms"), (indx) + orig_local_syms)
1577 #define ORIG_LSTRS(indx) (CHECK ((indx), orig_sym_hdr.issMax, "lstrs"), (indx) + orig_local_strs)
1578 #define ORIG_ESYMS(indx) (CHECK ((indx), orig_sym_hdr.iextMax, "esyms"), (indx) + orig_ext_syms)
1579 #define ORIG_ESTRS(indx) (CHECK ((indx), orig_sym_hdr.issExtMax, "estrs"), (indx) + orig_ext_strs)
1580 #define ORIG_OPT(indx) (CHECK ((indx), orig_sym_hdr.ioptMax, "opt"), (indx) + orig_opt_syms)
1581 #define ORIG_AUX(indx) (CHECK ((indx), orig_sym_hdr.iauxMax, "aux"), (indx) + orig_aux_syms)
1582 #define ORIG_RFDS(indx) (CHECK ((indx), orig_sym_hdr.crfd, "rfds"), (indx) + orig_rfds)
1584 /* Various other statics. */
1585 static HDRR symbolic_header; /* symbolic header */
1586 static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */
1587 static PDR *cur_proc_ptr = (PDR *) 0; /* current procedure header */
1588 static SYMR *cur_oproc_begin = (SYMR *) 0; /* original proc. sym begin info */
1589 static SYMR *cur_oproc_end = (SYMR *) 0; /* original proc. sym end info */
1590 static PDR *cur_oproc_ptr = (PDR *) 0; /* current original procedure*/
1591 static thead_t *cur_tag_head = (thead_t *)0; /* current tag head */
1592 static long file_offset = 0; /* current file offset */
1593 static long max_file_offset = 0; /* maximum file offset */
1594 static FILE *object_stream = (FILE *)0; /* file desc. to output .o */
1595 static FILE *obj_in_stream = (FILE *)0; /* file desc. to input .o */
1596 static char *progname = (char *)0; /* program name for errors */
1597 static char *input_name = "stdin"; /* name of input file */
1598 static char *object_name = (char *)0; /* tmp. name of object file */
1599 static char *obj_in_name = (char *)0; /* name of input object file */
1600 static char *cur_line_start = (char *)0; /* current line read in */
1601 static char *cur_line_ptr = (char *)0; /* ptr within current line */
1602 static unsigned cur_line_nbytes = 0; /* # bytes for current line */
1603 static unsigned cur_line_alloc = 0; /* # bytes total in buffer */
1604 static long line_number = 0; /* current input line number */
1605 static int debug = 0; /* trace functions */
1606 static int version = 0; /* print version # */
1607 static int had_errors = 0; /* != 0 if errors were found */
1608 static int rename_output = 0; /* != 0 if rename output file*/
1609 static int delete_input = 0; /* != 0 if delete input after done */
1610 static int stabs_seen = 0; /* != 0 if stabs have been seen */
1613 /* Pseudo symbol to use when putting stabs into the symbol table. */
1614 #ifndef STABS_SYMBOL
1615 #define STABS_SYMBOL "@stabs"
1618 static char stabs_symbol[] = STABS_SYMBOL;
1621 /* Forward reference for functions. See the definition for more details. */
1624 #define STATIC static
1627 STATIC int out_of_bounds __proto((symint_t, symint_t, const char *, int));
1629 STATIC shash_t *hash_string __proto((const char *,
1634 STATIC symint_t add_string __proto((varray_t *,
1640 STATIC symint_t add_local_symbol
1641 __proto((const char *,
1648 STATIC symint_t add_ext_symbol __proto((const char *,
1656 STATIC symint_t add_aux_sym_symint
1657 __proto((symint_t));
1659 STATIC symint_t add_aux_sym_rndx
1660 __proto((int, symint_t));
1662 STATIC symint_t add_aux_sym_tir __proto((type_info_t *,
1666 STATIC tag_t * get_tag __proto((const char *,
1671 STATIC void add_unknown_tag __proto((tag_t *));
1673 STATIC void add_procedure __proto((const char *,
1676 STATIC void add_file __proto((const char *,
1679 STATIC void add_bytes __proto((varray_t *,
1683 STATIC void add_varray_page __proto((varray_t *));
1685 STATIC void update_headers __proto((void));
1687 STATIC void write_varray __proto((varray_t *, off_t, const char *));
1688 STATIC void write_object __proto((void));
1689 STATIC char *st_to_string __proto((st_t));
1690 STATIC char *sc_to_string __proto((sc_t));
1691 STATIC char *read_line __proto((void));
1692 STATIC void parse_input __proto((void));
1693 STATIC void mark_stabs __proto((const char *));
1694 STATIC void parse_begin __proto((const char *));
1695 STATIC void parse_bend __proto((const char *));
1696 STATIC void parse_def __proto((const char *));
1697 STATIC void parse_end __proto((const char *));
1698 STATIC void parse_ent __proto((const char *));
1699 STATIC void parse_file __proto((const char *));
1700 STATIC void parse_stabs_common
1701 __proto((const char *, const char *, const char *));
1702 STATIC void parse_stabs __proto((const char *));
1703 STATIC void parse_stabn __proto((const char *));
1704 STATIC page_t *read_seek __proto((Size_t, off_t, const char *));
1705 STATIC void copy_object __proto((void));
1707 STATIC void catch_signal __proto((int));
1708 STATIC page_t *allocate_page __proto((void));
1710 STATIC page_t *allocate_multiple_pages
1713 STATIC void free_multiple_pages
1714 __proto((page_t *, Size_t));
1716 #ifndef MALLOC_CHECK
1717 STATIC page_t *allocate_cluster
1721 STATIC forward_t *allocate_forward __proto((void));
1722 STATIC scope_t *allocate_scope __proto((void));
1723 STATIC shash_t *allocate_shash __proto((void));
1724 STATIC tag_t *allocate_tag __proto((void));
1725 STATIC thash_t *allocate_thash __proto((void));
1726 STATIC thead_t *allocate_thead __proto((void));
1727 STATIC vlinks_t *allocate_vlinks __proto((void));
1729 STATIC void free_forward __proto((forward_t *));
1730 STATIC void free_scope __proto((scope_t *));
1731 STATIC void free_tag __proto((tag_t *));
1732 STATIC void free_thead __proto((thead_t *));
1734 STATIC char *local_index __proto((const char *, int));
1735 STATIC char *local_rindex __proto((const char *, int));
1738 extern char *sbrk __proto((int));
1739 extern PTR_T malloc __proto((Size_t));
1740 extern PTR_T calloc __proto((Size_t, Size_t));
1741 extern PTR_T realloc __proto((PTR_T, Size_t));
1742 extern void free __proto((PTR_T));
1744 extern char *mktemp __proto((char *));
1745 extern long strtol __proto((const char *, char **, int));
1747 extern char *optarg;
1750 extern char *version_string;
1751 extern char *sys_siglist[NSIG + 1];
1753 #ifndef SEEK_SET /* Symbolic constants for the "fseek" function: */
1754 #define SEEK_SET 0 /* Set file pointer to offset */
1755 #define SEEK_CUR 1 /* Set file pointer to its current value plus offset */
1756 #define SEEK_END 2 /* Set file pointer to the size of the file plus offset */
1760 /* List of assembler pseudo ops and beginning sequences that need
1761 special actions. Someday, this should be a hash table, and such,
1762 but for now a linear list of names and calls to memcmp will
1765 typedef struct _pseudo_ops {
1766 const char *name; /* pseudo-op in ascii */
1767 int len; /* length of name to compare */
1768 void (*func) __proto((const char *)); /* function to handle line */
1771 static pseudo_ops_t pseudo_ops[] = {
1772 { "#.def", sizeof("#.def")-1, parse_def },
1773 { "#.begin", sizeof("#.begin")-1, parse_begin },
1774 { "#.bend", sizeof("#.bend")-1, parse_bend },
1775 { ".end", sizeof(".end")-1, parse_end },
1776 { ".ent", sizeof(".ent")-1, parse_ent },
1777 { ".file", sizeof(".file")-1, parse_file },
1778 { "#.stabs", sizeof("#.stabs")-1, parse_stabs },
1779 { "#.stabn", sizeof("#.stabn")-1, parse_stabn },
1780 { ".stabs", sizeof(".stabs")-1, parse_stabs },
1781 { ".stabn", sizeof(".stabn")-1, parse_stabn },
1782 { "#@stabs", sizeof("#@stabs")-1, mark_stabs },
1786 /* Add a page to a varray object. */
1789 add_varray_page (vp)
1790 varray_t *vp; /* varray to add page to */
1792 vlinks_t *new_links = allocate_vlinks ();
1795 if (vp->object_size > 1)
1796 new_links->datum = (page_t *) xcalloc (1, vp->object_size);
1799 new_links->datum = allocate_page ();
1801 alloc_counts[ (int)alloc_type_varray ].total_alloc++;
1802 alloc_counts[ (int)alloc_type_varray ].total_pages++;
1804 new_links->start_index = vp->num_allocated;
1805 vp->objects_last_page = 0;
1807 if (vp->first == (vlinks_t *)0) /* first allocation? */
1808 vp->first = vp->last = new_links;
1810 { /* 2nd or greater allocation */
1811 new_links->prev = vp->last;
1812 vp->last->next = new_links;
1813 vp->last = new_links;
1818 /* Compute hash code (from tree.c) */
1823 hash_string (text, hash_len, hash_tbl, ret_hash_index)
1824 const char *text; /* ptr to text to hash */
1825 Ptrdiff_t hash_len; /* length of the text */
1826 shash_t **hash_tbl; /* hash table */
1827 symint_t *ret_hash_index; /* ptr to store hash index */
1829 register unsigned long hi;
1830 register Ptrdiff_t i;
1831 register shash_t *ptr;
1832 register int first_ch = *text;
1835 for (i = 0; i < hash_len; i++)
1836 hi = ((hi & 0x003fffff) * 613) + (text[i] & 0xff);
1838 hi &= (1 << HASHBITS) - 1;
1841 if (ret_hash_index != (symint_t *)0)
1842 *ret_hash_index = hi;
1844 for (ptr = hash_tbl[hi]; ptr != (shash_t *)0; ptr = ptr->next)
1845 if (hash_len == ptr->len
1846 && first_ch == ptr->string[0]
1847 && memcmp ((CPTR_T) text, (CPTR_T) ptr->string, hash_len) == 0)
1854 /* Add a string (and null pad) to one of the string tables. A
1855 consequence of hashing strings, is that we don't let strings
1856 cross page boundaries. The extra nulls will be ignored. */
1859 add_string (vp, hash_tbl, start, end_p1, ret_hash)
1860 varray_t *vp; /* string virtual array */
1861 shash_t **hash_tbl; /* ptr to hash table */
1862 const char *start; /* 1st byte in string */
1863 const char *end_p1; /* 1st byte after string */
1864 shash_t **ret_hash; /* return hash pointer */
1866 register Ptrdiff_t len = end_p1 - start;
1867 register shash_t *hash_ptr;
1870 if (len >= PAGE_USIZE)
1871 fatal ("String too big (%ld bytes)", (long) len);
1873 hash_ptr = hash_string (start, len, hash_tbl, &hi);
1874 if (hash_ptr == (shash_t *)0)
1878 if (vp->objects_last_page + len >= PAGE_USIZE)
1881 ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
1882 add_varray_page (vp);
1885 hash_ptr = allocate_shash ();
1886 hash_ptr->next = hash_tbl[hi];
1887 hash_tbl[hi] = hash_ptr;
1889 hash_ptr->len = len;
1890 hash_ptr->indx = vp->num_allocated;
1891 hash_ptr->string = p = & vp->last->datum->byte[ vp->objects_last_page ];
1893 vp->objects_last_page += len+1;
1894 vp->num_allocated += len+1;
1902 if (ret_hash != (shash_t **)0)
1903 *ret_hash = hash_ptr;
1905 return hash_ptr->indx;
1909 /* Add a local symbol. */
1912 add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
1913 const char *str_start; /* first byte in string */
1914 const char *str_end_p1; /* first byte after string */
1915 st_t type; /* symbol type */
1916 sc_t storage; /* storage class */
1917 symint_t value; /* value of symbol */
1918 symint_t indx; /* index to local/aux. syms */
1920 register symint_t ret;
1921 register SYMR *psym;
1922 register scope_t *pscope;
1923 register thead_t *ptag_head;
1924 register tag_t *ptag;
1925 register tag_t *ptag_next;
1926 register varray_t *vp = &cur_file_ptr->symbols;
1927 register int scope_delta = 0;
1928 shash_t *hash_ptr = (shash_t *)0;
1930 if (vp->objects_last_page == vp->objects_per_page)
1931 add_varray_page (vp);
1933 psym = &vp->last->datum->sym[ vp->objects_last_page++ ];
1935 psym->value = value;
1936 psym->st = (unsigned) type;
1937 psym->sc = (unsigned) storage;
1939 psym->iss = (str_start == (const char *)0)
1941 : add_string (&cur_file_ptr->strings,
1942 &cur_file_ptr->shash_head[0],
1947 ret = vp->num_allocated++;
1949 if (MIPS_IS_STAB(psym))
1952 /* Save the symbol within the hash table if this is a static
1953 item, and it has a name. */
1954 if (hash_ptr != (shash_t *)0
1955 && (type == st_Global || type == st_Static || type == st_Label
1956 || type == st_Proc || type == st_StaticProc))
1957 hash_ptr->sym_ptr = psym;
1959 /* push or pop a scope if appropriate. */
1965 case st_File: /* beginning of file */
1966 case st_Proc: /* procedure */
1967 case st_StaticProc: /* static procedure */
1968 case st_Block: /* begin scope */
1969 pscope = allocate_scope ();
1970 pscope->prev = cur_file_ptr->cur_scope;
1971 pscope->lsym = psym;
1972 pscope->lnumber = ret;
1973 pscope->type = type;
1974 cur_file_ptr->cur_scope = pscope;
1976 if (type != st_File)
1979 /* For every block type except file, struct, union, or
1980 enumeration blocks, push a level on the tag stack. We omit
1981 file types, so that tags can span file boundaries. */
1982 if (type != st_File && storage != sc_Info)
1984 ptag_head = allocate_thead ();
1985 ptag_head->first_tag = 0;
1986 ptag_head->prev = cur_tag_head;
1987 cur_tag_head = ptag_head;
1992 pscope = cur_file_ptr->cur_scope;
1993 if (pscope == (scope_t *)0)
1994 error ("internal error, too many st_End's");
1998 st_t begin_type = (st_t) pscope->lsym->st;
2000 if (begin_type != st_File)
2003 /* Except for file, structure, union, or enumeration end
2004 blocks remove all tags created within this scope. */
2005 if (begin_type != st_File && storage != sc_Info)
2007 ptag_head = cur_tag_head;
2008 cur_tag_head = ptag_head->prev;
2010 for (ptag = ptag_head->first_tag;
2014 if (ptag->forward_ref != (forward_t *)0)
2015 add_unknown_tag (ptag);
2017 ptag_next = ptag->same_block;
2018 ptag->hash_ptr->tag_ptr = ptag->same_name;
2022 free_thead (ptag_head);
2025 cur_file_ptr->cur_scope = pscope->prev;
2026 psym->index = pscope->lnumber; /* blk end gets begin sym # */
2028 if (storage != sc_Info)
2029 psym->iss = pscope->lsym->iss; /* blk end gets same name */
2031 if (begin_type == st_File || begin_type == st_Block)
2032 pscope->lsym->index = ret+1; /* block begin gets next sym # */
2034 /* Functions push two or more aux words as follows:
2035 1st word: index+1 of the end symbol
2036 2nd word: type of the function (plus any aux words needed).
2037 Also, tie the external pointer back to the function begin symbol. */
2041 pscope->lsym->index = add_aux_sym_symint (ret+1);
2042 type = add_aux_sym_tir (&last_func_type_info,
2044 &cur_file_ptr->thash_head[0]);
2047 last_func_eptr->ifd = cur_file_ptr->file_index;
2048 last_func_eptr->asym.index = type;
2052 free_scope (pscope);
2056 cur_file_ptr->nested_scopes += scope_delta;
2058 if (debug && type != st_File
2059 && (debug > 2 || type == st_Block || type == st_End
2060 || type == st_Proc || type == st_StaticProc))
2062 char *sc_str = sc_to_string (storage);
2063 char *st_str = st_to_string (type);
2064 int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
2067 "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
2068 value, depth, sc_str);
2070 if (str_start && str_end_p1 - str_start > 0)
2071 fprintf (stderr, " st= %-11s name= %.*s\n", st_str, str_end_p1 - str_start, str_start);
2074 Size_t len = strlen (st_str);
2075 fprintf (stderr, " st= %.*s\n", len-1, st_str);
2083 /* Add an external symbol. */
2086 add_ext_symbol (str_start, str_end_p1, type, storage, value, indx, ifd)
2087 const char *str_start; /* first byte in string */
2088 const char *str_end_p1; /* first byte after string */
2089 st_t type; /* symbol type */
2090 sc_t storage; /* storage class */
2091 long value; /* value of symbol */
2092 symint_t indx; /* index to local/aux. syms */
2093 int ifd; /* file index */
2095 register EXTR *psym;
2096 register varray_t *vp = &ext_symbols;
2097 shash_t *hash_ptr = (shash_t *)0;
2101 char *sc_str = sc_to_string (storage);
2102 char *st_str = st_to_string (type);
2105 "\tesym\tv= %10ld, ifd= %2d, sc= %-12s",
2106 value, ifd, sc_str);
2108 if (str_start && str_end_p1 - str_start > 0)
2109 fprintf (stderr, " st= %-11s name= %.*s\n", st_str, str_end_p1 - str_start, str_start);
2111 fprintf (stderr, " st= %s\n", st_str);
2114 if (vp->objects_last_page == vp->objects_per_page)
2115 add_varray_page (vp);
2117 psym = &vp->last->datum->esym[ vp->objects_last_page++ ];
2120 psym->asym.value = value;
2121 psym->asym.st = (unsigned) type;
2122 psym->asym.sc = (unsigned) storage;
2123 psym->asym.index = indx;
2124 psym->asym.iss = (str_start == (const char *)0)
2126 : add_string (&ext_strings,
2132 hash_ptr->esym_ptr = psym;
2133 return vp->num_allocated++;
2137 /* Add an auxiliary symbol (passing a symint). */
2140 add_aux_sym_symint (aux_word)
2141 symint_t aux_word; /* auxiliary information word */
2143 register AUXU *aux_ptr;
2144 register efdr_t *file_ptr = cur_file_ptr;
2145 register varray_t *vp = &file_ptr->aux_syms;
2147 if (vp->objects_last_page == vp->objects_per_page)
2148 add_varray_page (vp);
2150 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2151 aux_ptr->isym = aux_word;
2153 return vp->num_allocated++;
2157 /* Add an auxiliary symbol (passing a file/symbol index combo). */
2160 add_aux_sym_rndx (file_index, sym_index)
2164 register AUXU *aux_ptr;
2165 register efdr_t *file_ptr = cur_file_ptr;
2166 register varray_t *vp = &file_ptr->aux_syms;
2168 if (vp->objects_last_page == vp->objects_per_page)
2169 add_varray_page (vp);
2171 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2172 aux_ptr->rndx.rfd = file_index;
2173 aux_ptr->rndx.index = sym_index;
2175 return vp->num_allocated++;
2179 /* Add an auxiliary symbol (passing the basic type and possibly
2180 type qualifiers). */
2183 add_aux_sym_tir (t, state, hash_tbl)
2184 type_info_t *t; /* current type information */
2185 hash_state_t state; /* whether to hash type or not */
2186 thash_t **hash_tbl; /* pointer to hash table to use */
2188 register AUXU *aux_ptr;
2189 register efdr_t *file_ptr = cur_file_ptr;
2190 register varray_t *vp = &file_ptr->aux_syms;
2191 static AUXU init_aux;
2197 aux.ti.bt = (int) t->basic_type;
2198 aux.ti.continued = 0;
2199 aux.ti.fBitfield = t->bitfield;
2201 aux.ti.tq0 = (int) t->type_qualifiers[0];
2202 aux.ti.tq1 = (int) t->type_qualifiers[1];
2203 aux.ti.tq2 = (int) t->type_qualifiers[2];
2204 aux.ti.tq3 = (int) t->type_qualifiers[3];
2205 aux.ti.tq4 = (int) t->type_qualifiers[4];
2206 aux.ti.tq5 = (int) t->type_qualifiers[5];
2209 /* For anything that adds additional information, we must not hash,
2210 so check here, and reset our state. */
2212 if (state != hash_no
2213 && (t->type_qualifiers[0] == tq_Array
2214 || t->type_qualifiers[1] == tq_Array
2215 || t->type_qualifiers[2] == tq_Array
2216 || t->type_qualifiers[3] == tq_Array
2217 || t->type_qualifiers[4] == tq_Array
2218 || t->type_qualifiers[5] == tq_Array
2219 || t->basic_type == bt_Struct
2220 || t->basic_type == bt_Union
2221 || t->basic_type == bt_Enum
2223 || t->num_dims > 0))
2226 /* See if we can hash this type, and save some space, but some types
2227 can't be hashed (because they contain arrays or continuations),
2228 and others can be put into the hash list, but cannot use existing
2229 types because other aux entries precede this one. */
2231 if (state != hash_no)
2233 register thash_t *hash_ptr;
2234 register symint_t hi;
2236 hi = aux.isym & ((1 << HASHBITS) - 1);
2239 for (hash_ptr = hash_tbl[hi];
2240 hash_ptr != (thash_t *)0;
2241 hash_ptr = hash_ptr->next)
2243 if (aux.isym == hash_ptr->type.isym)
2247 if (hash_ptr != (thash_t *)0 && state == hash_yes)
2248 return hash_ptr->indx;
2250 if (hash_ptr == (thash_t *)0)
2252 hash_ptr = allocate_thash ();
2253 hash_ptr->next = hash_tbl[hi];
2254 hash_ptr->type = aux;
2255 hash_ptr->indx = vp->num_allocated;
2256 hash_tbl[hi] = hash_ptr;
2260 /* Everything is set up, add the aux symbol. */
2261 if (vp->objects_last_page == vp->objects_per_page)
2262 add_varray_page (vp);
2264 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2267 ret = vp->num_allocated++;
2269 /* Add bitfield length if it exists.
2271 NOTE: Mips documentation claims bitfield goes at the end of the
2272 AUX record, but the DECstation compiler emits it here.
2273 (This would only make a difference for enum bitfields.)
2275 Also note: We use the last size given since gcc may emit 2
2276 for an enum bitfield. */
2279 (void) add_aux_sym_symint ((symint_t)t->sizes[t->num_sizes-1]);
2282 /* Add tag information if needed. Structure, union, and enum
2283 references add 2 aux symbols: a [file index, symbol index]
2284 pointer to the structure type, and the current file index. */
2286 if (t->basic_type == bt_Struct
2287 || t->basic_type == bt_Union
2288 || t->basic_type == bt_Enum)
2290 register symint_t file_index = t->tag_ptr->ifd;
2291 register symint_t sym_index = t->tag_ptr->indx;
2295 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2296 (void) add_aux_sym_symint ((symint_t)-1);
2298 else if (sym_index != indexNil)
2300 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2301 (void) add_aux_sym_symint (file_index);
2305 register forward_t *forward_ref = allocate_forward ();
2307 forward_ref->type_ptr = aux_ptr;
2308 forward_ref->next = t->tag_ptr->forward_ref;
2309 t->tag_ptr->forward_ref = forward_ref;
2311 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2312 forward_ref->index_ptr
2313 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2315 (void) add_aux_sym_symint (file_index);
2316 forward_ref->ifd_ptr
2317 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2321 /* Add information about array bounds if they exist. */
2322 for (i = 0; i < t->num_dims; i++)
2324 (void) add_aux_sym_rndx (ST_RFDESCAPE,
2325 cur_file_ptr->int_type);
2327 (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/
2328 (void) add_aux_sym_symint ((symint_t)0); /* low bound */
2329 (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/
2330 (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */
2332 : (t->sizes[i] * 8) / t->dimensions[i]);
2335 /* NOTE: Mips documentation claism that the bitfield width goes here.
2336 But it needs to be emitted earlier. */
2342 /* Add a tag to the tag table (unless it already exists). */
2345 get_tag (tag_start, tag_end_p1, indx, basic_type)
2346 const char *tag_start; /* 1st byte of tag name */
2347 const char *tag_end_p1; /* 1st byte after tag name */
2348 symint_t indx; /* index of tag start block */
2349 bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
2353 hash_ptr = hash_string (tag_start,
2354 tag_end_p1 - tag_start,
2358 if (hash_ptr != (shash_t *)0
2359 && hash_ptr->tag_ptr != (tag_t *)0)
2361 tag_ptr = hash_ptr->tag_ptr;
2362 if (indx != indexNil)
2364 tag_ptr->basic_type = basic_type;
2365 tag_ptr->ifd = cur_file_ptr->file_index;
2366 tag_ptr->indx = indx;
2371 (void) add_string (&tag_strings,
2377 tag_ptr = allocate_tag ();
2378 tag_ptr->forward_ref = (forward_t *) 0;
2379 tag_ptr->hash_ptr = hash_ptr;
2380 tag_ptr->same_name = hash_ptr->tag_ptr;
2381 tag_ptr->basic_type = basic_type;
2382 tag_ptr->indx = indx;
2383 tag_ptr->ifd = (indx == indexNil) ? -1 : cur_file_ptr->file_index;
2384 tag_ptr->same_block = cur_tag_head->first_tag;
2386 cur_tag_head->first_tag = tag_ptr;
2387 hash_ptr->tag_ptr = tag_ptr;
2393 /* Add an unknown {struct, union, enum} tag. */
2396 add_unknown_tag (ptag)
2397 tag_t *ptag; /* pointer to tag information */
2399 shash_t *hash_ptr = ptag->hash_ptr;
2400 char *name_start = hash_ptr->string;
2401 char *name_end_p1 = name_start + hash_ptr->len;
2402 forward_t *f_next = ptag->forward_ref;
2405 int file_index = cur_file_ptr->file_index;
2409 char *agg_type = "{unknown aggregate type}";
2410 switch (ptag->basic_type)
2412 case bt_Struct: agg_type = "struct"; break;
2413 case bt_Union: agg_type = "union"; break;
2414 case bt_Enum: agg_type = "enum"; break;
2418 fprintf (stderr, "unknown %s %.*s found\n", agg_type,
2419 hash_ptr->len, name_start);
2422 sym_index = add_local_symbol (name_start,
2429 (void) add_local_symbol (name_start,
2436 while (f_next != (forward_t *)0)
2439 f_next = f_next->next;
2441 f_cur->ifd_ptr->isym = file_index;
2442 f_cur->index_ptr->rndx.index = sym_index;
2444 free_forward (f_cur);
2451 /* Add a procedure to the current file's list of procedures, and record
2452 this is the current procedure. If the assembler created a PDR for
2453 this procedure, use that to initialize the current PDR. */
2456 add_procedure (func_start, func_end_p1)
2457 const char *func_start; /* 1st byte of func name */
2458 const char *func_end_p1; /* 1st byte after func name */
2460 register PDR *new_proc_ptr;
2461 register efdr_t *file_ptr = cur_file_ptr;
2462 register varray_t *vp = &file_ptr->procs;
2463 register symint_t value = 0;
2464 register st_t proc_type = st_Proc;
2465 register shash_t *shash_ptr = hash_string (func_start,
2466 func_end_p1 - func_start,
2471 fputc ('\n', stderr);
2473 if (vp->objects_last_page == vp->objects_per_page)
2474 add_varray_page (vp);
2476 cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[ vp->objects_last_page++ ];
2478 vp->num_allocated++;
2481 /* Did the assembler create this procedure? If so, get the PDR information. */
2482 cur_oproc_ptr = (PDR *)0;
2483 if (shash_ptr != (shash_t *)0)
2485 register PDR *old_proc_ptr = shash_ptr->proc_ptr;
2486 register SYMR *sym_ptr = shash_ptr->sym_ptr;
2488 if (old_proc_ptr != (PDR *)0
2489 && sym_ptr != (SYMR *)0
2490 && ((st_t)sym_ptr->st == st_Proc || (st_t)sym_ptr->st == st_StaticProc))
2492 cur_oproc_begin = sym_ptr;
2493 cur_oproc_end = shash_ptr->end_ptr;
2494 value = sym_ptr->value;
2496 cur_oproc_ptr = old_proc_ptr;
2497 proc_type = (st_t)sym_ptr->st;
2498 *new_proc_ptr = *old_proc_ptr; /* initialize */
2502 if (cur_oproc_ptr == (PDR *)0)
2503 error ("Did not find a PDR block for %.*s", func_end_p1 - func_start, func_start);
2505 /* Determine the start of symbols. */
2506 new_proc_ptr->isym = file_ptr->symbols.num_allocated;
2508 /* Push the start of the function. */
2509 (void) add_local_symbol (func_start, func_end_p1,
2516 /* Add a new filename, and set up all of the file relative
2517 virtual arrays (strings, symbols, aux syms, etc.). Record
2518 where the current file structure lives. */
2521 add_file (file_start, file_end_p1)
2522 const char *file_start; /* first byte in string */
2523 const char *file_end_p1; /* first byte after string */
2525 static char zero_bytes[2] = { '\0', '\0' };
2527 register Ptrdiff_t len = file_end_p1 - file_start;
2528 register int first_ch = *file_start;
2529 register efdr_t *file_ptr;
2532 fprintf (stderr, "\tfile\t%.*s\n", len, file_start);
2534 /* See if the file has already been created. */
2535 for (file_ptr = first_file;
2536 file_ptr != (efdr_t *)0;
2537 file_ptr = file_ptr->next_file)
2539 if (first_ch == file_ptr->name[0]
2540 && file_ptr->name[len] == '\0'
2541 && memcmp ((CPTR_T) file_start, (CPTR_T) file_ptr->name, len) == 0)
2543 cur_file_ptr = file_ptr;
2548 /* If this is a new file, create it. */
2549 if (file_ptr == (efdr_t *)0)
2551 if (file_desc.objects_last_page == file_desc.objects_per_page)
2552 add_varray_page (&file_desc);
2554 file_ptr = cur_file_ptr =
2555 &file_desc.last->datum->file[ file_desc.objects_last_page++ ];
2556 *file_ptr = init_file;
2558 file_ptr->file_index = file_desc.num_allocated++;
2560 /* Allocate the string hash table. */
2561 file_ptr->shash_head = (shash_t **) allocate_page ();
2563 /* Make sure 0 byte in string table is null */
2564 add_string (&file_ptr->strings,
2565 &file_ptr->shash_head[0],
2570 if (file_end_p1 - file_start > PAGE_USIZE-2)
2571 fatal ("Filename goes over one page boundary.");
2573 /* Push the start of the filename. We assume that the filename
2574 will be stored at string offset 1. */
2575 (void) add_local_symbol (file_start, file_end_p1, st_File, sc_Text,
2576 (symint_t)0, (symint_t)0);
2577 file_ptr->fdr.rss = 1;
2578 file_ptr->name = &file_ptr->strings.last->datum->byte[1];
2579 file_ptr->name_len = file_end_p1 - file_start;
2581 /* Update the linked list of file descriptors. */
2582 *last_file_ptr = file_ptr;
2583 last_file_ptr = &file_ptr->next_file;
2585 /* Add void & int types to the file (void should be first to catch
2586 errant 0's within the index fields). */
2587 file_ptr->void_type = add_aux_sym_tir (&void_type_info,
2589 &cur_file_ptr->thash_head[0]);
2591 file_ptr->int_type = add_aux_sym_tir (&int_type_info,
2593 &cur_file_ptr->thash_head[0]);
2598 /* Add a stream of random bytes to a varray. */
2601 add_bytes (vp, input_ptr, nitems)
2602 varray_t *vp; /* virtual array to add too */
2603 char *input_ptr; /* start of the bytes */
2604 Size_t nitems; /* # items to move */
2606 register Size_t move_items;
2607 register Size_t move_bytes;
2612 if (vp->objects_last_page >= vp->objects_per_page)
2613 add_varray_page (vp);
2615 ptr = &vp->last->datum->byte[ vp->objects_last_page * vp->object_size ];
2616 move_items = vp->objects_per_page - vp->objects_last_page;
2617 if (move_items > nitems)
2618 move_items = nitems;
2620 move_bytes = move_items * vp->object_size;
2621 nitems -= move_items;
2623 if (move_bytes >= 32)
2625 (void) memcpy ((PTR_T) ptr, (CPTR_T) input_ptr, move_bytes);
2626 input_ptr += move_bytes;
2630 while (move_bytes-- > 0)
2631 *ptr++ = *input_ptr++;
2637 /* Convert storage class to string. */
2640 sc_to_string(storage_class)
2643 switch(storage_class)
2645 case sc_Nil: return "Nil,";
2646 case sc_Text: return "Text,";
2647 case sc_Data: return "Data,";
2648 case sc_Bss: return "Bss,";
2649 case sc_Register: return "Register,";
2650 case sc_Abs: return "Abs,";
2651 case sc_Undefined: return "Undefined,";
2652 case sc_CdbLocal: return "CdbLocal,";
2653 case sc_Bits: return "Bits,";
2654 case sc_CdbSystem: return "CdbSystem,";
2655 case sc_RegImage: return "RegImage,";
2656 case sc_Info: return "Info,";
2657 case sc_UserStruct: return "UserStruct,";
2658 case sc_SData: return "SData,";
2659 case sc_SBss: return "SBss,";
2660 case sc_RData: return "RData,";
2661 case sc_Var: return "Var,";
2662 case sc_Common: return "Common,";
2663 case sc_SCommon: return "SCommon,";
2664 case sc_VarRegister: return "VarRegister,";
2665 case sc_Variant: return "Variant,";
2666 case sc_SUndefined: return "SUndefined,";
2667 case sc_Init: return "Init,";
2668 case sc_Max: return "Max,";
2675 /* Convert symbol type to string. */
2678 st_to_string(symbol_type)
2683 case st_Nil: return "Nil,";
2684 case st_Global: return "Global,";
2685 case st_Static: return "Static,";
2686 case st_Param: return "Param,";
2687 case st_Local: return "Local,";
2688 case st_Label: return "Label,";
2689 case st_Proc: return "Proc,";
2690 case st_Block: return "Block,";
2691 case st_End: return "End,";
2692 case st_Member: return "Member,";
2693 case st_Typedef: return "Typedef,";
2694 case st_File: return "File,";
2695 case st_RegReloc: return "RegReloc,";
2696 case st_Forward: return "Forward,";
2697 case st_StaticProc: return "StaticProc,";
2698 case st_Constant: return "Constant,";
2699 case st_Str: return "String,";
2700 case st_Number: return "Number,";
2701 case st_Expr: return "Expr,";
2702 case st_Type: return "Type,";
2703 case st_Max: return "Max,";
2710 /* Read a line from standard input, and return the start of the buffer
2711 (which is grows if the line is too big). We split lines at the
2712 semi-colon, and return each logical line independently. */
2715 read_line __proto((void))
2717 static int line_split_p = 0;
2718 register int string_p = 0;
2719 register int comment_p = 0;
2723 if (cur_line_start == (char *)0)
2724 { /* allocate initial page */
2725 cur_line_start = (char *) allocate_page ();
2726 cur_line_alloc = PAGE_SIZE;
2733 cur_line_nbytes = 0;
2735 for (ptr = cur_line_start; (ch = getchar ()) != EOF; *ptr++ = ch)
2737 if (++cur_line_nbytes >= cur_line_alloc-1)
2739 register int num_pages = cur_line_alloc / PAGE_SIZE;
2740 register char *old_buffer = cur_line_start;
2742 cur_line_alloc += PAGE_SIZE;
2743 cur_line_start = (char *) allocate_multiple_pages (num_pages+1);
2744 memcpy (cur_line_start, old_buffer, num_pages * PAGE_SIZE);
2746 ptr = cur_line_start + cur_line_nbytes - 1;
2753 cur_line_ptr = cur_line_start;
2754 return cur_line_ptr;
2757 else if (ch == '\0')
2758 error ("Null character found in input");
2760 else if (!comment_p)
2763 string_p = !string_p;
2768 else if (ch == ';' && !string_p)
2773 cur_line_ptr = cur_line_start;
2774 return cur_line_ptr;
2780 pfatal_with_name (input_name);
2782 cur_line_ptr = (char *)0;
2787 /* Parse #.begin directives which have a label as the first argument
2788 which gives the location of the start of the block. */
2792 const char *start; /* start of directive */
2794 const char *end_p1; /* end of label */
2796 shash_t *hash_ptr; /* hash pointer to lookup label */
2798 if (cur_file_ptr == (efdr_t *)0)
2800 error ("#.begin directive without a preceding .file directive");
2804 if (cur_proc_ptr == (PDR *)0)
2806 error ("#.begin directive without a preceding .ent directive");
2810 for (end_p1 = start; (ch = *end_p1) != '\0' && !isspace (ch); end_p1++)
2813 hash_ptr = hash_string (start,
2818 if (hash_ptr == (shash_t *)0)
2820 error ("Label %.*s not found for #.begin", end_p1 - start, start);
2824 if (cur_oproc_begin == (SYMR *)0)
2826 error ("Procedure table %.*s not found for #.begin", end_p1 - start, start);
2830 (void) add_local_symbol ((const char *)0, (const char *)0,
2832 (symint_t)hash_ptr->sym_ptr->value - cur_oproc_begin->value,
2837 /* Parse #.bend directives which have a label as the first argument
2838 which gives the location of the end of the block. */
2842 const char *start; /* start of directive */
2844 const char *end_p1; /* end of label */
2846 shash_t *hash_ptr; /* hash pointer to lookup label */
2848 if (cur_file_ptr == (efdr_t *)0)
2850 error ("#.begin directive without a preceding .file directive");
2854 if (cur_proc_ptr == (PDR *)0)
2856 error ("#.bend directive without a preceding .ent directive");
2860 for (end_p1 = start; (ch = *end_p1) != '\0' && !isspace (ch); end_p1++)
2863 hash_ptr = hash_string (start,
2868 if (hash_ptr == (shash_t *)0)
2870 error ("Label %.*s not found for #.bend", end_p1 - start, start);
2874 if (cur_oproc_begin == (SYMR *)0)
2876 error ("Procedure table %.*s not found for #.bend", end_p1 - start, start);
2880 (void) add_local_symbol ((const char *)0, (const char *)0,
2882 (symint_t)hash_ptr->sym_ptr->value - cur_oproc_begin->value,
2887 /* Parse #.def directives, which are contain standard COFF subdirectives
2888 to describe the debugging format. These subdirectives include:
2890 .scl specify storage class
2891 .val specify a value
2892 .endef specify end of COFF directives
2893 .type specify the type
2894 .size specify the size of an array
2895 .dim specify an array dimension
2896 .tag specify a tag for a struct, union, or enum. */
2899 parse_def (name_start)
2900 const char *name_start; /* start of directive */
2902 const char *dir_start; /* start of current directive*/
2903 const char *dir_end_p1; /* end+1 of current directive*/
2904 const char *arg_start; /* start of current argument */
2905 const char *arg_end_p1; /* end+1 of current argument */
2906 const char *name_end_p1; /* end+1 of label */
2907 const char *tag_start = (const char *)0; /* start of tag name */
2908 const char *tag_end_p1 = (const char *)0; /* end+1 of tag name */
2909 sc_t storage_class = sc_Nil;
2910 st_t symbol_type = st_Nil;
2912 EXTR *eptr = (EXTR *)0; /* ext. sym equivalent to def*/
2913 int is_function = 0; /* != 0 if function */
2915 symint_t indx = cur_file_ptr->void_type;
2917 symint_t arg_number;
2918 symint_t temp_array[ N_TQ ];
2923 static int inside_enumeration = 0; /* is this an enumeration? */
2926 /* Initialize the type information. */
2930 /* Search for the end of the name being defined. */
2931 /* Allow spaces and such in names for G++ templates, which produce stabs
2934 #.def SMANIP<long unsigned int>; .scl 10; .type 0x8; .size 8; .endef */
2936 for (name_end_p1 = name_start; (ch = *name_end_p1) != ';' && ch != '\0'; name_end_p1++)
2941 error_line = __LINE__;
2946 /* Parse the remaining subdirectives now. */
2947 dir_start = name_end_p1+1;
2950 while ((ch = *dir_start) == ' ' || ch == '\t')
2955 error_line = __LINE__;
2961 if (dir_start[1] == 'e'
2962 && memcmp (dir_start, ".endef", sizeof (".endef")-1) == 0)
2965 /* Pick up the subdirective now */
2966 for (dir_end_p1 = dir_start+1;
2967 (ch = *dir_end_p1) != ' ' && ch != '\t';
2970 if (ch == '\0' || isspace (ch))
2972 error_line = __LINE__;
2978 /* Pick up the subdirective argument now. */
2979 arg_was_number = arg_number = 0;
2980 arg_end_p1 = (const char *)0;
2981 arg_start = dir_end_p1+1;
2983 while (ch == ' ' || ch == '\t')
2986 if (isdigit (ch) || ch == '-' || ch == '+')
2989 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
2990 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
2994 else if (ch == '\0' || isspace (ch))
2996 error_line = __LINE__;
3001 if (!arg_was_number)
3003 /* Allow spaces and such in names for G++ templates. */
3004 for (arg_end_p1 = arg_start+1;
3005 (ch = *arg_end_p1) != ';' && ch != '\0';
3011 error_line = __LINE__;
3017 /* Classify the directives now. */
3018 len = dir_end_p1 - dir_start;
3019 switch (dir_start[1])
3022 error_line = __LINE__;
3027 if (len == sizeof (".dim")-1
3028 && memcmp (dir_start, ".dim", sizeof (".dim")-1) == 0
3031 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
3033 *t_ptr = arg_number;
3034 while (*arg_end_p1 == ',' && arg_was_number)
3036 arg_start = arg_end_p1+1;
3038 while (ch == ' ' || ch == '\t')
3042 if (isdigit (ch) || ch == '-' || ch == '+')
3045 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
3046 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
3049 if (t_ptr == &temp_array[0])
3051 error_line = __LINE__;
3056 *--t_ptr = arg_number;
3060 /* Reverse order of dimensions. */
3061 while (t_ptr <= &temp_array[ N_TQ-1 ])
3063 if (t.num_dims >= N_TQ-1)
3065 error_line = __LINE__;
3070 t.dimensions[ t.num_dims++ ] = *t_ptr++;
3076 error_line = __LINE__;
3083 if (len == sizeof (".scl")-1
3084 && memcmp (dir_start, ".scl", sizeof (".scl")-1) == 0
3086 && arg_number < ((symint_t) C_MAX))
3088 /* If the symbol is a static or external, we have
3089 already gotten the appropriate type and class, so
3090 make sure we don't override those values. This is
3091 needed because there are some type and classes that
3092 are not in COFF, such as short data, etc. */
3093 if (symbol_type == st_Nil)
3095 symbol_type = map_coff_sym_type[arg_number];
3096 storage_class = map_coff_storage [arg_number];
3101 else if (len == sizeof (".size")-1
3102 && memcmp (dir_start, ".size", sizeof (".size")-1) == 0
3105 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
3107 *t_ptr = arg_number;
3108 while (*arg_end_p1 == ',' && arg_was_number)
3110 arg_start = arg_end_p1+1;
3112 while (ch == ' ' || ch == '\t')
3116 if (isdigit (ch) || ch == '-' || ch == '+')
3119 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
3120 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
3123 if (t_ptr == &temp_array[0])
3125 error_line = __LINE__;
3130 *--t_ptr = arg_number;
3134 /* Reverse order of sizes. */
3135 while (t_ptr <= &temp_array[ N_TQ-1 ])
3137 if (t.num_sizes >= N_TQ-1)
3139 error_line = __LINE__;
3144 t.sizes[ t.num_sizes++ ] = *t_ptr++;
3151 error_line = __LINE__;
3158 if (len == sizeof (".type")-1
3159 && memcmp (dir_start, ".type", sizeof (".type")-1) == 0
3162 tq_t *tq_ptr = &t.type_qualifiers[0];
3164 t.orig_type = (coff_type_t) (arg_number & N_BTMASK);
3165 t.basic_type = map_coff_types [(int)t.orig_type];
3166 for (i = N_TQ-1; i >= 0; i--)
3168 int dt = (arg_number >> ((i * N_TQ_SHIFT) + N_BT_SHIFT)
3171 if (dt != (int)DT_NON)
3172 *tq_ptr++ = map_coff_derived_type [dt];
3175 /* If this is a function, ignore it, so that we don't get
3176 two entries (one from the .ent, and one for the .def
3177 that precedes it). Save the type information so that
3178 the end block can properly add it after the begin block
3179 index. For MIPS knows what reason, we must strip off
3180 the function type at this point. */
3181 if (tq_ptr != &t.type_qualifiers[0] && tq_ptr[-1] == tq_Proc)
3184 tq_ptr[-1] = tq_Nil;
3190 else if (len == sizeof (".tag")-1
3191 && memcmp (dir_start, ".tag", sizeof (".tag")-1) == 0)
3193 tag_start = arg_start;
3194 tag_end_p1 = arg_end_p1;
3200 error_line = __LINE__;
3207 if (len == sizeof (".val")-1
3208 && memcmp (dir_start, ".val", sizeof (".val")-1) == 0)
3213 /* If the value is not an integer value, it must be the
3214 name of a static or global item. Look up the name in
3215 the original symbol table to pick up the storage
3216 class, symbol type, etc. */
3219 shash_t *orig_hash_ptr; /* hash within orig sym table*/
3220 shash_t *ext_hash_ptr; /* hash within ext. sym table*/
3222 ext_hash_ptr = hash_string (arg_start,
3223 arg_end_p1 - arg_start,
3227 if (ext_hash_ptr != (shash_t *)0
3228 && ext_hash_ptr->esym_ptr != (EXTR *)0)
3229 eptr = ext_hash_ptr->esym_ptr;
3231 orig_hash_ptr = hash_string (arg_start,
3232 arg_end_p1 - arg_start,
3236 if ((orig_hash_ptr == (shash_t *)0
3237 || orig_hash_ptr->sym_ptr == (SYMR *)0)
3238 && eptr == (EXTR *)0)
3240 fprintf (stderr, "warning, %.*s not found in original or external symbol tables, value defaults to 0\n",
3241 arg_end_p1 - arg_start,
3247 SYMR *ptr = (orig_hash_ptr != (shash_t *)0
3248 && orig_hash_ptr->sym_ptr != (SYMR *)0)
3249 ? orig_hash_ptr->sym_ptr
3252 symbol_type = (st_t) ptr->st;
3253 storage_class = (sc_t) ptr->sc;
3261 error_line = __LINE__;
3267 /* Set up to find next directive. */
3268 dir_start = arg_end_p1 + 1;
3272 t.extra_sizes = (tag_start != (char *)0);
3275 int diff = t.num_dims - t.num_sizes;
3276 int i = t.num_dims - 1;
3279 if (t.num_sizes != 1 || diff < 0)
3281 error_line = __LINE__;
3286 /* If this is an array, make sure the same number of dimensions
3287 and sizes were passed, creating extra sizes for multiply
3288 dimensioned arrays if not passed. */
3293 for (j = (sizeof (t.sizes) / sizeof (t.sizes[0])) - 1; j >= 0; j--)
3294 t.sizes[ j ] = ((j-diff) >= 0) ? t.sizes[ j-diff ] : 0;
3296 t.num_sizes = i + 1;
3297 for ( i--; i >= 0; i-- )
3299 if (t.dimensions[ i+1 ])
3300 t.sizes[ i ] = t.sizes[ i+1 ] / t.dimensions[ i+1 ];
3302 t.sizes[ i ] = t.sizes[ i+1 ];
3307 else if (symbol_type == st_Member && t.num_sizes - t.extra_sizes == 1)
3308 { /* Is this a bitfield? This is indicated by a structure memeber
3309 having a size field that isn't an array. */
3315 /* Except for enumeration members & begin/ending of scopes, put the
3316 type word in the aux. symbol table. */
3318 if (symbol_type == st_Block || symbol_type == st_End)
3321 else if (inside_enumeration)
3322 indx = cur_file_ptr->void_type;
3326 if (t.basic_type == bt_Struct
3327 || t.basic_type == bt_Union
3328 || t.basic_type == bt_Enum)
3330 if (tag_start == (char *)0)
3332 error ("No tag specified for %.*s",
3333 name_end_p1 - name_start,
3338 t.tag_ptr = get_tag (tag_start, tag_end_p1, (symint_t)indexNil,
3344 last_func_type_info = t;
3345 last_func_eptr = eptr;
3349 indx = add_aux_sym_tir (&t,
3351 &cur_file_ptr->thash_head[0]);
3355 /* If this is an external or static symbol, update the appropriate
3358 if (eptr != (EXTR *)0
3359 && (eptr->asym.index == indexNil || cur_proc_ptr == (PDR *)0))
3361 eptr->ifd = cur_file_ptr->file_index;
3362 eptr->asym.index = indx;
3366 /* Do any last minute adjustments that are necessary. */
3367 switch (symbol_type)
3373 /* For the beginning of structs, unions, and enumerations, the
3374 size info needs to be passed in the value field. */
3377 if (t.num_sizes - t.num_dims - t.extra_sizes != 1)
3379 error_line = __LINE__;
3387 inside_enumeration = (t.orig_type == T_ENUM);
3391 /* For the end of structs, unions, and enumerations, omit the
3392 name which is always ".eos". This needs to be done last, so
3393 that any error reporting above gives the correct name. */
3396 name_start = name_end_p1 = (const char *)0;
3397 value = inside_enumeration = 0;
3401 /* Members of structures and unions that aren't bitfields, need
3402 to adjust the value from a byte offset to a bit offset.
3403 Members of enumerations do not have the value adjusted, and
3404 can be distinguished by indx == indexNil. For enumerations,
3405 update the maximum enumeration value. */
3408 if (!t.bitfield && !inside_enumeration)
3415 /* Add the symbol, except for global symbols outside of functions,
3416 for which the external symbol table is fine enough. */
3418 if (eptr == (EXTR *)0
3419 || eptr->asym.st == (int)st_Nil
3420 || cur_proc_ptr != (PDR *)0)
3422 symint_t isym = add_local_symbol (name_start, name_end_p1,
3423 symbol_type, storage_class,
3427 /* deal with struct, union, and enum tags. */
3428 if (symbol_type == st_Block)
3430 /* Create or update the tag information. */
3431 tag_t *tag_ptr = get_tag (name_start,
3436 /* If there are any forward references, fill in the appropriate
3437 file and symbol indexes. */
3439 symint_t file_index = cur_file_ptr->file_index;
3440 forward_t *f_next = tag_ptr->forward_ref;
3443 while (f_next != (forward_t *)0)
3446 f_next = f_next->next;
3448 f_cur->ifd_ptr->isym = file_index;
3449 f_cur->index_ptr->rndx.index = isym;
3451 free_forward (f_cur);
3454 tag_ptr->forward_ref = (forward_t *)0;
3461 /* Error return, issue message. */
3464 error ("compiler error, badly formed #.def (internal line # = %d)", error_line);
3466 error ("compiler error, badly formed #.def");
3472 /* Parse .end directives. */
3476 const char *start; /* start of directive */
3478 register const char *start_func, *end_func_p1;
3480 register symint_t value;
3481 register FDR *orig_fdr;
3483 if (cur_file_ptr == (efdr_t *)0)
3485 error (".end directive without a preceding .file directive");
3489 if (cur_proc_ptr == (PDR *)0)
3491 error (".end directive without a preceding .ent directive");
3495 /* Get the function name, skipping whitespace. */
3496 for (start_func = start; isspace (*start_func); start_func++)
3500 if (!IS_ASM_IDENT (ch))
3502 error (".end directive has no name");
3506 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
3510 /* Get the value field for creating the end from the original object
3511 file (which we find by locating the procedure start, and using the
3512 pointer to the end+1 block and backing up. The index points to a
3513 two word aux. symbol, whose first word is the index of the end
3514 symbol, and the second word is the type of the function return
3517 orig_fdr = cur_file_ptr->orig_fdr;
3519 if (orig_fdr != (FDR *)0 && cur_oproc_end != (SYMR *)0)
3520 value = cur_oproc_end->value;
3523 error ("Cannot find .end block for %.*s", end_func_p1 - start_func, start_func);
3525 (void) add_local_symbol (start_func, end_func_p1,
3530 cur_proc_ptr = cur_oproc_ptr = (PDR *)0;
3534 /* Parse .ent directives. */
3538 const char *start; /* start of directive */
3540 register const char *start_func, *end_func_p1;
3543 if (cur_file_ptr == (efdr_t *)0)
3545 error (".ent directive without a preceding .file directive");
3549 if (cur_proc_ptr != (PDR *)0)
3551 error ("second .ent directive found before .end directive");
3555 for (start_func = start; isspace (*start_func); start_func++)
3559 if (!IS_ASM_IDENT (ch))
3561 error (".ent directive has no name");
3565 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
3568 (void) add_procedure (start_func, end_func_p1);
3572 /* Parse .file directives. */
3576 const char *start; /* start of directive */
3579 register char *start_name, *end_name_p1;
3581 (void) strtol (start, &p, 0);
3583 || (start_name = local_index (p, '"')) == (char *)0
3584 || (end_name_p1 = local_rindex (++start_name, '"')) == (char *)0)
3586 error ("Invalid .file directive");
3590 if (cur_proc_ptr != (PDR *)0)
3592 error ("No way to handle .file within .ent/.end section");
3596 add_file (start_name, end_name_p1);
3600 /* Make sure the @stabs symbol is emitted. */
3604 const char *start; /* Start of directive (ignored) */
3608 /* Add a dummy @stabs dymbol. */
3610 (void) add_local_symbol (stabs_symbol,
3611 stabs_symbol + sizeof (stabs_symbol),
3612 stNil, scInfo, -1, MIPS_MARK_STAB(0));
3618 /* Parse .stabs directives.
3620 .stabs directives have five fields:
3621 "string" a string, encoding the type information.
3622 code a numeric code, defined in <stab.h>
3624 0 a zero or line number
3625 value a numeric value or an address.
3627 If the value is relocatable, we transform this into:
3628 iss points as an index into string space
3629 value value from lookup of the name
3630 st st from lookup of the name
3631 sc sc from lookup of the name
3632 index code|CODE_MASK
3634 If the value is not relocatable, we transform this into:
3635 iss points as an index into string space
3639 index code|CODE_MASK
3641 .stabn directives have four fields (string is null):
3642 code a numeric code, defined in <stab.h>
3644 0 a zero or a line number
3645 value a numeric value or an address. */
3648 parse_stabs_common (string_start, string_end, rest)
3649 const char *string_start; /* start of string or NULL */
3650 const char *string_end; /* end+1 of string or NULL */
3651 const char *rest; /* rest of the directive. */
3653 efdr_t *save_file_ptr = cur_file_ptr;
3661 if (stabs_seen == 0)
3664 /* Read code from stabs. */
3665 if (!isdigit (*rest))
3667 error ("Invalid .stabs/.stabn directive, code is non-numeric");
3671 code = strtol (rest, &p, 0);
3673 /* Line number stabs are handled differently, since they have two values,
3674 the line number and the address of the label. We use the index field
3675 (aka code) to hold the line number, and the value field to hold the
3676 address. The symbol type is st_Label, which should be different from
3677 the other stabs, so that gdb can recognize it. */
3679 if (code == (int)N_SLINE)
3681 SYMR *sym_ptr, dummy_symr;
3685 if (p[0] != ',' || p[1] != '0' || p[2] != ',' || !isdigit (p[3]))
3687 error ("Invalid line number .stabs/.stabn directive");
3691 code = strtol (p+3, &p, 0);
3693 if (p[-1] != ',' || isdigit (ch) || !IS_ASM_IDENT (ch))
3695 error ("Invalid line number .stabs/.stabn directive");
3699 dummy_symr.index = code;
3700 if (dummy_symr.index != code)
3702 error ("Line number (%d) for .stabs/.stabn directive cannot fit in index field (20 bits)",
3708 shash_ptr = hash_string (p,
3713 if (shash_ptr == (shash_t *)0
3714 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *)0)
3716 error ("Invalid .stabs/.stabn directive, value not found");
3720 if ((st_t) sym_ptr->st != st_Label)
3722 error ("Invalid line number .stabs/.stabn directive");
3727 sc = (sc_t) sym_ptr->sc;
3728 value = sym_ptr->value;
3732 /* Skip ,<num>,<num>, */
3735 for (; isdigit (*p); p++)
3739 for (; isdigit (*p); p++)
3744 if (!IS_ASM_IDENT (ch) && ch != '-')
3747 error ("Invalid .stabs/.stabn directive, bad character");
3751 if (isdigit (ch) || ch == '-')
3755 value = strtol (p, &p, 0);
3758 error ("Invalid .stabs/.stabn directive, stuff after numeric value");
3762 else if (!IS_ASM_IDENT (ch))
3764 error ("Invalid .stabs/.stabn directive, bad character");
3771 const char *start, *end_p1;
3774 if ((end_p1 = strchr (start, '+')) == (char *)0)
3776 if ((end_p1 = strchr (start, '-')) == (char *)0)
3777 end_p1 = start + strlen(start) - 1;
3780 shash_ptr = hash_string (start,
3785 if (shash_ptr == (shash_t *)0
3786 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *)0)
3788 shash_ptr = hash_string (start,
3793 if (shash_ptr == (shash_t *)0
3794 || shash_ptr->esym_ptr == (EXTR *)0)
3796 error ("Invalid .stabs/.stabn directive, value not found");
3800 sym_ptr = &(shash_ptr->esym_ptr->asym);
3803 /* Traditionally, N_LBRAC and N_RBRAC are *not* relocated. */
3804 if (code == (int)N_LBRAC || code == (int)N_RBRAC)
3811 sc = (sc_t) sym_ptr->sc;
3812 st = (st_t) sym_ptr->st;
3814 value = sym_ptr->value;
3819 if (((!isdigit (*end_p1)) && (*end_p1 != '-'))
3820 || ((ch != '+') && (ch != '-')))
3822 error ("Invalid .stabs/.stabn directive, badly formed value");
3826 value += strtol (end_p1, &p, 0);
3828 value -= strtol (end_p1, &p, 0);
3832 error ("Invalid .stabs/.stabn directive, stuff after numeric value");
3837 code = MIPS_MARK_STAB(code);
3840 (void) add_local_symbol (string_start, string_end, st, sc, value, code);
3841 /* Restore normal file type. */
3842 cur_file_ptr = save_file_ptr;
3848 const char *start; /* start of directive */
3850 const char *end = local_index (start+1, '"');
3852 if (*start != '"' || end == (const char *)0 || end[1] != ',')
3854 error ("Invalid .stabs directive, no string");
3858 parse_stabs_common (start+1, end, end+2);
3864 const char *start; /* start of directive */
3866 parse_stabs_common ((const char *)0, (const char *)0, start);
3870 /* Parse the input file, and write the lines to the output file
3874 parse_input __proto((void))
3878 register thead_t *ptag_head;
3879 register tag_t *ptag;
3880 register tag_t *ptag_next;
3883 fprintf (stderr, "\tinput\n");
3885 /* Add a dummy scope block around the entire compilation unit for
3886 structures defined outside of blocks. */
3887 ptag_head = allocate_thead ();
3888 ptag_head->first_tag = 0;
3889 ptag_head->prev = cur_tag_head;
3890 cur_tag_head = ptag_head;
3892 while ((p = read_line ()) != (char *)0)
3894 /* Skip leading blanks */
3895 while (isspace (*p))
3898 /* See if it's a directive we handle. If so, dispatch handler. */
3899 for (i = 0; i < sizeof (pseudo_ops) / sizeof (pseudo_ops[0]); i++)
3900 if (memcmp (p, pseudo_ops[i].name, pseudo_ops[i].len) == 0
3901 && isspace (p[pseudo_ops[i].len]))
3903 p += pseudo_ops[i].len; /* skip to first argument */
3904 while (isspace (*p))
3907 (*pseudo_ops[i].func)( p );
3912 /* Process any tags at global level. */
3913 ptag_head = cur_tag_head;
3914 cur_tag_head = ptag_head->prev;
3916 for (ptag = ptag_head->first_tag;
3920 if (ptag->forward_ref != (forward_t *)0)
3921 add_unknown_tag (ptag);
3923 ptag_next = ptag->same_block;
3924 ptag->hash_ptr->tag_ptr = ptag->same_name;
3928 free_thead (ptag_head);
3933 /* Update the global headers with the final offsets in preparation
3934 to write out the .T file. */
3937 update_headers __proto((void))
3939 register symint_t i;
3940 register efdr_t *file_ptr;
3942 /* Set up the symbolic header. */
3943 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
3944 symbolic_header.magic = orig_sym_hdr.magic;
3945 symbolic_header.vstamp = orig_sym_hdr.vstamp;
3947 /* Set up global counts. */
3948 symbolic_header.issExtMax = ext_strings.num_allocated;
3949 symbolic_header.idnMax = dense_num.num_allocated;
3950 symbolic_header.ifdMax = file_desc.num_allocated;
3951 symbolic_header.iextMax = ext_symbols.num_allocated;
3952 symbolic_header.ilineMax = orig_sym_hdr.ilineMax;
3953 symbolic_header.ioptMax = orig_sym_hdr.ioptMax;
3954 symbolic_header.cbLine = orig_sym_hdr.cbLine;
3955 symbolic_header.crfd = orig_sym_hdr.crfd;
3958 /* Loop through each file, figuring out how many local syms,
3959 line numbers, etc. there are. Also, put out end symbol
3960 for the filename. */
3962 for (file_ptr = first_file;
3963 file_ptr != (efdr_t *)0;
3964 file_ptr = file_ptr->next_file)
3966 cur_file_ptr = file_ptr;
3967 (void) add_local_symbol ((const char *)0, (const char *)0,
3972 file_ptr->fdr.cpd = file_ptr->procs.num_allocated;
3973 file_ptr->fdr.ipdFirst = symbolic_header.ipdMax;
3974 symbolic_header.ipdMax += file_ptr->fdr.cpd;
3976 file_ptr->fdr.csym = file_ptr->symbols.num_allocated;
3977 file_ptr->fdr.isymBase = symbolic_header.isymMax;
3978 symbolic_header.isymMax += file_ptr->fdr.csym;
3980 file_ptr->fdr.caux = file_ptr->aux_syms.num_allocated;
3981 file_ptr->fdr.iauxBase = symbolic_header.iauxMax;
3982 symbolic_header.iauxMax += file_ptr->fdr.caux;
3984 file_ptr->fdr.cbSs = file_ptr->strings.num_allocated;
3985 file_ptr->fdr.issBase = symbolic_header.issMax;
3986 symbolic_header.issMax += file_ptr->fdr.cbSs;
3990 i = WORD_ALIGN (symbolic_header.cbLine); /* line numbers */
3993 symbolic_header.cbLineOffset = file_offset;
3997 i = symbolic_header.ioptMax; /* optimization symbols */
4000 symbolic_header.cbOptOffset = file_offset;
4001 file_offset += i * sizeof (OPTR);
4004 i = symbolic_header.idnMax; /* dense numbers */
4007 symbolic_header.cbDnOffset = file_offset;
4008 file_offset += i * sizeof (DNR);
4011 i = symbolic_header.ipdMax; /* procedure tables */
4014 symbolic_header.cbPdOffset = file_offset;
4015 file_offset += i * sizeof (PDR);
4018 i = symbolic_header.isymMax; /* local symbols */
4021 symbolic_header.cbSymOffset = file_offset;
4022 file_offset += i * sizeof (SYMR);
4025 i = symbolic_header.iauxMax; /* aux syms. */
4028 symbolic_header.cbAuxOffset = file_offset;
4029 file_offset += i * sizeof (TIR);
4032 i = WORD_ALIGN (symbolic_header.issMax); /* local strings */
4035 symbolic_header.cbSsOffset = file_offset;
4039 i = WORD_ALIGN (symbolic_header.issExtMax); /* external strings */
4042 symbolic_header.cbSsExtOffset = file_offset;
4046 i = symbolic_header.ifdMax; /* file tables */
4049 symbolic_header.cbFdOffset = file_offset;
4050 file_offset += i * sizeof (FDR);
4053 i = symbolic_header.crfd; /* relative file descriptors */
4056 symbolic_header.cbRfdOffset = file_offset;
4057 file_offset += i * sizeof (symint_t);
4060 i = symbolic_header.iextMax; /* external symbols */
4063 symbolic_header.cbExtOffset = file_offset;
4064 file_offset += i * sizeof (EXTR);
4069 /* Write out a varray at a given location. */
4072 write_varray (vp, offset, str)
4073 varray_t *vp; /* virtual array */
4074 off_t offset; /* offset to write varray to */
4075 const char *str; /* string to print out when tracing */
4077 int num_write, sys_write;
4080 if (vp->num_allocated == 0)
4084 fprintf (stderr, "\twarray\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4085 vp, offset, vp->num_allocated * vp->object_size, str);
4087 if (file_offset != offset
4088 && fseek (object_stream, (long)offset, SEEK_SET) < 0)
4089 pfatal_with_name (object_name);
4091 for (ptr = vp->first; ptr != (vlinks_t *)0; ptr = ptr->next)
4093 num_write = (ptr->next == (vlinks_t *)0)
4094 ? vp->objects_last_page * vp->object_size
4095 : vp->objects_per_page * vp->object_size;
4097 sys_write = fwrite ((PTR_T) ptr->datum, 1, num_write, object_stream);
4099 pfatal_with_name (object_name);
4101 else if (sys_write != num_write)
4102 fatal ("Wrote %d bytes to %s, system returned %d",
4107 file_offset += num_write;
4112 /* Write out the symbol table in the object file. */
4115 write_object __proto((void))
4122 fprintf (stderr, "\n\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4123 (PTR_T *) &symbolic_header, 0, sizeof (symbolic_header),
4126 sys_write = fwrite ((PTR_T) &symbolic_header,
4128 sizeof (symbolic_header),
4132 pfatal_with_name (object_name);
4134 else if (sys_write != sizeof (symbolic_header))
4135 fatal ("Wrote %d bytes to %s, system returned %d",
4136 sizeof (symbolic_header),
4141 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
4143 if (symbolic_header.cbLine > 0) /* line numbers */
4147 if (file_offset != symbolic_header.cbLineOffset
4148 && fseek (object_stream, symbolic_header.cbLineOffset, SEEK_SET) != 0)
4149 pfatal_with_name (object_name);
4152 fprintf (stderr, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4153 (PTR_T *) &orig_linenum, symbolic_header.cbLineOffset,
4154 symbolic_header.cbLine, "Line numbers");
4156 sys_write = fwrite ((PTR_T) orig_linenum,
4158 symbolic_header.cbLine,
4162 pfatal_with_name (object_name);
4164 else if (sys_write != symbolic_header.cbLine)
4165 fatal ("Wrote %d bytes to %s, system returned %d",
4166 symbolic_header.cbLine,
4170 file_offset = symbolic_header.cbLineOffset + symbolic_header.cbLine;
4173 if (symbolic_header.ioptMax > 0) /* optimization symbols */
4176 long num_write = symbolic_header.ioptMax * sizeof (OPTR);
4178 if (file_offset != symbolic_header.cbOptOffset
4179 && fseek (object_stream, symbolic_header.cbOptOffset, SEEK_SET) != 0)
4180 pfatal_with_name (object_name);
4183 fprintf (stderr, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4184 (PTR_T *) &orig_opt_syms, symbolic_header.cbOptOffset,
4185 num_write, "Optimizer symbols");
4187 sys_write = fwrite ((PTR_T) orig_opt_syms,
4193 pfatal_with_name (object_name);
4195 else if (sys_write != num_write)
4196 fatal ("Wrote %d bytes to %s, system returned %d",
4201 file_offset = symbolic_header.cbOptOffset + num_write;
4204 if (symbolic_header.idnMax > 0) /* dense numbers */
4205 write_varray (&dense_num, (off_t)symbolic_header.cbDnOffset, "Dense numbers");
4207 if (symbolic_header.ipdMax > 0) /* procedure tables */
4209 offset = symbolic_header.cbPdOffset;
4210 for (file_ptr = first_file;
4211 file_ptr != (efdr_t *)0;
4212 file_ptr = file_ptr->next_file)
4214 write_varray (&file_ptr->procs, offset, "Procedure tables");
4215 offset = file_offset;
4219 if (symbolic_header.isymMax > 0) /* local symbols */
4221 offset = symbolic_header.cbSymOffset;
4222 for (file_ptr = first_file;
4223 file_ptr != (efdr_t *)0;
4224 file_ptr = file_ptr->next_file)
4226 write_varray (&file_ptr->symbols, offset, "Local symbols");
4227 offset = file_offset;
4231 if (symbolic_header.iauxMax > 0) /* aux symbols */
4233 offset = symbolic_header.cbAuxOffset;
4234 for (file_ptr = first_file;
4235 file_ptr != (efdr_t *)0;
4236 file_ptr = file_ptr->next_file)
4238 write_varray (&file_ptr->aux_syms, offset, "Aux. symbols");
4239 offset = file_offset;
4243 if (symbolic_header.issMax > 0) /* local strings */
4245 offset = symbolic_header.cbSsOffset;
4246 for (file_ptr = first_file;
4247 file_ptr != (efdr_t *)0;
4248 file_ptr = file_ptr->next_file)
4250 write_varray (&file_ptr->strings, offset, "Local strings");
4251 offset = file_offset;
4255 if (symbolic_header.issExtMax > 0) /* external strings */
4256 write_varray (&ext_strings, symbolic_header.cbSsExtOffset, "External strings");
4258 if (symbolic_header.ifdMax > 0) /* file tables */
4260 offset = symbolic_header.cbFdOffset;
4261 if (file_offset != offset
4262 && fseek (object_stream, (long)offset, SEEK_SET) < 0)
4263 pfatal_with_name (object_name);
4265 file_offset = offset;
4266 for (file_ptr = first_file;
4267 file_ptr != (efdr_t *)0;
4268 file_ptr = file_ptr->next_file)
4271 fprintf (stderr, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4272 (PTR_T *) &file_ptr->fdr, file_offset, sizeof (FDR), "File header");
4274 sys_write = fwrite (&file_ptr->fdr,
4280 pfatal_with_name (object_name);
4282 else if (sys_write != sizeof (FDR))
4283 fatal ("Wrote %d bytes to %s, system returned %d",
4288 file_offset = offset += sizeof (FDR);
4292 if (symbolic_header.crfd > 0) /* relative file descriptors */
4295 symint_t num_write = symbolic_header.crfd * sizeof (symint_t);
4297 if (file_offset != symbolic_header.cbRfdOffset
4298 && fseek (object_stream, symbolic_header.cbRfdOffset, SEEK_SET) != 0)
4299 pfatal_with_name (object_name);
4302 fprintf (stderr, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4303 (PTR_T *) &orig_rfds, symbolic_header.cbRfdOffset,
4304 num_write, "Relative file descriptors");
4306 sys_write = fwrite (orig_rfds,
4312 pfatal_with_name (object_name);
4314 else if (sys_write != num_write)
4315 fatal ("Wrote %d bytes to %s, system returned %d",
4320 file_offset = symbolic_header.cbRfdOffset + num_write;
4323 if (symbolic_header.issExtMax > 0) /* external symbols */
4324 write_varray (&ext_symbols, (off_t)symbolic_header.cbExtOffset, "External symbols");
4326 if (fclose (object_stream) != 0)
4327 pfatal_with_name (object_name);
4331 /* Read some bytes at a specified location, and return a pointer. */
4334 read_seek (size, offset, str)
4335 Size_t size; /* # bytes to read */
4336 off_t offset; /* offset to read at */
4337 const char *str; /* name for tracing */
4342 if (size == 0) /* nothing to read */
4346 fprintf (stderr, "\trseek\tsize = %7u, offset = %7u, currently at %7u, %s\n",
4347 size, offset, file_offset, str);
4349 #ifndef MALLOC_CHECK
4350 ptr = allocate_multiple_pages ((size + PAGE_USIZE - 1) / PAGE_USIZE);
4352 ptr = (page_t *) xcalloc (1, size);
4355 /* If we need to seek, and the distance is nearby, just do some reads,
4356 to speed things up. */
4357 if (file_offset != offset)
4359 symint_t difference = offset - file_offset;
4363 char small_buffer[8];
4365 sys_read = fread (small_buffer, 1, difference, obj_in_stream);
4367 pfatal_with_name (obj_in_name);
4369 if (sys_read != difference)
4370 fatal ("Wanted to read %d bytes from %s, system returned %d",
4375 else if (fseek (obj_in_stream, offset, SEEK_SET) < 0)
4376 pfatal_with_name (obj_in_name);
4379 sys_read = fread ((PTR_T)ptr, 1, size, obj_in_stream);
4381 pfatal_with_name (obj_in_name);
4383 if (sys_read != size)
4384 fatal ("Wanted to read %d bytes from %s, system returned %d",
4389 file_offset = offset + size;
4391 if (file_offset > max_file_offset)
4392 max_file_offset = file_offset;
4398 /* Read the existing object file (and copy to the output object file
4399 if it is different from the input object file), and remove the old
4403 copy_object __proto((void))
4405 char buffer[ PAGE_SIZE ];
4406 register int sys_read;
4407 register int remaining;
4408 register int num_write;
4409 register int sys_write;
4410 register int fd, es;
4411 register int delete_ifd = 0;
4412 register int *remap_file_number;
4413 struct stat stat_buf;
4416 fprintf (stderr, "\tcopy\n");
4418 if (fstat (fileno (obj_in_stream), &stat_buf) != 0
4419 || fseek (obj_in_stream, 0L, SEEK_SET) != 0)
4420 pfatal_with_name (obj_in_name);
4422 sys_read = fread ((PTR_T) &orig_file_header,
4424 sizeof (struct filehdr),
4428 pfatal_with_name (obj_in_name);
4430 else if (sys_read == 0 && feof (obj_in_stream))
4431 return; /* create a .T file sans file header */
4433 else if (sys_read < sizeof (struct filehdr))
4434 fatal ("Wanted to read %d bytes from %s, system returned %d",
4435 sizeof (struct filehdr),
4440 if (orig_file_header.f_nsyms != sizeof (HDRR))
4441 fatal ("%s symbolic header wrong size (%d bytes, should be %d)",
4442 input_name, orig_file_header.f_nsyms, sizeof (HDRR));
4445 /* Read in the current symbolic header. */
4446 if (fseek (obj_in_stream, (long) orig_file_header.f_symptr, SEEK_SET) != 0)
4447 pfatal_with_name (input_name);
4449 sys_read = fread ((PTR_T) &orig_sym_hdr,
4451 sizeof (orig_sym_hdr),
4455 pfatal_with_name (object_name);
4457 else if (sys_read < sizeof (struct filehdr))
4458 fatal ("Wanted to read %d bytes from %s, system returned %d",
4459 sizeof (struct filehdr),
4464 /* Read in each of the sections if they exist in the object file.
4465 We read things in in the order the mips assembler creates the
4466 sections, so in theory no extra seeks are done.
4468 For simplicity sake, round each read up to a page boundary,
4469 we may want to revisit this later.... */
4471 file_offset = orig_file_header.f_symptr + sizeof (struct filehdr);
4473 if (orig_sym_hdr.cbLine > 0) /* line numbers */
4474 orig_linenum = (char *) read_seek ((Size_t)orig_sym_hdr.cbLine,
4475 orig_sym_hdr.cbLineOffset,
4478 if (orig_sym_hdr.ipdMax > 0) /* procedure tables */
4479 orig_procs = (PDR *) read_seek ((Size_t)orig_sym_hdr.ipdMax * sizeof (PDR),
4480 orig_sym_hdr.cbPdOffset,
4481 "Procedure tables");
4483 if (orig_sym_hdr.isymMax > 0) /* local symbols */
4484 orig_local_syms = (SYMR *) read_seek ((Size_t)orig_sym_hdr.isymMax * sizeof (SYMR),
4485 orig_sym_hdr.cbSymOffset,
4488 if (orig_sym_hdr.iauxMax > 0) /* aux symbols */
4489 orig_aux_syms = (AUXU *) read_seek ((Size_t)orig_sym_hdr.iauxMax * sizeof (AUXU),
4490 orig_sym_hdr.cbAuxOffset,
4493 if (orig_sym_hdr.issMax > 0) /* local strings */
4494 orig_local_strs = (char *) read_seek ((Size_t)orig_sym_hdr.issMax,
4495 orig_sym_hdr.cbSsOffset,
4498 if (orig_sym_hdr.issExtMax > 0) /* external strings */
4499 orig_ext_strs = (char *) read_seek ((Size_t)orig_sym_hdr.issExtMax,
4500 orig_sym_hdr.cbSsExtOffset,
4501 "External strings");
4503 if (orig_sym_hdr.ifdMax > 0) /* file tables */
4504 orig_files = (FDR *) read_seek ((Size_t)orig_sym_hdr.ifdMax * sizeof (FDR),
4505 orig_sym_hdr.cbFdOffset,
4508 if (orig_sym_hdr.crfd > 0) /* relative file descriptors */
4509 orig_rfds = (symint_t *) read_seek ((Size_t)orig_sym_hdr.crfd * sizeof (symint_t),
4510 orig_sym_hdr.cbRfdOffset,
4511 "Relative file descriptors");
4513 if (orig_sym_hdr.issExtMax > 0) /* external symbols */
4514 orig_ext_syms = (EXTR *) read_seek ((Size_t)orig_sym_hdr.iextMax * sizeof (EXTR),
4515 orig_sym_hdr.cbExtOffset,
4516 "External symbols");
4518 if (orig_sym_hdr.idnMax > 0) /* dense numbers */
4520 orig_dense = (DNR *) read_seek ((Size_t)orig_sym_hdr.idnMax * sizeof (DNR),
4521 orig_sym_hdr.cbDnOffset,
4524 add_bytes (&dense_num, (char *) orig_dense, (Size_t)orig_sym_hdr.idnMax);
4527 if (orig_sym_hdr.ioptMax > 0) /* opt symbols */
4528 orig_opt_syms = (OPTR *) read_seek ((Size_t)orig_sym_hdr.ioptMax * sizeof (OPTR),
4529 orig_sym_hdr.cbOptOffset,
4530 "Optimizer symbols");
4534 /* Abort if the symbol table is not last. */
4535 if (max_file_offset != stat_buf.st_size)
4536 fatal ("Symbol table is not last (symbol table ends at %ld, .o ends at %ld",
4541 /* If the first original file descriptor is a dummy which the assembler
4542 put out, but there are no symbols in it, skip it now. */
4543 if (orig_sym_hdr.ifdMax > 1
4544 && orig_files->csym == 2
4545 && orig_files->caux == 0)
4547 char *filename = orig_local_strs + (orig_files->issBase + orig_files->rss);
4548 char *suffix = local_rindex (filename, '.');
4550 if (suffix != (char *)0 && strcmp (suffix, ".s") == 0)
4555 /* Create array to map original file numbers to the new file numbers
4556 (in case there are duplicate filenames, we collapse them into one
4557 file section, the MIPS assembler may or may not collapse them). */
4559 remap_file_number = (int *) alloca (sizeof (int) * orig_sym_hdr.ifdMax);
4561 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
4563 register FDR *fd_ptr = ORIG_FILES (fd);
4564 register char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
4566 /* file support itself. */
4567 add_file (filename, filename + strlen (filename));
4568 remap_file_number[fd] = cur_file_ptr->file_index;
4571 if (delete_ifd > 0) /* just in case */
4572 remap_file_number[0] = remap_file_number[1];
4575 /* Loop, adding each of the external symbols. These must be in
4576 order or otherwise we would have to change the relocation
4577 entries. We don't just call add_bytes, because we need to have
4578 the names put into the external hash table. We set the type to
4579 'void' for now, and parse_def will fill in the correct type if it
4580 is in the symbol table. We must add the external symbols before
4581 the locals, since the locals do lookups against the externals. */
4584 fprintf (stderr, "\tehash\n");
4586 for (es = 0; es < orig_sym_hdr.iextMax; es++)
4588 register EXTR *eptr = orig_ext_syms + es;
4589 register char *ename = ORIG_ESTRS (eptr->asym.iss);
4590 register unsigned ifd = eptr->ifd;
4592 (void) add_ext_symbol (ename,
4593 ename + strlen (ename),
4594 (st_t) eptr->asym.st,
4595 (sc_t) eptr->asym.sc,
4597 (symint_t)((eptr->asym.index == indexNil) ? indexNil : 0),
4598 (ifd < orig_sym_hdr.ifdMax) ? remap_file_number[ ifd ] : ifd);
4602 /* For each of the files in the object file, copy the symbols, and such
4603 into the varrays for the new object file. */
4605 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
4607 register FDR *fd_ptr = ORIG_FILES (fd);
4608 register char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
4609 register SYMR *sym_start;
4611 register SYMR *sym_end_p1;
4612 register PDR *proc_start;
4614 register PDR *proc_end_p1;
4616 /* file support itself. */
4617 add_file (filename, filename + strlen (filename));
4618 cur_file_ptr->orig_fdr = fd_ptr;
4620 /* Copy stuff that's just passed through (such as line #'s) */
4621 cur_file_ptr->fdr.adr = fd_ptr->adr;
4622 cur_file_ptr->fdr.ilineBase = fd_ptr->ilineBase;
4623 cur_file_ptr->fdr.cline = fd_ptr->cline;
4624 cur_file_ptr->fdr.rfdBase = fd_ptr->rfdBase;
4625 cur_file_ptr->fdr.crfd = fd_ptr->crfd;
4626 cur_file_ptr->fdr.cbLineOffset = fd_ptr->cbLineOffset;
4627 cur_file_ptr->fdr.cbLine = fd_ptr->cbLine;
4628 cur_file_ptr->fdr.fMerge = fd_ptr->fMerge;
4629 cur_file_ptr->fdr.fReadin = fd_ptr->fReadin;
4630 cur_file_ptr->fdr.glevel = fd_ptr->glevel;
4633 fprintf (stderr, "\thash\tstart, filename %s\n", filename);
4635 /* For each of the static and global symbols defined, add them
4636 to the hash table of original symbols, so we can look up
4639 sym_start = ORIG_LSYMS (fd_ptr->isymBase);
4640 sym_end_p1 = sym_start + fd_ptr->csym;
4641 for (sym = sym_start; sym < sym_end_p1; sym++)
4643 switch ((st_t) sym->st)
4654 auto symint_t hash_index;
4655 register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
4656 register Size_t len = strlen (str);
4657 register shash_t *shash_ptr = hash_string (str,
4662 if (shash_ptr != (shash_t *)0)
4663 error ("internal error, %s is already in original symbol table", str);
4667 shash_ptr = allocate_shash ();
4668 shash_ptr->next = orig_str_hash[hash_index];
4669 orig_str_hash[hash_index] = shash_ptr;
4671 shash_ptr->len = len;
4672 shash_ptr->indx = indexNil;
4673 shash_ptr->string = str;
4674 shash_ptr->sym_ptr = sym;
4680 if ((sc_t) sym->sc == sc_Text)
4682 register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
4686 register Size_t len = strlen (str);
4687 register shash_t *shash_ptr = hash_string (str,
4692 if (shash_ptr != (shash_t *)0)
4693 shash_ptr->end_ptr = sym;
4703 fprintf (stderr, "\thash\tdone, filename %s\n", filename);
4704 fprintf (stderr, "\tproc\tstart, filename %s\n", filename);
4707 /* Go through each of the procedures in this file, and add the
4708 procedure pointer to the hash entry for the given name. */
4710 proc_start = ORIG_PROCS (fd_ptr->ipdFirst);
4711 proc_end_p1 = proc_start + fd_ptr->cpd;
4712 for (proc = proc_start; proc < proc_end_p1; proc++)
4714 register SYMR *proc_sym = ORIG_LSYMS (fd_ptr->isymBase + proc->isym);
4715 register char *str = ORIG_LSTRS (fd_ptr->issBase + proc_sym->iss);
4716 register Size_t len = strlen (str);
4717 register shash_t *shash_ptr = hash_string (str,
4722 if (shash_ptr == (shash_t *)0)
4723 error ("internal error, function %s is not in original symbol table", str);
4726 shash_ptr->proc_ptr = proc;
4730 fprintf (stderr, "\tproc\tdone, filename %s\n", filename);
4733 cur_file_ptr = first_file;
4736 /* Copy all of the object file up to the symbol table. Originally
4737 we were going to use ftruncate, but that doesn't seem to work
4738 on Ultrix 3.1.... */
4740 if (fseek (obj_in_stream, (long)0, SEEK_SET) != 0)
4741 pfatal_with_name (obj_in_name);
4743 if (fseek (object_stream, (long)0, SEEK_SET) != 0)
4744 pfatal_with_name (object_name);
4746 for (remaining = orig_file_header.f_symptr;
4748 remaining -= num_write)
4750 num_write = (remaining <= sizeof (buffer)) ? remaining : sizeof (buffer);
4751 sys_read = fread ((PTR_T) buffer, 1, num_write, obj_in_stream);
4753 pfatal_with_name (obj_in_name);
4755 else if (sys_read != num_write)
4756 fatal ("Wanted to read %d bytes from %s, system returned %d",
4761 sys_write = fwrite (buffer, 1, num_write, object_stream);
4763 pfatal_with_name (object_name);
4765 else if (sys_write != num_write)
4766 fatal ("Wrote %d bytes to %s, system returned %d",
4774 /* Ye olde main program. */
4782 char *p = local_rindex (argv[0], '/');
4787 progname = (p != 0) ? p+1 : argv[0];
4789 (void) signal (SIGSEGV, catch_signal);
4790 (void) signal (SIGBUS, catch_signal);
4791 (void) signal (SIGABRT, catch_signal);
4793 #if !defined(__SABER__) && !defined(lint)
4794 if (sizeof (efdr_t) > PAGE_USIZE)
4795 fatal ("Efdr_t has a sizeof %d bytes, when it should be less than %d",
4799 if (sizeof (page_t) != PAGE_USIZE)
4800 fatal ("Page_t has a sizeof %d bytes, when it should be %d",
4806 alloc_counts[ alloc_type_none ].alloc_name = "none";
4807 alloc_counts[ alloc_type_scope ].alloc_name = "scope";
4808 alloc_counts[ alloc_type_vlinks ].alloc_name = "vlinks";
4809 alloc_counts[ alloc_type_shash ].alloc_name = "shash";
4810 alloc_counts[ alloc_type_thash ].alloc_name = "thash";
4811 alloc_counts[ alloc_type_tag ].alloc_name = "tag";
4812 alloc_counts[ alloc_type_forward ].alloc_name = "forward";
4813 alloc_counts[ alloc_type_thead ].alloc_name = "thead";
4814 alloc_counts[ alloc_type_varray ].alloc_name = "varray";
4816 int_type_info = type_info_init;
4817 int_type_info.basic_type = bt_Int;
4819 void_type_info = type_info_init;
4820 void_type_info.basic_type = bt_Void;
4822 while ((option = getopt (argc, argv, "d:i:I:o:v")) != EOF)
4830 debug = strtol (optarg, &num_end, 0);
4831 if ((unsigned)debug > 4 || num_end == optarg)
4837 if (rename_output || obj_in_name != (char *)0)
4842 /* fall through to 'i' case. */
4845 if (obj_in_name == (char *)0)
4847 obj_in_name = optarg;
4855 if (object_name == (char *)0)
4856 object_name = optarg;
4866 if (obj_in_name == (char *)0 && optind <= argc - 2)
4867 obj_in_name = argv[--argc];
4869 if (object_name == (char *)0 && optind <= argc - 2)
4870 object_name = argv[--argc];
4872 /* If there is an output name, but no input name use
4873 the same file for both, deleting the name between
4874 opening it for input and opening it for output. */
4875 if (obj_in_name == (char *)0 && object_name != (char *)0)
4877 obj_in_name = object_name;
4881 if (object_name == (char *)0 || had_errors || optind != argc - 1)
4883 fprintf (stderr, "Calling Sequence:\n");
4884 fprintf (stderr, "\tmips-tfile [-d <num>] [-v] [-i <o-in-file>] -o <o-out-file> <s-file> (or)\n");
4885 fprintf (stderr, "\tmips-tfile [-d <num>] [-v] [-I <o-in-file>] -o <o-out-file> <s-file> (or)\n");
4886 fprintf (stderr, "\tmips-tfile [-d <num>] [-v] <s-file> <o-in-file> <o-out-file>\n");
4887 fprintf (stderr, "\n");
4888 fprintf (stderr, "Debug levels are:\n");
4889 fprintf (stderr, " 1\tGeneral debug + trace functions/blocks.\n");
4890 fprintf (stderr, " 2\tDebug level 1 + trace externals.\n");
4891 fprintf (stderr, " 3\tDebug level 2 + trace all symbols.\n");
4892 fprintf (stderr, " 4\tDebug level 3 + trace memory allocations.\n");
4899 fprintf (stderr, "mips-tfile version %s", version_string);
4900 #ifdef TARGET_VERSION
4903 fputc ('\n', stderr);
4906 if (obj_in_name == (char *)0)
4907 obj_in_name = object_name;
4909 if (rename_output && rename (object_name, obj_in_name) != 0)
4911 char *buffer = (char *) allocate_multiple_pages (4);
4917 /* Rename failed, copy input file */
4918 in_fd = open (object_name, O_RDONLY, 0666);
4920 pfatal_with_name (object_name);
4922 out_fd = open (obj_in_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
4924 pfatal_with_name (obj_in_name);
4926 while ((len = read (in_fd, buffer, 4*PAGE_SIZE)) > 0)
4928 len2 = write (out_fd, buffer, len);
4930 pfatal_with_name (object_name);
4933 fatal ("wrote %d bytes to %s, expected to write %d", len2, obj_in_name, len);
4936 free_multiple_pages ((page_t *)buffer, 4);
4939 pfatal_with_name (object_name);
4941 if (close (in_fd) < 0)
4942 pfatal_with_name (object_name);
4944 if (close (out_fd) < 0)
4945 pfatal_with_name (obj_in_name);
4948 /* Must open input before output, since the output may be the same file, and
4949 we need to get the input handle before truncating it. */
4950 obj_in_stream = fopen (obj_in_name, "r");
4951 if (obj_in_stream == (FILE *)0)
4952 pfatal_with_name (obj_in_name);
4954 if (delete_input && unlink (obj_in_name) != 0)
4955 pfatal_with_name (obj_in_name);
4957 object_stream = fopen (object_name, "w");
4958 if (object_stream == (FILE *)0)
4959 pfatal_with_name (object_name);
4961 if (strcmp (argv[optind], "-") != 0)
4963 input_name = argv[optind];
4964 if (freopen (argv[optind], "r", stdin) != stdin)
4965 pfatal_with_name (argv[optind]);
4968 copy_object (); /* scan & copy object file */
4969 parse_input (); /* scan all of input */
4971 update_headers (); /* write out tfile */
4976 fprintf (stderr, "\n\tAllocation summary:\n\n");
4977 for (i = (int)alloc_type_none; i < (int)alloc_type_last; i++)
4978 if (alloc_counts[i].total_alloc)
4981 "\t%s\t%5d allocation(s), %5d free(s), %2d page(s)\n",
4982 alloc_counts[i].alloc_name,
4983 alloc_counts[i].total_alloc,
4984 alloc_counts[i].total_free,
4985 alloc_counts[i].total_pages);
4989 return (had_errors) ? 1 : 0;
4993 /* Catch a signal and exit without dumping core. */
4996 catch_signal (signum)
4999 (void) signal (signum, SIG_DFL); /* just in case... */
5000 fatal (sys_siglist[signum]);
5003 /* Print a fatal error message. NAME is the text.
5004 Also include a system error message based on `errno'. */
5007 pfatal_with_name (msg)
5010 int save_errno = errno; /* just in case.... */
5011 if (line_number > 0)
5012 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5014 fprintf (stderr, "%s:", progname);
5018 fprintf (stderr, "[errno = 0] %s\n", msg);
5026 /* Procedure to abort with an out of bounds error message. It has
5027 type int, so it can be used with an ?: expression within the
5028 ORIG_xxx macros, but the function never returns. */
5031 out_of_bounds (indx, max, str, prog_line)
5032 symint_t indx; /* index that is out of bounds */
5033 symint_t max; /* maximum index */
5034 const char *str; /* string to print out */
5035 int prog_line; /* line number within mips-tfile.c */
5037 if (indx < max) /* just in case */
5040 fprintf (stderr, "%s, %s:%ld index %u is out of bounds for %s, max is %u, mips-tfile.c line# %d\n",
5041 progname, input_name, line_number, indx, str, max, prog_line);
5044 return 0; /* turn off warning messages */
5048 /* Allocate a cluster of pages. USE_MALLOC says that malloc does not
5049 like sbrk's behind it's back (or sbrk isn't available). If we use
5050 sbrk, we assume it gives us zeroed pages. */
5052 #ifndef MALLOC_CHECK
5056 allocate_cluster (npages)
5059 register page_t *value = (page_t *) calloc (npages, PAGE_USIZE);
5062 fatal ("Virtual memory exhausted.");
5065 fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
5070 #else /* USE_MALLOC */
5073 allocate_cluster (npages)
5076 register page_t *ptr = (page_t *) sbrk (0); /* current sbreak */
5077 unsigned long offset = ((unsigned long) ptr) & (PAGE_SIZE - 1);
5079 if (offset != 0) /* align to a page boundary */
5081 if (sbrk (PAGE_USIZE - offset) == (char *)-1)
5082 pfatal_with_name ("allocate_cluster");
5084 ptr = (page_t *) (((char *)ptr) + PAGE_SIZE - offset);
5087 if (sbrk (npages * PAGE_USIZE) == (char *)-1)
5088 pfatal_with_name ("allocate_cluster");
5091 fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, ptr);
5096 #endif /* USE_MALLOC */
5099 static page_t *cluster_ptr = NULL;
5100 static unsigned pages_left = 0;
5102 #endif /* MALLOC_CHECK */
5105 /* Allocate some pages (which is initialized to 0). */
5108 allocate_multiple_pages (npages)
5111 #ifndef MALLOC_CHECK
5112 if (pages_left == 0 && npages < MAX_CLUSTER_PAGES)
5114 pages_left = MAX_CLUSTER_PAGES;
5115 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
5118 if (npages <= pages_left)
5120 page_t *ptr = cluster_ptr;
5121 cluster_ptr += npages;
5122 pages_left -= npages;
5126 return allocate_cluster (npages);
5128 #else /* MALLOC_CHECK */
5129 return (page_t *) xcalloc (npages, PAGE_SIZE);
5131 #endif /* MALLOC_CHECK */
5135 /* Release some pages. */
5138 free_multiple_pages (page_ptr, npages)
5142 #ifndef MALLOC_CHECK
5143 if (pages_left == 0)
5145 cluster_ptr = page_ptr;
5146 pages_left = npages;
5149 else if ((page_ptr + npages) == cluster_ptr)
5151 cluster_ptr -= npages;
5152 pages_left += npages;
5155 /* otherwise the page is not freed. If more than call is
5156 done, we probably should worry about it, but at present,
5157 the free pages is done right after an allocate. */
5159 #else /* MALLOC_CHECK */
5160 free ((char *) page_ptr);
5162 #endif /* MALLOC_CHECK */
5166 /* Allocate one page (which is initialized to 0). */
5169 allocate_page __proto((void))
5171 #ifndef MALLOC_CHECK
5172 if (pages_left == 0)
5174 pages_left = MAX_CLUSTER_PAGES;
5175 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
5179 return cluster_ptr++;
5181 #else /* MALLOC_CHECK */
5182 return (page_t *) xcalloc (1, PAGE_SIZE);
5184 #endif /* MALLOC_CHECK */
5188 /* Allocate scoping information. */
5191 allocate_scope __proto((void))
5193 register scope_t *ptr;
5194 static scope_t initial_scope;
5196 #ifndef MALLOC_CHECK
5197 ptr = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope;
5198 if (ptr != (scope_t *)0)
5199 alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr->free;
5203 register int unallocated = alloc_counts[ (int)alloc_type_scope ].unallocated;
5204 register page_t *cur_page = alloc_counts[ (int)alloc_type_scope ].cur_page;
5206 if (unallocated == 0)
5208 unallocated = PAGE_SIZE / sizeof (scope_t);
5209 alloc_counts[ (int)alloc_type_scope ].cur_page = cur_page = allocate_page ();
5210 alloc_counts[ (int)alloc_type_scope ].total_pages++;
5213 ptr = &cur_page->scope[ --unallocated ];
5214 alloc_counts[ (int)alloc_type_scope ].unallocated = unallocated;
5218 ptr = (scope_t *) xmalloc (sizeof (scope_t));
5222 alloc_counts[ (int)alloc_type_scope ].total_alloc++;
5223 *ptr = initial_scope;
5227 /* Free scoping information. */
5233 alloc_counts[ (int)alloc_type_scope ].total_free++;
5235 #ifndef MALLOC_CHECK
5236 ptr->free = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope;
5237 alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr;
5240 xfree ((PTR_T) ptr);
5246 /* Allocate links for pages in a virtual array. */
5249 allocate_vlinks __proto((void))
5251 register vlinks_t *ptr;
5252 static vlinks_t initial_vlinks;
5254 #ifndef MALLOC_CHECK
5255 register int unallocated = alloc_counts[ (int)alloc_type_vlinks ].unallocated;
5256 register page_t *cur_page = alloc_counts[ (int)alloc_type_vlinks ].cur_page;
5258 if (unallocated == 0)
5260 unallocated = PAGE_SIZE / sizeof (vlinks_t);
5261 alloc_counts[ (int)alloc_type_vlinks ].cur_page = cur_page = allocate_page ();
5262 alloc_counts[ (int)alloc_type_vlinks ].total_pages++;
5265 ptr = &cur_page->vlinks[ --unallocated ];
5266 alloc_counts[ (int)alloc_type_vlinks ].unallocated = unallocated;
5269 ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
5273 alloc_counts[ (int)alloc_type_vlinks ].total_alloc++;
5274 *ptr = initial_vlinks;
5279 /* Allocate string hash buckets. */
5282 allocate_shash __proto((void))
5284 register shash_t *ptr;
5285 static shash_t initial_shash;
5287 #ifndef MALLOC_CHECK
5288 register int unallocated = alloc_counts[ (int)alloc_type_shash ].unallocated;
5289 register page_t *cur_page = alloc_counts[ (int)alloc_type_shash ].cur_page;
5291 if (unallocated == 0)
5293 unallocated = PAGE_SIZE / sizeof (shash_t);
5294 alloc_counts[ (int)alloc_type_shash ].cur_page = cur_page = allocate_page ();
5295 alloc_counts[ (int)alloc_type_shash ].total_pages++;
5298 ptr = &cur_page->shash[ --unallocated ];
5299 alloc_counts[ (int)alloc_type_shash ].unallocated = unallocated;
5302 ptr = (shash_t *) xmalloc (sizeof (shash_t));
5306 alloc_counts[ (int)alloc_type_shash ].total_alloc++;
5307 *ptr = initial_shash;
5312 /* Allocate type hash buckets. */
5315 allocate_thash __proto((void))
5317 register thash_t *ptr;
5318 static thash_t initial_thash;
5320 #ifndef MALLOC_CHECK
5321 register int unallocated = alloc_counts[ (int)alloc_type_thash ].unallocated;
5322 register page_t *cur_page = alloc_counts[ (int)alloc_type_thash ].cur_page;
5324 if (unallocated == 0)
5326 unallocated = PAGE_SIZE / sizeof (thash_t);
5327 alloc_counts[ (int)alloc_type_thash ].cur_page = cur_page = allocate_page ();
5328 alloc_counts[ (int)alloc_type_thash ].total_pages++;
5331 ptr = &cur_page->thash[ --unallocated ];
5332 alloc_counts[ (int)alloc_type_thash ].unallocated = unallocated;
5335 ptr = (thash_t *) xmalloc (sizeof (thash_t));
5339 alloc_counts[ (int)alloc_type_thash ].total_alloc++;
5340 *ptr = initial_thash;
5345 /* Allocate structure, union, or enum tag information. */
5348 allocate_tag __proto((void))
5350 register tag_t *ptr;
5351 static tag_t initial_tag;
5353 #ifndef MALLOC_CHECK
5354 ptr = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag;
5355 if (ptr != (tag_t *)0)
5356 alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr->free;
5360 register int unallocated = alloc_counts[ (int)alloc_type_tag ].unallocated;
5361 register page_t *cur_page = alloc_counts[ (int)alloc_type_tag ].cur_page;
5363 if (unallocated == 0)
5365 unallocated = PAGE_SIZE / sizeof (tag_t);
5366 alloc_counts[ (int)alloc_type_tag ].cur_page = cur_page = allocate_page ();
5367 alloc_counts[ (int)alloc_type_tag ].total_pages++;
5370 ptr = &cur_page->tag[ --unallocated ];
5371 alloc_counts[ (int)alloc_type_tag ].unallocated = unallocated;
5375 ptr = (tag_t *) xmalloc (sizeof (tag_t));
5379 alloc_counts[ (int)alloc_type_tag ].total_alloc++;
5384 /* Free scoping information. */
5390 alloc_counts[ (int)alloc_type_tag ].total_free++;
5392 #ifndef MALLOC_CHECK
5393 ptr->free = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag;
5394 alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr;
5397 xfree ((PTR_T) ptr);
5403 /* Allocate forward reference to a yet unknown tag. */
5406 allocate_forward __proto((void))
5408 register forward_t *ptr;
5409 static forward_t initial_forward;
5411 #ifndef MALLOC_CHECK
5412 ptr = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward;
5413 if (ptr != (forward_t *)0)
5414 alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr->free;
5418 register int unallocated = alloc_counts[ (int)alloc_type_forward ].unallocated;
5419 register page_t *cur_page = alloc_counts[ (int)alloc_type_forward ].cur_page;
5421 if (unallocated == 0)
5423 unallocated = PAGE_SIZE / sizeof (forward_t);
5424 alloc_counts[ (int)alloc_type_forward ].cur_page = cur_page = allocate_page ();
5425 alloc_counts[ (int)alloc_type_forward ].total_pages++;
5428 ptr = &cur_page->forward[ --unallocated ];
5429 alloc_counts[ (int)alloc_type_forward ].unallocated = unallocated;
5433 ptr = (forward_t *) xmalloc (sizeof (forward_t));
5437 alloc_counts[ (int)alloc_type_forward ].total_alloc++;
5438 *ptr = initial_forward;
5442 /* Free scoping information. */
5448 alloc_counts[ (int)alloc_type_forward ].total_free++;
5450 #ifndef MALLOC_CHECK
5451 ptr->free = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward;
5452 alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr;
5455 xfree ((PTR_T) ptr);
5461 /* Allocate head of type hash list. */
5464 allocate_thead __proto((void))
5466 register thead_t *ptr;
5467 static thead_t initial_thead;
5469 #ifndef MALLOC_CHECK
5470 ptr = alloc_counts[ (int)alloc_type_thead ].free_list.f_thead;
5471 if (ptr != (thead_t *)0)
5472 alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr->free;
5476 register int unallocated = alloc_counts[ (int)alloc_type_thead ].unallocated;
5477 register page_t *cur_page = alloc_counts[ (int)alloc_type_thead ].cur_page;
5479 if (unallocated == 0)
5481 unallocated = PAGE_SIZE / sizeof (thead_t);
5482 alloc_counts[ (int)alloc_type_thead ].cur_page = cur_page = allocate_page ();
5483 alloc_counts[ (int)alloc_type_thead ].total_pages++;
5486 ptr = &cur_page->thead[ --unallocated ];
5487 alloc_counts[ (int)alloc_type_thead ].unallocated = unallocated;
5491 ptr = (thead_t *) xmalloc (sizeof (thead_t));
5495 alloc_counts[ (int)alloc_type_thead ].total_alloc++;
5496 *ptr = initial_thead;
5500 /* Free scoping information. */
5506 alloc_counts[ (int)alloc_type_thead ].total_free++;
5508 #ifndef MALLOC_CHECK
5509 ptr->free = (thead_t *) alloc_counts[ (int)alloc_type_thead ].free_list.f_thead;
5510 alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr;
5513 xfree ((PTR_T) ptr);
5518 #endif /* MIPS_DEBUGGING_INFO */
5521 /* Output an error message and exit */
5531 if (line_number > 0)
5532 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5534 fprintf (stderr, "%s:", progname);
5537 format = va_arg (ap, char *);
5538 vfprintf (stderr, format, ap);
5540 fprintf (stderr, "\n");
5541 if (line_number > 0)
5542 fprintf (stderr, "line:\t%s\n", cur_line_start);
5556 if (line_number > 0)
5557 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5559 fprintf (stderr, "%s:", progname);
5562 format = va_arg (ap, char *);
5563 vfprintf (stderr, format, ap);
5564 fprintf (stderr, "\n");
5565 if (line_number > 0)
5566 fprintf (stderr, "line:\t%s\n", cur_line_start);
5574 /* More 'friendly' abort that prints the line and file.
5575 config.h can #define abort fancy_abort if you like that sort of thing. */
5580 fatal ("Internal abort.");
5584 /* When `malloc.c' is compiled with `rcheck' defined,
5585 it calls this function to report clobberage. */
5594 /* Same as `malloc' but report error if no memory available. */
5600 register PTR_T value = malloc (size);
5602 fatal ("Virtual memory exhausted.");
5605 fprintf (stderr, "\tmalloc\tptr = 0x%.8x, size = %10u\n", value, size);
5610 /* Same as `calloc' but report error if no memory available. */
5613 xcalloc (size1, size2)
5614 Size_t size1, size2;
5616 register PTR_T value = calloc (size1, size2);
5618 fatal ("Virtual memory exhausted.");
5621 fprintf (stderr, "\tcalloc\tptr = 0x%.8x, size1 = %10u, size2 = %10u [%u]\n",
5622 value, size1, size2, size1+size2);
5627 /* Same as `realloc' but report error if no memory available. */
5630 xrealloc (ptr, size)
5634 register PTR_T result = realloc (ptr, size);
5636 fatal ("Virtual memory exhausted.");
5639 fprintf (stderr, "\trealloc\tptr = 0x%.8x, size = %10u, orig = 0x%.8x\n",
5650 fprintf (stderr, "\tfree\tptr = 0x%.8x\n", ptr);
5656 /* Define our own index/rindex, since the local and global symbol
5657 structures as defined by MIPS has an 'index' field. */
5660 local_index (str, sentinel)
5666 for ( ; (ch = *str) != sentinel; str++)
5676 local_rindex (str, sentinel)
5681 const char *ret = (const char *)0;
5683 for ( ; (ch = *str) != '\0'; str++)