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;
2049 /* The index for an external st_Proc symbol is the index
2050 of the st_Proc symbol in the local symbol table. */
2051 last_func_eptr->asym.index = psym->index;
2055 free_scope (pscope);
2059 cur_file_ptr->nested_scopes += scope_delta;
2061 if (debug && type != st_File
2062 && (debug > 2 || type == st_Block || type == st_End
2063 || type == st_Proc || type == st_StaticProc))
2065 char *sc_str = sc_to_string (storage);
2066 char *st_str = st_to_string (type);
2067 int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
2070 "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
2071 value, depth, sc_str);
2073 if (str_start && str_end_p1 - str_start > 0)
2074 fprintf (stderr, " st= %-11s name= %.*s\n", st_str, str_end_p1 - str_start, str_start);
2077 Size_t len = strlen (st_str);
2078 fprintf (stderr, " st= %.*s\n", len-1, st_str);
2086 /* Add an external symbol. */
2089 add_ext_symbol (str_start, str_end_p1, type, storage, value, indx, ifd)
2090 const char *str_start; /* first byte in string */
2091 const char *str_end_p1; /* first byte after string */
2092 st_t type; /* symbol type */
2093 sc_t storage; /* storage class */
2094 long value; /* value of symbol */
2095 symint_t indx; /* index to local/aux. syms */
2096 int ifd; /* file index */
2098 register EXTR *psym;
2099 register varray_t *vp = &ext_symbols;
2100 shash_t *hash_ptr = (shash_t *)0;
2104 char *sc_str = sc_to_string (storage);
2105 char *st_str = st_to_string (type);
2108 "\tesym\tv= %10ld, ifd= %2d, sc= %-12s",
2109 value, ifd, sc_str);
2111 if (str_start && str_end_p1 - str_start > 0)
2112 fprintf (stderr, " st= %-11s name= %.*s\n", st_str, str_end_p1 - str_start, str_start);
2114 fprintf (stderr, " st= %s\n", st_str);
2117 if (vp->objects_last_page == vp->objects_per_page)
2118 add_varray_page (vp);
2120 psym = &vp->last->datum->esym[ vp->objects_last_page++ ];
2123 psym->asym.value = value;
2124 psym->asym.st = (unsigned) type;
2125 psym->asym.sc = (unsigned) storage;
2126 psym->asym.index = indx;
2127 psym->asym.iss = (str_start == (const char *)0)
2129 : add_string (&ext_strings,
2135 hash_ptr->esym_ptr = psym;
2136 return vp->num_allocated++;
2140 /* Add an auxiliary symbol (passing a symint). */
2143 add_aux_sym_symint (aux_word)
2144 symint_t aux_word; /* auxiliary information word */
2146 register AUXU *aux_ptr;
2147 register efdr_t *file_ptr = cur_file_ptr;
2148 register varray_t *vp = &file_ptr->aux_syms;
2150 if (vp->objects_last_page == vp->objects_per_page)
2151 add_varray_page (vp);
2153 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2154 aux_ptr->isym = aux_word;
2156 return vp->num_allocated++;
2160 /* Add an auxiliary symbol (passing a file/symbol index combo). */
2163 add_aux_sym_rndx (file_index, sym_index)
2167 register AUXU *aux_ptr;
2168 register efdr_t *file_ptr = cur_file_ptr;
2169 register varray_t *vp = &file_ptr->aux_syms;
2171 if (vp->objects_last_page == vp->objects_per_page)
2172 add_varray_page (vp);
2174 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2175 aux_ptr->rndx.rfd = file_index;
2176 aux_ptr->rndx.index = sym_index;
2178 return vp->num_allocated++;
2182 /* Add an auxiliary symbol (passing the basic type and possibly
2183 type qualifiers). */
2186 add_aux_sym_tir (t, state, hash_tbl)
2187 type_info_t *t; /* current type information */
2188 hash_state_t state; /* whether to hash type or not */
2189 thash_t **hash_tbl; /* pointer to hash table to use */
2191 register AUXU *aux_ptr;
2192 register efdr_t *file_ptr = cur_file_ptr;
2193 register varray_t *vp = &file_ptr->aux_syms;
2194 static AUXU init_aux;
2200 aux.ti.bt = (int) t->basic_type;
2201 aux.ti.continued = 0;
2202 aux.ti.fBitfield = t->bitfield;
2204 aux.ti.tq0 = (int) t->type_qualifiers[0];
2205 aux.ti.tq1 = (int) t->type_qualifiers[1];
2206 aux.ti.tq2 = (int) t->type_qualifiers[2];
2207 aux.ti.tq3 = (int) t->type_qualifiers[3];
2208 aux.ti.tq4 = (int) t->type_qualifiers[4];
2209 aux.ti.tq5 = (int) t->type_qualifiers[5];
2212 /* For anything that adds additional information, we must not hash,
2213 so check here, and reset our state. */
2215 if (state != hash_no
2216 && (t->type_qualifiers[0] == tq_Array
2217 || t->type_qualifiers[1] == tq_Array
2218 || t->type_qualifiers[2] == tq_Array
2219 || t->type_qualifiers[3] == tq_Array
2220 || t->type_qualifiers[4] == tq_Array
2221 || t->type_qualifiers[5] == tq_Array
2222 || t->basic_type == bt_Struct
2223 || t->basic_type == bt_Union
2224 || t->basic_type == bt_Enum
2226 || t->num_dims > 0))
2229 /* See if we can hash this type, and save some space, but some types
2230 can't be hashed (because they contain arrays or continuations),
2231 and others can be put into the hash list, but cannot use existing
2232 types because other aux entries precede this one. */
2234 if (state != hash_no)
2236 register thash_t *hash_ptr;
2237 register symint_t hi;
2239 hi = aux.isym & ((1 << HASHBITS) - 1);
2242 for (hash_ptr = hash_tbl[hi];
2243 hash_ptr != (thash_t *)0;
2244 hash_ptr = hash_ptr->next)
2246 if (aux.isym == hash_ptr->type.isym)
2250 if (hash_ptr != (thash_t *)0 && state == hash_yes)
2251 return hash_ptr->indx;
2253 if (hash_ptr == (thash_t *)0)
2255 hash_ptr = allocate_thash ();
2256 hash_ptr->next = hash_tbl[hi];
2257 hash_ptr->type = aux;
2258 hash_ptr->indx = vp->num_allocated;
2259 hash_tbl[hi] = hash_ptr;
2263 /* Everything is set up, add the aux symbol. */
2264 if (vp->objects_last_page == vp->objects_per_page)
2265 add_varray_page (vp);
2267 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2270 ret = vp->num_allocated++;
2272 /* Add bitfield length if it exists.
2274 NOTE: Mips documentation claims bitfield goes at the end of the
2275 AUX record, but the DECstation compiler emits it here.
2276 (This would only make a difference for enum bitfields.)
2278 Also note: We use the last size given since gcc may emit 2
2279 for an enum bitfield. */
2282 (void) add_aux_sym_symint ((symint_t)t->sizes[t->num_sizes-1]);
2285 /* Add tag information if needed. Structure, union, and enum
2286 references add 2 aux symbols: a [file index, symbol index]
2287 pointer to the structure type, and the current file index. */
2289 if (t->basic_type == bt_Struct
2290 || t->basic_type == bt_Union
2291 || t->basic_type == bt_Enum)
2293 register symint_t file_index = t->tag_ptr->ifd;
2294 register symint_t sym_index = t->tag_ptr->indx;
2298 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2299 (void) add_aux_sym_symint ((symint_t)-1);
2301 else if (sym_index != indexNil)
2303 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2304 (void) add_aux_sym_symint (file_index);
2308 register forward_t *forward_ref = allocate_forward ();
2310 forward_ref->type_ptr = aux_ptr;
2311 forward_ref->next = t->tag_ptr->forward_ref;
2312 t->tag_ptr->forward_ref = forward_ref;
2314 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2315 forward_ref->index_ptr
2316 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2318 (void) add_aux_sym_symint (file_index);
2319 forward_ref->ifd_ptr
2320 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2324 /* Add information about array bounds if they exist. */
2325 for (i = 0; i < t->num_dims; i++)
2327 (void) add_aux_sym_rndx (ST_RFDESCAPE,
2328 cur_file_ptr->int_type);
2330 (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/
2331 (void) add_aux_sym_symint ((symint_t)0); /* low bound */
2332 (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/
2333 (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */
2335 : (t->sizes[i] * 8) / t->dimensions[i]);
2338 /* NOTE: Mips documentation claism that the bitfield width goes here.
2339 But it needs to be emitted earlier. */
2345 /* Add a tag to the tag table (unless it already exists). */
2348 get_tag (tag_start, tag_end_p1, indx, basic_type)
2349 const char *tag_start; /* 1st byte of tag name */
2350 const char *tag_end_p1; /* 1st byte after tag name */
2351 symint_t indx; /* index of tag start block */
2352 bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
2356 hash_ptr = hash_string (tag_start,
2357 tag_end_p1 - tag_start,
2361 if (hash_ptr != (shash_t *)0
2362 && hash_ptr->tag_ptr != (tag_t *)0)
2364 tag_ptr = hash_ptr->tag_ptr;
2365 if (indx != indexNil)
2367 tag_ptr->basic_type = basic_type;
2368 tag_ptr->ifd = cur_file_ptr->file_index;
2369 tag_ptr->indx = indx;
2374 (void) add_string (&tag_strings,
2380 tag_ptr = allocate_tag ();
2381 tag_ptr->forward_ref = (forward_t *) 0;
2382 tag_ptr->hash_ptr = hash_ptr;
2383 tag_ptr->same_name = hash_ptr->tag_ptr;
2384 tag_ptr->basic_type = basic_type;
2385 tag_ptr->indx = indx;
2386 tag_ptr->ifd = (indx == indexNil) ? -1 : cur_file_ptr->file_index;
2387 tag_ptr->same_block = cur_tag_head->first_tag;
2389 cur_tag_head->first_tag = tag_ptr;
2390 hash_ptr->tag_ptr = tag_ptr;
2396 /* Add an unknown {struct, union, enum} tag. */
2399 add_unknown_tag (ptag)
2400 tag_t *ptag; /* pointer to tag information */
2402 shash_t *hash_ptr = ptag->hash_ptr;
2403 char *name_start = hash_ptr->string;
2404 char *name_end_p1 = name_start + hash_ptr->len;
2405 forward_t *f_next = ptag->forward_ref;
2408 int file_index = cur_file_ptr->file_index;
2412 char *agg_type = "{unknown aggregate type}";
2413 switch (ptag->basic_type)
2415 case bt_Struct: agg_type = "struct"; break;
2416 case bt_Union: agg_type = "union"; break;
2417 case bt_Enum: agg_type = "enum"; break;
2421 fprintf (stderr, "unknown %s %.*s found\n", agg_type,
2422 hash_ptr->len, name_start);
2425 sym_index = add_local_symbol (name_start,
2432 (void) add_local_symbol (name_start,
2439 while (f_next != (forward_t *)0)
2442 f_next = f_next->next;
2444 f_cur->ifd_ptr->isym = file_index;
2445 f_cur->index_ptr->rndx.index = sym_index;
2447 free_forward (f_cur);
2454 /* Add a procedure to the current file's list of procedures, and record
2455 this is the current procedure. If the assembler created a PDR for
2456 this procedure, use that to initialize the current PDR. */
2459 add_procedure (func_start, func_end_p1)
2460 const char *func_start; /* 1st byte of func name */
2461 const char *func_end_p1; /* 1st byte after func name */
2463 register PDR *new_proc_ptr;
2464 register efdr_t *file_ptr = cur_file_ptr;
2465 register varray_t *vp = &file_ptr->procs;
2466 register symint_t value = 0;
2467 register st_t proc_type = st_Proc;
2468 register shash_t *shash_ptr = hash_string (func_start,
2469 func_end_p1 - func_start,
2474 fputc ('\n', stderr);
2476 if (vp->objects_last_page == vp->objects_per_page)
2477 add_varray_page (vp);
2479 cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[ vp->objects_last_page++ ];
2481 vp->num_allocated++;
2484 /* Did the assembler create this procedure? If so, get the PDR information. */
2485 cur_oproc_ptr = (PDR *)0;
2486 if (shash_ptr != (shash_t *)0)
2488 register PDR *old_proc_ptr = shash_ptr->proc_ptr;
2489 register SYMR *sym_ptr = shash_ptr->sym_ptr;
2491 if (old_proc_ptr != (PDR *)0
2492 && sym_ptr != (SYMR *)0
2493 && ((st_t)sym_ptr->st == st_Proc || (st_t)sym_ptr->st == st_StaticProc))
2495 cur_oproc_begin = sym_ptr;
2496 cur_oproc_end = shash_ptr->end_ptr;
2497 value = sym_ptr->value;
2499 cur_oproc_ptr = old_proc_ptr;
2500 proc_type = (st_t)sym_ptr->st;
2501 *new_proc_ptr = *old_proc_ptr; /* initialize */
2505 if (cur_oproc_ptr == (PDR *)0)
2506 error ("Did not find a PDR block for %.*s", func_end_p1 - func_start, func_start);
2508 /* Determine the start of symbols. */
2509 new_proc_ptr->isym = file_ptr->symbols.num_allocated;
2511 /* Push the start of the function. */
2512 (void) add_local_symbol (func_start, func_end_p1,
2519 /* Add a new filename, and set up all of the file relative
2520 virtual arrays (strings, symbols, aux syms, etc.). Record
2521 where the current file structure lives. */
2524 add_file (file_start, file_end_p1)
2525 const char *file_start; /* first byte in string */
2526 const char *file_end_p1; /* first byte after string */
2528 static char zero_bytes[2] = { '\0', '\0' };
2530 register Ptrdiff_t len = file_end_p1 - file_start;
2531 register int first_ch = *file_start;
2532 register efdr_t *file_ptr;
2535 fprintf (stderr, "\tfile\t%.*s\n", len, file_start);
2537 /* See if the file has already been created. */
2538 for (file_ptr = first_file;
2539 file_ptr != (efdr_t *)0;
2540 file_ptr = file_ptr->next_file)
2542 if (first_ch == file_ptr->name[0]
2543 && file_ptr->name[len] == '\0'
2544 && memcmp ((CPTR_T) file_start, (CPTR_T) file_ptr->name, len) == 0)
2546 cur_file_ptr = file_ptr;
2551 /* If this is a new file, create it. */
2552 if (file_ptr == (efdr_t *)0)
2554 if (file_desc.objects_last_page == file_desc.objects_per_page)
2555 add_varray_page (&file_desc);
2557 file_ptr = cur_file_ptr =
2558 &file_desc.last->datum->file[ file_desc.objects_last_page++ ];
2559 *file_ptr = init_file;
2561 file_ptr->file_index = file_desc.num_allocated++;
2563 /* Allocate the string hash table. */
2564 file_ptr->shash_head = (shash_t **) allocate_page ();
2566 /* Make sure 0 byte in string table is null */
2567 add_string (&file_ptr->strings,
2568 &file_ptr->shash_head[0],
2573 if (file_end_p1 - file_start > PAGE_USIZE-2)
2574 fatal ("Filename goes over one page boundary.");
2576 /* Push the start of the filename. We assume that the filename
2577 will be stored at string offset 1. */
2578 (void) add_local_symbol (file_start, file_end_p1, st_File, sc_Text,
2579 (symint_t)0, (symint_t)0);
2580 file_ptr->fdr.rss = 1;
2581 file_ptr->name = &file_ptr->strings.last->datum->byte[1];
2582 file_ptr->name_len = file_end_p1 - file_start;
2584 /* Update the linked list of file descriptors. */
2585 *last_file_ptr = file_ptr;
2586 last_file_ptr = &file_ptr->next_file;
2588 /* Add void & int types to the file (void should be first to catch
2589 errant 0's within the index fields). */
2590 file_ptr->void_type = add_aux_sym_tir (&void_type_info,
2592 &cur_file_ptr->thash_head[0]);
2594 file_ptr->int_type = add_aux_sym_tir (&int_type_info,
2596 &cur_file_ptr->thash_head[0]);
2601 /* Add a stream of random bytes to a varray. */
2604 add_bytes (vp, input_ptr, nitems)
2605 varray_t *vp; /* virtual array to add too */
2606 char *input_ptr; /* start of the bytes */
2607 Size_t nitems; /* # items to move */
2609 register Size_t move_items;
2610 register Size_t move_bytes;
2615 if (vp->objects_last_page >= vp->objects_per_page)
2616 add_varray_page (vp);
2618 ptr = &vp->last->datum->byte[ vp->objects_last_page * vp->object_size ];
2619 move_items = vp->objects_per_page - vp->objects_last_page;
2620 if (move_items > nitems)
2621 move_items = nitems;
2623 move_bytes = move_items * vp->object_size;
2624 nitems -= move_items;
2626 if (move_bytes >= 32)
2628 (void) memcpy ((PTR_T) ptr, (CPTR_T) input_ptr, move_bytes);
2629 input_ptr += move_bytes;
2633 while (move_bytes-- > 0)
2634 *ptr++ = *input_ptr++;
2640 /* Convert storage class to string. */
2643 sc_to_string(storage_class)
2646 switch(storage_class)
2648 case sc_Nil: return "Nil,";
2649 case sc_Text: return "Text,";
2650 case sc_Data: return "Data,";
2651 case sc_Bss: return "Bss,";
2652 case sc_Register: return "Register,";
2653 case sc_Abs: return "Abs,";
2654 case sc_Undefined: return "Undefined,";
2655 case sc_CdbLocal: return "CdbLocal,";
2656 case sc_Bits: return "Bits,";
2657 case sc_CdbSystem: return "CdbSystem,";
2658 case sc_RegImage: return "RegImage,";
2659 case sc_Info: return "Info,";
2660 case sc_UserStruct: return "UserStruct,";
2661 case sc_SData: return "SData,";
2662 case sc_SBss: return "SBss,";
2663 case sc_RData: return "RData,";
2664 case sc_Var: return "Var,";
2665 case sc_Common: return "Common,";
2666 case sc_SCommon: return "SCommon,";
2667 case sc_VarRegister: return "VarRegister,";
2668 case sc_Variant: return "Variant,";
2669 case sc_SUndefined: return "SUndefined,";
2670 case sc_Init: return "Init,";
2671 case sc_Max: return "Max,";
2678 /* Convert symbol type to string. */
2681 st_to_string(symbol_type)
2686 case st_Nil: return "Nil,";
2687 case st_Global: return "Global,";
2688 case st_Static: return "Static,";
2689 case st_Param: return "Param,";
2690 case st_Local: return "Local,";
2691 case st_Label: return "Label,";
2692 case st_Proc: return "Proc,";
2693 case st_Block: return "Block,";
2694 case st_End: return "End,";
2695 case st_Member: return "Member,";
2696 case st_Typedef: return "Typedef,";
2697 case st_File: return "File,";
2698 case st_RegReloc: return "RegReloc,";
2699 case st_Forward: return "Forward,";
2700 case st_StaticProc: return "StaticProc,";
2701 case st_Constant: return "Constant,";
2702 case st_Str: return "String,";
2703 case st_Number: return "Number,";
2704 case st_Expr: return "Expr,";
2705 case st_Type: return "Type,";
2706 case st_Max: return "Max,";
2713 /* Read a line from standard input, and return the start of the buffer
2714 (which is grows if the line is too big). We split lines at the
2715 semi-colon, and return each logical line independently. */
2718 read_line __proto((void))
2720 static int line_split_p = 0;
2721 register int string_p = 0;
2722 register int comment_p = 0;
2726 if (cur_line_start == (char *)0)
2727 { /* allocate initial page */
2728 cur_line_start = (char *) allocate_page ();
2729 cur_line_alloc = PAGE_SIZE;
2736 cur_line_nbytes = 0;
2738 for (ptr = cur_line_start; (ch = getchar ()) != EOF; *ptr++ = ch)
2740 if (++cur_line_nbytes >= cur_line_alloc-1)
2742 register int num_pages = cur_line_alloc / PAGE_SIZE;
2743 register char *old_buffer = cur_line_start;
2745 cur_line_alloc += PAGE_SIZE;
2746 cur_line_start = (char *) allocate_multiple_pages (num_pages+1);
2747 memcpy (cur_line_start, old_buffer, num_pages * PAGE_SIZE);
2749 ptr = cur_line_start + cur_line_nbytes - 1;
2756 cur_line_ptr = cur_line_start;
2757 return cur_line_ptr;
2760 else if (ch == '\0')
2761 error ("Null character found in input");
2763 else if (!comment_p)
2766 string_p = !string_p;
2771 else if (ch == ';' && !string_p)
2776 cur_line_ptr = cur_line_start;
2777 return cur_line_ptr;
2783 pfatal_with_name (input_name);
2785 cur_line_ptr = (char *)0;
2790 /* Parse #.begin directives which have a label as the first argument
2791 which gives the location of the start of the block. */
2795 const char *start; /* start of directive */
2797 const char *end_p1; /* end of label */
2799 shash_t *hash_ptr; /* hash pointer to lookup label */
2801 if (cur_file_ptr == (efdr_t *)0)
2803 error ("#.begin directive without a preceding .file directive");
2807 if (cur_proc_ptr == (PDR *)0)
2809 error ("#.begin directive without a preceding .ent directive");
2813 for (end_p1 = start; (ch = *end_p1) != '\0' && !isspace (ch); end_p1++)
2816 hash_ptr = hash_string (start,
2821 if (hash_ptr == (shash_t *)0)
2823 error ("Label %.*s not found for #.begin", end_p1 - start, start);
2827 if (cur_oproc_begin == (SYMR *)0)
2829 error ("Procedure table %.*s not found for #.begin", end_p1 - start, start);
2833 (void) add_local_symbol ((const char *)0, (const char *)0,
2835 (symint_t)hash_ptr->sym_ptr->value - cur_oproc_begin->value,
2840 /* Parse #.bend directives which have a label as the first argument
2841 which gives the location of the end of the block. */
2845 const char *start; /* start of directive */
2847 const char *end_p1; /* end of label */
2849 shash_t *hash_ptr; /* hash pointer to lookup label */
2851 if (cur_file_ptr == (efdr_t *)0)
2853 error ("#.begin directive without a preceding .file directive");
2857 if (cur_proc_ptr == (PDR *)0)
2859 error ("#.bend directive without a preceding .ent directive");
2863 for (end_p1 = start; (ch = *end_p1) != '\0' && !isspace (ch); end_p1++)
2866 hash_ptr = hash_string (start,
2871 if (hash_ptr == (shash_t *)0)
2873 error ("Label %.*s not found for #.bend", end_p1 - start, start);
2877 if (cur_oproc_begin == (SYMR *)0)
2879 error ("Procedure table %.*s not found for #.bend", end_p1 - start, start);
2883 (void) add_local_symbol ((const char *)0, (const char *)0,
2885 (symint_t)hash_ptr->sym_ptr->value - cur_oproc_begin->value,
2890 /* Parse #.def directives, which are contain standard COFF subdirectives
2891 to describe the debugging format. These subdirectives include:
2893 .scl specify storage class
2894 .val specify a value
2895 .endef specify end of COFF directives
2896 .type specify the type
2897 .size specify the size of an array
2898 .dim specify an array dimension
2899 .tag specify a tag for a struct, union, or enum. */
2902 parse_def (name_start)
2903 const char *name_start; /* start of directive */
2905 const char *dir_start; /* start of current directive*/
2906 const char *dir_end_p1; /* end+1 of current directive*/
2907 const char *arg_start; /* start of current argument */
2908 const char *arg_end_p1; /* end+1 of current argument */
2909 const char *name_end_p1; /* end+1 of label */
2910 const char *tag_start = (const char *)0; /* start of tag name */
2911 const char *tag_end_p1 = (const char *)0; /* end+1 of tag name */
2912 sc_t storage_class = sc_Nil;
2913 st_t symbol_type = st_Nil;
2915 EXTR *eptr = (EXTR *)0; /* ext. sym equivalent to def*/
2916 int is_function = 0; /* != 0 if function */
2918 symint_t indx = cur_file_ptr->void_type;
2920 symint_t arg_number;
2921 symint_t temp_array[ N_TQ ];
2926 static int inside_enumeration = 0; /* is this an enumeration? */
2929 /* Initialize the type information. */
2933 /* Search for the end of the name being defined. */
2934 /* Allow spaces and such in names for G++ templates, which produce stabs
2937 #.def SMANIP<long unsigned int>; .scl 10; .type 0x8; .size 8; .endef */
2939 for (name_end_p1 = name_start; (ch = *name_end_p1) != ';' && ch != '\0'; name_end_p1++)
2944 error_line = __LINE__;
2949 /* Parse the remaining subdirectives now. */
2950 dir_start = name_end_p1+1;
2953 while ((ch = *dir_start) == ' ' || ch == '\t')
2958 error_line = __LINE__;
2964 if (dir_start[1] == 'e'
2965 && memcmp (dir_start, ".endef", sizeof (".endef")-1) == 0)
2968 /* Pick up the subdirective now */
2969 for (dir_end_p1 = dir_start+1;
2970 (ch = *dir_end_p1) != ' ' && ch != '\t';
2973 if (ch == '\0' || isspace (ch))
2975 error_line = __LINE__;
2981 /* Pick up the subdirective argument now. */
2982 arg_was_number = arg_number = 0;
2983 arg_end_p1 = (const char *)0;
2984 arg_start = dir_end_p1+1;
2986 while (ch == ' ' || ch == '\t')
2989 if (isdigit (ch) || ch == '-' || ch == '+')
2992 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
2993 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
2997 else if (ch == '\0' || isspace (ch))
2999 error_line = __LINE__;
3004 if (!arg_was_number)
3006 /* Allow spaces and such in names for G++ templates. */
3007 for (arg_end_p1 = arg_start+1;
3008 (ch = *arg_end_p1) != ';' && ch != '\0';
3014 error_line = __LINE__;
3020 /* Classify the directives now. */
3021 len = dir_end_p1 - dir_start;
3022 switch (dir_start[1])
3025 error_line = __LINE__;
3030 if (len == sizeof (".dim")-1
3031 && memcmp (dir_start, ".dim", sizeof (".dim")-1) == 0
3034 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
3036 *t_ptr = arg_number;
3037 while (*arg_end_p1 == ',' && arg_was_number)
3039 arg_start = arg_end_p1+1;
3041 while (ch == ' ' || ch == '\t')
3045 if (isdigit (ch) || ch == '-' || ch == '+')
3048 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
3049 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
3052 if (t_ptr == &temp_array[0])
3054 error_line = __LINE__;
3059 *--t_ptr = arg_number;
3063 /* Reverse order of dimensions. */
3064 while (t_ptr <= &temp_array[ N_TQ-1 ])
3066 if (t.num_dims >= N_TQ-1)
3068 error_line = __LINE__;
3073 t.dimensions[ t.num_dims++ ] = *t_ptr++;
3079 error_line = __LINE__;
3086 if (len == sizeof (".scl")-1
3087 && memcmp (dir_start, ".scl", sizeof (".scl")-1) == 0
3089 && arg_number < ((symint_t) C_MAX))
3091 /* If the symbol is a static or external, we have
3092 already gotten the appropriate type and class, so
3093 make sure we don't override those values. This is
3094 needed because there are some type and classes that
3095 are not in COFF, such as short data, etc. */
3096 if (symbol_type == st_Nil)
3098 symbol_type = map_coff_sym_type[arg_number];
3099 storage_class = map_coff_storage [arg_number];
3104 else if (len == sizeof (".size")-1
3105 && memcmp (dir_start, ".size", sizeof (".size")-1) == 0
3108 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
3110 *t_ptr = arg_number;
3111 while (*arg_end_p1 == ',' && arg_was_number)
3113 arg_start = arg_end_p1+1;
3115 while (ch == ' ' || ch == '\t')
3119 if (isdigit (ch) || ch == '-' || ch == '+')
3122 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
3123 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
3126 if (t_ptr == &temp_array[0])
3128 error_line = __LINE__;
3133 *--t_ptr = arg_number;
3137 /* Reverse order of sizes. */
3138 while (t_ptr <= &temp_array[ N_TQ-1 ])
3140 if (t.num_sizes >= N_TQ-1)
3142 error_line = __LINE__;
3147 t.sizes[ t.num_sizes++ ] = *t_ptr++;
3154 error_line = __LINE__;
3161 if (len == sizeof (".type")-1
3162 && memcmp (dir_start, ".type", sizeof (".type")-1) == 0
3165 tq_t *tq_ptr = &t.type_qualifiers[0];
3167 t.orig_type = (coff_type_t) (arg_number & N_BTMASK);
3168 t.basic_type = map_coff_types [(int)t.orig_type];
3169 for (i = N_TQ-1; i >= 0; i--)
3171 int dt = (arg_number >> ((i * N_TQ_SHIFT) + N_BT_SHIFT)
3174 if (dt != (int)DT_NON)
3175 *tq_ptr++ = map_coff_derived_type [dt];
3178 /* If this is a function, ignore it, so that we don't get
3179 two entries (one from the .ent, and one for the .def
3180 that precedes it). Save the type information so that
3181 the end block can properly add it after the begin block
3182 index. For MIPS knows what reason, we must strip off
3183 the function type at this point. */
3184 if (tq_ptr != &t.type_qualifiers[0] && tq_ptr[-1] == tq_Proc)
3187 tq_ptr[-1] = tq_Nil;
3193 else if (len == sizeof (".tag")-1
3194 && memcmp (dir_start, ".tag", sizeof (".tag")-1) == 0)
3196 tag_start = arg_start;
3197 tag_end_p1 = arg_end_p1;
3203 error_line = __LINE__;
3210 if (len == sizeof (".val")-1
3211 && memcmp (dir_start, ".val", sizeof (".val")-1) == 0)
3216 /* If the value is not an integer value, it must be the
3217 name of a static or global item. Look up the name in
3218 the original symbol table to pick up the storage
3219 class, symbol type, etc. */
3222 shash_t *orig_hash_ptr; /* hash within orig sym table*/
3223 shash_t *ext_hash_ptr; /* hash within ext. sym table*/
3225 ext_hash_ptr = hash_string (arg_start,
3226 arg_end_p1 - arg_start,
3230 if (ext_hash_ptr != (shash_t *)0
3231 && ext_hash_ptr->esym_ptr != (EXTR *)0)
3232 eptr = ext_hash_ptr->esym_ptr;
3234 orig_hash_ptr = hash_string (arg_start,
3235 arg_end_p1 - arg_start,
3239 if ((orig_hash_ptr == (shash_t *)0
3240 || orig_hash_ptr->sym_ptr == (SYMR *)0)
3241 && eptr == (EXTR *)0)
3243 fprintf (stderr, "warning, %.*s not found in original or external symbol tables, value defaults to 0\n",
3244 arg_end_p1 - arg_start,
3250 SYMR *ptr = (orig_hash_ptr != (shash_t *)0
3251 && orig_hash_ptr->sym_ptr != (SYMR *)0)
3252 ? orig_hash_ptr->sym_ptr
3255 symbol_type = (st_t) ptr->st;
3256 storage_class = (sc_t) ptr->sc;
3264 error_line = __LINE__;
3270 /* Set up to find next directive. */
3271 dir_start = arg_end_p1 + 1;
3275 t.extra_sizes = (tag_start != (char *)0);
3278 int diff = t.num_dims - t.num_sizes;
3279 int i = t.num_dims - 1;
3282 if (t.num_sizes != 1 || diff < 0)
3284 error_line = __LINE__;
3289 /* If this is an array, make sure the same number of dimensions
3290 and sizes were passed, creating extra sizes for multiply
3291 dimensioned arrays if not passed. */
3296 for (j = (sizeof (t.sizes) / sizeof (t.sizes[0])) - 1; j >= 0; j--)
3297 t.sizes[ j ] = ((j-diff) >= 0) ? t.sizes[ j-diff ] : 0;
3299 t.num_sizes = i + 1;
3300 for ( i--; i >= 0; i-- )
3302 if (t.dimensions[ i+1 ])
3303 t.sizes[ i ] = t.sizes[ i+1 ] / t.dimensions[ i+1 ];
3305 t.sizes[ i ] = t.sizes[ i+1 ];
3310 else if (symbol_type == st_Member && t.num_sizes - t.extra_sizes == 1)
3311 { /* Is this a bitfield? This is indicated by a structure memeber
3312 having a size field that isn't an array. */
3318 /* Except for enumeration members & begin/ending of scopes, put the
3319 type word in the aux. symbol table. */
3321 if (symbol_type == st_Block || symbol_type == st_End)
3324 else if (inside_enumeration)
3325 indx = cur_file_ptr->void_type;
3329 if (t.basic_type == bt_Struct
3330 || t.basic_type == bt_Union
3331 || t.basic_type == bt_Enum)
3333 if (tag_start == (char *)0)
3335 error ("No tag specified for %.*s",
3336 name_end_p1 - name_start,
3341 t.tag_ptr = get_tag (tag_start, tag_end_p1, (symint_t)indexNil,
3347 last_func_type_info = t;
3348 last_func_eptr = eptr;
3352 indx = add_aux_sym_tir (&t,
3354 &cur_file_ptr->thash_head[0]);
3358 /* If this is an external or static symbol, update the appropriate
3361 if (eptr != (EXTR *)0
3362 && (eptr->asym.index == indexNil || cur_proc_ptr == (PDR *)0))
3364 eptr->ifd = cur_file_ptr->file_index;
3365 eptr->asym.index = indx;
3369 /* Do any last minute adjustments that are necessary. */
3370 switch (symbol_type)
3376 /* For the beginning of structs, unions, and enumerations, the
3377 size info needs to be passed in the value field. */
3380 if (t.num_sizes - t.num_dims - t.extra_sizes != 1)
3382 error_line = __LINE__;
3390 inside_enumeration = (t.orig_type == T_ENUM);
3394 /* For the end of structs, unions, and enumerations, omit the
3395 name which is always ".eos". This needs to be done last, so
3396 that any error reporting above gives the correct name. */
3399 name_start = name_end_p1 = (const char *)0;
3400 value = inside_enumeration = 0;
3404 /* Members of structures and unions that aren't bitfields, need
3405 to adjust the value from a byte offset to a bit offset.
3406 Members of enumerations do not have the value adjusted, and
3407 can be distinguished by indx == indexNil. For enumerations,
3408 update the maximum enumeration value. */
3411 if (!t.bitfield && !inside_enumeration)
3418 /* Add the symbol, except for global symbols outside of functions,
3419 for which the external symbol table is fine enough. */
3421 if (eptr == (EXTR *)0
3422 || eptr->asym.st == (int)st_Nil
3423 || cur_proc_ptr != (PDR *)0)
3425 symint_t isym = add_local_symbol (name_start, name_end_p1,
3426 symbol_type, storage_class,
3430 /* deal with struct, union, and enum tags. */
3431 if (symbol_type == st_Block)
3433 /* Create or update the tag information. */
3434 tag_t *tag_ptr = get_tag (name_start,
3439 /* If there are any forward references, fill in the appropriate
3440 file and symbol indexes. */
3442 symint_t file_index = cur_file_ptr->file_index;
3443 forward_t *f_next = tag_ptr->forward_ref;
3446 while (f_next != (forward_t *)0)
3449 f_next = f_next->next;
3451 f_cur->ifd_ptr->isym = file_index;
3452 f_cur->index_ptr->rndx.index = isym;
3454 free_forward (f_cur);
3457 tag_ptr->forward_ref = (forward_t *)0;
3464 /* Error return, issue message. */
3467 error ("compiler error, badly formed #.def (internal line # = %d)", error_line);
3469 error ("compiler error, badly formed #.def");
3475 /* Parse .end directives. */
3479 const char *start; /* start of directive */
3481 register const char *start_func, *end_func_p1;
3483 register symint_t value;
3484 register FDR *orig_fdr;
3486 if (cur_file_ptr == (efdr_t *)0)
3488 error (".end directive without a preceding .file directive");
3492 if (cur_proc_ptr == (PDR *)0)
3494 error (".end directive without a preceding .ent directive");
3498 /* Get the function name, skipping whitespace. */
3499 for (start_func = start; isspace (*start_func); start_func++)
3503 if (!IS_ASM_IDENT (ch))
3505 error (".end directive has no name");
3509 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
3513 /* Get the value field for creating the end from the original object
3514 file (which we find by locating the procedure start, and using the
3515 pointer to the end+1 block and backing up. The index points to a
3516 two word aux. symbol, whose first word is the index of the end
3517 symbol, and the second word is the type of the function return
3520 orig_fdr = cur_file_ptr->orig_fdr;
3522 if (orig_fdr != (FDR *)0 && cur_oproc_end != (SYMR *)0)
3523 value = cur_oproc_end->value;
3526 error ("Cannot find .end block for %.*s", end_func_p1 - start_func, start_func);
3528 (void) add_local_symbol (start_func, end_func_p1,
3533 cur_proc_ptr = cur_oproc_ptr = (PDR *)0;
3537 /* Parse .ent directives. */
3541 const char *start; /* start of directive */
3543 register const char *start_func, *end_func_p1;
3546 if (cur_file_ptr == (efdr_t *)0)
3548 error (".ent directive without a preceding .file directive");
3552 if (cur_proc_ptr != (PDR *)0)
3554 error ("second .ent directive found before .end directive");
3558 for (start_func = start; isspace (*start_func); start_func++)
3562 if (!IS_ASM_IDENT (ch))
3564 error (".ent directive has no name");
3568 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
3571 (void) add_procedure (start_func, end_func_p1);
3575 /* Parse .file directives. */
3579 const char *start; /* start of directive */
3582 register char *start_name, *end_name_p1;
3584 (void) strtol (start, &p, 0);
3586 || (start_name = local_index (p, '"')) == (char *)0
3587 || (end_name_p1 = local_rindex (++start_name, '"')) == (char *)0)
3589 error ("Invalid .file directive");
3593 if (cur_proc_ptr != (PDR *)0)
3595 error ("No way to handle .file within .ent/.end section");
3599 add_file (start_name, end_name_p1);
3603 /* Make sure the @stabs symbol is emitted. */
3607 const char *start; /* Start of directive (ignored) */
3611 /* Add a dummy @stabs dymbol. */
3613 (void) add_local_symbol (stabs_symbol,
3614 stabs_symbol + sizeof (stabs_symbol),
3615 stNil, scInfo, -1, MIPS_MARK_STAB(0));
3621 /* Parse .stabs directives.
3623 .stabs directives have five fields:
3624 "string" a string, encoding the type information.
3625 code a numeric code, defined in <stab.h>
3627 0 a zero or line number
3628 value a numeric value or an address.
3630 If the value is relocatable, we transform this into:
3631 iss points as an index into string space
3632 value value from lookup of the name
3633 st st from lookup of the name
3634 sc sc from lookup of the name
3635 index code|CODE_MASK
3637 If the value is not relocatable, we transform this into:
3638 iss points as an index into string space
3642 index code|CODE_MASK
3644 .stabn directives have four fields (string is null):
3645 code a numeric code, defined in <stab.h>
3647 0 a zero or a line number
3648 value a numeric value or an address. */
3651 parse_stabs_common (string_start, string_end, rest)
3652 const char *string_start; /* start of string or NULL */
3653 const char *string_end; /* end+1 of string or NULL */
3654 const char *rest; /* rest of the directive. */
3656 efdr_t *save_file_ptr = cur_file_ptr;
3664 if (stabs_seen == 0)
3667 /* Read code from stabs. */
3668 if (!isdigit (*rest))
3670 error ("Invalid .stabs/.stabn directive, code is non-numeric");
3674 code = strtol (rest, &p, 0);
3676 /* Line number stabs are handled differently, since they have two values,
3677 the line number and the address of the label. We use the index field
3678 (aka code) to hold the line number, and the value field to hold the
3679 address. The symbol type is st_Label, which should be different from
3680 the other stabs, so that gdb can recognize it. */
3682 if (code == (int)N_SLINE)
3684 SYMR *sym_ptr, dummy_symr;
3688 if (p[0] != ',' || p[1] != '0' || p[2] != ',' || !isdigit (p[3]))
3690 error ("Invalid line number .stabs/.stabn directive");
3694 code = strtol (p+3, &p, 0);
3696 if (p[-1] != ',' || isdigit (ch) || !IS_ASM_IDENT (ch))
3698 error ("Invalid line number .stabs/.stabn directive");
3702 dummy_symr.index = code;
3703 if (dummy_symr.index != code)
3705 error ("Line number (%d) for .stabs/.stabn directive cannot fit in index field (20 bits)",
3711 shash_ptr = hash_string (p,
3716 if (shash_ptr == (shash_t *)0
3717 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *)0)
3719 error ("Invalid .stabs/.stabn directive, value not found");
3723 if ((st_t) sym_ptr->st != st_Label)
3725 error ("Invalid line number .stabs/.stabn directive");
3730 sc = (sc_t) sym_ptr->sc;
3731 value = sym_ptr->value;
3735 /* Skip ,<num>,<num>, */
3738 for (; isdigit (*p); p++)
3742 for (; isdigit (*p); p++)
3747 if (!IS_ASM_IDENT (ch) && ch != '-')
3750 error ("Invalid .stabs/.stabn directive, bad character");
3754 if (isdigit (ch) || ch == '-')
3758 value = strtol (p, &p, 0);
3761 error ("Invalid .stabs/.stabn directive, stuff after numeric value");
3765 else if (!IS_ASM_IDENT (ch))
3767 error ("Invalid .stabs/.stabn directive, bad character");
3774 const char *start, *end_p1;
3777 if ((end_p1 = strchr (start, '+')) == (char *)0)
3779 if ((end_p1 = strchr (start, '-')) == (char *)0)
3780 end_p1 = start + strlen(start) - 1;
3783 shash_ptr = hash_string (start,
3788 if (shash_ptr == (shash_t *)0
3789 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *)0)
3791 shash_ptr = hash_string (start,
3796 if (shash_ptr == (shash_t *)0
3797 || shash_ptr->esym_ptr == (EXTR *)0)
3799 error ("Invalid .stabs/.stabn directive, value not found");
3803 sym_ptr = &(shash_ptr->esym_ptr->asym);
3806 /* Traditionally, N_LBRAC and N_RBRAC are *not* relocated. */
3807 if (code == (int)N_LBRAC || code == (int)N_RBRAC)
3814 sc = (sc_t) sym_ptr->sc;
3815 st = (st_t) sym_ptr->st;
3817 value = sym_ptr->value;
3822 if (((!isdigit (*end_p1)) && (*end_p1 != '-'))
3823 || ((ch != '+') && (ch != '-')))
3825 error ("Invalid .stabs/.stabn directive, badly formed value");
3829 value += strtol (end_p1, &p, 0);
3831 value -= strtol (end_p1, &p, 0);
3835 error ("Invalid .stabs/.stabn directive, stuff after numeric value");
3840 code = MIPS_MARK_STAB(code);
3843 (void) add_local_symbol (string_start, string_end, st, sc, value, code);
3844 /* Restore normal file type. */
3845 cur_file_ptr = save_file_ptr;
3851 const char *start; /* start of directive */
3853 const char *end = local_index (start+1, '"');
3855 if (*start != '"' || end == (const char *)0 || end[1] != ',')
3857 error ("Invalid .stabs directive, no string");
3861 parse_stabs_common (start+1, end, end+2);
3867 const char *start; /* start of directive */
3869 parse_stabs_common ((const char *)0, (const char *)0, start);
3873 /* Parse the input file, and write the lines to the output file
3877 parse_input __proto((void))
3881 register thead_t *ptag_head;
3882 register tag_t *ptag;
3883 register tag_t *ptag_next;
3886 fprintf (stderr, "\tinput\n");
3888 /* Add a dummy scope block around the entire compilation unit for
3889 structures defined outside of blocks. */
3890 ptag_head = allocate_thead ();
3891 ptag_head->first_tag = 0;
3892 ptag_head->prev = cur_tag_head;
3893 cur_tag_head = ptag_head;
3895 while ((p = read_line ()) != (char *)0)
3897 /* Skip leading blanks */
3898 while (isspace (*p))
3901 /* See if it's a directive we handle. If so, dispatch handler. */
3902 for (i = 0; i < sizeof (pseudo_ops) / sizeof (pseudo_ops[0]); i++)
3903 if (memcmp (p, pseudo_ops[i].name, pseudo_ops[i].len) == 0
3904 && isspace (p[pseudo_ops[i].len]))
3906 p += pseudo_ops[i].len; /* skip to first argument */
3907 while (isspace (*p))
3910 (*pseudo_ops[i].func)( p );
3915 /* Process any tags at global level. */
3916 ptag_head = cur_tag_head;
3917 cur_tag_head = ptag_head->prev;
3919 for (ptag = ptag_head->first_tag;
3923 if (ptag->forward_ref != (forward_t *)0)
3924 add_unknown_tag (ptag);
3926 ptag_next = ptag->same_block;
3927 ptag->hash_ptr->tag_ptr = ptag->same_name;
3931 free_thead (ptag_head);
3936 /* Update the global headers with the final offsets in preparation
3937 to write out the .T file. */
3940 update_headers __proto((void))
3942 register symint_t i;
3943 register efdr_t *file_ptr;
3945 /* Set up the symbolic header. */
3946 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
3947 symbolic_header.magic = orig_sym_hdr.magic;
3948 symbolic_header.vstamp = orig_sym_hdr.vstamp;
3950 /* Set up global counts. */
3951 symbolic_header.issExtMax = ext_strings.num_allocated;
3952 symbolic_header.idnMax = dense_num.num_allocated;
3953 symbolic_header.ifdMax = file_desc.num_allocated;
3954 symbolic_header.iextMax = ext_symbols.num_allocated;
3955 symbolic_header.ilineMax = orig_sym_hdr.ilineMax;
3956 symbolic_header.ioptMax = orig_sym_hdr.ioptMax;
3957 symbolic_header.cbLine = orig_sym_hdr.cbLine;
3958 symbolic_header.crfd = orig_sym_hdr.crfd;
3961 /* Loop through each file, figuring out how many local syms,
3962 line numbers, etc. there are. Also, put out end symbol
3963 for the filename. */
3965 for (file_ptr = first_file;
3966 file_ptr != (efdr_t *)0;
3967 file_ptr = file_ptr->next_file)
3969 cur_file_ptr = file_ptr;
3970 (void) add_local_symbol ((const char *)0, (const char *)0,
3975 file_ptr->fdr.cpd = file_ptr->procs.num_allocated;
3976 file_ptr->fdr.ipdFirst = symbolic_header.ipdMax;
3977 symbolic_header.ipdMax += file_ptr->fdr.cpd;
3979 file_ptr->fdr.csym = file_ptr->symbols.num_allocated;
3980 file_ptr->fdr.isymBase = symbolic_header.isymMax;
3981 symbolic_header.isymMax += file_ptr->fdr.csym;
3983 file_ptr->fdr.caux = file_ptr->aux_syms.num_allocated;
3984 file_ptr->fdr.iauxBase = symbolic_header.iauxMax;
3985 symbolic_header.iauxMax += file_ptr->fdr.caux;
3987 file_ptr->fdr.cbSs = file_ptr->strings.num_allocated;
3988 file_ptr->fdr.issBase = symbolic_header.issMax;
3989 symbolic_header.issMax += file_ptr->fdr.cbSs;
3993 i = WORD_ALIGN (symbolic_header.cbLine); /* line numbers */
3996 symbolic_header.cbLineOffset = file_offset;
4000 i = symbolic_header.ioptMax; /* optimization symbols */
4003 symbolic_header.cbOptOffset = file_offset;
4004 file_offset += i * sizeof (OPTR);
4007 i = symbolic_header.idnMax; /* dense numbers */
4010 symbolic_header.cbDnOffset = file_offset;
4011 file_offset += i * sizeof (DNR);
4014 i = symbolic_header.ipdMax; /* procedure tables */
4017 symbolic_header.cbPdOffset = file_offset;
4018 file_offset += i * sizeof (PDR);
4021 i = symbolic_header.isymMax; /* local symbols */
4024 symbolic_header.cbSymOffset = file_offset;
4025 file_offset += i * sizeof (SYMR);
4028 i = symbolic_header.iauxMax; /* aux syms. */
4031 symbolic_header.cbAuxOffset = file_offset;
4032 file_offset += i * sizeof (TIR);
4035 i = WORD_ALIGN (symbolic_header.issMax); /* local strings */
4038 symbolic_header.cbSsOffset = file_offset;
4042 i = WORD_ALIGN (symbolic_header.issExtMax); /* external strings */
4045 symbolic_header.cbSsExtOffset = file_offset;
4049 i = symbolic_header.ifdMax; /* file tables */
4052 symbolic_header.cbFdOffset = file_offset;
4053 file_offset += i * sizeof (FDR);
4056 i = symbolic_header.crfd; /* relative file descriptors */
4059 symbolic_header.cbRfdOffset = file_offset;
4060 file_offset += i * sizeof (symint_t);
4063 i = symbolic_header.iextMax; /* external symbols */
4066 symbolic_header.cbExtOffset = file_offset;
4067 file_offset += i * sizeof (EXTR);
4072 /* Write out a varray at a given location. */
4075 write_varray (vp, offset, str)
4076 varray_t *vp; /* virtual array */
4077 off_t offset; /* offset to write varray to */
4078 const char *str; /* string to print out when tracing */
4080 int num_write, sys_write;
4083 if (vp->num_allocated == 0)
4087 fprintf (stderr, "\twarray\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4088 vp, offset, vp->num_allocated * vp->object_size, str);
4090 if (file_offset != offset
4091 && fseek (object_stream, (long)offset, SEEK_SET) < 0)
4092 pfatal_with_name (object_name);
4094 for (ptr = vp->first; ptr != (vlinks_t *)0; ptr = ptr->next)
4096 num_write = (ptr->next == (vlinks_t *)0)
4097 ? vp->objects_last_page * vp->object_size
4098 : vp->objects_per_page * vp->object_size;
4100 sys_write = fwrite ((PTR_T) ptr->datum, 1, num_write, object_stream);
4102 pfatal_with_name (object_name);
4104 else if (sys_write != num_write)
4105 fatal ("Wrote %d bytes to %s, system returned %d",
4110 file_offset += num_write;
4115 /* Write out the symbol table in the object file. */
4118 write_object __proto((void))
4125 fprintf (stderr, "\n\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4126 (PTR_T *) &symbolic_header, 0, sizeof (symbolic_header),
4129 sys_write = fwrite ((PTR_T) &symbolic_header,
4131 sizeof (symbolic_header),
4135 pfatal_with_name (object_name);
4137 else if (sys_write != sizeof (symbolic_header))
4138 fatal ("Wrote %d bytes to %s, system returned %d",
4139 sizeof (symbolic_header),
4144 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
4146 if (symbolic_header.cbLine > 0) /* line numbers */
4150 if (file_offset != symbolic_header.cbLineOffset
4151 && fseek (object_stream, symbolic_header.cbLineOffset, SEEK_SET) != 0)
4152 pfatal_with_name (object_name);
4155 fprintf (stderr, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4156 (PTR_T *) &orig_linenum, symbolic_header.cbLineOffset,
4157 symbolic_header.cbLine, "Line numbers");
4159 sys_write = fwrite ((PTR_T) orig_linenum,
4161 symbolic_header.cbLine,
4165 pfatal_with_name (object_name);
4167 else if (sys_write != symbolic_header.cbLine)
4168 fatal ("Wrote %d bytes to %s, system returned %d",
4169 symbolic_header.cbLine,
4173 file_offset = symbolic_header.cbLineOffset + symbolic_header.cbLine;
4176 if (symbolic_header.ioptMax > 0) /* optimization symbols */
4179 long num_write = symbolic_header.ioptMax * sizeof (OPTR);
4181 if (file_offset != symbolic_header.cbOptOffset
4182 && fseek (object_stream, symbolic_header.cbOptOffset, SEEK_SET) != 0)
4183 pfatal_with_name (object_name);
4186 fprintf (stderr, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4187 (PTR_T *) &orig_opt_syms, symbolic_header.cbOptOffset,
4188 num_write, "Optimizer symbols");
4190 sys_write = fwrite ((PTR_T) orig_opt_syms,
4196 pfatal_with_name (object_name);
4198 else if (sys_write != num_write)
4199 fatal ("Wrote %d bytes to %s, system returned %d",
4204 file_offset = symbolic_header.cbOptOffset + num_write;
4207 if (symbolic_header.idnMax > 0) /* dense numbers */
4208 write_varray (&dense_num, (off_t)symbolic_header.cbDnOffset, "Dense numbers");
4210 if (symbolic_header.ipdMax > 0) /* procedure tables */
4212 offset = symbolic_header.cbPdOffset;
4213 for (file_ptr = first_file;
4214 file_ptr != (efdr_t *)0;
4215 file_ptr = file_ptr->next_file)
4217 write_varray (&file_ptr->procs, offset, "Procedure tables");
4218 offset = file_offset;
4222 if (symbolic_header.isymMax > 0) /* local symbols */
4224 offset = symbolic_header.cbSymOffset;
4225 for (file_ptr = first_file;
4226 file_ptr != (efdr_t *)0;
4227 file_ptr = file_ptr->next_file)
4229 write_varray (&file_ptr->symbols, offset, "Local symbols");
4230 offset = file_offset;
4234 if (symbolic_header.iauxMax > 0) /* aux symbols */
4236 offset = symbolic_header.cbAuxOffset;
4237 for (file_ptr = first_file;
4238 file_ptr != (efdr_t *)0;
4239 file_ptr = file_ptr->next_file)
4241 write_varray (&file_ptr->aux_syms, offset, "Aux. symbols");
4242 offset = file_offset;
4246 if (symbolic_header.issMax > 0) /* local strings */
4248 offset = symbolic_header.cbSsOffset;
4249 for (file_ptr = first_file;
4250 file_ptr != (efdr_t *)0;
4251 file_ptr = file_ptr->next_file)
4253 write_varray (&file_ptr->strings, offset, "Local strings");
4254 offset = file_offset;
4258 if (symbolic_header.issExtMax > 0) /* external strings */
4259 write_varray (&ext_strings, symbolic_header.cbSsExtOffset, "External strings");
4261 if (symbolic_header.ifdMax > 0) /* file tables */
4263 offset = symbolic_header.cbFdOffset;
4264 if (file_offset != offset
4265 && fseek (object_stream, (long)offset, SEEK_SET) < 0)
4266 pfatal_with_name (object_name);
4268 file_offset = offset;
4269 for (file_ptr = first_file;
4270 file_ptr != (efdr_t *)0;
4271 file_ptr = file_ptr->next_file)
4274 fprintf (stderr, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4275 (PTR_T *) &file_ptr->fdr, file_offset, sizeof (FDR), "File header");
4277 sys_write = fwrite (&file_ptr->fdr,
4283 pfatal_with_name (object_name);
4285 else if (sys_write != sizeof (FDR))
4286 fatal ("Wrote %d bytes to %s, system returned %d",
4291 file_offset = offset += sizeof (FDR);
4295 if (symbolic_header.crfd > 0) /* relative file descriptors */
4298 symint_t num_write = symbolic_header.crfd * sizeof (symint_t);
4300 if (file_offset != symbolic_header.cbRfdOffset
4301 && fseek (object_stream, symbolic_header.cbRfdOffset, SEEK_SET) != 0)
4302 pfatal_with_name (object_name);
4305 fprintf (stderr, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4306 (PTR_T *) &orig_rfds, symbolic_header.cbRfdOffset,
4307 num_write, "Relative file descriptors");
4309 sys_write = fwrite (orig_rfds,
4315 pfatal_with_name (object_name);
4317 else if (sys_write != num_write)
4318 fatal ("Wrote %d bytes to %s, system returned %d",
4323 file_offset = symbolic_header.cbRfdOffset + num_write;
4326 if (symbolic_header.issExtMax > 0) /* external symbols */
4327 write_varray (&ext_symbols, (off_t)symbolic_header.cbExtOffset, "External symbols");
4329 if (fclose (object_stream) != 0)
4330 pfatal_with_name (object_name);
4334 /* Read some bytes at a specified location, and return a pointer. */
4337 read_seek (size, offset, str)
4338 Size_t size; /* # bytes to read */
4339 off_t offset; /* offset to read at */
4340 const char *str; /* name for tracing */
4345 if (size == 0) /* nothing to read */
4349 fprintf (stderr, "\trseek\tsize = %7u, offset = %7u, currently at %7u, %s\n",
4350 size, offset, file_offset, str);
4352 #ifndef MALLOC_CHECK
4353 ptr = allocate_multiple_pages ((size + PAGE_USIZE - 1) / PAGE_USIZE);
4355 ptr = (page_t *) xcalloc (1, size);
4358 /* If we need to seek, and the distance is nearby, just do some reads,
4359 to speed things up. */
4360 if (file_offset != offset)
4362 symint_t difference = offset - file_offset;
4366 char small_buffer[8];
4368 sys_read = fread (small_buffer, 1, difference, obj_in_stream);
4370 pfatal_with_name (obj_in_name);
4372 if (sys_read != difference)
4373 fatal ("Wanted to read %d bytes from %s, system returned %d",
4378 else if (fseek (obj_in_stream, offset, SEEK_SET) < 0)
4379 pfatal_with_name (obj_in_name);
4382 sys_read = fread ((PTR_T)ptr, 1, size, obj_in_stream);
4384 pfatal_with_name (obj_in_name);
4386 if (sys_read != size)
4387 fatal ("Wanted to read %d bytes from %s, system returned %d",
4392 file_offset = offset + size;
4394 if (file_offset > max_file_offset)
4395 max_file_offset = file_offset;
4401 /* Read the existing object file (and copy to the output object file
4402 if it is different from the input object file), and remove the old
4406 copy_object __proto((void))
4408 char buffer[ PAGE_SIZE ];
4409 register int sys_read;
4410 register int remaining;
4411 register int num_write;
4412 register int sys_write;
4413 register int fd, es;
4414 register int delete_ifd = 0;
4415 register int *remap_file_number;
4416 struct stat stat_buf;
4419 fprintf (stderr, "\tcopy\n");
4421 if (fstat (fileno (obj_in_stream), &stat_buf) != 0
4422 || fseek (obj_in_stream, 0L, SEEK_SET) != 0)
4423 pfatal_with_name (obj_in_name);
4425 sys_read = fread ((PTR_T) &orig_file_header,
4427 sizeof (struct filehdr),
4431 pfatal_with_name (obj_in_name);
4433 else if (sys_read == 0 && feof (obj_in_stream))
4434 return; /* create a .T file sans file header */
4436 else if (sys_read < sizeof (struct filehdr))
4437 fatal ("Wanted to read %d bytes from %s, system returned %d",
4438 sizeof (struct filehdr),
4443 if (orig_file_header.f_nsyms != sizeof (HDRR))
4444 fatal ("%s symbolic header wrong size (%d bytes, should be %d)",
4445 input_name, orig_file_header.f_nsyms, sizeof (HDRR));
4448 /* Read in the current symbolic header. */
4449 if (fseek (obj_in_stream, (long) orig_file_header.f_symptr, SEEK_SET) != 0)
4450 pfatal_with_name (input_name);
4452 sys_read = fread ((PTR_T) &orig_sym_hdr,
4454 sizeof (orig_sym_hdr),
4458 pfatal_with_name (object_name);
4460 else if (sys_read < sizeof (struct filehdr))
4461 fatal ("Wanted to read %d bytes from %s, system returned %d",
4462 sizeof (struct filehdr),
4467 /* Read in each of the sections if they exist in the object file.
4468 We read things in in the order the mips assembler creates the
4469 sections, so in theory no extra seeks are done.
4471 For simplicity sake, round each read up to a page boundary,
4472 we may want to revisit this later.... */
4474 file_offset = orig_file_header.f_symptr + sizeof (struct filehdr);
4476 if (orig_sym_hdr.cbLine > 0) /* line numbers */
4477 orig_linenum = (char *) read_seek ((Size_t)orig_sym_hdr.cbLine,
4478 orig_sym_hdr.cbLineOffset,
4481 if (orig_sym_hdr.ipdMax > 0) /* procedure tables */
4482 orig_procs = (PDR *) read_seek ((Size_t)orig_sym_hdr.ipdMax * sizeof (PDR),
4483 orig_sym_hdr.cbPdOffset,
4484 "Procedure tables");
4486 if (orig_sym_hdr.isymMax > 0) /* local symbols */
4487 orig_local_syms = (SYMR *) read_seek ((Size_t)orig_sym_hdr.isymMax * sizeof (SYMR),
4488 orig_sym_hdr.cbSymOffset,
4491 if (orig_sym_hdr.iauxMax > 0) /* aux symbols */
4492 orig_aux_syms = (AUXU *) read_seek ((Size_t)orig_sym_hdr.iauxMax * sizeof (AUXU),
4493 orig_sym_hdr.cbAuxOffset,
4496 if (orig_sym_hdr.issMax > 0) /* local strings */
4497 orig_local_strs = (char *) read_seek ((Size_t)orig_sym_hdr.issMax,
4498 orig_sym_hdr.cbSsOffset,
4501 if (orig_sym_hdr.issExtMax > 0) /* external strings */
4502 orig_ext_strs = (char *) read_seek ((Size_t)orig_sym_hdr.issExtMax,
4503 orig_sym_hdr.cbSsExtOffset,
4504 "External strings");
4506 if (orig_sym_hdr.ifdMax > 0) /* file tables */
4507 orig_files = (FDR *) read_seek ((Size_t)orig_sym_hdr.ifdMax * sizeof (FDR),
4508 orig_sym_hdr.cbFdOffset,
4511 if (orig_sym_hdr.crfd > 0) /* relative file descriptors */
4512 orig_rfds = (symint_t *) read_seek ((Size_t)orig_sym_hdr.crfd * sizeof (symint_t),
4513 orig_sym_hdr.cbRfdOffset,
4514 "Relative file descriptors");
4516 if (orig_sym_hdr.issExtMax > 0) /* external symbols */
4517 orig_ext_syms = (EXTR *) read_seek ((Size_t)orig_sym_hdr.iextMax * sizeof (EXTR),
4518 orig_sym_hdr.cbExtOffset,
4519 "External symbols");
4521 if (orig_sym_hdr.idnMax > 0) /* dense numbers */
4523 orig_dense = (DNR *) read_seek ((Size_t)orig_sym_hdr.idnMax * sizeof (DNR),
4524 orig_sym_hdr.cbDnOffset,
4527 add_bytes (&dense_num, (char *) orig_dense, (Size_t)orig_sym_hdr.idnMax);
4530 if (orig_sym_hdr.ioptMax > 0) /* opt symbols */
4531 orig_opt_syms = (OPTR *) read_seek ((Size_t)orig_sym_hdr.ioptMax * sizeof (OPTR),
4532 orig_sym_hdr.cbOptOffset,
4533 "Optimizer symbols");
4537 /* Abort if the symbol table is not last. */
4538 if (max_file_offset != stat_buf.st_size)
4539 fatal ("Symbol table is not last (symbol table ends at %ld, .o ends at %ld",
4544 /* If the first original file descriptor is a dummy which the assembler
4545 put out, but there are no symbols in it, skip it now. */
4546 if (orig_sym_hdr.ifdMax > 1
4547 && orig_files->csym == 2
4548 && orig_files->caux == 0)
4550 char *filename = orig_local_strs + (orig_files->issBase + orig_files->rss);
4551 char *suffix = local_rindex (filename, '.');
4553 if (suffix != (char *)0 && strcmp (suffix, ".s") == 0)
4558 /* Create array to map original file numbers to the new file numbers
4559 (in case there are duplicate filenames, we collapse them into one
4560 file section, the MIPS assembler may or may not collapse them). */
4562 remap_file_number = (int *) alloca (sizeof (int) * orig_sym_hdr.ifdMax);
4564 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
4566 register FDR *fd_ptr = ORIG_FILES (fd);
4567 register char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
4569 /* file support itself. */
4570 add_file (filename, filename + strlen (filename));
4571 remap_file_number[fd] = cur_file_ptr->file_index;
4574 if (delete_ifd > 0) /* just in case */
4575 remap_file_number[0] = remap_file_number[1];
4578 /* Loop, adding each of the external symbols. These must be in
4579 order or otherwise we would have to change the relocation
4580 entries. We don't just call add_bytes, because we need to have
4581 the names put into the external hash table. We set the type to
4582 'void' for now, and parse_def will fill in the correct type if it
4583 is in the symbol table. We must add the external symbols before
4584 the locals, since the locals do lookups against the externals. */
4587 fprintf (stderr, "\tehash\n");
4589 for (es = 0; es < orig_sym_hdr.iextMax; es++)
4591 register EXTR *eptr = orig_ext_syms + es;
4592 register char *ename = ORIG_ESTRS (eptr->asym.iss);
4593 register unsigned ifd = eptr->ifd;
4595 (void) add_ext_symbol (ename,
4596 ename + strlen (ename),
4597 (st_t) eptr->asym.st,
4598 (sc_t) eptr->asym.sc,
4600 (symint_t)((eptr->asym.index == indexNil) ? indexNil : 0),
4601 (ifd < orig_sym_hdr.ifdMax) ? remap_file_number[ ifd ] : ifd);
4605 /* For each of the files in the object file, copy the symbols, and such
4606 into the varrays for the new object file. */
4608 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
4610 register FDR *fd_ptr = ORIG_FILES (fd);
4611 register char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
4612 register SYMR *sym_start;
4614 register SYMR *sym_end_p1;
4615 register PDR *proc_start;
4617 register PDR *proc_end_p1;
4619 /* file support itself. */
4620 add_file (filename, filename + strlen (filename));
4621 cur_file_ptr->orig_fdr = fd_ptr;
4623 /* Copy stuff that's just passed through (such as line #'s) */
4624 cur_file_ptr->fdr.adr = fd_ptr->adr;
4625 cur_file_ptr->fdr.ilineBase = fd_ptr->ilineBase;
4626 cur_file_ptr->fdr.cline = fd_ptr->cline;
4627 cur_file_ptr->fdr.rfdBase = fd_ptr->rfdBase;
4628 cur_file_ptr->fdr.crfd = fd_ptr->crfd;
4629 cur_file_ptr->fdr.cbLineOffset = fd_ptr->cbLineOffset;
4630 cur_file_ptr->fdr.cbLine = fd_ptr->cbLine;
4631 cur_file_ptr->fdr.fMerge = fd_ptr->fMerge;
4632 cur_file_ptr->fdr.fReadin = fd_ptr->fReadin;
4633 cur_file_ptr->fdr.glevel = fd_ptr->glevel;
4636 fprintf (stderr, "\thash\tstart, filename %s\n", filename);
4638 /* For each of the static and global symbols defined, add them
4639 to the hash table of original symbols, so we can look up
4642 sym_start = ORIG_LSYMS (fd_ptr->isymBase);
4643 sym_end_p1 = sym_start + fd_ptr->csym;
4644 for (sym = sym_start; sym < sym_end_p1; sym++)
4646 switch ((st_t) sym->st)
4657 auto symint_t hash_index;
4658 register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
4659 register Size_t len = strlen (str);
4660 register shash_t *shash_ptr = hash_string (str,
4665 if (shash_ptr != (shash_t *)0)
4666 error ("internal error, %s is already in original symbol table", str);
4670 shash_ptr = allocate_shash ();
4671 shash_ptr->next = orig_str_hash[hash_index];
4672 orig_str_hash[hash_index] = shash_ptr;
4674 shash_ptr->len = len;
4675 shash_ptr->indx = indexNil;
4676 shash_ptr->string = str;
4677 shash_ptr->sym_ptr = sym;
4683 if ((sc_t) sym->sc == sc_Text)
4685 register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
4689 register Size_t len = strlen (str);
4690 register shash_t *shash_ptr = hash_string (str,
4695 if (shash_ptr != (shash_t *)0)
4696 shash_ptr->end_ptr = sym;
4706 fprintf (stderr, "\thash\tdone, filename %s\n", filename);
4707 fprintf (stderr, "\tproc\tstart, filename %s\n", filename);
4710 /* Go through each of the procedures in this file, and add the
4711 procedure pointer to the hash entry for the given name. */
4713 proc_start = ORIG_PROCS (fd_ptr->ipdFirst);
4714 proc_end_p1 = proc_start + fd_ptr->cpd;
4715 for (proc = proc_start; proc < proc_end_p1; proc++)
4717 register SYMR *proc_sym = ORIG_LSYMS (fd_ptr->isymBase + proc->isym);
4718 register char *str = ORIG_LSTRS (fd_ptr->issBase + proc_sym->iss);
4719 register Size_t len = strlen (str);
4720 register shash_t *shash_ptr = hash_string (str,
4725 if (shash_ptr == (shash_t *)0)
4726 error ("internal error, function %s is not in original symbol table", str);
4729 shash_ptr->proc_ptr = proc;
4733 fprintf (stderr, "\tproc\tdone, filename %s\n", filename);
4736 cur_file_ptr = first_file;
4739 /* Copy all of the object file up to the symbol table. Originally
4740 we were going to use ftruncate, but that doesn't seem to work
4741 on Ultrix 3.1.... */
4743 if (fseek (obj_in_stream, (long)0, SEEK_SET) != 0)
4744 pfatal_with_name (obj_in_name);
4746 if (fseek (object_stream, (long)0, SEEK_SET) != 0)
4747 pfatal_with_name (object_name);
4749 for (remaining = orig_file_header.f_symptr;
4751 remaining -= num_write)
4753 num_write = (remaining <= sizeof (buffer)) ? remaining : sizeof (buffer);
4754 sys_read = fread ((PTR_T) buffer, 1, num_write, obj_in_stream);
4756 pfatal_with_name (obj_in_name);
4758 else if (sys_read != num_write)
4759 fatal ("Wanted to read %d bytes from %s, system returned %d",
4764 sys_write = fwrite (buffer, 1, num_write, object_stream);
4766 pfatal_with_name (object_name);
4768 else if (sys_write != num_write)
4769 fatal ("Wrote %d bytes to %s, system returned %d",
4777 /* Ye olde main program. */
4785 char *p = local_rindex (argv[0], '/');
4790 progname = (p != 0) ? p+1 : argv[0];
4792 (void) signal (SIGSEGV, catch_signal);
4793 (void) signal (SIGBUS, catch_signal);
4794 (void) signal (SIGABRT, catch_signal);
4796 #if !defined(__SABER__) && !defined(lint)
4797 if (sizeof (efdr_t) > PAGE_USIZE)
4798 fatal ("Efdr_t has a sizeof %d bytes, when it should be less than %d",
4802 if (sizeof (page_t) != PAGE_USIZE)
4803 fatal ("Page_t has a sizeof %d bytes, when it should be %d",
4809 alloc_counts[ alloc_type_none ].alloc_name = "none";
4810 alloc_counts[ alloc_type_scope ].alloc_name = "scope";
4811 alloc_counts[ alloc_type_vlinks ].alloc_name = "vlinks";
4812 alloc_counts[ alloc_type_shash ].alloc_name = "shash";
4813 alloc_counts[ alloc_type_thash ].alloc_name = "thash";
4814 alloc_counts[ alloc_type_tag ].alloc_name = "tag";
4815 alloc_counts[ alloc_type_forward ].alloc_name = "forward";
4816 alloc_counts[ alloc_type_thead ].alloc_name = "thead";
4817 alloc_counts[ alloc_type_varray ].alloc_name = "varray";
4819 int_type_info = type_info_init;
4820 int_type_info.basic_type = bt_Int;
4822 void_type_info = type_info_init;
4823 void_type_info.basic_type = bt_Void;
4825 while ((option = getopt (argc, argv, "d:i:I:o:v")) != EOF)
4833 debug = strtol (optarg, &num_end, 0);
4834 if ((unsigned)debug > 4 || num_end == optarg)
4840 if (rename_output || obj_in_name != (char *)0)
4845 /* fall through to 'i' case. */
4848 if (obj_in_name == (char *)0)
4850 obj_in_name = optarg;
4858 if (object_name == (char *)0)
4859 object_name = optarg;
4869 if (obj_in_name == (char *)0 && optind <= argc - 2)
4870 obj_in_name = argv[--argc];
4872 if (object_name == (char *)0 && optind <= argc - 2)
4873 object_name = argv[--argc];
4875 /* If there is an output name, but no input name use
4876 the same file for both, deleting the name between
4877 opening it for input and opening it for output. */
4878 if (obj_in_name == (char *)0 && object_name != (char *)0)
4880 obj_in_name = object_name;
4884 if (object_name == (char *)0 || had_errors || optind != argc - 1)
4886 fprintf (stderr, "Calling Sequence:\n");
4887 fprintf (stderr, "\tmips-tfile [-d <num>] [-v] [-i <o-in-file>] -o <o-out-file> <s-file> (or)\n");
4888 fprintf (stderr, "\tmips-tfile [-d <num>] [-v] [-I <o-in-file>] -o <o-out-file> <s-file> (or)\n");
4889 fprintf (stderr, "\tmips-tfile [-d <num>] [-v] <s-file> <o-in-file> <o-out-file>\n");
4890 fprintf (stderr, "\n");
4891 fprintf (stderr, "Debug levels are:\n");
4892 fprintf (stderr, " 1\tGeneral debug + trace functions/blocks.\n");
4893 fprintf (stderr, " 2\tDebug level 1 + trace externals.\n");
4894 fprintf (stderr, " 3\tDebug level 2 + trace all symbols.\n");
4895 fprintf (stderr, " 4\tDebug level 3 + trace memory allocations.\n");
4902 fprintf (stderr, "mips-tfile version %s", version_string);
4903 #ifdef TARGET_VERSION
4906 fputc ('\n', stderr);
4909 if (obj_in_name == (char *)0)
4910 obj_in_name = object_name;
4912 if (rename_output && rename (object_name, obj_in_name) != 0)
4914 char *buffer = (char *) allocate_multiple_pages (4);
4920 /* Rename failed, copy input file */
4921 in_fd = open (object_name, O_RDONLY, 0666);
4923 pfatal_with_name (object_name);
4925 out_fd = open (obj_in_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
4927 pfatal_with_name (obj_in_name);
4929 while ((len = read (in_fd, buffer, 4*PAGE_SIZE)) > 0)
4931 len2 = write (out_fd, buffer, len);
4933 pfatal_with_name (object_name);
4936 fatal ("wrote %d bytes to %s, expected to write %d", len2, obj_in_name, len);
4939 free_multiple_pages ((page_t *)buffer, 4);
4942 pfatal_with_name (object_name);
4944 if (close (in_fd) < 0)
4945 pfatal_with_name (object_name);
4947 if (close (out_fd) < 0)
4948 pfatal_with_name (obj_in_name);
4951 /* Must open input before output, since the output may be the same file, and
4952 we need to get the input handle before truncating it. */
4953 obj_in_stream = fopen (obj_in_name, "r");
4954 if (obj_in_stream == (FILE *)0)
4955 pfatal_with_name (obj_in_name);
4957 if (delete_input && unlink (obj_in_name) != 0)
4958 pfatal_with_name (obj_in_name);
4960 object_stream = fopen (object_name, "w");
4961 if (object_stream == (FILE *)0)
4962 pfatal_with_name (object_name);
4964 if (strcmp (argv[optind], "-") != 0)
4966 input_name = argv[optind];
4967 if (freopen (argv[optind], "r", stdin) != stdin)
4968 pfatal_with_name (argv[optind]);
4971 copy_object (); /* scan & copy object file */
4972 parse_input (); /* scan all of input */
4974 update_headers (); /* write out tfile */
4979 fprintf (stderr, "\n\tAllocation summary:\n\n");
4980 for (i = (int)alloc_type_none; i < (int)alloc_type_last; i++)
4981 if (alloc_counts[i].total_alloc)
4984 "\t%s\t%5d allocation(s), %5d free(s), %2d page(s)\n",
4985 alloc_counts[i].alloc_name,
4986 alloc_counts[i].total_alloc,
4987 alloc_counts[i].total_free,
4988 alloc_counts[i].total_pages);
4992 return (had_errors) ? 1 : 0;
4996 /* Catch a signal and exit without dumping core. */
4999 catch_signal (signum)
5002 (void) signal (signum, SIG_DFL); /* just in case... */
5003 fatal (sys_siglist[signum]);
5006 /* Print a fatal error message. NAME is the text.
5007 Also include a system error message based on `errno'. */
5010 pfatal_with_name (msg)
5013 int save_errno = errno; /* just in case.... */
5014 if (line_number > 0)
5015 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5017 fprintf (stderr, "%s:", progname);
5021 fprintf (stderr, "[errno = 0] %s\n", msg);
5029 /* Procedure to abort with an out of bounds error message. It has
5030 type int, so it can be used with an ?: expression within the
5031 ORIG_xxx macros, but the function never returns. */
5034 out_of_bounds (indx, max, str, prog_line)
5035 symint_t indx; /* index that is out of bounds */
5036 symint_t max; /* maximum index */
5037 const char *str; /* string to print out */
5038 int prog_line; /* line number within mips-tfile.c */
5040 if (indx < max) /* just in case */
5043 fprintf (stderr, "%s, %s:%ld index %u is out of bounds for %s, max is %u, mips-tfile.c line# %d\n",
5044 progname, input_name, line_number, indx, str, max, prog_line);
5047 return 0; /* turn off warning messages */
5051 /* Allocate a cluster of pages. USE_MALLOC says that malloc does not
5052 like sbrk's behind it's back (or sbrk isn't available). If we use
5053 sbrk, we assume it gives us zeroed pages. */
5055 #ifndef MALLOC_CHECK
5059 allocate_cluster (npages)
5062 register page_t *value = (page_t *) calloc (npages, PAGE_USIZE);
5065 fatal ("Virtual memory exhausted.");
5068 fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
5073 #else /* USE_MALLOC */
5076 allocate_cluster (npages)
5079 register page_t *ptr = (page_t *) sbrk (0); /* current sbreak */
5080 unsigned long offset = ((unsigned long) ptr) & (PAGE_SIZE - 1);
5082 if (offset != 0) /* align to a page boundary */
5084 if (sbrk (PAGE_USIZE - offset) == (char *)-1)
5085 pfatal_with_name ("allocate_cluster");
5087 ptr = (page_t *) (((char *)ptr) + PAGE_SIZE - offset);
5090 if (sbrk (npages * PAGE_USIZE) == (char *)-1)
5091 pfatal_with_name ("allocate_cluster");
5094 fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, ptr);
5099 #endif /* USE_MALLOC */
5102 static page_t *cluster_ptr = NULL;
5103 static unsigned pages_left = 0;
5105 #endif /* MALLOC_CHECK */
5108 /* Allocate some pages (which is initialized to 0). */
5111 allocate_multiple_pages (npages)
5114 #ifndef MALLOC_CHECK
5115 if (pages_left == 0 && npages < MAX_CLUSTER_PAGES)
5117 pages_left = MAX_CLUSTER_PAGES;
5118 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
5121 if (npages <= pages_left)
5123 page_t *ptr = cluster_ptr;
5124 cluster_ptr += npages;
5125 pages_left -= npages;
5129 return allocate_cluster (npages);
5131 #else /* MALLOC_CHECK */
5132 return (page_t *) xcalloc (npages, PAGE_SIZE);
5134 #endif /* MALLOC_CHECK */
5138 /* Release some pages. */
5141 free_multiple_pages (page_ptr, npages)
5145 #ifndef MALLOC_CHECK
5146 if (pages_left == 0)
5148 cluster_ptr = page_ptr;
5149 pages_left = npages;
5152 else if ((page_ptr + npages) == cluster_ptr)
5154 cluster_ptr -= npages;
5155 pages_left += npages;
5158 /* otherwise the page is not freed. If more than call is
5159 done, we probably should worry about it, but at present,
5160 the free pages is done right after an allocate. */
5162 #else /* MALLOC_CHECK */
5163 free ((char *) page_ptr);
5165 #endif /* MALLOC_CHECK */
5169 /* Allocate one page (which is initialized to 0). */
5172 allocate_page __proto((void))
5174 #ifndef MALLOC_CHECK
5175 if (pages_left == 0)
5177 pages_left = MAX_CLUSTER_PAGES;
5178 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
5182 return cluster_ptr++;
5184 #else /* MALLOC_CHECK */
5185 return (page_t *) xcalloc (1, PAGE_SIZE);
5187 #endif /* MALLOC_CHECK */
5191 /* Allocate scoping information. */
5194 allocate_scope __proto((void))
5196 register scope_t *ptr;
5197 static scope_t initial_scope;
5199 #ifndef MALLOC_CHECK
5200 ptr = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope;
5201 if (ptr != (scope_t *)0)
5202 alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr->free;
5206 register int unallocated = alloc_counts[ (int)alloc_type_scope ].unallocated;
5207 register page_t *cur_page = alloc_counts[ (int)alloc_type_scope ].cur_page;
5209 if (unallocated == 0)
5211 unallocated = PAGE_SIZE / sizeof (scope_t);
5212 alloc_counts[ (int)alloc_type_scope ].cur_page = cur_page = allocate_page ();
5213 alloc_counts[ (int)alloc_type_scope ].total_pages++;
5216 ptr = &cur_page->scope[ --unallocated ];
5217 alloc_counts[ (int)alloc_type_scope ].unallocated = unallocated;
5221 ptr = (scope_t *) xmalloc (sizeof (scope_t));
5225 alloc_counts[ (int)alloc_type_scope ].total_alloc++;
5226 *ptr = initial_scope;
5230 /* Free scoping information. */
5236 alloc_counts[ (int)alloc_type_scope ].total_free++;
5238 #ifndef MALLOC_CHECK
5239 ptr->free = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope;
5240 alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr;
5243 xfree ((PTR_T) ptr);
5249 /* Allocate links for pages in a virtual array. */
5252 allocate_vlinks __proto((void))
5254 register vlinks_t *ptr;
5255 static vlinks_t initial_vlinks;
5257 #ifndef MALLOC_CHECK
5258 register int unallocated = alloc_counts[ (int)alloc_type_vlinks ].unallocated;
5259 register page_t *cur_page = alloc_counts[ (int)alloc_type_vlinks ].cur_page;
5261 if (unallocated == 0)
5263 unallocated = PAGE_SIZE / sizeof (vlinks_t);
5264 alloc_counts[ (int)alloc_type_vlinks ].cur_page = cur_page = allocate_page ();
5265 alloc_counts[ (int)alloc_type_vlinks ].total_pages++;
5268 ptr = &cur_page->vlinks[ --unallocated ];
5269 alloc_counts[ (int)alloc_type_vlinks ].unallocated = unallocated;
5272 ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
5276 alloc_counts[ (int)alloc_type_vlinks ].total_alloc++;
5277 *ptr = initial_vlinks;
5282 /* Allocate string hash buckets. */
5285 allocate_shash __proto((void))
5287 register shash_t *ptr;
5288 static shash_t initial_shash;
5290 #ifndef MALLOC_CHECK
5291 register int unallocated = alloc_counts[ (int)alloc_type_shash ].unallocated;
5292 register page_t *cur_page = alloc_counts[ (int)alloc_type_shash ].cur_page;
5294 if (unallocated == 0)
5296 unallocated = PAGE_SIZE / sizeof (shash_t);
5297 alloc_counts[ (int)alloc_type_shash ].cur_page = cur_page = allocate_page ();
5298 alloc_counts[ (int)alloc_type_shash ].total_pages++;
5301 ptr = &cur_page->shash[ --unallocated ];
5302 alloc_counts[ (int)alloc_type_shash ].unallocated = unallocated;
5305 ptr = (shash_t *) xmalloc (sizeof (shash_t));
5309 alloc_counts[ (int)alloc_type_shash ].total_alloc++;
5310 *ptr = initial_shash;
5315 /* Allocate type hash buckets. */
5318 allocate_thash __proto((void))
5320 register thash_t *ptr;
5321 static thash_t initial_thash;
5323 #ifndef MALLOC_CHECK
5324 register int unallocated = alloc_counts[ (int)alloc_type_thash ].unallocated;
5325 register page_t *cur_page = alloc_counts[ (int)alloc_type_thash ].cur_page;
5327 if (unallocated == 0)
5329 unallocated = PAGE_SIZE / sizeof (thash_t);
5330 alloc_counts[ (int)alloc_type_thash ].cur_page = cur_page = allocate_page ();
5331 alloc_counts[ (int)alloc_type_thash ].total_pages++;
5334 ptr = &cur_page->thash[ --unallocated ];
5335 alloc_counts[ (int)alloc_type_thash ].unallocated = unallocated;
5338 ptr = (thash_t *) xmalloc (sizeof (thash_t));
5342 alloc_counts[ (int)alloc_type_thash ].total_alloc++;
5343 *ptr = initial_thash;
5348 /* Allocate structure, union, or enum tag information. */
5351 allocate_tag __proto((void))
5353 register tag_t *ptr;
5354 static tag_t initial_tag;
5356 #ifndef MALLOC_CHECK
5357 ptr = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag;
5358 if (ptr != (tag_t *)0)
5359 alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr->free;
5363 register int unallocated = alloc_counts[ (int)alloc_type_tag ].unallocated;
5364 register page_t *cur_page = alloc_counts[ (int)alloc_type_tag ].cur_page;
5366 if (unallocated == 0)
5368 unallocated = PAGE_SIZE / sizeof (tag_t);
5369 alloc_counts[ (int)alloc_type_tag ].cur_page = cur_page = allocate_page ();
5370 alloc_counts[ (int)alloc_type_tag ].total_pages++;
5373 ptr = &cur_page->tag[ --unallocated ];
5374 alloc_counts[ (int)alloc_type_tag ].unallocated = unallocated;
5378 ptr = (tag_t *) xmalloc (sizeof (tag_t));
5382 alloc_counts[ (int)alloc_type_tag ].total_alloc++;
5387 /* Free scoping information. */
5393 alloc_counts[ (int)alloc_type_tag ].total_free++;
5395 #ifndef MALLOC_CHECK
5396 ptr->free = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag;
5397 alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr;
5400 xfree ((PTR_T) ptr);
5406 /* Allocate forward reference to a yet unknown tag. */
5409 allocate_forward __proto((void))
5411 register forward_t *ptr;
5412 static forward_t initial_forward;
5414 #ifndef MALLOC_CHECK
5415 ptr = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward;
5416 if (ptr != (forward_t *)0)
5417 alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr->free;
5421 register int unallocated = alloc_counts[ (int)alloc_type_forward ].unallocated;
5422 register page_t *cur_page = alloc_counts[ (int)alloc_type_forward ].cur_page;
5424 if (unallocated == 0)
5426 unallocated = PAGE_SIZE / sizeof (forward_t);
5427 alloc_counts[ (int)alloc_type_forward ].cur_page = cur_page = allocate_page ();
5428 alloc_counts[ (int)alloc_type_forward ].total_pages++;
5431 ptr = &cur_page->forward[ --unallocated ];
5432 alloc_counts[ (int)alloc_type_forward ].unallocated = unallocated;
5436 ptr = (forward_t *) xmalloc (sizeof (forward_t));
5440 alloc_counts[ (int)alloc_type_forward ].total_alloc++;
5441 *ptr = initial_forward;
5445 /* Free scoping information. */
5451 alloc_counts[ (int)alloc_type_forward ].total_free++;
5453 #ifndef MALLOC_CHECK
5454 ptr->free = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward;
5455 alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr;
5458 xfree ((PTR_T) ptr);
5464 /* Allocate head of type hash list. */
5467 allocate_thead __proto((void))
5469 register thead_t *ptr;
5470 static thead_t initial_thead;
5472 #ifndef MALLOC_CHECK
5473 ptr = alloc_counts[ (int)alloc_type_thead ].free_list.f_thead;
5474 if (ptr != (thead_t *)0)
5475 alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr->free;
5479 register int unallocated = alloc_counts[ (int)alloc_type_thead ].unallocated;
5480 register page_t *cur_page = alloc_counts[ (int)alloc_type_thead ].cur_page;
5482 if (unallocated == 0)
5484 unallocated = PAGE_SIZE / sizeof (thead_t);
5485 alloc_counts[ (int)alloc_type_thead ].cur_page = cur_page = allocate_page ();
5486 alloc_counts[ (int)alloc_type_thead ].total_pages++;
5489 ptr = &cur_page->thead[ --unallocated ];
5490 alloc_counts[ (int)alloc_type_thead ].unallocated = unallocated;
5494 ptr = (thead_t *) xmalloc (sizeof (thead_t));
5498 alloc_counts[ (int)alloc_type_thead ].total_alloc++;
5499 *ptr = initial_thead;
5503 /* Free scoping information. */
5509 alloc_counts[ (int)alloc_type_thead ].total_free++;
5511 #ifndef MALLOC_CHECK
5512 ptr->free = (thead_t *) alloc_counts[ (int)alloc_type_thead ].free_list.f_thead;
5513 alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr;
5516 xfree ((PTR_T) ptr);
5521 #endif /* MIPS_DEBUGGING_INFO */
5524 /* Output an error message and exit */
5534 if (line_number > 0)
5535 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5537 fprintf (stderr, "%s:", progname);
5540 format = va_arg (ap, char *);
5541 vfprintf (stderr, format, ap);
5543 fprintf (stderr, "\n");
5544 if (line_number > 0)
5545 fprintf (stderr, "line:\t%s\n", cur_line_start);
5559 if (line_number > 0)
5560 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5562 fprintf (stderr, "%s:", progname);
5565 format = va_arg (ap, char *);
5566 vfprintf (stderr, format, ap);
5567 fprintf (stderr, "\n");
5568 if (line_number > 0)
5569 fprintf (stderr, "line:\t%s\n", cur_line_start);
5577 /* More 'friendly' abort that prints the line and file.
5578 config.h can #define abort fancy_abort if you like that sort of thing. */
5583 fatal ("Internal abort.");
5587 /* When `malloc.c' is compiled with `rcheck' defined,
5588 it calls this function to report clobberage. */
5597 /* Same as `malloc' but report error if no memory available. */
5603 register PTR_T value = malloc (size);
5605 fatal ("Virtual memory exhausted.");
5608 fprintf (stderr, "\tmalloc\tptr = 0x%.8x, size = %10u\n", value, size);
5613 /* Same as `calloc' but report error if no memory available. */
5616 xcalloc (size1, size2)
5617 Size_t size1, size2;
5619 register PTR_T value = calloc (size1, size2);
5621 fatal ("Virtual memory exhausted.");
5624 fprintf (stderr, "\tcalloc\tptr = 0x%.8x, size1 = %10u, size2 = %10u [%u]\n",
5625 value, size1, size2, size1+size2);
5630 /* Same as `realloc' but report error if no memory available. */
5633 xrealloc (ptr, size)
5637 register PTR_T result = realloc (ptr, size);
5639 fatal ("Virtual memory exhausted.");
5642 fprintf (stderr, "\trealloc\tptr = 0x%.8x, size = %10u, orig = 0x%.8x\n",
5653 fprintf (stderr, "\tfree\tptr = 0x%.8x\n", ptr);
5659 /* Define our own index/rindex, since the local and global symbol
5660 structures as defined by MIPS has an 'index' field. */
5663 local_index (str, sentinel)
5669 for ( ; (ch = *str) != sentinel; str++)
5679 local_rindex (str, sentinel)
5684 const char *ret = (const char *)0;
5686 for ( ; (ch = *str) != '\0'; str++)