1 /* Update the symbol table (the .T file) in a MIPS object to
2 contain debugging information specified by the GNU compiler
3 in the form of comments (the mips assembler does not support
4 assembly access to debug information).
5 Copyright (C) 1991, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
6 Contributed by Michael Meissner (meissner@cygnus.com).
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, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
26 /* Here is a brief description of the MIPS ECOFF symbol table. The
27 MIPS symbol table has the following pieces:
33 +-- Dense number table
41 +-- Relative file descriptors
53 The symbolic header points to each of the other tables, and also
54 contains the number of entries. It also contains a magic number
55 and MIPS compiler version number, such as 2.0.
57 The auxiliary table is a series of 32 bit integers, that are
58 referenced as needed from the local symbol table. Unlike standard
59 COFF, the aux. information does not follow the symbol that uses
60 it, but rather is a separate table. In theory, this would allow
61 the MIPS compilers to collapse duplicate aux. entries, but I've not
62 noticed this happening with the 1.31 compiler suite. The different
63 types of aux. entries are:
65 1) dnLow: Low bound on array dimension.
67 2) dnHigh: High bound on array dimension.
69 3) isym: Index to the local symbol which is the start of the
70 function for the end of function first aux. entry.
72 4) width: Width of structures and bitfields.
74 5) count: Count of ranges for variant part.
76 6) rndx: A relative index into the symbol table. The relative
77 index field has two parts: rfd which is a pointer into the
78 relative file index table or ST_RFDESCAPE which says the next
79 aux. entry is the file number, and index: which is the pointer
80 into the local symbol within a given file table. This is for
81 things like references to types defined in another file.
83 7) Type information: This is like the COFF type bits, except it
84 is 32 bits instead of 16; they still have room to add new
85 basic types; and they can handle more than 6 levels of array,
86 pointer, function, etc. Each type information field contains
87 the following structure members:
89 a) fBitfield: a bit that says this is a bitfield, and the
90 size in bits follows as the next aux. entry.
92 b) continued: a bit that says the next aux. entry is a
93 continuation of the current type information (in case
94 there are more than 6 levels of array/ptr/function).
96 c) bt: an integer containing the base type before adding
97 array, pointer, function, etc. qualifiers. The
98 current base types that I have documentation for are:
101 btAdr -- address - integer same size as ptr
103 btUChar -- unsigned character
105 btUShort -- unsigned short
107 btUInt -- unsigned int
109 btULong -- unsigned long
110 btFloat -- float (real)
111 btDouble -- Double (real)
112 btStruct -- Structure (Record)
113 btUnion -- Union (variant)
115 btTypedef -- defined via a typedef isymRef
116 btRange -- subrange of int
118 btComplex -- fortran complex
119 btDComplex -- fortran double complex
120 btIndirect -- forward or unnamed typedef
121 btFixedDec -- Fixed Decimal
122 btFloatDec -- Float Decimal
123 btString -- Varying Length Character String
124 btBit -- Aligned Bit String
126 btVoid -- Void (MIPS cc revision >= 2.00)
128 d) tq0 - tq5: type qualifier fields as needed. The
129 current type qualifier fields I have documentation for
132 tqNil -- no more qualifiers
136 tqFar -- 8086 far pointers
140 The dense number table is used in the front ends, and disappears by
141 the time the .o is created.
143 With the 1.31 compiler suite, the optimization symbols don't seem
144 to be used as far as I can tell.
146 The linker is the first entity that creates the relative file
147 descriptor table, and I believe it is used so that the individual
148 file table pointers don't have to be rewritten when the objects are
149 merged together into the program file.
151 Unlike COFF, the basic symbol & string tables are split into
152 external and local symbols/strings. The relocation information
153 only goes off of the external symbol table, and the debug
154 information only goes off of the internal symbol table. The
155 external symbols can have links to an appropriate file index and
156 symbol within the file to give it the appropriate type information.
157 Because of this, the external symbols are actually larger than the
158 internal symbols (to contain the link information), and contain the
159 local symbol structure as a member, though this member is not the
160 first member of the external symbol structure (!). I suspect this
161 split is to make strip easier to deal with.
163 Each file table has offsets for where the line numbers, local
164 strings, local symbols, and procedure table starts from within the
165 global tables, and the indexs are reset to 0 for each of those
168 The procedure table contains the binary equivalents of the .ent
169 (start of the function address), .frame (what register is the
170 virtual frame pointer, constant offset from the register to obtain
171 the VFP, and what register holds the return address), .mask/.fmask
172 (bitmask of saved registers, and where the first register is stored
173 relative to the VFP) assembler directives. It also contains the
174 low and high bounds of the line numbers if debugging is turned on.
176 The line number table is a compressed form of the normal COFF line
177 table. Each line number entry is either 1 or 3 bytes long, and
178 contains a signed delta from the previous line, and an unsigned
179 count of the number of instructions this statement takes.
181 The local symbol table contains the following fields:
183 1) iss: index to the local string table giving the name of the
186 2) value: value of the symbol (address, register number, etc.).
188 3) st: symbol type. The current symbol types are:
190 stNil -- Nuthin' special
191 stGlobal -- external symbol
193 stParam -- procedure argument
194 stLocal -- local variable
196 stProc -- External Procedure
197 stBlock -- beginning of block
198 stEnd -- end (of anything)
199 stMember -- member (of anything)
200 stTypedef -- type definition
202 stRegReloc -- register relocation
203 stForward -- forwarding address
204 stStaticProc -- Static procedure
207 4) sc: storage class. The current storage classes are:
209 scText -- text symbol
210 scData -- initialized data symbol
211 scBss -- un-initialized data symbol
212 scRegister -- value of symbol is register number
213 scAbs -- value of symbol is absolute
214 scUndefined -- who knows?
215 scCdbLocal -- variable's value is IN se->va.??
216 scBits -- this is a bit field
217 scCdbSystem -- value is IN debugger's address space
218 scRegImage -- register value saved on stack
219 scInfo -- symbol contains debugger information
220 scUserStruct -- addr in struct user for current process
221 scSData -- load time only small data
222 scSBss -- load time only small common
223 scRData -- load time only read only data
224 scVar -- Var parameter (fortranpascal)
225 scCommon -- common variable
226 scSCommon -- small common
227 scVarRegister -- Var parameter in a register
228 scVariant -- Variant record
229 scSUndefined -- small undefined(external) data
230 scInit -- .init section symbol
232 5) index: pointer to a local symbol or aux. entry.
236 For the following program:
241 printf("Hello World!\n");
245 Mips-tdump produces the following information:
250 timestamp 645311799, Wed Jun 13 17:16:39 1990
251 symbolic header offset 284
252 symbolic header size 96
256 Symbolic header, magic number = 0x7009, vstamp = 1.31:
258 Info Offset Number Bytes
259 ==== ====== ====== =====
261 Line numbers 380 4 4 [13]
263 Procedures Tables 384 1 52
264 Local Symbols 436 16 192
265 Optimization Symbols 0 0 0
266 Auxiliary Symbols 628 39 156
267 Local Strings 784 80 80
268 External Strings 864 144 144
269 File Tables 1008 2 144
271 External Symbols 1152 20 320
275 Name index = 1 Readin = No
276 Merge = No Endian = LITTLE
277 Debug level = G2 Language = C
280 Info Start Number Size Offset
281 ==== ===== ====== ==== ======
282 Local strings 0 15 15 784
283 Local symbols 0 6 72 436
284 Line numbers 0 13 13 380
285 Optimization symbols 0 0 0 0
286 Procedures 0 1 52 384
287 Auxiliary symbols 0 14 56 628
288 Relative Files 0 0 0 0
290 There are 6 local symbols, starting at 436
292 Symbol# 0: "hello2.c"
295 Storage class = Text Index = 6
296 Symbol type = File Value = 0
302 Storage class = Text Index = 12
303 Symbol type = Proc Value = 0
308 Storage class = Text Index = 4
309 Symbol type = Block Value = 8
314 Storage class = Text Index = 2
315 Symbol type = End Value = 28
320 Storage class = Text Index = 1
321 Symbol type = End Value = 52
323 Symbol# 5: "hello2.c"
326 Storage class = Text Index = 0
327 Symbol type = End Value = 0
329 There are 14 auxiliary table entries, starting at 628.
331 * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
332 * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
333 * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0]
334 * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0]
335 * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
336 * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0]
337 * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0]
338 * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0]
339 * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0]
340 * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0]
341 * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0]
342 * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0]
343 #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0]
344 #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
346 There are 1 procedure descriptor entries, starting at 0.
348 Procedure descriptor 0:
349 Name index = 10 Name = "main"
350 .mask 0x80000000,-4 .fmask 0x00000000,0
352 Opt. start = -1 Symbols start = 1
353 First line # = 3 Last line # = 6
354 Line Offset = 0 Address = 0x00000000
356 There are 4 bytes holding line numbers, starting at 380.
357 Line 3, delta 0, count 2
358 Line 4, delta 1, count 3
359 Line 5, delta 1, count 2
360 Line 6, delta 1, count 6
362 File #1, "/usr/include/stdio.h"
364 Name index = 1 Readin = No
365 Merge = Yes Endian = LITTLE
366 Debug level = G2 Language = C
369 Info Start Number Size Offset
370 ==== ===== ====== ==== ======
371 Local strings 15 65 65 799
372 Local symbols 6 10 120 508
373 Line numbers 0 0 0 380
374 Optimization symbols 0 0 0 0
376 Auxiliary symbols 14 25 100 684
377 Relative Files 0 0 0 0
379 There are 10 local symbols, starting at 442
381 Symbol# 0: "/usr/include/stdio.h"
384 Storage class = Text Index = 10
385 Symbol type = File Value = 0
390 Storage class = Info Index = 9
391 Symbol type = Block Value = 20
396 Storage class = Info Index = 4
397 Symbol type = Member Value = 0
402 Storage class = Info Index = 15
403 Symbol type = Member Value = 32
408 Storage class = Info Index = 16
409 Symbol type = Member Value = 64
414 Storage class = Info Index = 4
415 Symbol type = Member Value = 96
420 Storage class = Info Index = 3
421 Symbol type = Member Value = 128
426 Storage class = Info Index = 2
427 Symbol type = Member Value = 144
432 Storage class = Info Index = 1
433 Symbol type = End Value = 0
435 Symbol# 9: "/usr/include/stdio.h"
438 Storage class = Text Index = 0
439 Symbol type = End Value = 0
441 There are 25 auxiliary table entries, starting at 642.
443 * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
444 #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
445 #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
446 * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0]
447 * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1]
448 * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
449 * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4]
450 * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
451 * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
452 * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0]
453 * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0]
454 * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
455 * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
456 * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
457 * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
458 * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
459 * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
460 * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
461 * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
462 * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
463 * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
464 * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
465 * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
466 * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
467 * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
469 There are 0 procedure descriptor entries, starting at 1.
471 There are 20 external symbols, starting at 1152
474 Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
475 String index = 0 Ifd = 1
476 Storage class = Nil Index = 17
477 Symbol type = Global Value = 60
480 String index = 5 Ifd = 1
481 Storage class = Nil Index = 1048575
482 Symbol type = Proc Value = 0
485 String index = 11 Ifd = 1
486 Storage class = Nil Index = 1048575
487 Symbol type = Proc Value = 0
490 String index = 18 Ifd = 1
491 Storage class = Nil Index = 1048575
492 Symbol type = Proc Value = 0
495 String index = 26 Ifd = 1
496 Storage class = Nil Index = 1048575
497 Symbol type = Proc Value = 0
500 String index = 32 Ifd = 1
501 Storage class = Nil Index = 1048575
502 Symbol type = Proc Value = 0
505 String index = 40 Ifd = 1
506 Storage class = Nil Index = 1048575
507 Symbol type = Proc Value = 0
510 String index = 46 Ifd = 1
511 Storage class = Nil Index = 1048575
512 Symbol type = Proc Value = 0
515 String index = 53 Ifd = 1
516 Storage class = Nil Index = 1048575
517 Symbol type = Proc Value = 0
519 Symbol# 9: "setbuffer"
520 String index = 60 Ifd = 1
521 Storage class = Nil Index = 1048575
522 Symbol type = Proc Value = 0
524 Symbol# 10: "setlinebuf"
525 String index = 70 Ifd = 1
526 Storage class = Nil Index = 1048575
527 Symbol type = Proc Value = 0
530 String index = 81 Ifd = 1
531 Storage class = Nil Index = 1048575
532 Symbol type = Proc Value = 0
535 String index = 87 Ifd = 1
536 Storage class = Nil Index = 1048575
537 Symbol type = Proc Value = 0
539 Symbol# 13: "ctermid"
540 String index = 92 Ifd = 1
541 Storage class = Nil Index = 1048575
542 Symbol type = Proc Value = 0
544 Symbol# 14: "cuserid"
545 String index = 100 Ifd = 1
546 Storage class = Nil Index = 1048575
547 Symbol type = Proc Value = 0
549 Symbol# 15: "tempnam"
550 String index = 108 Ifd = 1
551 Storage class = Nil Index = 1048575
552 Symbol type = Proc Value = 0
555 String index = 116 Ifd = 1
556 Storage class = Nil Index = 1048575
557 Symbol type = Proc Value = 0
559 Symbol# 17: "sprintf"
560 String index = 123 Ifd = 1
561 Storage class = Nil Index = 1048575
562 Symbol type = Proc Value = 0
566 String index = 131 Ifd = 0
567 Storage class = Text Index = 1
568 Symbol type = Proc Value = 0
571 String index = 136 Ifd = 0
572 Storage class = Undefined Index = 1048575
573 Symbol type = Proc Value = 0
575 The following auxiliary table entries were unused:
579 #3 16 0x00000010 short
581 #5 32 0x00000020 long
582 #6 40 0x00000028 float
583 #7 44 0x0000002c double
584 #8 12 0x0000000c unsigned char
585 #9 20 0x00000014 unsigned short
586 #10 28 0x0000001c unsigned int
587 #11 36 0x00000024 unsigned long
588 #14 0 0x00000000 void
589 #15 24 0x00000018 int
590 #19 32 0x00000020 long
591 #20 40 0x00000028 float
592 #21 44 0x0000002c double
593 #22 12 0x0000000c unsigned char
594 #23 20 0x00000014 unsigned short
595 #24 28 0x0000001c unsigned int
596 #25 36 0x00000024 unsigned long
597 #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 }
613 #define __proto(x) PARAMS(x)
614 /* Should PTR_T and CPTR_T be typedef'ed in terms of PTR ??? */
617 typedef const void *CPTR_T;
620 #if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */
622 typedef void *CPTR_T;
625 typedef char *PTR_T; /* Ultrix 3.1 */
626 typedef char *CPTR_T;
631 /* Do to size_t being defined in sys/types.h and different
632 in stddef.h, we have to do this by hand..... Note, these
633 types are correct for MIPS based systems, and may not be
634 correct for other systems. Ultrix 4.0 and Silicon Graphics
635 have this fixed, but since the following is correct, and
636 the fact that including stddef.h gets you GCC's version
637 instead of the standard one it's not worth it to fix it. */
639 #if defined(__OSF1__) || defined(__OSF__) || defined(__osf__)
640 #define Size_t long unsigned int
642 #define Size_t unsigned int
644 #define Ptrdiff_t long
646 /* The following might be called from obstack or malloc,
647 so they can't be static. */
649 extern void pfatal_with_name
651 extern void fancy_abort __proto((void));
652 void botch __proto((const char *));
653 extern PTR_T xmalloc __proto((Size_t));
654 extern PTR_T xcalloc __proto((Size_t, Size_t));
655 extern PTR_T xrealloc __proto((PTR_T, Size_t));
656 extern void xfree __proto((PTR_T));
658 extern void fatal PVPROTO((const char *format, ...));
659 extern void error PVPROTO((const char *format, ...));
661 #ifndef MIPS_DEBUGGING_INFO
663 static int line_number;
664 static int cur_line_start;
666 static int had_errors;
667 static char *progname;
668 static char *input_name;
673 fprintf (stderr, "Mips-tfile should only be run on a MIPS computer!\n");
677 #else /* MIPS_DEBUGGING defined */
679 /* The local and global symbols have a field index, so undo any defines
680 of index -> strchr and rindex -> strrchr. */
686 #include <sys/stat.h>
688 #ifndef CROSS_COMPILE
691 #include "mips/a.out.h"
692 #endif /* CROSS_COMPILE */
694 #if defined (USG) || !defined (HAVE_STAB_H)
695 #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */
697 #include <stab.h> /* On BSD, use the system's stab.h. */
700 #include "machmode.h"
703 #define STAB_CODE_TYPE enum __stab_debug_code
705 #define STAB_CODE_TYPE int
714 #define IS_ASM_IDENT(ch) \
715 (ISALNUM (ch) || (ch) == '_' || (ch) == '.' || (ch) == '$')
718 /* Redefinition of storage classes as an enumeration for better
722 sc_Nil = scNil, /* no storage class */
723 sc_Text = scText, /* text symbol */
724 sc_Data = scData, /* initialized data symbol */
725 sc_Bss = scBss, /* un-initialized data symbol */
726 sc_Register = scRegister, /* value of symbol is register number */
727 sc_Abs = scAbs, /* value of symbol is absolute */
728 sc_Undefined = scUndefined, /* who knows? */
729 sc_CdbLocal = scCdbLocal, /* variable's value is IN se->va.?? */
730 sc_Bits = scBits, /* this is a bit field */
731 sc_CdbSystem = scCdbSystem, /* value is IN CDB's address space */
732 sc_RegImage = scRegImage, /* register value saved on stack */
733 sc_Info = scInfo, /* symbol contains debugger information */
734 sc_UserStruct = scUserStruct, /* addr in struct user for current process */
735 sc_SData = scSData, /* load time only small data */
736 sc_SBss = scSBss, /* load time only small common */
737 sc_RData = scRData, /* load time only read only data */
738 sc_Var = scVar, /* Var parameter (fortran,pascal) */
739 sc_Common = scCommon, /* common variable */
740 sc_SCommon = scSCommon, /* small common */
741 sc_VarRegister = scVarRegister, /* Var parameter in a register */
742 sc_Variant = scVariant, /* Variant record */
743 sc_SUndefined = scSUndefined, /* small undefined(external) data */
744 sc_Init = scInit, /* .init section symbol */
745 sc_Max = scMax /* Max storage class+1 */
748 /* Redefinition of symbol type. */
751 st_Nil = stNil, /* Nuthin' special */
752 st_Global = stGlobal, /* external symbol */
753 st_Static = stStatic, /* static */
754 st_Param = stParam, /* procedure argument */
755 st_Local = stLocal, /* local variable */
756 st_Label = stLabel, /* label */
757 st_Proc = stProc, /* " " Procedure */
758 st_Block = stBlock, /* beginning of block */
759 st_End = stEnd, /* end (of anything) */
760 st_Member = stMember, /* member (of anything - struct/union/enum */
761 st_Typedef = stTypedef, /* type definition */
762 st_File = stFile, /* file name */
763 st_RegReloc = stRegReloc, /* register relocation */
764 st_Forward = stForward, /* forwarding address */
765 st_StaticProc = stStaticProc, /* load time only static procs */
766 st_Constant = stConstant, /* const */
767 st_Str = stStr, /* string */
768 st_Number = stNumber, /* pure number (ie. 4 NOR 2+2) */
769 st_Expr = stExpr, /* 2+2 vs. 4 */
770 st_Type = stType, /* post-coercion SER */
771 st_Max = stMax /* max type+1 */
774 /* Redefinition of type qualifiers. */
777 tq_Nil = tqNil, /* bt is what you see */
778 tq_Ptr = tqPtr, /* pointer */
779 tq_Proc = tqProc, /* procedure */
780 tq_Array = tqArray, /* duh */
781 tq_Far = tqFar, /* longer addressing - 8086/8 land */
782 tq_Vol = tqVol, /* volatile */
783 tq_Max = tqMax /* Max type qualifier+1 */
786 /* Redefinition of basic types. */
789 bt_Nil = btNil, /* undefined */
790 bt_Adr = btAdr, /* address - integer same size as pointer */
791 bt_Char = btChar, /* character */
792 bt_UChar = btUChar, /* unsigned character */
793 bt_Short = btShort, /* short */
794 bt_UShort = btUShort, /* unsigned short */
795 bt_Int = btInt, /* int */
796 bt_UInt = btUInt, /* unsigned int */
797 bt_Long = btLong, /* long */
798 bt_ULong = btULong, /* unsigned long */
799 bt_Float = btFloat, /* float (real) */
800 bt_Double = btDouble, /* Double (real) */
801 bt_Struct = btStruct, /* Structure (Record) */
802 bt_Union = btUnion, /* Union (variant) */
803 bt_Enum = btEnum, /* Enumerated */
804 bt_Typedef = btTypedef, /* defined via a typedef, isymRef points */
805 bt_Range = btRange, /* subrange of int */
806 bt_Set = btSet, /* pascal sets */
807 bt_Complex = btComplex, /* fortran complex */
808 bt_DComplex = btDComplex, /* fortran double complex */
809 bt_Indirect = btIndirect, /* forward or unnamed typedef */
810 bt_FixedDec = btFixedDec, /* Fixed Decimal */
811 bt_FloatDec = btFloatDec, /* Float Decimal */
812 bt_String = btString, /* Varying Length Character String */
813 bt_Bit = btBit, /* Aligned Bit String */
814 bt_Picture = btPicture, /* Picture */
817 bt_Void = btVoid, /* Void */
819 #define bt_Void bt_Nil
822 bt_Max = btMax /* Max basic type+1 */
827 /* Basic COFF storage classes. */
859 /* Regular COFF fundamental type. */
860 typedef enum coff_type {
880 /* Regular COFF derived types. */
881 typedef enum coff_dt {
889 #define N_BTMASK 017 /* bitmask to isolate basic type */
890 #define N_TMASK 003 /* bitmask to isolate derived type */
891 #define N_BT_SHIFT 4 /* # bits to shift past basic type */
892 #define N_TQ_SHIFT 2 /* # bits to shift derived types */
893 #define N_TQ 6 /* # of type qualifiers */
895 /* States for whether to hash type or not. */
896 typedef enum hash_state {
897 hash_no = 0, /* don't hash type */
898 hash_yes = 1, /* ok to hash type, or use previous hash */
899 hash_record = 2 /* ok to record hash, but don't use prev. */
903 /* Types of different sized allocation requests. */
905 alloc_type_none, /* dummy value */
906 alloc_type_scope, /* nested scopes linked list */
907 alloc_type_vlinks, /* glue linking pages in varray */
908 alloc_type_shash, /* string hash element */
909 alloc_type_thash, /* type hash element */
910 alloc_type_tag, /* struct/union/tag element */
911 alloc_type_forward, /* element to hold unknown tag */
912 alloc_type_thead, /* head of type hash list */
913 alloc_type_varray, /* general varray allocation */
914 alloc_type_last /* last+1 element for array bounds */
918 #define WORD_ALIGN(x) (((x) + (sizeof (long) - 1)) & ~ (sizeof (long) - 1))
919 #define DWORD_ALIGN(x) (((x) + 7) & ~7)
922 /* Structures to provide n-number of virtual arrays, each of which can
923 grow linearly, and which are written in the object file as sequential
924 pages. On systems with a BSD malloc that define USE_MALLOC, the
925 MAX_CLUSTER_PAGES should be 1 less than a power of two, since malloc
926 adds its overhead, and rounds up to the next power of 2. Pages are
927 linked together via a linked list.
929 If PAGE_SIZE is > 4096, the string length in the shash_t structure
930 can't be represented (assuming there are strings > 4096 bytes). */
933 #define PAGE_SIZE 4096 /* size of varray pages */
936 #define PAGE_USIZE ((Size_t)PAGE_SIZE)
939 #ifndef MAX_CLUSTER_PAGES /* # pages to get from system */
940 #ifndef USE_MALLOC /* in one memory request */
941 #define MAX_CLUSTER_PAGES 64
943 #define MAX_CLUSTER_PAGES 63
948 /* Linked list connecting separate page allocations. */
949 typedef struct vlinks {
950 struct vlinks *prev; /* previous set of pages */
951 struct vlinks *next; /* next set of pages */
952 union page *datum; /* start of page */
953 unsigned long start_index; /* starting index # of page */
957 /* Virtual array header. */
958 typedef struct varray {
959 vlinks_t *first; /* first page link */
960 vlinks_t *last; /* last page link */
961 unsigned long num_allocated; /* # objects allocated */
962 unsigned short object_size; /* size in bytes of each object */
963 unsigned short objects_per_page; /* # objects that can fit on a page */
964 unsigned short objects_last_page; /* # objects allocated on last page */
968 #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
970 #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
973 #define INIT_VARRAY(type) { /* macro to initialize a varray */ \
974 (vlinks_t *) 0, /* first */ \
975 (vlinks_t *) 0, /* last */ \
976 0, /* num_allocated */ \
977 sizeof (type), /* object_size */ \
978 OBJECTS_PER_PAGE (type), /* objects_per_page */ \
979 OBJECTS_PER_PAGE (type), /* objects_last_page */ \
982 /* Master type for indexes within the symbol table. */
983 typedef unsigned long symint_t;
986 /* Linked list support for nested scopes (file, block, structure, etc.). */
987 typedef struct scope {
988 struct scope *prev; /* previous scope level */
989 struct scope *free; /* free list pointer */
990 SYMR *lsym; /* pointer to local symbol node */
991 symint_t lnumber; /* lsym index */
992 st_t type; /* type of the node */
996 /* Forward reference list for tags referenced, but not yet defined. */
997 typedef struct forward {
998 struct forward *next; /* next forward reference */
999 struct forward *free; /* free list pointer */
1000 AUXU *ifd_ptr; /* pointer to store file index */
1001 AUXU *index_ptr; /* pointer to store symbol index */
1002 AUXU *type_ptr; /* pointer to munge type info */
1006 /* Linked list support for tags. The first tag in the list is always
1007 the current tag for that block. */
1008 typedef struct tag {
1009 struct tag *free; /* free list pointer */
1010 struct shash *hash_ptr; /* pointer to the hash table head */
1011 struct tag *same_name; /* tag with same name in outer scope */
1012 struct tag *same_block; /* next tag defined in the same block. */
1013 struct forward *forward_ref; /* list of forward references */
1014 bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
1015 symint_t ifd; /* file # tag defined in */
1016 symint_t indx; /* index within file's local symbols */
1020 /* Head of a block's linked list of tags. */
1021 typedef struct thead {
1022 struct thead *prev; /* previous block */
1023 struct thead *free; /* free list pointer */
1024 struct tag *first_tag; /* first tag in block defined */
1028 /* Union containing pointers to each the small structures which are freed up. */
1029 typedef union small_free {
1030 scope_t *f_scope; /* scope structure */
1031 thead_t *f_thead; /* tag head structure */
1032 tag_t *f_tag; /* tag element structure */
1033 forward_t *f_forward; /* forward tag reference */
1037 /* String hash table support. The size of the hash table must fit
1041 #define SHASH_SIZE 1009
1044 #define HASH_LEN_MAX ((1 << 12) - 1) /* Max length we can store */
1046 typedef struct shash {
1047 struct shash *next; /* next hash value */
1048 char *string; /* string we are hashing */
1049 symint_t len; /* string length */
1050 symint_t indx; /* index within string table */
1051 EXTR *esym_ptr; /* global symbol pointer */
1052 SYMR *sym_ptr; /* local symbol pointer */
1053 SYMR *end_ptr; /* symbol pointer to end block */
1054 tag_t *tag_ptr; /* tag pointer */
1055 PDR *proc_ptr; /* procedure descriptor pointer */
1059 /* Type hash table support. The size of the hash table must fit
1060 within a page with the other extended file descriptor information.
1061 Because unique types which are hashed are fewer in number than
1062 strings, we use a smaller hash value. */
1065 #define THASH_SIZE 113
1068 typedef struct thash {
1069 struct thash *next; /* next hash value */
1070 AUXU type; /* type we are hashing */
1071 symint_t indx; /* index within string table */
1075 /* Extended file descriptor that contains all of the support necessary
1076 to add things to each file separately. */
1077 typedef struct efdr {
1078 FDR fdr; /* File header to be written out */
1079 FDR *orig_fdr; /* original file header */
1080 char *name; /* filename */
1081 int name_len; /* length of the filename */
1082 symint_t void_type; /* aux. pointer to 'void' type */
1083 symint_t int_type; /* aux. pointer to 'int' type */
1084 scope_t *cur_scope; /* current nested scopes */
1085 symint_t file_index; /* current file number */
1086 int nested_scopes; /* # nested scopes */
1087 varray_t strings; /* local strings */
1088 varray_t symbols; /* local symbols */
1089 varray_t procs; /* procedures */
1090 varray_t aux_syms; /* auxiliary symbols */
1091 struct efdr *next_file; /* next file descriptor */
1092 /* string/type hash tables */
1093 shash_t **shash_head; /* string hash table */
1094 thash_t *thash_head[THASH_SIZE];
1097 /* Pre-initialized extended file structure. */
1098 static efdr_t init_file =
1100 { /* FDR structure */
1101 0, /* adr: memory address of beginning of file */
1102 0, /* rss: file name (of source, if known) */
1103 0, /* issBase: file's string space */
1104 0, /* cbSs: number of bytes in the ss */
1105 0, /* isymBase: beginning of symbols */
1106 0, /* csym: count file's of symbols */
1107 0, /* ilineBase: file's line symbols */
1108 0, /* cline: count of file's line symbols */
1109 0, /* ioptBase: file's optimization entries */
1110 0, /* copt: count of file's optimization entries */
1111 0, /* ipdFirst: start of procedures for this file */
1112 0, /* cpd: count of procedures for this file */
1113 0, /* iauxBase: file's auxiliary entries */
1114 0, /* caux: count of file's auxiliary entries */
1115 0, /* rfdBase: index into the file indirect table */
1116 0, /* crfd: count file indirect entries */
1117 langC, /* lang: language for this file */
1118 1, /* fMerge: whether this file can be merged */
1119 0, /* fReadin: true if read in (not just created) */
1120 #ifdef HOST_WORDS_BIG_ENDIAN
1121 1, /* fBigendian: if 1, compiled on big endian machine */
1123 0, /* fBigendian: if 1, compiled on big endian machine */
1125 GLEVEL_2, /* glevel: level this file was compiled with */
1126 0, /* reserved: reserved for future use */
1127 0, /* cbLineOffset: byte offset from header for this file ln's */
1128 0, /* cbLine: size of lines for this file */
1131 (FDR *) 0, /* orig_fdr: original file header pointer */
1132 (char *) 0, /* name: pointer to filename */
1133 0, /* name_len: length of filename */
1134 0, /* void_type: ptr to aux node for void type */
1135 0, /* int_type: ptr to aux node for int type */
1136 (scope_t *) 0, /* cur_scope: current scope being processed */
1137 0, /* file_index: current file # */
1138 0, /* nested_scopes: # nested scopes */
1139 INIT_VARRAY (char), /* strings: local string varray */
1140 INIT_VARRAY (SYMR), /* symbols: local symbols varray */
1141 INIT_VARRAY (PDR), /* procs: procedure varray */
1142 INIT_VARRAY (AUXU), /* aux_syms: auxiliary symbols varray */
1144 (struct efdr *) 0, /* next_file: next file structure */
1146 (shash_t **) 0, /* shash_head: string hash table */
1147 { 0 }, /* thash_head: type hash table */
1151 static efdr_t *first_file; /* first file descriptor */
1152 static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */
1155 /* Union of various things that are held in pages. */
1156 typedef union page {
1157 char byte [ PAGE_SIZE ];
1158 unsigned char ubyte [ PAGE_SIZE ];
1159 efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
1160 FDR ofile [ PAGE_SIZE / sizeof (FDR) ];
1161 PDR proc [ PAGE_SIZE / sizeof (PDR) ];
1162 SYMR sym [ PAGE_SIZE / sizeof (SYMR) ];
1163 EXTR esym [ PAGE_SIZE / sizeof (EXTR) ];
1164 AUXU aux [ PAGE_SIZE / sizeof (AUXU) ];
1165 DNR dense [ PAGE_SIZE / sizeof (DNR) ];
1166 scope_t scope [ PAGE_SIZE / sizeof (scope_t) ];
1167 vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ];
1168 shash_t shash [ PAGE_SIZE / sizeof (shash_t) ];
1169 thash_t thash [ PAGE_SIZE / sizeof (thash_t) ];
1170 tag_t tag [ PAGE_SIZE / sizeof (tag_t) ];
1171 forward_t forward [ PAGE_SIZE / sizeof (forward_t) ];
1172 thead_t thead [ PAGE_SIZE / sizeof (thead_t) ];
1176 /* Structure holding allocation information for small sized structures. */
1177 typedef struct alloc_info {
1178 char *alloc_name; /* name of this allocation type (must be first) */
1179 page_t *cur_page; /* current page being allocated from */
1180 small_free_t free_list; /* current free list if any */
1181 int unallocated; /* number of elements unallocated on page */
1182 int total_alloc; /* total number of allocations */
1183 int total_free; /* total number of frees */
1184 int total_pages; /* total number of pages allocated */
1187 /* Type information collected together. */
1188 typedef struct type_info {
1189 bt_t basic_type; /* basic type */
1190 coff_type_t orig_type; /* original COFF-based type */
1191 int num_tq; /* # type qualifiers */
1192 int num_dims; /* # dimensions */
1193 int num_sizes; /* # sizes */
1194 int extra_sizes; /* # extra sizes not tied with dims */
1195 tag_t * tag_ptr; /* tag pointer */
1196 int bitfield; /* symbol is a bitfield */
1197 int unknown_tag; /* this is an unknown tag */
1198 tq_t type_qualifiers[N_TQ]; /* type qualifiers (ptr, func, array)*/
1199 symint_t dimensions [N_TQ]; /* dimensions for each array */
1200 symint_t sizes [N_TQ+2]; /* sizes of each array slice + size of
1201 struct/union/enum + bitfield size */
1204 /* Pre-initialized type_info struct. */
1205 static type_info_t type_info_init = {
1206 bt_Nil, /* basic type */
1207 T_NULL, /* original COFF-based type */
1208 0, /* # type qualifiers */
1209 0, /* # dimensions */
1211 0, /* sizes not tied with dims */
1212 NULL, /* ptr to tag */
1214 0, /* unknown tag */
1215 { /* type qualifiers */
1244 /* Global virtual arrays & hash table for external strings as well as
1245 for the tags table and global tables for file descriptors, and
1248 static varray_t file_desc = INIT_VARRAY (efdr_t);
1249 static varray_t dense_num = INIT_VARRAY (DNR);
1250 static varray_t tag_strings = INIT_VARRAY (char);
1251 static varray_t ext_strings = INIT_VARRAY (char);
1252 static varray_t ext_symbols = INIT_VARRAY (EXTR);
1254 static shash_t *orig_str_hash[SHASH_SIZE];
1255 static shash_t *ext_str_hash [SHASH_SIZE];
1256 static shash_t *tag_hash [SHASH_SIZE];
1258 /* Static types for int and void. Also, remember the last function's
1259 type (which is set up when we encounter the declaration for the
1260 function, and used when the end block for the function is emitted. */
1262 static type_info_t int_type_info;
1263 static type_info_t void_type_info;
1264 static type_info_t last_func_type_info;
1265 static EXTR *last_func_eptr;
1268 /* Convert COFF basic type to ECOFF basic type. The T_NULL type
1269 really should use bt_Void, but this causes the current ecoff GDB to
1270 issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
1271 2.0) doesn't understand it, even though the compiler generates it.
1272 Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
1273 suite, but for now go with what works. */
1275 static bt_t map_coff_types[ (int)T_MAX ] = {
1276 bt_Nil, /* T_NULL */
1278 bt_Char, /* T_CHAR */
1279 bt_Short, /* T_SHORT */
1281 bt_Long, /* T_LONG */
1282 bt_Float, /* T_FLOAT */
1283 bt_Double, /* T_DOUBLE */
1284 bt_Struct, /* T_STRUCT */
1285 bt_Union, /* T_UNION */
1286 bt_Enum, /* T_ENUM */
1287 bt_Enum, /* T_MOE */
1288 bt_UChar, /* T_UCHAR */
1289 bt_UShort, /* T_USHORT */
1290 bt_UInt, /* T_UINT */
1291 bt_ULong /* T_ULONG */
1294 /* Convert COFF storage class to ECOFF storage class. */
1295 static sc_t map_coff_storage[ (int)C_MAX ] = {
1296 sc_Nil, /* 0: C_NULL */
1297 sc_Abs, /* 1: C_AUTO auto var */
1298 sc_Undefined, /* 2: C_EXT external */
1299 sc_Data, /* 3: C_STAT static */
1300 sc_Register, /* 4: C_REG register */
1301 sc_Undefined, /* 5: C_EXTDEF ??? */
1302 sc_Text, /* 6: C_LABEL label */
1303 sc_Text, /* 7: C_ULABEL user label */
1304 sc_Info, /* 8: C_MOS member of struct */
1305 sc_Abs, /* 9: C_ARG argument */
1306 sc_Info, /* 10: C_STRTAG struct tag */
1307 sc_Info, /* 11: C_MOU member of union */
1308 sc_Info, /* 12: C_UNTAG union tag */
1309 sc_Info, /* 13: C_TPDEF typedef */
1310 sc_Data, /* 14: C_USTATIC ??? */
1311 sc_Info, /* 15: C_ENTAG enum tag */
1312 sc_Info, /* 16: C_MOE member of enum */
1313 sc_Register, /* 17: C_REGPARM register parameter */
1314 sc_Bits, /* 18; C_FIELD bitfield */
1396 sc_Text, /* 100: C_BLOCK block start/end */
1397 sc_Text, /* 101: C_FCN function start/end */
1398 sc_Info, /* 102: C_EOS end of struct/union/enum */
1399 sc_Nil, /* 103: C_FILE file start */
1400 sc_Nil, /* 104: C_LINE line number */
1401 sc_Nil, /* 105: C_ALIAS combined type info */
1402 sc_Nil, /* 106: C_HIDDEN ??? */
1405 /* Convert COFF storage class to ECOFF symbol type. */
1406 static st_t map_coff_sym_type[ (int)C_MAX ] = {
1407 st_Nil, /* 0: C_NULL */
1408 st_Local, /* 1: C_AUTO auto var */
1409 st_Global, /* 2: C_EXT external */
1410 st_Static, /* 3: C_STAT static */
1411 st_Local, /* 4: C_REG register */
1412 st_Global, /* 5: C_EXTDEF ??? */
1413 st_Label, /* 6: C_LABEL label */
1414 st_Label, /* 7: C_ULABEL user label */
1415 st_Member, /* 8: C_MOS member of struct */
1416 st_Param, /* 9: C_ARG argument */
1417 st_Block, /* 10: C_STRTAG struct tag */
1418 st_Member, /* 11: C_MOU member of union */
1419 st_Block, /* 12: C_UNTAG union tag */
1420 st_Typedef, /* 13: C_TPDEF typedef */
1421 st_Static, /* 14: C_USTATIC ??? */
1422 st_Block, /* 15: C_ENTAG enum tag */
1423 st_Member, /* 16: C_MOE member of enum */
1424 st_Param, /* 17: C_REGPARM register parameter */
1425 st_Member, /* 18; C_FIELD bitfield */
1507 st_Block, /* 100: C_BLOCK block start/end */
1508 st_Proc, /* 101: C_FCN function start/end */
1509 st_End, /* 102: C_EOS end of struct/union/enum */
1510 st_File, /* 103: C_FILE file start */
1511 st_Nil, /* 104: C_LINE line number */
1512 st_Nil, /* 105: C_ALIAS combined type info */
1513 st_Nil, /* 106: C_HIDDEN ??? */
1516 /* Map COFF derived types to ECOFF type qualifiers. */
1517 static tq_t map_coff_derived_type[ (int)DT_MAX ] = {
1518 tq_Nil, /* 0: DT_NON no more qualifiers */
1519 tq_Ptr, /* 1: DT_PTR pointer */
1520 tq_Proc, /* 2: DT_FCN function */
1521 tq_Array, /* 3: DT_ARY array */
1525 /* Keep track of different sized allocation requests. */
1526 static alloc_info_t alloc_counts[ (int)alloc_type_last ];
1529 /* Pointers and such to the original symbol table that is read in. */
1530 static struct filehdr orig_file_header; /* global object file header */
1532 static HDRR orig_sym_hdr; /* symbolic header on input */
1533 static char *orig_linenum; /* line numbers */
1534 static DNR *orig_dense; /* dense numbers */
1535 static PDR *orig_procs; /* procedures */
1536 static SYMR *orig_local_syms; /* local symbols */
1537 static OPTR *orig_opt_syms; /* optimization symbols */
1538 static AUXU *orig_aux_syms; /* auxiliary symbols */
1539 static char *orig_local_strs; /* local strings */
1540 static char *orig_ext_strs; /* external strings */
1541 static FDR *orig_files; /* file descriptors */
1542 static symint_t *orig_rfds; /* relative file desc's */
1543 static EXTR *orig_ext_syms; /* external symbols */
1545 /* Macros to convert an index into a given object within the original
1547 #define CHECK(num,max,str) \
1548 (((unsigned long)num > (unsigned long)max) ? out_of_bounds (num, max, str, __LINE__) : 0)
1550 #define ORIG_LINENUM(indx) (CHECK ((indx), orig_sym_hdr.cbLine, "line#"), (indx) + orig_linenum)
1551 #define ORIG_DENSE(indx) (CHECK ((indx), orig_sym_hdr.idnMax, "dense"), (indx) + orig_dense)
1552 #define ORIG_PROCS(indx) (CHECK ((indx), orig_sym_hdr.ipdMax, "procs"), (indx) + orig_procs)
1553 #define ORIG_FILES(indx) (CHECK ((indx), orig_sym_hdr.ifdMax, "funcs"), (indx) + orig_files)
1554 #define ORIG_LSYMS(indx) (CHECK ((indx), orig_sym_hdr.isymMax, "lsyms"), (indx) + orig_local_syms)
1555 #define ORIG_LSTRS(indx) (CHECK ((indx), orig_sym_hdr.issMax, "lstrs"), (indx) + orig_local_strs)
1556 #define ORIG_ESYMS(indx) (CHECK ((indx), orig_sym_hdr.iextMax, "esyms"), (indx) + orig_ext_syms)
1557 #define ORIG_ESTRS(indx) (CHECK ((indx), orig_sym_hdr.issExtMax, "estrs"), (indx) + orig_ext_strs)
1558 #define ORIG_OPT(indx) (CHECK ((indx), orig_sym_hdr.ioptMax, "opt"), (indx) + orig_opt_syms)
1559 #define ORIG_AUX(indx) (CHECK ((indx), orig_sym_hdr.iauxMax, "aux"), (indx) + orig_aux_syms)
1560 #define ORIG_RFDS(indx) (CHECK ((indx), orig_sym_hdr.crfd, "rfds"), (indx) + orig_rfds)
1562 /* Various other statics. */
1563 static HDRR symbolic_header; /* symbolic header */
1564 static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */
1565 static PDR *cur_proc_ptr = (PDR *) 0; /* current procedure header */
1566 static SYMR *cur_oproc_begin = (SYMR *) 0; /* original proc. sym begin info */
1567 static SYMR *cur_oproc_end = (SYMR *) 0; /* original proc. sym end info */
1568 static PDR *cur_oproc_ptr = (PDR *) 0; /* current original procedure*/
1569 static thead_t *cur_tag_head = (thead_t *) 0;/* current tag head */
1570 static long file_offset = 0; /* current file offset */
1571 static long max_file_offset = 0; /* maximum file offset */
1572 static FILE *object_stream = (FILE *) 0; /* file desc. to output .o */
1573 static FILE *obj_in_stream = (FILE *) 0; /* file desc. to input .o */
1574 static char *progname = (char *) 0; /* program name for errors */
1575 static char *input_name = "stdin"; /* name of input file */
1576 static char *object_name = (char *) 0; /* tmp. name of object file */
1577 static char *obj_in_name = (char *) 0; /* name of input object file */
1578 static char *cur_line_start = (char *) 0; /* current line read in */
1579 static char *cur_line_ptr = (char *) 0; /* ptr within current line */
1580 static unsigned cur_line_nbytes = 0; /* # bytes for current line */
1581 static unsigned cur_line_alloc = 0; /* # bytes total in buffer */
1582 static long line_number = 0; /* current input line number */
1583 static int debug = 0; /* trace functions */
1584 static int version = 0; /* print version # */
1585 static int had_errors = 0; /* != 0 if errors were found */
1586 static int rename_output = 0; /* != 0 if rename output file*/
1587 static int delete_input = 0; /* != 0 if delete input after done */
1588 static int stabs_seen = 0; /* != 0 if stabs have been seen */
1591 /* Pseudo symbol to use when putting stabs into the symbol table. */
1592 #ifndef STABS_SYMBOL
1593 #define STABS_SYMBOL "@stabs"
1596 static char stabs_symbol[] = STABS_SYMBOL;
1599 /* Forward reference for functions. See the definition for more details. */
1602 #define STATIC static
1605 STATIC int out_of_bounds __proto((symint_t, symint_t, const char *, int));
1607 STATIC shash_t *hash_string __proto((const char *,
1612 STATIC symint_t add_string __proto((varray_t *,
1618 STATIC symint_t add_local_symbol
1619 __proto((const char *,
1626 STATIC symint_t add_ext_symbol __proto((const char *,
1634 STATIC symint_t add_aux_sym_symint
1635 __proto((symint_t));
1637 STATIC symint_t add_aux_sym_rndx
1638 __proto((int, symint_t));
1640 STATIC symint_t add_aux_sym_tir __proto((type_info_t *,
1644 STATIC tag_t * get_tag __proto((const char *,
1649 STATIC void add_unknown_tag __proto((tag_t *));
1651 STATIC void add_procedure __proto((const char *,
1654 STATIC void add_file __proto((const char *,
1657 STATIC void add_bytes __proto((varray_t *,
1661 STATIC void add_varray_page __proto((varray_t *));
1663 STATIC void update_headers __proto((void));
1665 STATIC void write_varray __proto((varray_t *, off_t, const char *));
1666 STATIC void write_object __proto((void));
1667 STATIC char *st_to_string __proto((st_t));
1668 STATIC char *sc_to_string __proto((sc_t));
1669 STATIC char *read_line __proto((void));
1670 STATIC void parse_input __proto((void));
1671 STATIC void mark_stabs __proto((const char *));
1672 STATIC void parse_begin __proto((const char *));
1673 STATIC void parse_bend __proto((const char *));
1674 STATIC void parse_def __proto((const char *));
1675 STATIC void parse_end __proto((const char *));
1676 STATIC void parse_ent __proto((const char *));
1677 STATIC void parse_file __proto((const char *));
1678 STATIC void parse_stabs_common
1679 __proto((const char *, const char *, const char *));
1680 STATIC void parse_stabs __proto((const char *));
1681 STATIC void parse_stabn __proto((const char *));
1682 STATIC page_t *read_seek __proto((Size_t, off_t, const char *));
1683 STATIC void copy_object __proto((void));
1685 STATIC void catch_signal __proto((int));
1686 STATIC page_t *allocate_page __proto((void));
1688 STATIC page_t *allocate_multiple_pages
1691 STATIC void free_multiple_pages
1692 __proto((page_t *, Size_t));
1694 #ifndef MALLOC_CHECK
1695 STATIC page_t *allocate_cluster
1699 STATIC forward_t *allocate_forward __proto((void));
1700 STATIC scope_t *allocate_scope __proto((void));
1701 STATIC shash_t *allocate_shash __proto((void));
1702 STATIC tag_t *allocate_tag __proto((void));
1703 STATIC thash_t *allocate_thash __proto((void));
1704 STATIC thead_t *allocate_thead __proto((void));
1705 STATIC vlinks_t *allocate_vlinks __proto((void));
1707 STATIC void free_forward __proto((forward_t *));
1708 STATIC void free_scope __proto((scope_t *));
1709 STATIC void free_tag __proto((tag_t *));
1710 STATIC void free_thead __proto((thead_t *));
1712 STATIC char *local_index __proto((const char *, int));
1713 STATIC char *local_rindex __proto((const char *, int));
1714 STATIC const char *my_strsignal __proto((int));
1716 extern char *mktemp __proto((char *));
1717 extern long strtol __proto((const char *, char **, int));
1719 extern char *optarg;
1722 extern char *version_string;
1724 /* List of assembler pseudo ops and beginning sequences that need
1725 special actions. Someday, this should be a hash table, and such,
1726 but for now a linear list of names and calls to memcmp will
1729 typedef struct _pseudo_ops {
1730 const char *name; /* pseudo-op in ascii */
1731 int len; /* length of name to compare */
1732 void (*func) __proto((const char *)); /* function to handle line */
1735 static pseudo_ops_t pseudo_ops[] = {
1736 { "#.def", sizeof("#.def")-1, parse_def },
1737 { "#.begin", sizeof("#.begin")-1, parse_begin },
1738 { "#.bend", sizeof("#.bend")-1, parse_bend },
1739 { ".end", sizeof(".end")-1, parse_end },
1740 { ".ent", sizeof(".ent")-1, parse_ent },
1741 { ".file", sizeof(".file")-1, parse_file },
1742 { "#.stabs", sizeof("#.stabs")-1, parse_stabs },
1743 { "#.stabn", sizeof("#.stabn")-1, parse_stabn },
1744 { ".stabs", sizeof(".stabs")-1, parse_stabs },
1745 { ".stabn", sizeof(".stabn")-1, parse_stabn },
1746 { "#@stabs", sizeof("#@stabs")-1, mark_stabs },
1750 /* Add a page to a varray object. */
1753 add_varray_page (vp)
1754 varray_t *vp; /* varray to add page to */
1756 vlinks_t *new_links = allocate_vlinks ();
1759 if (vp->object_size > 1)
1760 new_links->datum = (page_t *) xcalloc (1, vp->object_size);
1763 new_links->datum = allocate_page ();
1765 alloc_counts[ (int)alloc_type_varray ].total_alloc++;
1766 alloc_counts[ (int)alloc_type_varray ].total_pages++;
1768 new_links->start_index = vp->num_allocated;
1769 vp->objects_last_page = 0;
1771 if (vp->first == (vlinks_t *) 0) /* first allocation? */
1772 vp->first = vp->last = new_links;
1774 { /* 2nd or greater allocation */
1775 new_links->prev = vp->last;
1776 vp->last->next = new_links;
1777 vp->last = new_links;
1782 /* Compute hash code (from tree.c) */
1787 hash_string (text, hash_len, hash_tbl, ret_hash_index)
1788 const char *text; /* ptr to text to hash */
1789 Ptrdiff_t hash_len; /* length of the text */
1790 shash_t **hash_tbl; /* hash table */
1791 symint_t *ret_hash_index; /* ptr to store hash index */
1793 register unsigned long hi;
1794 register Ptrdiff_t i;
1795 register shash_t *ptr;
1796 register int first_ch = *text;
1799 for (i = 0; i < hash_len; i++)
1800 hi = ((hi & 0x003fffff) * 613) + (text[i] & 0xff);
1802 hi &= (1 << HASHBITS) - 1;
1805 if (ret_hash_index != (symint_t *) 0)
1806 *ret_hash_index = hi;
1808 for (ptr = hash_tbl[hi]; ptr != (shash_t *) 0; ptr = ptr->next)
1809 if (hash_len == ptr->len
1810 && first_ch == ptr->string[0]
1811 && memcmp ((CPTR_T) text, (CPTR_T) ptr->string, hash_len) == 0)
1818 /* Add a string (and null pad) to one of the string tables. A
1819 consequence of hashing strings, is that we don't let strings
1820 cross page boundaries. The extra nulls will be ignored. */
1823 add_string (vp, hash_tbl, start, end_p1, ret_hash)
1824 varray_t *vp; /* string virtual array */
1825 shash_t **hash_tbl; /* ptr to hash table */
1826 const char *start; /* 1st byte in string */
1827 const char *end_p1; /* 1st byte after string */
1828 shash_t **ret_hash; /* return hash pointer */
1830 register Ptrdiff_t len = end_p1 - start;
1831 register shash_t *hash_ptr;
1834 if (len >= PAGE_USIZE)
1835 fatal ("String too big (%ld bytes)", (long) len);
1837 hash_ptr = hash_string (start, len, hash_tbl, &hi);
1838 if (hash_ptr == (shash_t *) 0)
1842 if (vp->objects_last_page + len >= PAGE_USIZE)
1845 = ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
1846 add_varray_page (vp);
1849 hash_ptr = allocate_shash ();
1850 hash_ptr->next = hash_tbl[hi];
1851 hash_tbl[hi] = hash_ptr;
1853 hash_ptr->len = len;
1854 hash_ptr->indx = vp->num_allocated;
1855 hash_ptr->string = p = & vp->last->datum->byte[ vp->objects_last_page ];
1857 vp->objects_last_page += len+1;
1858 vp->num_allocated += len+1;
1866 if (ret_hash != (shash_t **) 0)
1867 *ret_hash = hash_ptr;
1869 return hash_ptr->indx;
1873 /* Add a local symbol. */
1876 add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
1877 const char *str_start; /* first byte in string */
1878 const char *str_end_p1; /* first byte after string */
1879 st_t type; /* symbol type */
1880 sc_t storage; /* storage class */
1881 symint_t value; /* value of symbol */
1882 symint_t indx; /* index to local/aux. syms */
1884 register symint_t ret;
1885 register SYMR *psym;
1886 register scope_t *pscope;
1887 register thead_t *ptag_head;
1888 register tag_t *ptag;
1889 register tag_t *ptag_next;
1890 register varray_t *vp = &cur_file_ptr->symbols;
1891 register int scope_delta = 0;
1892 shash_t *hash_ptr = (shash_t *) 0;
1894 if (vp->objects_last_page == vp->objects_per_page)
1895 add_varray_page (vp);
1897 psym = &vp->last->datum->sym[ vp->objects_last_page++ ];
1899 psym->value = value;
1900 psym->st = (unsigned) type;
1901 psym->sc = (unsigned) storage;
1903 psym->iss = (str_start == (const char *) 0)
1905 : add_string (&cur_file_ptr->strings,
1906 &cur_file_ptr->shash_head[0],
1911 ret = vp->num_allocated++;
1913 if (MIPS_IS_STAB(psym))
1916 /* Save the symbol within the hash table if this is a static
1917 item, and it has a name. */
1918 if (hash_ptr != (shash_t *) 0
1919 && (type == st_Global || type == st_Static || type == st_Label
1920 || type == st_Proc || type == st_StaticProc))
1921 hash_ptr->sym_ptr = psym;
1923 /* push or pop a scope if appropriate. */
1929 case st_File: /* beginning of file */
1930 case st_Proc: /* procedure */
1931 case st_StaticProc: /* static procedure */
1932 case st_Block: /* begin scope */
1933 pscope = allocate_scope ();
1934 pscope->prev = cur_file_ptr->cur_scope;
1935 pscope->lsym = psym;
1936 pscope->lnumber = ret;
1937 pscope->type = type;
1938 cur_file_ptr->cur_scope = pscope;
1940 if (type != st_File)
1943 /* For every block type except file, struct, union, or
1944 enumeration blocks, push a level on the tag stack. We omit
1945 file types, so that tags can span file boundaries. */
1946 if (type != st_File && storage != sc_Info)
1948 ptag_head = allocate_thead ();
1949 ptag_head->first_tag = 0;
1950 ptag_head->prev = cur_tag_head;
1951 cur_tag_head = ptag_head;
1956 pscope = cur_file_ptr->cur_scope;
1957 if (pscope == (scope_t *)0)
1958 error ("internal error, too many st_End's");
1962 st_t begin_type = (st_t) pscope->lsym->st;
1964 if (begin_type != st_File)
1967 /* Except for file, structure, union, or enumeration end
1968 blocks remove all tags created within this scope. */
1969 if (begin_type != st_File && storage != sc_Info)
1971 ptag_head = cur_tag_head;
1972 cur_tag_head = ptag_head->prev;
1974 for (ptag = ptag_head->first_tag;
1975 ptag != (tag_t *) 0;
1978 if (ptag->forward_ref != (forward_t *) 0)
1979 add_unknown_tag (ptag);
1981 ptag_next = ptag->same_block;
1982 ptag->hash_ptr->tag_ptr = ptag->same_name;
1986 free_thead (ptag_head);
1989 cur_file_ptr->cur_scope = pscope->prev;
1990 psym->index = pscope->lnumber; /* blk end gets begin sym # */
1992 if (storage != sc_Info)
1993 psym->iss = pscope->lsym->iss; /* blk end gets same name */
1995 if (begin_type == st_File || begin_type == st_Block)
1996 pscope->lsym->index = ret+1; /* block begin gets next sym # */
1998 /* Functions push two or more aux words as follows:
1999 1st word: index+1 of the end symbol
2000 2nd word: type of the function (plus any aux words needed).
2001 Also, tie the external pointer back to the function begin symbol. */
2005 pscope->lsym->index = add_aux_sym_symint (ret+1);
2006 type = add_aux_sym_tir (&last_func_type_info,
2008 &cur_file_ptr->thash_head[0]);
2011 last_func_eptr->ifd = cur_file_ptr->file_index;
2013 /* The index for an external st_Proc symbol is the index
2014 of the st_Proc symbol in the local symbol table. */
2015 last_func_eptr->asym.index = psym->index;
2019 free_scope (pscope);
2023 cur_file_ptr->nested_scopes += scope_delta;
2025 if (debug && type != st_File
2026 && (debug > 2 || type == st_Block || type == st_End
2027 || type == st_Proc || type == st_StaticProc))
2029 char *sc_str = sc_to_string (storage);
2030 char *st_str = st_to_string (type);
2031 int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
2034 "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
2035 value, depth, sc_str);
2037 if (str_start && str_end_p1 - str_start > 0)
2038 fprintf (stderr, " st= %-11s name= %.*s\n",
2039 st_str, (int) (str_end_p1 - str_start), str_start);
2042 Size_t len = strlen (st_str);
2043 fprintf (stderr, " st= %.*s\n", (int) (len-1), st_str);
2051 /* Add an external symbol. */
2054 add_ext_symbol (str_start, str_end_p1, type, storage, value, indx, ifd)
2055 const char *str_start; /* first byte in string */
2056 const char *str_end_p1; /* first byte after string */
2057 st_t type; /* symbol type */
2058 sc_t storage; /* storage class */
2059 long value; /* value of symbol */
2060 symint_t indx; /* index to local/aux. syms */
2061 int ifd; /* file index */
2063 register EXTR *psym;
2064 register varray_t *vp = &ext_symbols;
2065 shash_t *hash_ptr = (shash_t *) 0;
2069 char *sc_str = sc_to_string (storage);
2070 char *st_str = st_to_string (type);
2073 "\tesym\tv= %10ld, ifd= %2d, sc= %-12s",
2074 value, ifd, sc_str);
2076 if (str_start && str_end_p1 - str_start > 0)
2077 fprintf (stderr, " st= %-11s name= %.*s\n",
2078 st_str, (int) (str_end_p1 - str_start), str_start);
2080 fprintf (stderr, " st= %s\n", st_str);
2083 if (vp->objects_last_page == vp->objects_per_page)
2084 add_varray_page (vp);
2086 psym = &vp->last->datum->esym[ vp->objects_last_page++ ];
2089 psym->asym.value = value;
2090 psym->asym.st = (unsigned) type;
2091 psym->asym.sc = (unsigned) storage;
2092 psym->asym.index = indx;
2093 psym->asym.iss = (str_start == (const char *) 0)
2095 : add_string (&ext_strings,
2101 hash_ptr->esym_ptr = psym;
2102 return vp->num_allocated++;
2106 /* Add an auxiliary symbol (passing a symint). */
2109 add_aux_sym_symint (aux_word)
2110 symint_t aux_word; /* auxiliary information word */
2112 register AUXU *aux_ptr;
2113 register efdr_t *file_ptr = cur_file_ptr;
2114 register varray_t *vp = &file_ptr->aux_syms;
2116 if (vp->objects_last_page == vp->objects_per_page)
2117 add_varray_page (vp);
2119 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2120 aux_ptr->isym = aux_word;
2122 return vp->num_allocated++;
2126 /* Add an auxiliary symbol (passing a file/symbol index combo). */
2129 add_aux_sym_rndx (file_index, sym_index)
2133 register AUXU *aux_ptr;
2134 register efdr_t *file_ptr = cur_file_ptr;
2135 register varray_t *vp = &file_ptr->aux_syms;
2137 if (vp->objects_last_page == vp->objects_per_page)
2138 add_varray_page (vp);
2140 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2141 aux_ptr->rndx.rfd = file_index;
2142 aux_ptr->rndx.index = sym_index;
2144 return vp->num_allocated++;
2148 /* Add an auxiliary symbol (passing the basic type and possibly
2149 type qualifiers). */
2152 add_aux_sym_tir (t, state, hash_tbl)
2153 type_info_t *t; /* current type information */
2154 hash_state_t state; /* whether to hash type or not */
2155 thash_t **hash_tbl; /* pointer to hash table to use */
2157 register AUXU *aux_ptr;
2158 register efdr_t *file_ptr = cur_file_ptr;
2159 register varray_t *vp = &file_ptr->aux_syms;
2160 static AUXU init_aux;
2166 aux.ti.bt = (int) t->basic_type;
2167 aux.ti.continued = 0;
2168 aux.ti.fBitfield = t->bitfield;
2170 aux.ti.tq0 = (int) t->type_qualifiers[0];
2171 aux.ti.tq1 = (int) t->type_qualifiers[1];
2172 aux.ti.tq2 = (int) t->type_qualifiers[2];
2173 aux.ti.tq3 = (int) t->type_qualifiers[3];
2174 aux.ti.tq4 = (int) t->type_qualifiers[4];
2175 aux.ti.tq5 = (int) t->type_qualifiers[5];
2178 /* For anything that adds additional information, we must not hash,
2179 so check here, and reset our state. */
2181 if (state != hash_no
2182 && (t->type_qualifiers[0] == tq_Array
2183 || t->type_qualifiers[1] == tq_Array
2184 || t->type_qualifiers[2] == tq_Array
2185 || t->type_qualifiers[3] == tq_Array
2186 || t->type_qualifiers[4] == tq_Array
2187 || t->type_qualifiers[5] == tq_Array
2188 || t->basic_type == bt_Struct
2189 || t->basic_type == bt_Union
2190 || t->basic_type == bt_Enum
2192 || t->num_dims > 0))
2195 /* See if we can hash this type, and save some space, but some types
2196 can't be hashed (because they contain arrays or continuations),
2197 and others can be put into the hash list, but cannot use existing
2198 types because other aux entries precede this one. */
2200 if (state != hash_no)
2202 register thash_t *hash_ptr;
2203 register symint_t hi;
2205 hi = aux.isym & ((1 << HASHBITS) - 1);
2208 for (hash_ptr = hash_tbl[hi];
2209 hash_ptr != (thash_t *) 0;
2210 hash_ptr = hash_ptr->next)
2212 if (aux.isym == hash_ptr->type.isym)
2216 if (hash_ptr != (thash_t *) 0 && state == hash_yes)
2217 return hash_ptr->indx;
2219 if (hash_ptr == (thash_t *) 0)
2221 hash_ptr = allocate_thash ();
2222 hash_ptr->next = hash_tbl[hi];
2223 hash_ptr->type = aux;
2224 hash_ptr->indx = vp->num_allocated;
2225 hash_tbl[hi] = hash_ptr;
2229 /* Everything is set up, add the aux symbol. */
2230 if (vp->objects_last_page == vp->objects_per_page)
2231 add_varray_page (vp);
2233 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
2236 ret = vp->num_allocated++;
2238 /* Add bitfield length if it exists.
2240 NOTE: Mips documentation claims bitfield goes at the end of the
2241 AUX record, but the DECstation compiler emits it here.
2242 (This would only make a difference for enum bitfields.)
2244 Also note: We use the last size given since gcc may emit 2
2245 for an enum bitfield. */
2248 (void) add_aux_sym_symint ((symint_t)t->sizes[t->num_sizes-1]);
2251 /* Add tag information if needed. Structure, union, and enum
2252 references add 2 aux symbols: a [file index, symbol index]
2253 pointer to the structure type, and the current file index. */
2255 if (t->basic_type == bt_Struct
2256 || t->basic_type == bt_Union
2257 || t->basic_type == bt_Enum)
2259 register symint_t file_index = t->tag_ptr->ifd;
2260 register symint_t sym_index = t->tag_ptr->indx;
2264 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2265 (void) add_aux_sym_symint ((symint_t)-1);
2267 else if (sym_index != indexNil)
2269 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2270 (void) add_aux_sym_symint (file_index);
2274 register forward_t *forward_ref = allocate_forward ();
2276 forward_ref->type_ptr = aux_ptr;
2277 forward_ref->next = t->tag_ptr->forward_ref;
2278 t->tag_ptr->forward_ref = forward_ref;
2280 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
2281 forward_ref->index_ptr
2282 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2284 (void) add_aux_sym_symint (file_index);
2285 forward_ref->ifd_ptr
2286 = &vp->last->datum->aux[ vp->objects_last_page - 1];
2290 /* Add information about array bounds if they exist. */
2291 for (i = 0; i < t->num_dims; i++)
2293 (void) add_aux_sym_rndx (ST_RFDESCAPE,
2294 cur_file_ptr->int_type);
2296 (void) add_aux_sym_symint (cur_file_ptr->file_index); /* file index*/
2297 (void) add_aux_sym_symint ((symint_t) 0); /* low bound */
2298 (void) add_aux_sym_symint (t->dimensions[i] - 1); /* high bound*/
2299 (void) add_aux_sym_symint ((t->dimensions[i] == 0) /* stride */
2301 : (t->sizes[i] * 8) / t->dimensions[i]);
2304 /* NOTE: Mips documentation claims that the bitfield width goes here.
2305 But it needs to be emitted earlier. */
2311 /* Add a tag to the tag table (unless it already exists). */
2314 get_tag (tag_start, tag_end_p1, indx, basic_type)
2315 const char *tag_start; /* 1st byte of tag name */
2316 const char *tag_end_p1; /* 1st byte after tag name */
2317 symint_t indx; /* index of tag start block */
2318 bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
2322 hash_ptr = hash_string (tag_start,
2323 tag_end_p1 - tag_start,
2327 if (hash_ptr != (shash_t *) 0
2328 && hash_ptr->tag_ptr != (tag_t *) 0)
2330 tag_ptr = hash_ptr->tag_ptr;
2331 if (indx != indexNil)
2333 tag_ptr->basic_type = basic_type;
2334 tag_ptr->ifd = cur_file_ptr->file_index;
2335 tag_ptr->indx = indx;
2340 (void) add_string (&tag_strings,
2346 tag_ptr = allocate_tag ();
2347 tag_ptr->forward_ref = (forward_t *) 0;
2348 tag_ptr->hash_ptr = hash_ptr;
2349 tag_ptr->same_name = hash_ptr->tag_ptr;
2350 tag_ptr->basic_type = basic_type;
2351 tag_ptr->indx = indx;
2352 tag_ptr->ifd = (indx == indexNil) ? -1 : cur_file_ptr->file_index;
2353 tag_ptr->same_block = cur_tag_head->first_tag;
2355 cur_tag_head->first_tag = tag_ptr;
2356 hash_ptr->tag_ptr = tag_ptr;
2362 /* Add an unknown {struct, union, enum} tag. */
2365 add_unknown_tag (ptag)
2366 tag_t *ptag; /* pointer to tag information */
2368 shash_t *hash_ptr = ptag->hash_ptr;
2369 char *name_start = hash_ptr->string;
2370 char *name_end_p1 = name_start + hash_ptr->len;
2371 forward_t *f_next = ptag->forward_ref;
2374 int file_index = cur_file_ptr->file_index;
2378 char *agg_type = "{unknown aggregate type}";
2379 switch (ptag->basic_type)
2381 case bt_Struct: agg_type = "struct"; break;
2382 case bt_Union: agg_type = "union"; break;
2383 case bt_Enum: agg_type = "enum"; break;
2387 fprintf (stderr, "unknown %s %.*s found\n",
2388 agg_type, (int) hash_ptr->len, name_start);
2391 sym_index = add_local_symbol (name_start,
2398 (void) add_local_symbol (name_start,
2405 while (f_next != (forward_t *) 0)
2408 f_next = f_next->next;
2410 f_cur->ifd_ptr->isym = file_index;
2411 f_cur->index_ptr->rndx.index = sym_index;
2413 free_forward (f_cur);
2420 /* Add a procedure to the current file's list of procedures, and record
2421 this is the current procedure. If the assembler created a PDR for
2422 this procedure, use that to initialize the current PDR. */
2425 add_procedure (func_start, func_end_p1)
2426 const char *func_start; /* 1st byte of func name */
2427 const char *func_end_p1; /* 1st byte after func name */
2429 register PDR *new_proc_ptr;
2430 register efdr_t *file_ptr = cur_file_ptr;
2431 register varray_t *vp = &file_ptr->procs;
2432 register symint_t value = 0;
2433 register st_t proc_type = st_Proc;
2434 register shash_t *shash_ptr = hash_string (func_start,
2435 func_end_p1 - func_start,
2440 fputc ('\n', stderr);
2442 if (vp->objects_last_page == vp->objects_per_page)
2443 add_varray_page (vp);
2445 cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[ vp->objects_last_page++ ];
2447 vp->num_allocated++;
2450 /* Did the assembler create this procedure? If so, get the PDR information. */
2451 cur_oproc_ptr = (PDR *) 0;
2452 if (shash_ptr != (shash_t *) 0)
2454 register PDR *old_proc_ptr = shash_ptr->proc_ptr;
2455 register SYMR *sym_ptr = shash_ptr->sym_ptr;
2457 if (old_proc_ptr != (PDR *) 0
2458 && sym_ptr != (SYMR *) 0
2459 && ((st_t)sym_ptr->st == st_Proc || (st_t)sym_ptr->st == st_StaticProc))
2461 cur_oproc_begin = sym_ptr;
2462 cur_oproc_end = shash_ptr->end_ptr;
2463 value = sym_ptr->value;
2465 cur_oproc_ptr = old_proc_ptr;
2466 proc_type = (st_t)sym_ptr->st;
2467 *new_proc_ptr = *old_proc_ptr; /* initialize */
2471 if (cur_oproc_ptr == (PDR *) 0)
2472 error ("Did not find a PDR block for %.*s", func_end_p1 - func_start, func_start);
2474 /* Determine the start of symbols. */
2475 new_proc_ptr->isym = file_ptr->symbols.num_allocated;
2477 /* Push the start of the function. */
2478 (void) add_local_symbol (func_start, func_end_p1,
2485 /* Add a new filename, and set up all of the file relative
2486 virtual arrays (strings, symbols, aux syms, etc.). Record
2487 where the current file structure lives. */
2490 add_file (file_start, file_end_p1)
2491 const char *file_start; /* first byte in string */
2492 const char *file_end_p1; /* first byte after string */
2494 static char zero_bytes[2] = { '\0', '\0' };
2496 register Ptrdiff_t len = file_end_p1 - file_start;
2497 register int first_ch = *file_start;
2498 register efdr_t *file_ptr;
2501 fprintf (stderr, "\tfile\t%.*s\n", (int) len, file_start);
2503 /* See if the file has already been created. */
2504 for (file_ptr = first_file;
2505 file_ptr != (efdr_t *) 0;
2506 file_ptr = file_ptr->next_file)
2508 if (first_ch == file_ptr->name[0]
2509 && file_ptr->name[len] == '\0'
2510 && memcmp ((CPTR_T) file_start, (CPTR_T) file_ptr->name, len) == 0)
2512 cur_file_ptr = file_ptr;
2517 /* If this is a new file, create it. */
2518 if (file_ptr == (efdr_t *) 0)
2520 if (file_desc.objects_last_page == file_desc.objects_per_page)
2521 add_varray_page (&file_desc);
2523 file_ptr = cur_file_ptr
2524 = &file_desc.last->datum->file[ file_desc.objects_last_page++ ];
2525 *file_ptr = init_file;
2527 file_ptr->file_index = file_desc.num_allocated++;
2529 /* Allocate the string hash table. */
2530 file_ptr->shash_head = (shash_t **) allocate_page ();
2532 /* Make sure 0 byte in string table is null */
2533 add_string (&file_ptr->strings,
2534 &file_ptr->shash_head[0],
2539 if (file_end_p1 - file_start > PAGE_USIZE-2)
2540 fatal ("Filename goes over one page boundary.");
2542 /* Push the start of the filename. We assume that the filename
2543 will be stored at string offset 1. */
2544 (void) add_local_symbol (file_start, file_end_p1, st_File, sc_Text,
2545 (symint_t) 0, (symint_t) 0);
2546 file_ptr->fdr.rss = 1;
2547 file_ptr->name = &file_ptr->strings.last->datum->byte[1];
2548 file_ptr->name_len = file_end_p1 - file_start;
2550 /* Update the linked list of file descriptors. */
2551 *last_file_ptr = file_ptr;
2552 last_file_ptr = &file_ptr->next_file;
2554 /* Add void & int types to the file (void should be first to catch
2555 errant 0's within the index fields). */
2556 file_ptr->void_type = add_aux_sym_tir (&void_type_info,
2558 &cur_file_ptr->thash_head[0]);
2560 file_ptr->int_type = add_aux_sym_tir (&int_type_info,
2562 &cur_file_ptr->thash_head[0]);
2567 /* Add a stream of random bytes to a varray. */
2570 add_bytes (vp, input_ptr, nitems)
2571 varray_t *vp; /* virtual array to add too */
2572 char *input_ptr; /* start of the bytes */
2573 Size_t nitems; /* # items to move */
2575 register Size_t move_items;
2576 register Size_t move_bytes;
2581 if (vp->objects_last_page >= vp->objects_per_page)
2582 add_varray_page (vp);
2584 ptr = &vp->last->datum->byte[ vp->objects_last_page * vp->object_size ];
2585 move_items = vp->objects_per_page - vp->objects_last_page;
2586 if (move_items > nitems)
2587 move_items = nitems;
2589 move_bytes = move_items * vp->object_size;
2590 nitems -= move_items;
2592 if (move_bytes >= 32)
2594 (void) memcpy ((PTR_T) ptr, (CPTR_T) input_ptr, move_bytes);
2595 input_ptr += move_bytes;
2599 while (move_bytes-- > 0)
2600 *ptr++ = *input_ptr++;
2606 /* Convert storage class to string. */
2609 sc_to_string(storage_class)
2612 switch(storage_class)
2614 case sc_Nil: return "Nil,";
2615 case sc_Text: return "Text,";
2616 case sc_Data: return "Data,";
2617 case sc_Bss: return "Bss,";
2618 case sc_Register: return "Register,";
2619 case sc_Abs: return "Abs,";
2620 case sc_Undefined: return "Undefined,";
2621 case sc_CdbLocal: return "CdbLocal,";
2622 case sc_Bits: return "Bits,";
2623 case sc_CdbSystem: return "CdbSystem,";
2624 case sc_RegImage: return "RegImage,";
2625 case sc_Info: return "Info,";
2626 case sc_UserStruct: return "UserStruct,";
2627 case sc_SData: return "SData,";
2628 case sc_SBss: return "SBss,";
2629 case sc_RData: return "RData,";
2630 case sc_Var: return "Var,";
2631 case sc_Common: return "Common,";
2632 case sc_SCommon: return "SCommon,";
2633 case sc_VarRegister: return "VarRegister,";
2634 case sc_Variant: return "Variant,";
2635 case sc_SUndefined: return "SUndefined,";
2636 case sc_Init: return "Init,";
2637 case sc_Max: return "Max,";
2644 /* Convert symbol type to string. */
2647 st_to_string(symbol_type)
2652 case st_Nil: return "Nil,";
2653 case st_Global: return "Global,";
2654 case st_Static: return "Static,";
2655 case st_Param: return "Param,";
2656 case st_Local: return "Local,";
2657 case st_Label: return "Label,";
2658 case st_Proc: return "Proc,";
2659 case st_Block: return "Block,";
2660 case st_End: return "End,";
2661 case st_Member: return "Member,";
2662 case st_Typedef: return "Typedef,";
2663 case st_File: return "File,";
2664 case st_RegReloc: return "RegReloc,";
2665 case st_Forward: return "Forward,";
2666 case st_StaticProc: return "StaticProc,";
2667 case st_Constant: return "Constant,";
2668 case st_Str: return "String,";
2669 case st_Number: return "Number,";
2670 case st_Expr: return "Expr,";
2671 case st_Type: return "Type,";
2672 case st_Max: return "Max,";
2679 /* Read a line from standard input, and return the start of the buffer
2680 (which is grows if the line is too big). We split lines at the
2681 semi-colon, and return each logical line independently. */
2684 read_line __proto((void))
2686 static int line_split_p = 0;
2687 register int string_p = 0;
2688 register int comment_p = 0;
2692 if (cur_line_start == (char *) 0)
2693 { /* allocate initial page */
2694 cur_line_start = (char *) allocate_page ();
2695 cur_line_alloc = PAGE_SIZE;
2702 cur_line_nbytes = 0;
2704 for (ptr = cur_line_start; (ch = getchar ()) != EOF; *ptr++ = ch)
2706 if (++cur_line_nbytes >= cur_line_alloc-1)
2708 register int num_pages = cur_line_alloc / PAGE_SIZE;
2709 register char *old_buffer = cur_line_start;
2711 cur_line_alloc += PAGE_SIZE;
2712 cur_line_start = (char *) allocate_multiple_pages (num_pages+1);
2713 memcpy (cur_line_start, old_buffer, num_pages * PAGE_SIZE);
2715 ptr = cur_line_start + cur_line_nbytes - 1;
2722 cur_line_ptr = cur_line_start;
2723 return cur_line_ptr;
2726 else if (ch == '\0')
2727 error ("Null character found in input");
2729 else if (!comment_p)
2732 string_p = !string_p;
2737 else if (ch == ';' && !string_p)
2742 cur_line_ptr = cur_line_start;
2743 return cur_line_ptr;
2749 pfatal_with_name (input_name);
2751 cur_line_ptr = (char *) 0;
2756 /* Parse #.begin directives which have a label as the first argument
2757 which gives the location of the start of the block. */
2761 const char *start; /* start of directive */
2763 const char *end_p1; /* end of label */
2765 shash_t *hash_ptr; /* hash pointer to lookup label */
2767 if (cur_file_ptr == (efdr_t *) 0)
2769 error ("#.begin directive without a preceding .file directive");
2773 if (cur_proc_ptr == (PDR *) 0)
2775 error ("#.begin directive without a preceding .ent directive");
2779 for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++)
2782 hash_ptr = hash_string (start,
2787 if (hash_ptr == (shash_t *) 0)
2789 error ("Label %.*s not found for #.begin", end_p1 - start, start);
2793 if (cur_oproc_begin == (SYMR *) 0)
2795 error ("Procedure table %.*s not found for #.begin", end_p1 - start, start);
2799 (void) add_local_symbol ((const char *) 0, (const char *) 0,
2801 (symint_t) hash_ptr->sym_ptr->value - cur_oproc_begin->value,
2806 /* Parse #.bend directives which have a label as the first argument
2807 which gives the location of the end of the block. */
2811 const char *start; /* start of directive */
2813 const char *end_p1; /* end of label */
2815 shash_t *hash_ptr; /* hash pointer to lookup label */
2817 if (cur_file_ptr == (efdr_t *) 0)
2819 error ("#.begin directive without a preceding .file directive");
2823 if (cur_proc_ptr == (PDR *) 0)
2825 error ("#.bend directive without a preceding .ent directive");
2829 for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++)
2832 hash_ptr = hash_string (start,
2837 if (hash_ptr == (shash_t *) 0)
2839 error ("Label %.*s not found for #.bend", end_p1 - start, start);
2843 if (cur_oproc_begin == (SYMR *) 0)
2845 error ("Procedure table %.*s not found for #.bend", end_p1 - start, start);
2849 (void) add_local_symbol ((const char *) 0, (const char *) 0,
2851 (symint_t)hash_ptr->sym_ptr->value - cur_oproc_begin->value,
2856 /* Parse #.def directives, which are contain standard COFF subdirectives
2857 to describe the debugging format. These subdirectives include:
2859 .scl specify storage class
2860 .val specify a value
2861 .endef specify end of COFF directives
2862 .type specify the type
2863 .size specify the size of an array
2864 .dim specify an array dimension
2865 .tag specify a tag for a struct, union, or enum. */
2868 parse_def (name_start)
2869 const char *name_start; /* start of directive */
2871 const char *dir_start; /* start of current directive*/
2872 const char *dir_end_p1; /* end+1 of current directive*/
2873 const char *arg_start; /* start of current argument */
2874 const char *arg_end_p1; /* end+1 of current argument */
2875 const char *name_end_p1; /* end+1 of label */
2876 const char *tag_start = (const char *) 0; /* start of tag name */
2877 const char *tag_end_p1 = (const char *) 0; /* end+1 of tag name */
2878 sc_t storage_class = sc_Nil;
2879 st_t symbol_type = st_Nil;
2881 EXTR *eptr = (EXTR *) 0; /* ext. sym equivalent to def*/
2882 int is_function = 0; /* != 0 if function */
2884 symint_t indx = cur_file_ptr->void_type;
2886 symint_t arg_number;
2887 symint_t temp_array[ N_TQ ];
2892 static int inside_enumeration = 0; /* is this an enumeration? */
2895 /* Initialize the type information. */
2899 /* Search for the end of the name being defined. */
2900 /* Allow spaces and such in names for G++ templates, which produce stabs
2903 #.def SMANIP<long unsigned int>; .scl 10; .type 0x8; .size 8; .endef */
2905 for (name_end_p1 = name_start; (ch = *name_end_p1) != ';' && ch != '\0'; name_end_p1++)
2910 error_line = __LINE__;
2915 /* Parse the remaining subdirectives now. */
2916 dir_start = name_end_p1+1;
2919 while ((ch = *dir_start) == ' ' || ch == '\t')
2924 error_line = __LINE__;
2930 if (dir_start[1] == 'e'
2931 && memcmp (dir_start, ".endef", sizeof (".endef")-1) == 0)
2934 /* Pick up the subdirective now */
2935 for (dir_end_p1 = dir_start+1;
2936 (ch = *dir_end_p1) != ' ' && ch != '\t';
2939 if (ch == '\0' || ISSPACE (ch))
2941 error_line = __LINE__;
2947 /* Pick up the subdirective argument now. */
2948 arg_was_number = arg_number = 0;
2949 arg_end_p1 = (const char *) 0;
2950 arg_start = dir_end_p1+1;
2952 while (ch == ' ' || ch == '\t')
2955 if (ISDIGIT (ch) || ch == '-' || ch == '+')
2958 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
2959 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
2963 else if (ch == '\0' || ISSPACE (ch))
2965 error_line = __LINE__;
2970 if (!arg_was_number)
2972 /* Allow spaces and such in names for G++ templates. */
2973 for (arg_end_p1 = arg_start+1;
2974 (ch = *arg_end_p1) != ';' && ch != '\0';
2980 error_line = __LINE__;
2986 /* Classify the directives now. */
2987 len = dir_end_p1 - dir_start;
2988 switch (dir_start[1])
2991 error_line = __LINE__;
2996 if (len == sizeof (".dim")-1
2997 && memcmp (dir_start, ".dim", sizeof (".dim")-1) == 0
3000 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
3002 *t_ptr = arg_number;
3003 while (*arg_end_p1 == ',' && arg_was_number)
3005 arg_start = arg_end_p1+1;
3007 while (ch == ' ' || ch == '\t')
3011 if (ISDIGIT (ch) || ch == '-' || ch == '+')
3014 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
3015 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
3018 if (t_ptr == &temp_array[0])
3020 error_line = __LINE__;
3025 *--t_ptr = arg_number;
3029 /* Reverse order of dimensions. */
3030 while (t_ptr <= &temp_array[ N_TQ-1 ])
3032 if (t.num_dims >= N_TQ-1)
3034 error_line = __LINE__;
3039 t.dimensions[ t.num_dims++ ] = *t_ptr++;
3045 error_line = __LINE__;
3052 if (len == sizeof (".scl")-1
3053 && memcmp (dir_start, ".scl", sizeof (".scl")-1) == 0
3055 && arg_number < ((symint_t) C_MAX))
3057 /* If the symbol is a static or external, we have
3058 already gotten the appropriate type and class, so
3059 make sure we don't override those values. This is
3060 needed because there are some type and classes that
3061 are not in COFF, such as short data, etc. */
3062 if (symbol_type == st_Nil)
3064 symbol_type = map_coff_sym_type[arg_number];
3065 storage_class = map_coff_storage [arg_number];
3070 else if (len == sizeof (".size")-1
3071 && memcmp (dir_start, ".size", sizeof (".size")-1) == 0
3074 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
3076 *t_ptr = arg_number;
3077 while (*arg_end_p1 == ',' && arg_was_number)
3079 arg_start = arg_end_p1+1;
3081 while (ch == ' ' || ch == '\t')
3085 if (ISDIGIT (ch) || ch == '-' || ch == '+')
3088 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
3089 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
3092 if (t_ptr == &temp_array[0])
3094 error_line = __LINE__;
3099 *--t_ptr = arg_number;
3103 /* Reverse order of sizes. */
3104 while (t_ptr <= &temp_array[ N_TQ-1 ])
3106 if (t.num_sizes >= N_TQ-1)
3108 error_line = __LINE__;
3113 t.sizes[ t.num_sizes++ ] = *t_ptr++;
3120 error_line = __LINE__;
3127 if (len == sizeof (".type")-1
3128 && memcmp (dir_start, ".type", sizeof (".type")-1) == 0
3131 tq_t *tq_ptr = &t.type_qualifiers[0];
3133 t.orig_type = (coff_type_t) (arg_number & N_BTMASK);
3134 t.basic_type = map_coff_types [(int)t.orig_type];
3135 for (i = N_TQ-1; i >= 0; i--)
3137 int dt = (arg_number >> ((i * N_TQ_SHIFT) + N_BT_SHIFT)
3140 if (dt != (int)DT_NON)
3141 *tq_ptr++ = map_coff_derived_type [dt];
3144 /* If this is a function, ignore it, so that we don't get
3145 two entries (one from the .ent, and one for the .def
3146 that precedes it). Save the type information so that
3147 the end block can properly add it after the begin block
3148 index. For MIPS knows what reason, we must strip off
3149 the function type at this point. */
3150 if (tq_ptr != &t.type_qualifiers[0] && tq_ptr[-1] == tq_Proc)
3153 tq_ptr[-1] = tq_Nil;
3159 else if (len == sizeof (".tag")-1
3160 && memcmp (dir_start, ".tag", sizeof (".tag")-1) == 0)
3162 tag_start = arg_start;
3163 tag_end_p1 = arg_end_p1;
3169 error_line = __LINE__;
3176 if (len == sizeof (".val")-1
3177 && memcmp (dir_start, ".val", sizeof (".val")-1) == 0)
3182 /* If the value is not an integer value, it must be the
3183 name of a static or global item. Look up the name in
3184 the original symbol table to pick up the storage
3185 class, symbol type, etc. */
3188 shash_t *orig_hash_ptr; /* hash within orig sym table*/
3189 shash_t *ext_hash_ptr; /* hash within ext. sym table*/
3191 ext_hash_ptr = hash_string (arg_start,
3192 arg_end_p1 - arg_start,
3196 if (ext_hash_ptr != (shash_t *) 0
3197 && ext_hash_ptr->esym_ptr != (EXTR *) 0)
3198 eptr = ext_hash_ptr->esym_ptr;
3200 orig_hash_ptr = hash_string (arg_start,
3201 arg_end_p1 - arg_start,
3205 if ((orig_hash_ptr == (shash_t *) 0
3206 || orig_hash_ptr->sym_ptr == (SYMR *) 0)
3207 && eptr == (EXTR *) 0)
3209 fprintf (stderr, "warning, %.*s not found in original or external symbol tables, value defaults to 0\n",
3210 (int) (arg_end_p1 - arg_start),
3216 SYMR *ptr = (orig_hash_ptr != (shash_t *) 0
3217 && orig_hash_ptr->sym_ptr != (SYMR *) 0)
3218 ? orig_hash_ptr->sym_ptr
3221 symbol_type = (st_t) ptr->st;
3222 storage_class = (sc_t) ptr->sc;
3230 error_line = __LINE__;
3236 /* Set up to find next directive. */
3237 dir_start = arg_end_p1 + 1;
3241 if (storage_class == sc_Bits)
3251 int num_real_sizes = t.num_sizes - t.extra_sizes;
3252 int diff = t.num_dims - num_real_sizes;
3253 int i = t.num_dims - 1;
3256 if (num_real_sizes != 1 || diff < 0)
3258 error_line = __LINE__;
3263 /* If this is an array, make sure the same number of dimensions
3264 and sizes were passed, creating extra sizes for multiply
3265 dimensioned arrays if not passed. */
3269 for (j = (sizeof (t.sizes) / sizeof (t.sizes[0])) - 1; j >= 0; j--)
3270 t.sizes[ j ] = ((j-diff) >= 0) ? t.sizes[ j-diff ] : 0;
3272 t.num_sizes = i + 1;
3273 for ( i--; i >= 0; i-- )
3275 if (t.dimensions[ i+1 ])
3276 t.sizes[ i ] = t.sizes[ i+1 ] / t.dimensions[ i+1 ];
3278 t.sizes[ i ] = t.sizes[ i+1 ];
3283 /* Except for enumeration members & begin/ending of scopes, put the
3284 type word in the aux. symbol table. */
3286 if (symbol_type == st_Block || symbol_type == st_End)
3289 else if (inside_enumeration)
3290 indx = cur_file_ptr->void_type;
3294 if (t.basic_type == bt_Struct
3295 || t.basic_type == bt_Union
3296 || t.basic_type == bt_Enum)
3298 if (tag_start == (char *) 0)
3300 error ("No tag specified for %.*s",
3301 name_end_p1 - name_start,
3306 t.tag_ptr = get_tag (tag_start, tag_end_p1, (symint_t)indexNil,
3312 last_func_type_info = t;
3313 last_func_eptr = eptr;
3317 indx = add_aux_sym_tir (&t,
3319 &cur_file_ptr->thash_head[0]);
3323 /* If this is an external or static symbol, update the appropriate
3326 if (eptr != (EXTR *) 0
3327 && (eptr->asym.index == indexNil || cur_proc_ptr == (PDR *) 0))
3329 eptr->ifd = cur_file_ptr->file_index;
3330 eptr->asym.index = indx;
3334 /* Do any last minute adjustments that are necessary. */
3335 switch (symbol_type)
3341 /* For the beginning of structs, unions, and enumerations, the
3342 size info needs to be passed in the value field. */
3345 if (t.num_sizes - t.num_dims - t.extra_sizes != 1)
3347 error_line = __LINE__;
3355 inside_enumeration = (t.orig_type == T_ENUM);
3359 /* For the end of structs, unions, and enumerations, omit the
3360 name which is always ".eos". This needs to be done last, so
3361 that any error reporting above gives the correct name. */
3364 name_start = name_end_p1 = (const char *) 0;
3365 value = inside_enumeration = 0;
3369 /* Members of structures and unions that aren't bitfields, need
3370 to adjust the value from a byte offset to a bit offset.
3371 Members of enumerations do not have the value adjusted, and
3372 can be distinguished by indx == indexNil. For enumerations,
3373 update the maximum enumeration value. */
3376 if (!t.bitfield && !inside_enumeration)
3383 /* Add the symbol, except for global symbols outside of functions,
3384 for which the external symbol table is fine enough. */
3386 if (eptr == (EXTR *) 0
3387 || eptr->asym.st == (int)st_Nil
3388 || cur_proc_ptr != (PDR *) 0)
3390 symint_t isym = add_local_symbol (name_start, name_end_p1,
3391 symbol_type, storage_class,
3395 /* deal with struct, union, and enum tags. */
3396 if (symbol_type == st_Block)
3398 /* Create or update the tag information. */
3399 tag_t *tag_ptr = get_tag (name_start,
3404 /* If there are any forward references, fill in the appropriate
3405 file and symbol indexes. */
3407 symint_t file_index = cur_file_ptr->file_index;
3408 forward_t *f_next = tag_ptr->forward_ref;
3411 while (f_next != (forward_t *) 0)
3414 f_next = f_next->next;
3416 f_cur->ifd_ptr->isym = file_index;
3417 f_cur->index_ptr->rndx.index = isym;
3419 free_forward (f_cur);
3422 tag_ptr->forward_ref = (forward_t *) 0;
3429 /* Error return, issue message. */
3432 error ("compiler error, badly formed #.def (internal line # = %d)", error_line);
3434 error ("compiler error, badly formed #.def");
3440 /* Parse .end directives. */
3444 const char *start; /* start of directive */
3446 register const char *start_func, *end_func_p1;
3448 register symint_t value;
3449 register FDR *orig_fdr;
3451 if (cur_file_ptr == (efdr_t *) 0)
3453 error (".end directive without a preceding .file directive");
3457 if (cur_proc_ptr == (PDR *) 0)
3459 error (".end directive without a preceding .ent directive");
3463 /* Get the function name, skipping whitespace. */
3464 for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++)
3468 if (!IS_ASM_IDENT (ch))
3470 error (".end directive has no name");
3474 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
3478 /* Get the value field for creating the end from the original object
3479 file (which we find by locating the procedure start, and using the
3480 pointer to the end+1 block and backing up. The index points to a
3481 two word aux. symbol, whose first word is the index of the end
3482 symbol, and the second word is the type of the function return
3485 orig_fdr = cur_file_ptr->orig_fdr;
3487 if (orig_fdr != (FDR *)0 && cur_oproc_end != (SYMR *) 0)
3488 value = cur_oproc_end->value;
3491 error ("Cannot find .end block for %.*s", end_func_p1 - start_func, start_func);
3493 (void) add_local_symbol (start_func, end_func_p1,
3498 cur_proc_ptr = cur_oproc_ptr = (PDR *) 0;
3502 /* Parse .ent directives. */
3506 const char *start; /* start of directive */
3508 register const char *start_func, *end_func_p1;
3511 if (cur_file_ptr == (efdr_t *) 0)
3513 error (".ent directive without a preceding .file directive");
3517 if (cur_proc_ptr != (PDR *) 0)
3519 error ("second .ent directive found before .end directive");
3523 for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++)
3527 if (!IS_ASM_IDENT (ch))
3529 error (".ent directive has no name");
3533 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
3536 (void) add_procedure (start_func, end_func_p1);
3540 /* Parse .file directives. */
3544 const char *start; /* start of directive */
3547 register char *start_name, *end_name_p1;
3549 (void) strtol (start, &p, 0);
3551 || (start_name = local_index (p, '"')) == (char *) 0
3552 || (end_name_p1 = local_rindex (++start_name, '"')) == (char *) 0)
3554 error ("Invalid .file directive");
3558 if (cur_proc_ptr != (PDR *) 0)
3560 error ("No way to handle .file within .ent/.end section");
3564 add_file (start_name, end_name_p1);
3568 /* Make sure the @stabs symbol is emitted. */
3572 const char *start; /* Start of directive (ignored) */
3576 /* Add a dummy @stabs symbol. */
3578 (void) add_local_symbol (stabs_symbol,
3579 stabs_symbol + sizeof (stabs_symbol),
3580 stNil, scInfo, -1, MIPS_MARK_STAB(0));
3586 /* Parse .stabs directives.
3588 .stabs directives have five fields:
3589 "string" a string, encoding the type information.
3590 code a numeric code, defined in <stab.h>
3592 0 a zero or line number
3593 value a numeric value or an address.
3595 If the value is relocatable, we transform this into:
3596 iss points as an index into string space
3597 value value from lookup of the name
3598 st st from lookup of the name
3599 sc sc from lookup of the name
3600 index code|CODE_MASK
3602 If the value is not relocatable, we transform this into:
3603 iss points as an index into string space
3607 index code|CODE_MASK
3609 .stabn directives have four fields (string is null):
3610 code a numeric code, defined in <stab.h>
3612 0 a zero or a line number
3613 value a numeric value or an address. */
3616 parse_stabs_common (string_start, string_end, rest)
3617 const char *string_start; /* start of string or NULL */
3618 const char *string_end; /* end+1 of string or NULL */
3619 const char *rest; /* rest of the directive. */
3621 efdr_t *save_file_ptr = cur_file_ptr;
3629 if (stabs_seen == 0)
3632 /* Read code from stabs. */
3633 if (!ISDIGIT (*rest))
3635 error ("Invalid .stabs/.stabn directive, code is non-numeric");
3639 code = strtol (rest, &p, 0);
3641 /* Line number stabs are handled differently, since they have two values,
3642 the line number and the address of the label. We use the index field
3643 (aka code) to hold the line number, and the value field to hold the
3644 address. The symbol type is st_Label, which should be different from
3645 the other stabs, so that gdb can recognize it. */
3647 if (code == (int)N_SLINE)
3649 SYMR *sym_ptr, dummy_symr;
3653 if (p[0] != ',' || p[1] != '0' || p[2] != ',' || !ISDIGIT (p[3]))
3655 error ("Invalid line number .stabs/.stabn directive");
3659 code = strtol (p+3, &p, 0);
3661 if (p[-1] != ',' || ISDIGIT (ch) || !IS_ASM_IDENT (ch))
3663 error ("Invalid line number .stabs/.stabn directive");
3667 dummy_symr.index = code;
3668 if (dummy_symr.index != code)
3670 error ("Line number (%d) for .stabs/.stabn directive cannot fit in index field (20 bits)",
3676 shash_ptr = hash_string (p,
3681 if (shash_ptr == (shash_t *) 0
3682 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0)
3684 error ("Invalid .stabs/.stabn directive, value not found");
3688 if ((st_t) sym_ptr->st != st_Label)
3690 error ("Invalid line number .stabs/.stabn directive");
3695 sc = (sc_t) sym_ptr->sc;
3696 value = sym_ptr->value;
3700 /* Skip ,<num>,<num>, */
3703 for (; ISDIGIT (*p); p++)
3707 for (; ISDIGIT (*p); p++)
3712 if (!IS_ASM_IDENT (ch) && ch != '-')
3715 error ("Invalid .stabs/.stabn directive, bad character");
3719 if (ISDIGIT (ch) || ch == '-')
3723 value = strtol (p, &p, 0);
3726 error ("Invalid .stabs/.stabn directive, stuff after numeric value");
3730 else if (!IS_ASM_IDENT (ch))
3732 error ("Invalid .stabs/.stabn directive, bad character");
3739 const char *start, *end_p1;
3742 if ((end_p1 = strchr (start, '+')) == (char *) 0)
3744 if ((end_p1 = strchr (start, '-')) == (char *) 0)
3745 end_p1 = start + strlen(start) - 1;
3748 shash_ptr = hash_string (start,
3753 if (shash_ptr == (shash_t *) 0
3754 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0)
3756 shash_ptr = hash_string (start,
3761 if (shash_ptr == (shash_t *) 0
3762 || shash_ptr->esym_ptr == (EXTR *) 0)
3764 error ("Invalid .stabs/.stabn directive, value not found");
3768 sym_ptr = &(shash_ptr->esym_ptr->asym);
3771 /* Traditionally, N_LBRAC and N_RBRAC are *not* relocated. */
3772 if (code == (int) N_LBRAC || code == (int) N_RBRAC)
3779 sc = (sc_t) sym_ptr->sc;
3780 st = (st_t) sym_ptr->st;
3782 value = sym_ptr->value;
3787 if (((!ISDIGIT (*end_p1)) && (*end_p1 != '-'))
3788 || ((ch != '+') && (ch != '-')))
3790 error ("Invalid .stabs/.stabn directive, badly formed value");
3794 value += strtol (end_p1, &p, 0);
3796 value -= strtol (end_p1, &p, 0);
3800 error ("Invalid .stabs/.stabn directive, stuff after numeric value");
3805 code = MIPS_MARK_STAB(code);
3808 (void) add_local_symbol (string_start, string_end, st, sc, value, code);
3809 /* Restore normal file type. */
3810 cur_file_ptr = save_file_ptr;
3816 const char *start; /* start of directive */
3818 const char *end = local_index (start+1, '"');
3820 if (*start != '"' || end == (const char *) 0 || end[1] != ',')
3822 error ("Invalid .stabs directive, no string");
3826 parse_stabs_common (start+1, end, end+2);
3832 const char *start; /* start of directive */
3834 parse_stabs_common ((const char *) 0, (const char *) 0, start);
3838 /* Parse the input file, and write the lines to the output file
3842 parse_input __proto((void))
3846 register thead_t *ptag_head;
3847 register tag_t *ptag;
3848 register tag_t *ptag_next;
3851 fprintf (stderr, "\tinput\n");
3853 /* Add a dummy scope block around the entire compilation unit for
3854 structures defined outside of blocks. */
3855 ptag_head = allocate_thead ();
3856 ptag_head->first_tag = 0;
3857 ptag_head->prev = cur_tag_head;
3858 cur_tag_head = ptag_head;
3860 while ((p = read_line ()) != (char *) 0)
3862 /* Skip leading blanks */
3863 while (ISSPACE ((unsigned char)*p))
3866 /* See if it's a directive we handle. If so, dispatch handler. */
3867 for (i = 0; i < sizeof (pseudo_ops) / sizeof (pseudo_ops[0]); i++)
3868 if (memcmp (p, pseudo_ops[i].name, pseudo_ops[i].len) == 0
3869 && ISSPACE ((unsigned char)(p[pseudo_ops[i].len])))
3871 p += pseudo_ops[i].len; /* skip to first argument */
3872 while (ISSPACE ((unsigned char)*p))
3875 (*pseudo_ops[i].func)( p );
3880 /* Process any tags at global level. */
3881 ptag_head = cur_tag_head;
3882 cur_tag_head = ptag_head->prev;
3884 for (ptag = ptag_head->first_tag;
3885 ptag != (tag_t *) 0;
3888 if (ptag->forward_ref != (forward_t *) 0)
3889 add_unknown_tag (ptag);
3891 ptag_next = ptag->same_block;
3892 ptag->hash_ptr->tag_ptr = ptag->same_name;
3896 free_thead (ptag_head);
3901 /* Update the global headers with the final offsets in preparation
3902 to write out the .T file. */
3905 update_headers __proto((void))
3907 register symint_t i;
3908 register efdr_t *file_ptr;
3910 /* Set up the symbolic header. */
3911 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
3912 symbolic_header.magic = orig_sym_hdr.magic;
3913 symbolic_header.vstamp = orig_sym_hdr.vstamp;
3915 /* Set up global counts. */
3916 symbolic_header.issExtMax = ext_strings.num_allocated;
3917 symbolic_header.idnMax = dense_num.num_allocated;
3918 symbolic_header.ifdMax = file_desc.num_allocated;
3919 symbolic_header.iextMax = ext_symbols.num_allocated;
3920 symbolic_header.ilineMax = orig_sym_hdr.ilineMax;
3921 symbolic_header.ioptMax = orig_sym_hdr.ioptMax;
3922 symbolic_header.cbLine = orig_sym_hdr.cbLine;
3923 symbolic_header.crfd = orig_sym_hdr.crfd;
3926 /* Loop through each file, figuring out how many local syms,
3927 line numbers, etc. there are. Also, put out end symbol
3928 for the filename. */
3930 for (file_ptr = first_file;
3931 file_ptr != (efdr_t *) 0;
3932 file_ptr = file_ptr->next_file)
3934 register SYMR *sym_start;
3936 register SYMR *sym_end_p1;
3937 register FDR *fd_ptr = file_ptr->orig_fdr;
3939 cur_file_ptr = file_ptr;
3941 /* Copy st_Static symbols from the original local symbol table if
3942 they did not get added to the new local symbol table.
3943 This happens with stabs-in-ecoff or if the source file is
3944 compiled without debugging. */
3945 sym_start = ORIG_LSYMS (fd_ptr->isymBase);
3946 sym_end_p1 = sym_start + fd_ptr->csym;
3947 for (sym = sym_start; sym < sym_end_p1; sym++)
3949 if ((st_t)sym->st == st_Static)
3951 register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
3952 register Size_t len = strlen (str);
3953 register shash_t *hash_ptr;
3955 /* Ignore internal labels. */
3956 if (str[0] == '$' && str[1] == 'L')
3958 hash_ptr = hash_string (str,
3960 &file_ptr->shash_head[0],
3962 if (hash_ptr == (shash_t *) 0)
3964 (void) add_local_symbol (str, str + len,
3965 (st_t)sym->st, (sc_t)sym->sc,
3966 (symint_t)sym->value,
3967 (symint_t)indexNil);
3971 (void) add_local_symbol ((const char *) 0, (const char *) 0,
3976 file_ptr->fdr.cpd = file_ptr->procs.num_allocated;
3977 file_ptr->fdr.ipdFirst = symbolic_header.ipdMax;
3978 symbolic_header.ipdMax += file_ptr->fdr.cpd;
3980 file_ptr->fdr.csym = file_ptr->symbols.num_allocated;
3981 file_ptr->fdr.isymBase = symbolic_header.isymMax;
3982 symbolic_header.isymMax += file_ptr->fdr.csym;
3984 file_ptr->fdr.caux = file_ptr->aux_syms.num_allocated;
3985 file_ptr->fdr.iauxBase = symbolic_header.iauxMax;
3986 symbolic_header.iauxMax += file_ptr->fdr.caux;
3988 file_ptr->fdr.cbSs = file_ptr->strings.num_allocated;
3989 file_ptr->fdr.issBase = symbolic_header.issMax;
3990 symbolic_header.issMax += file_ptr->fdr.cbSs;
3993 #ifndef ALIGN_SYMTABLE_OFFSET
3994 #define ALIGN_SYMTABLE_OFFSET(OFFSET) (OFFSET)
3997 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
3998 i = WORD_ALIGN (symbolic_header.cbLine); /* line numbers */
4001 symbolic_header.cbLineOffset = file_offset;
4003 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4006 i = symbolic_header.ioptMax; /* optimization symbols */
4009 symbolic_header.cbOptOffset = file_offset;
4010 file_offset += i * sizeof (OPTR);
4011 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4014 i = symbolic_header.idnMax; /* dense numbers */
4017 symbolic_header.cbDnOffset = file_offset;
4018 file_offset += i * sizeof (DNR);
4019 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4022 i = symbolic_header.ipdMax; /* procedure tables */
4025 symbolic_header.cbPdOffset = file_offset;
4026 file_offset += i * sizeof (PDR);
4027 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4030 i = symbolic_header.isymMax; /* local symbols */
4033 symbolic_header.cbSymOffset = file_offset;
4034 file_offset += i * sizeof (SYMR);
4035 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4038 i = symbolic_header.iauxMax; /* aux syms. */
4041 symbolic_header.cbAuxOffset = file_offset;
4042 file_offset += i * sizeof (TIR);
4043 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4046 i = WORD_ALIGN (symbolic_header.issMax); /* local strings */
4049 symbolic_header.cbSsOffset = file_offset;
4051 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4054 i = WORD_ALIGN (symbolic_header.issExtMax); /* external strings */
4057 symbolic_header.cbSsExtOffset = file_offset;
4059 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4062 i = symbolic_header.ifdMax; /* file tables */
4065 symbolic_header.cbFdOffset = file_offset;
4066 file_offset += i * sizeof (FDR);
4067 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4070 i = symbolic_header.crfd; /* relative file descriptors */
4073 symbolic_header.cbRfdOffset = file_offset;
4074 file_offset += i * sizeof (symint_t);
4075 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4078 i = symbolic_header.iextMax; /* external symbols */
4081 symbolic_header.cbExtOffset = file_offset;
4082 file_offset += i * sizeof (EXTR);
4083 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
4088 /* Write out a varray at a given location. */
4091 write_varray (vp, offset, str)
4092 varray_t *vp; /* virtual array */
4093 off_t offset; /* offset to write varray to */
4094 const char *str; /* string to print out when tracing */
4096 int num_write, sys_write;
4099 if (vp->num_allocated == 0)
4104 fputs ("\twarray\tvp = ", stderr);
4105 fprintf (stderr, HOST_PTR_PRINTF, vp);
4106 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4107 (unsigned long) offset, vp->num_allocated * vp->object_size, str);
4110 if (file_offset != offset
4111 && fseek (object_stream, (long)offset, SEEK_SET) < 0)
4112 pfatal_with_name (object_name);
4114 for (ptr = vp->first; ptr != (vlinks_t *) 0; ptr = ptr->next)
4116 num_write = (ptr->next == (vlinks_t *) 0)
4117 ? vp->objects_last_page * vp->object_size
4118 : vp->objects_per_page * vp->object_size;
4120 sys_write = fwrite ((PTR_T) ptr->datum, 1, num_write, object_stream);
4122 pfatal_with_name (object_name);
4124 else if (sys_write != num_write)
4125 fatal ("Wrote %d bytes to %s, system returned %d",
4130 file_offset += num_write;
4135 /* Write out the symbol table in the object file. */
4138 write_object __proto((void))
4146 fputs ("\n\twrite\tvp = ", stderr);
4147 fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &symbolic_header);
4148 fprintf (stderr, ", offset = %7u, size = %7lu, %s\n",
4149 0, (unsigned long) sizeof (symbolic_header), "symbolic header");
4152 sys_write = fwrite ((PTR_T) &symbolic_header,
4154 sizeof (symbolic_header),
4158 pfatal_with_name (object_name);
4160 else if (sys_write != sizeof (symbolic_header))
4161 fatal ("Wrote %d bytes to %s, system returned %d",
4162 sizeof (symbolic_header),
4167 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
4169 if (symbolic_header.cbLine > 0) /* line numbers */
4173 if (file_offset != symbolic_header.cbLineOffset
4174 && fseek (object_stream, symbolic_header.cbLineOffset, SEEK_SET) != 0)
4175 pfatal_with_name (object_name);
4179 fputs ("\twrite\tvp = ", stderr);
4180 fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &orig_linenum);
4181 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4182 (long) symbolic_header.cbLineOffset,
4183 (long) symbolic_header.cbLine, "Line numbers");
4186 sys_write = fwrite ((PTR_T) orig_linenum,
4188 symbolic_header.cbLine,
4192 pfatal_with_name (object_name);
4194 else if (sys_write != symbolic_header.cbLine)
4195 fatal ("Wrote %d bytes to %s, system returned %d",
4196 symbolic_header.cbLine,
4200 file_offset = symbolic_header.cbLineOffset + symbolic_header.cbLine;
4203 if (symbolic_header.ioptMax > 0) /* optimization symbols */
4206 long num_write = symbolic_header.ioptMax * sizeof (OPTR);
4208 if (file_offset != symbolic_header.cbOptOffset
4209 && fseek (object_stream, symbolic_header.cbOptOffset, SEEK_SET) != 0)
4210 pfatal_with_name (object_name);
4214 fputs ("\twrite\tvp = ", stderr);
4215 fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &orig_opt_syms);
4216 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4217 (long) symbolic_header.cbOptOffset,
4218 num_write, "Optimizer symbols");
4221 sys_write = fwrite ((PTR_T) orig_opt_syms,
4227 pfatal_with_name (object_name);
4229 else if (sys_write != num_write)
4230 fatal ("Wrote %d bytes to %s, system returned %d",
4235 file_offset = symbolic_header.cbOptOffset + num_write;
4238 if (symbolic_header.idnMax > 0) /* dense numbers */
4239 write_varray (&dense_num, (off_t)symbolic_header.cbDnOffset, "Dense numbers");
4241 if (symbolic_header.ipdMax > 0) /* procedure tables */
4243 offset = symbolic_header.cbPdOffset;
4244 for (file_ptr = first_file;
4245 file_ptr != (efdr_t *) 0;
4246 file_ptr = file_ptr->next_file)
4248 write_varray (&file_ptr->procs, offset, "Procedure tables");
4249 offset = file_offset;
4253 if (symbolic_header.isymMax > 0) /* local symbols */
4255 offset = symbolic_header.cbSymOffset;
4256 for (file_ptr = first_file;
4257 file_ptr != (efdr_t *) 0;
4258 file_ptr = file_ptr->next_file)
4260 write_varray (&file_ptr->symbols, offset, "Local symbols");
4261 offset = file_offset;
4265 if (symbolic_header.iauxMax > 0) /* aux symbols */
4267 offset = symbolic_header.cbAuxOffset;
4268 for (file_ptr = first_file;
4269 file_ptr != (efdr_t *) 0;
4270 file_ptr = file_ptr->next_file)
4272 write_varray (&file_ptr->aux_syms, offset, "Aux. symbols");
4273 offset = file_offset;
4277 if (symbolic_header.issMax > 0) /* local strings */
4279 offset = symbolic_header.cbSsOffset;
4280 for (file_ptr = first_file;
4281 file_ptr != (efdr_t *) 0;
4282 file_ptr = file_ptr->next_file)
4284 write_varray (&file_ptr->strings, offset, "Local strings");
4285 offset = file_offset;
4289 if (symbolic_header.issExtMax > 0) /* external strings */
4290 write_varray (&ext_strings, symbolic_header.cbSsExtOffset, "External strings");
4292 if (symbolic_header.ifdMax > 0) /* file tables */
4294 offset = symbolic_header.cbFdOffset;
4295 if (file_offset != offset
4296 && fseek (object_stream, (long)offset, SEEK_SET) < 0)
4297 pfatal_with_name (object_name);
4299 file_offset = offset;
4300 for (file_ptr = first_file;
4301 file_ptr != (efdr_t *) 0;
4302 file_ptr = file_ptr->next_file)
4306 fputs ("\twrite\tvp = ", stderr);
4307 fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &file_ptr->fdr);
4308 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4309 file_offset, (unsigned long) sizeof (FDR),
4313 sys_write = fwrite (&file_ptr->fdr,
4319 pfatal_with_name (object_name);
4321 else if (sys_write != sizeof (FDR))
4322 fatal ("Wrote %d bytes to %s, system returned %d",
4327 file_offset = offset += sizeof (FDR);
4331 if (symbolic_header.crfd > 0) /* relative file descriptors */
4334 symint_t num_write = symbolic_header.crfd * sizeof (symint_t);
4336 if (file_offset != symbolic_header.cbRfdOffset
4337 && fseek (object_stream, symbolic_header.cbRfdOffset, SEEK_SET) != 0)
4338 pfatal_with_name (object_name);
4342 fputs ("\twrite\tvp = ", stderr);
4343 fprintf (stderr, HOST_PTR_PRINTF, (PTR_T *) &orig_rfds);
4344 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
4345 (long) symbolic_header.cbRfdOffset,
4346 num_write, "Relative file descriptors");
4349 sys_write = fwrite (orig_rfds,
4355 pfatal_with_name (object_name);
4357 else if (sys_write != num_write)
4358 fatal ("Wrote %d bytes to %s, system returned %d",
4363 file_offset = symbolic_header.cbRfdOffset + num_write;
4366 if (symbolic_header.issExtMax > 0) /* external symbols */
4367 write_varray (&ext_symbols, (off_t)symbolic_header.cbExtOffset, "External symbols");
4369 if (fclose (object_stream) != 0)
4370 pfatal_with_name (object_name);
4374 /* Read some bytes at a specified location, and return a pointer. */
4377 read_seek (size, offset, str)
4378 Size_t size; /* # bytes to read */
4379 off_t offset; /* offset to read at */
4380 const char *str; /* name for tracing */
4385 if (size == 0) /* nothing to read */
4386 return (page_t *) 0;
4390 "\trseek\tsize = %7lu, offset = %7lu, currently at %7lu, %s\n",
4391 (unsigned long) size, (unsigned long) offset, file_offset, str);
4393 #ifndef MALLOC_CHECK
4394 ptr = allocate_multiple_pages ((size + PAGE_USIZE - 1) / PAGE_USIZE);
4396 ptr = (page_t *) xcalloc (1, size);
4399 /* If we need to seek, and the distance is nearby, just do some reads,
4400 to speed things up. */
4401 if (file_offset != offset)
4403 symint_t difference = offset - file_offset;
4407 char small_buffer[8];
4409 sys_read = fread (small_buffer, 1, difference, obj_in_stream);
4411 pfatal_with_name (obj_in_name);
4413 if (sys_read != difference)
4414 fatal ("Wanted to read %d bytes from %s, system returned %d",
4419 else if (fseek (obj_in_stream, offset, SEEK_SET) < 0)
4420 pfatal_with_name (obj_in_name);
4423 sys_read = fread ((PTR_T)ptr, 1, size, obj_in_stream);
4425 pfatal_with_name (obj_in_name);
4427 if (sys_read != size)
4428 fatal ("Wanted to read %d bytes from %s, system returned %d",
4433 file_offset = offset + size;
4435 if (file_offset > max_file_offset)
4436 max_file_offset = file_offset;
4442 /* Read the existing object file (and copy to the output object file
4443 if it is different from the input object file), and remove the old
4447 copy_object __proto((void))
4449 char buffer[ PAGE_SIZE ];
4450 register int sys_read;
4451 register int remaining;
4452 register int num_write;
4453 register int sys_write;
4454 register int fd, es;
4455 register int delete_ifd = 0;
4456 register int *remap_file_number;
4457 struct stat stat_buf;
4460 fprintf (stderr, "\tcopy\n");
4462 if (fstat (fileno (obj_in_stream), &stat_buf) != 0
4463 || fseek (obj_in_stream, 0L, SEEK_SET) != 0)
4464 pfatal_with_name (obj_in_name);
4466 sys_read = fread ((PTR_T) &orig_file_header,
4468 sizeof (struct filehdr),
4472 pfatal_with_name (obj_in_name);
4474 else if (sys_read == 0 && feof (obj_in_stream))
4475 return; /* create a .T file sans file header */
4477 else if (sys_read < sizeof (struct filehdr))
4478 fatal ("Wanted to read %d bytes from %s, system returned %d",
4479 sizeof (struct filehdr),
4484 if (orig_file_header.f_nsyms != sizeof (HDRR))
4485 fatal ("%s symbolic header wrong size (%d bytes, should be %d)",
4486 input_name, orig_file_header.f_nsyms, sizeof (HDRR));
4489 /* Read in the current symbolic header. */
4490 if (fseek (obj_in_stream, (long) orig_file_header.f_symptr, SEEK_SET) != 0)
4491 pfatal_with_name (input_name);
4493 sys_read = fread ((PTR_T) &orig_sym_hdr,
4495 sizeof (orig_sym_hdr),
4499 pfatal_with_name (object_name);
4501 else if (sys_read < sizeof (struct filehdr))
4502 fatal ("Wanted to read %d bytes from %s, system returned %d",
4503 sizeof (struct filehdr),
4508 /* Read in each of the sections if they exist in the object file.
4509 We read things in in the order the mips assembler creates the
4510 sections, so in theory no extra seeks are done.
4512 For simplicity sake, round each read up to a page boundary,
4513 we may want to revisit this later.... */
4515 file_offset = orig_file_header.f_symptr + sizeof (struct filehdr);
4517 if (orig_sym_hdr.cbLine > 0) /* line numbers */
4518 orig_linenum = (char *) read_seek ((Size_t)orig_sym_hdr.cbLine,
4519 orig_sym_hdr.cbLineOffset,
4522 if (orig_sym_hdr.ipdMax > 0) /* procedure tables */
4523 orig_procs = (PDR *) read_seek ((Size_t)orig_sym_hdr.ipdMax * sizeof (PDR),
4524 orig_sym_hdr.cbPdOffset,
4525 "Procedure tables");
4527 if (orig_sym_hdr.isymMax > 0) /* local symbols */
4528 orig_local_syms = (SYMR *) read_seek ((Size_t)orig_sym_hdr.isymMax * sizeof (SYMR),
4529 orig_sym_hdr.cbSymOffset,
4532 if (orig_sym_hdr.iauxMax > 0) /* aux symbols */
4533 orig_aux_syms = (AUXU *) read_seek ((Size_t)orig_sym_hdr.iauxMax * sizeof (AUXU),
4534 orig_sym_hdr.cbAuxOffset,
4537 if (orig_sym_hdr.issMax > 0) /* local strings */
4538 orig_local_strs = (char *) read_seek ((Size_t)orig_sym_hdr.issMax,
4539 orig_sym_hdr.cbSsOffset,
4542 if (orig_sym_hdr.issExtMax > 0) /* external strings */
4543 orig_ext_strs = (char *) read_seek ((Size_t)orig_sym_hdr.issExtMax,
4544 orig_sym_hdr.cbSsExtOffset,
4545 "External strings");
4547 if (orig_sym_hdr.ifdMax > 0) /* file tables */
4548 orig_files = (FDR *) read_seek ((Size_t)orig_sym_hdr.ifdMax * sizeof (FDR),
4549 orig_sym_hdr.cbFdOffset,
4552 if (orig_sym_hdr.crfd > 0) /* relative file descriptors */
4553 orig_rfds = (symint_t *) read_seek ((Size_t)orig_sym_hdr.crfd * sizeof (symint_t),
4554 orig_sym_hdr.cbRfdOffset,
4555 "Relative file descriptors");
4557 if (orig_sym_hdr.issExtMax > 0) /* external symbols */
4558 orig_ext_syms = (EXTR *) read_seek ((Size_t)orig_sym_hdr.iextMax * sizeof (EXTR),
4559 orig_sym_hdr.cbExtOffset,
4560 "External symbols");
4562 if (orig_sym_hdr.idnMax > 0) /* dense numbers */
4564 orig_dense = (DNR *) read_seek ((Size_t)orig_sym_hdr.idnMax * sizeof (DNR),
4565 orig_sym_hdr.cbDnOffset,
4568 add_bytes (&dense_num, (char *) orig_dense, (Size_t)orig_sym_hdr.idnMax);
4571 if (orig_sym_hdr.ioptMax > 0) /* opt symbols */
4572 orig_opt_syms = (OPTR *) read_seek ((Size_t)orig_sym_hdr.ioptMax * sizeof (OPTR),
4573 orig_sym_hdr.cbOptOffset,
4574 "Optimizer symbols");
4578 /* Abort if the symbol table is not last. */
4579 if (max_file_offset != stat_buf.st_size)
4580 fatal ("Symbol table is not last (symbol table ends at %ld, .o ends at %ld",
4585 /* If the first original file descriptor is a dummy which the assembler
4586 put out, but there are no symbols in it, skip it now. */
4587 if (orig_sym_hdr.ifdMax > 1
4588 && orig_files->csym == 2
4589 && orig_files->caux == 0)
4591 char *filename = orig_local_strs + (orig_files->issBase + orig_files->rss);
4592 char *suffix = local_rindex (filename, '.');
4594 if (suffix != (char *) 0 && strcmp (suffix, ".s") == 0)
4599 /* Create array to map original file numbers to the new file numbers
4600 (in case there are duplicate filenames, we collapse them into one
4601 file section, the MIPS assembler may or may not collapse them). */
4603 remap_file_number = (int *) alloca (sizeof (int) * orig_sym_hdr.ifdMax);
4605 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
4607 register FDR *fd_ptr = ORIG_FILES (fd);
4608 register char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
4610 /* file support itself. */
4611 add_file (filename, filename + strlen (filename));
4612 remap_file_number[fd] = cur_file_ptr->file_index;
4615 if (delete_ifd > 0) /* just in case */
4616 remap_file_number[0] = remap_file_number[1];
4619 /* Loop, adding each of the external symbols. These must be in
4620 order or otherwise we would have to change the relocation
4621 entries. We don't just call add_bytes, because we need to have
4622 the names put into the external hash table. We set the type to
4623 'void' for now, and parse_def will fill in the correct type if it
4624 is in the symbol table. We must add the external symbols before
4625 the locals, since the locals do lookups against the externals. */
4628 fprintf (stderr, "\tehash\n");
4630 for (es = 0; es < orig_sym_hdr.iextMax; es++)
4632 register EXTR *eptr = orig_ext_syms + es;
4633 register char *ename = ORIG_ESTRS (eptr->asym.iss);
4634 register unsigned ifd = eptr->ifd;
4636 (void) add_ext_symbol (ename,
4637 ename + strlen (ename),
4638 (st_t) eptr->asym.st,
4639 (sc_t) eptr->asym.sc,
4641 (symint_t) ((eptr->asym.index == indexNil) ? indexNil : 0),
4642 (ifd < orig_sym_hdr.ifdMax) ? remap_file_number[ ifd ] : ifd);
4646 /* For each of the files in the object file, copy the symbols, and such
4647 into the varrays for the new object file. */
4649 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
4651 register FDR *fd_ptr = ORIG_FILES (fd);
4652 register char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
4653 register SYMR *sym_start;
4655 register SYMR *sym_end_p1;
4656 register PDR *proc_start;
4658 register PDR *proc_end_p1;
4660 /* file support itself. */
4661 add_file (filename, filename + strlen (filename));
4662 cur_file_ptr->orig_fdr = fd_ptr;
4664 /* Copy stuff that's just passed through (such as line #'s) */
4665 cur_file_ptr->fdr.adr = fd_ptr->adr;
4666 cur_file_ptr->fdr.ilineBase = fd_ptr->ilineBase;
4667 cur_file_ptr->fdr.cline = fd_ptr->cline;
4668 cur_file_ptr->fdr.rfdBase = fd_ptr->rfdBase;
4669 cur_file_ptr->fdr.crfd = fd_ptr->crfd;
4670 cur_file_ptr->fdr.cbLineOffset = fd_ptr->cbLineOffset;
4671 cur_file_ptr->fdr.cbLine = fd_ptr->cbLine;
4672 cur_file_ptr->fdr.fMerge = fd_ptr->fMerge;
4673 cur_file_ptr->fdr.fReadin = fd_ptr->fReadin;
4674 cur_file_ptr->fdr.glevel = fd_ptr->glevel;
4677 fprintf (stderr, "\thash\tstart, filename %s\n", filename);
4679 /* For each of the static and global symbols defined, add them
4680 to the hash table of original symbols, so we can look up
4683 sym_start = ORIG_LSYMS (fd_ptr->isymBase);
4684 sym_end_p1 = sym_start + fd_ptr->csym;
4685 for (sym = sym_start; sym < sym_end_p1; sym++)
4687 switch ((st_t) sym->st)
4698 auto symint_t hash_index;
4699 register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
4700 register Size_t len = strlen (str);
4701 register shash_t *shash_ptr = hash_string (str,
4706 if (shash_ptr != (shash_t *) 0)
4707 error ("internal error, %s is already in original symbol table", str);
4711 shash_ptr = allocate_shash ();
4712 shash_ptr->next = orig_str_hash[hash_index];
4713 orig_str_hash[hash_index] = shash_ptr;
4715 shash_ptr->len = len;
4716 shash_ptr->indx = indexNil;
4717 shash_ptr->string = str;
4718 shash_ptr->sym_ptr = sym;
4724 if ((sc_t) sym->sc == sc_Text)
4726 register char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
4730 register Size_t len = strlen (str);
4731 register shash_t *shash_ptr = hash_string (str,
4736 if (shash_ptr != (shash_t *) 0)
4737 shash_ptr->end_ptr = sym;
4747 fprintf (stderr, "\thash\tdone, filename %s\n", filename);
4748 fprintf (stderr, "\tproc\tstart, filename %s\n", filename);
4751 /* Go through each of the procedures in this file, and add the
4752 procedure pointer to the hash entry for the given name. */
4754 proc_start = ORIG_PROCS (fd_ptr->ipdFirst);
4755 proc_end_p1 = proc_start + fd_ptr->cpd;
4756 for (proc = proc_start; proc < proc_end_p1; proc++)
4758 register SYMR *proc_sym = ORIG_LSYMS (fd_ptr->isymBase + proc->isym);
4759 register char *str = ORIG_LSTRS (fd_ptr->issBase + proc_sym->iss);
4760 register Size_t len = strlen (str);
4761 register shash_t *shash_ptr = hash_string (str,
4766 if (shash_ptr == (shash_t *) 0)
4767 error ("internal error, function %s is not in original symbol table", str);
4770 shash_ptr->proc_ptr = proc;
4774 fprintf (stderr, "\tproc\tdone, filename %s\n", filename);
4777 cur_file_ptr = first_file;
4780 /* Copy all of the object file up to the symbol table. Originally
4781 we were going to use ftruncate, but that doesn't seem to work
4782 on Ultrix 3.1.... */
4784 if (fseek (obj_in_stream, (long) 0, SEEK_SET) != 0)
4785 pfatal_with_name (obj_in_name);
4787 if (fseek (object_stream, (long) 0, SEEK_SET) != 0)
4788 pfatal_with_name (object_name);
4790 for (remaining = orig_file_header.f_symptr;
4792 remaining -= num_write)
4794 num_write = (remaining <= sizeof (buffer)) ? remaining : sizeof (buffer);
4795 sys_read = fread ((PTR_T) buffer, 1, num_write, obj_in_stream);
4797 pfatal_with_name (obj_in_name);
4799 else if (sys_read != num_write)
4800 fatal ("Wanted to read %d bytes from %s, system returned %d",
4805 sys_write = fwrite (buffer, 1, num_write, object_stream);
4807 pfatal_with_name (object_name);
4809 else if (sys_write != num_write)
4810 fatal ("Wrote %d bytes to %s, system returned %d",
4818 /* Ye olde main program. */
4826 char *p = local_rindex (argv[0], '/');
4831 progname = (p != 0) ? p+1 : argv[0];
4833 (void) signal (SIGSEGV, catch_signal);
4834 (void) signal (SIGBUS, catch_signal);
4835 (void) signal (SIGABRT, catch_signal);
4837 #if !defined(__SABER__) && !defined(lint)
4838 if (sizeof (efdr_t) > PAGE_USIZE)
4839 fatal ("Efdr_t has a sizeof %d bytes, when it should be less than %d",
4843 if (sizeof (page_t) != PAGE_USIZE)
4844 fatal ("Page_t has a sizeof %d bytes, when it should be %d",
4850 alloc_counts[ alloc_type_none ].alloc_name = "none";
4851 alloc_counts[ alloc_type_scope ].alloc_name = "scope";
4852 alloc_counts[ alloc_type_vlinks ].alloc_name = "vlinks";
4853 alloc_counts[ alloc_type_shash ].alloc_name = "shash";
4854 alloc_counts[ alloc_type_thash ].alloc_name = "thash";
4855 alloc_counts[ alloc_type_tag ].alloc_name = "tag";
4856 alloc_counts[ alloc_type_forward ].alloc_name = "forward";
4857 alloc_counts[ alloc_type_thead ].alloc_name = "thead";
4858 alloc_counts[ alloc_type_varray ].alloc_name = "varray";
4860 int_type_info = type_info_init;
4861 int_type_info.basic_type = bt_Int;
4863 void_type_info = type_info_init;
4864 void_type_info.basic_type = bt_Void;
4866 while ((option = getopt (argc, argv, "d:i:I:o:v")) != EOF)
4874 debug = strtol (optarg, &num_end, 0);
4875 if ((unsigned)debug > 4 || num_end == optarg)
4881 if (rename_output || obj_in_name != (char *) 0)
4886 /* fall through to 'i' case. */
4889 if (obj_in_name == (char *) 0)
4891 obj_in_name = optarg;
4899 if (object_name == (char *) 0)
4900 object_name = optarg;
4910 if (obj_in_name == (char *) 0 && optind <= argc - 2)
4911 obj_in_name = argv[--argc];
4913 if (object_name == (char *) 0 && optind <= argc - 2)
4914 object_name = argv[--argc];
4916 /* If there is an output name, but no input name use
4917 the same file for both, deleting the name between
4918 opening it for input and opening it for output. */
4919 if (obj_in_name == (char *) 0 && object_name != (char *)0)
4921 obj_in_name = object_name;
4925 if (object_name == (char *) 0 || had_errors || optind != argc - 1)
4927 fprintf (stderr, "Calling Sequence:\n");
4928 fprintf (stderr, "\tmips-tfile [-d <num>] [-v] [-i <o-in-file>] -o <o-out-file> <s-file> (or)\n");
4929 fprintf (stderr, "\tmips-tfile [-d <num>] [-v] [-I <o-in-file>] -o <o-out-file> <s-file> (or)\n");
4930 fprintf (stderr, "\tmips-tfile [-d <num>] [-v] <s-file> <o-in-file> <o-out-file>\n");
4931 fprintf (stderr, "\n");
4932 fprintf (stderr, "Debug levels are:\n");
4933 fprintf (stderr, " 1\tGeneral debug + trace functions/blocks.\n");
4934 fprintf (stderr, " 2\tDebug level 1 + trace externals.\n");
4935 fprintf (stderr, " 3\tDebug level 2 + trace all symbols.\n");
4936 fprintf (stderr, " 4\tDebug level 3 + trace memory allocations.\n");
4943 fprintf (stderr, "mips-tfile version %s", version_string);
4944 #ifdef TARGET_VERSION
4947 fputc ('\n', stderr);
4950 if (obj_in_name == (char *) 0)
4951 obj_in_name = object_name;
4953 if (rename_output && rename (object_name, obj_in_name) != 0)
4955 char *buffer = (char *) allocate_multiple_pages (4);
4961 /* Rename failed, copy input file */
4962 in_fd = open (object_name, O_RDONLY, 0666);
4964 pfatal_with_name (object_name);
4966 out_fd = open (obj_in_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
4968 pfatal_with_name (obj_in_name);
4970 while ((len = read (in_fd, buffer, 4*PAGE_SIZE)) > 0)
4972 len2 = write (out_fd, buffer, len);
4974 pfatal_with_name (object_name);
4977 fatal ("wrote %d bytes to %s, expected to write %d", len2, obj_in_name, len);
4980 free_multiple_pages ((page_t *)buffer, 4);
4983 pfatal_with_name (object_name);
4985 if (close (in_fd) < 0)
4986 pfatal_with_name (object_name);
4988 if (close (out_fd) < 0)
4989 pfatal_with_name (obj_in_name);
4992 /* Must open input before output, since the output may be the same file, and
4993 we need to get the input handle before truncating it. */
4994 obj_in_stream = fopen (obj_in_name, "r");
4995 if (obj_in_stream == (FILE *) 0)
4996 pfatal_with_name (obj_in_name);
4998 if (delete_input && unlink (obj_in_name) != 0)
4999 pfatal_with_name (obj_in_name);
5001 object_stream = fopen (object_name, "w");
5002 if (object_stream == (FILE *) 0)
5003 pfatal_with_name (object_name);
5005 if (strcmp (argv[optind], "-") != 0)
5007 input_name = argv[optind];
5008 if (freopen (argv[optind], "r", stdin) != stdin)
5009 pfatal_with_name (argv[optind]);
5012 copy_object (); /* scan & copy object file */
5013 parse_input (); /* scan all of input */
5015 update_headers (); /* write out tfile */
5020 fprintf (stderr, "\n\tAllocation summary:\n\n");
5021 for (i = (int)alloc_type_none; i < (int)alloc_type_last; i++)
5022 if (alloc_counts[i].total_alloc)
5025 "\t%s\t%5d allocation(s), %5d free(s), %2d page(s)\n",
5026 alloc_counts[i].alloc_name,
5027 alloc_counts[i].total_alloc,
5028 alloc_counts[i].total_free,
5029 alloc_counts[i].total_pages);
5033 return (had_errors) ? 1 : 0;
5041 #ifdef HAVE_STRSIGNAL
5042 return strsignal (s);
5044 if (s >= 0 && s < NSIG)
5046 # ifdef NO_SYS_SIGLIST
5047 static char buffer[30];
5049 sprintf (buffer, "Unknown signal %d", s);
5052 return sys_siglist[s];
5057 #endif /* HAVE_STRSIGNAL */
5060 /* Catch a signal and exit without dumping core. */
5063 catch_signal (signum)
5066 (void) signal (signum, SIG_DFL); /* just in case... */
5067 fatal (my_strsignal(signum));
5070 /* Print a fatal error message. NAME is the text.
5071 Also include a system error message based on `errno'. */
5074 pfatal_with_name (msg)
5077 int save_errno = errno; /* just in case.... */
5078 if (line_number > 0)
5079 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5081 fprintf (stderr, "%s:", progname);
5085 fprintf (stderr, "[errno = 0] %s\n", msg);
5093 /* Procedure to abort with an out of bounds error message. It has
5094 type int, so it can be used with an ?: expression within the
5095 ORIG_xxx macros, but the function never returns. */
5098 out_of_bounds (indx, max, str, prog_line)
5099 symint_t indx; /* index that is out of bounds */
5100 symint_t max; /* maximum index */
5101 const char *str; /* string to print out */
5102 int prog_line; /* line number within mips-tfile.c */
5104 if (indx < max) /* just in case */
5107 fprintf (stderr, "%s, %s:%ld index %lu is out of bounds for %s, max is %lu, mips-tfile.c line# %d\n",
5108 progname, input_name, line_number, indx, str, max, prog_line);
5111 return 0; /* turn off warning messages */
5115 /* Allocate a cluster of pages. USE_MALLOC says that malloc does not
5116 like sbrk's behind its back (or sbrk isn't available). If we use
5117 sbrk, we assume it gives us zeroed pages. */
5119 #ifndef MALLOC_CHECK
5123 allocate_cluster (npages)
5126 register page_t *value = (page_t *) calloc (npages, PAGE_USIZE);
5129 fatal ("Virtual memory exhausted.");
5132 fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
5137 #else /* USE_MALLOC */
5140 allocate_cluster (npages)
5143 register page_t *ptr = (page_t *) sbrk (0); /* current sbreak */
5144 unsigned long offset = ((unsigned long) ptr) & (PAGE_SIZE - 1);
5146 if (offset != 0) /* align to a page boundary */
5148 if (sbrk (PAGE_USIZE - offset) == (char *)-1)
5149 pfatal_with_name ("allocate_cluster");
5151 ptr = (page_t *) (((char *)ptr) + PAGE_SIZE - offset);
5154 if (sbrk (npages * PAGE_USIZE) == (char *)-1)
5155 pfatal_with_name ("allocate_cluster");
5159 fprintf (stderr, "\talloc\tnpages = %lu, value = ",
5160 (unsigned long) npages);
5161 fprintf (stderr, HOST_PTR_PRINTF, ptr);
5162 fputs ("\n", stderr);
5168 #endif /* USE_MALLOC */
5171 static page_t *cluster_ptr = NULL;
5172 static unsigned pages_left = 0;
5174 #endif /* MALLOC_CHECK */
5177 /* Allocate some pages (which is initialized to 0). */
5180 allocate_multiple_pages (npages)
5183 #ifndef MALLOC_CHECK
5184 if (pages_left == 0 && npages < MAX_CLUSTER_PAGES)
5186 pages_left = MAX_CLUSTER_PAGES;
5187 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
5190 if (npages <= pages_left)
5192 page_t *ptr = cluster_ptr;
5193 cluster_ptr += npages;
5194 pages_left -= npages;
5198 return allocate_cluster (npages);
5200 #else /* MALLOC_CHECK */
5201 return (page_t *) xcalloc (npages, PAGE_SIZE);
5203 #endif /* MALLOC_CHECK */
5207 /* Release some pages. */
5210 free_multiple_pages (page_ptr, npages)
5214 #ifndef MALLOC_CHECK
5215 if (pages_left == 0)
5217 cluster_ptr = page_ptr;
5218 pages_left = npages;
5221 else if ((page_ptr + npages) == cluster_ptr)
5223 cluster_ptr -= npages;
5224 pages_left += npages;
5227 /* otherwise the page is not freed. If more than call is
5228 done, we probably should worry about it, but at present,
5229 the free pages is done right after an allocate. */
5231 #else /* MALLOC_CHECK */
5232 free ((char *) page_ptr);
5234 #endif /* MALLOC_CHECK */
5238 /* Allocate one page (which is initialized to 0). */
5241 allocate_page __proto((void))
5243 #ifndef MALLOC_CHECK
5244 if (pages_left == 0)
5246 pages_left = MAX_CLUSTER_PAGES;
5247 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
5251 return cluster_ptr++;
5253 #else /* MALLOC_CHECK */
5254 return (page_t *) xcalloc (1, PAGE_SIZE);
5256 #endif /* MALLOC_CHECK */
5260 /* Allocate scoping information. */
5263 allocate_scope __proto((void))
5265 register scope_t *ptr;
5266 static scope_t initial_scope;
5268 #ifndef MALLOC_CHECK
5269 ptr = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope;
5270 if (ptr != (scope_t *) 0)
5271 alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr->free;
5275 register int unallocated = alloc_counts[ (int)alloc_type_scope ].unallocated;
5276 register page_t *cur_page = alloc_counts[ (int)alloc_type_scope ].cur_page;
5278 if (unallocated == 0)
5280 unallocated = PAGE_SIZE / sizeof (scope_t);
5281 alloc_counts[ (int)alloc_type_scope ].cur_page = cur_page = allocate_page ();
5282 alloc_counts[ (int)alloc_type_scope ].total_pages++;
5285 ptr = &cur_page->scope[ --unallocated ];
5286 alloc_counts[ (int)alloc_type_scope ].unallocated = unallocated;
5290 ptr = (scope_t *) xmalloc (sizeof (scope_t));
5294 alloc_counts[ (int)alloc_type_scope ].total_alloc++;
5295 *ptr = initial_scope;
5299 /* Free scoping information. */
5305 alloc_counts[ (int)alloc_type_scope ].total_free++;
5307 #ifndef MALLOC_CHECK
5308 ptr->free = alloc_counts[ (int)alloc_type_scope ].free_list.f_scope;
5309 alloc_counts[ (int)alloc_type_scope ].free_list.f_scope = ptr;
5312 xfree ((PTR_T) ptr);
5318 /* Allocate links for pages in a virtual array. */
5321 allocate_vlinks __proto((void))
5323 register vlinks_t *ptr;
5324 static vlinks_t initial_vlinks;
5326 #ifndef MALLOC_CHECK
5327 register int unallocated = alloc_counts[ (int)alloc_type_vlinks ].unallocated;
5328 register page_t *cur_page = alloc_counts[ (int)alloc_type_vlinks ].cur_page;
5330 if (unallocated == 0)
5332 unallocated = PAGE_SIZE / sizeof (vlinks_t);
5333 alloc_counts[ (int)alloc_type_vlinks ].cur_page = cur_page = allocate_page ();
5334 alloc_counts[ (int)alloc_type_vlinks ].total_pages++;
5337 ptr = &cur_page->vlinks[ --unallocated ];
5338 alloc_counts[ (int)alloc_type_vlinks ].unallocated = unallocated;
5341 ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
5345 alloc_counts[ (int)alloc_type_vlinks ].total_alloc++;
5346 *ptr = initial_vlinks;
5351 /* Allocate string hash buckets. */
5354 allocate_shash __proto((void))
5356 register shash_t *ptr;
5357 static shash_t initial_shash;
5359 #ifndef MALLOC_CHECK
5360 register int unallocated = alloc_counts[ (int)alloc_type_shash ].unallocated;
5361 register page_t *cur_page = alloc_counts[ (int)alloc_type_shash ].cur_page;
5363 if (unallocated == 0)
5365 unallocated = PAGE_SIZE / sizeof (shash_t);
5366 alloc_counts[ (int)alloc_type_shash ].cur_page = cur_page = allocate_page ();
5367 alloc_counts[ (int)alloc_type_shash ].total_pages++;
5370 ptr = &cur_page->shash[ --unallocated ];
5371 alloc_counts[ (int)alloc_type_shash ].unallocated = unallocated;
5374 ptr = (shash_t *) xmalloc (sizeof (shash_t));
5378 alloc_counts[ (int)alloc_type_shash ].total_alloc++;
5379 *ptr = initial_shash;
5384 /* Allocate type hash buckets. */
5387 allocate_thash __proto((void))
5389 register thash_t *ptr;
5390 static thash_t initial_thash;
5392 #ifndef MALLOC_CHECK
5393 register int unallocated = alloc_counts[ (int)alloc_type_thash ].unallocated;
5394 register page_t *cur_page = alloc_counts[ (int)alloc_type_thash ].cur_page;
5396 if (unallocated == 0)
5398 unallocated = PAGE_SIZE / sizeof (thash_t);
5399 alloc_counts[ (int)alloc_type_thash ].cur_page = cur_page = allocate_page ();
5400 alloc_counts[ (int)alloc_type_thash ].total_pages++;
5403 ptr = &cur_page->thash[ --unallocated ];
5404 alloc_counts[ (int)alloc_type_thash ].unallocated = unallocated;
5407 ptr = (thash_t *) xmalloc (sizeof (thash_t));
5411 alloc_counts[ (int)alloc_type_thash ].total_alloc++;
5412 *ptr = initial_thash;
5417 /* Allocate structure, union, or enum tag information. */
5420 allocate_tag __proto((void))
5422 register tag_t *ptr;
5423 static tag_t initial_tag;
5425 #ifndef MALLOC_CHECK
5426 ptr = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag;
5427 if (ptr != (tag_t *) 0)
5428 alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr->free;
5432 register int unallocated = alloc_counts[ (int)alloc_type_tag ].unallocated;
5433 register page_t *cur_page = alloc_counts[ (int)alloc_type_tag ].cur_page;
5435 if (unallocated == 0)
5437 unallocated = PAGE_SIZE / sizeof (tag_t);
5438 alloc_counts[ (int)alloc_type_tag ].cur_page = cur_page = allocate_page ();
5439 alloc_counts[ (int)alloc_type_tag ].total_pages++;
5442 ptr = &cur_page->tag[ --unallocated ];
5443 alloc_counts[ (int)alloc_type_tag ].unallocated = unallocated;
5447 ptr = (tag_t *) xmalloc (sizeof (tag_t));
5451 alloc_counts[ (int)alloc_type_tag ].total_alloc++;
5456 /* Free scoping information. */
5462 alloc_counts[ (int)alloc_type_tag ].total_free++;
5464 #ifndef MALLOC_CHECK
5465 ptr->free = alloc_counts[ (int)alloc_type_tag ].free_list.f_tag;
5466 alloc_counts[ (int)alloc_type_tag ].free_list.f_tag = ptr;
5469 xfree ((PTR_T) ptr);
5475 /* Allocate forward reference to a yet unknown tag. */
5478 allocate_forward __proto((void))
5480 register forward_t *ptr;
5481 static forward_t initial_forward;
5483 #ifndef MALLOC_CHECK
5484 ptr = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward;
5485 if (ptr != (forward_t *) 0)
5486 alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr->free;
5490 register int unallocated = alloc_counts[ (int)alloc_type_forward ].unallocated;
5491 register page_t *cur_page = alloc_counts[ (int)alloc_type_forward ].cur_page;
5493 if (unallocated == 0)
5495 unallocated = PAGE_SIZE / sizeof (forward_t);
5496 alloc_counts[ (int)alloc_type_forward ].cur_page = cur_page = allocate_page ();
5497 alloc_counts[ (int)alloc_type_forward ].total_pages++;
5500 ptr = &cur_page->forward[ --unallocated ];
5501 alloc_counts[ (int)alloc_type_forward ].unallocated = unallocated;
5505 ptr = (forward_t *) xmalloc (sizeof (forward_t));
5509 alloc_counts[ (int)alloc_type_forward ].total_alloc++;
5510 *ptr = initial_forward;
5514 /* Free scoping information. */
5520 alloc_counts[ (int)alloc_type_forward ].total_free++;
5522 #ifndef MALLOC_CHECK
5523 ptr->free = alloc_counts[ (int)alloc_type_forward ].free_list.f_forward;
5524 alloc_counts[ (int)alloc_type_forward ].free_list.f_forward = ptr;
5527 xfree ((PTR_T) ptr);
5533 /* Allocate head of type hash list. */
5536 allocate_thead __proto((void))
5538 register thead_t *ptr;
5539 static thead_t initial_thead;
5541 #ifndef MALLOC_CHECK
5542 ptr = alloc_counts[ (int)alloc_type_thead ].free_list.f_thead;
5543 if (ptr != (thead_t *) 0)
5544 alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr->free;
5548 register int unallocated = alloc_counts[ (int)alloc_type_thead ].unallocated;
5549 register page_t *cur_page = alloc_counts[ (int)alloc_type_thead ].cur_page;
5551 if (unallocated == 0)
5553 unallocated = PAGE_SIZE / sizeof (thead_t);
5554 alloc_counts[ (int)alloc_type_thead ].cur_page = cur_page = allocate_page ();
5555 alloc_counts[ (int)alloc_type_thead ].total_pages++;
5558 ptr = &cur_page->thead[ --unallocated ];
5559 alloc_counts[ (int)alloc_type_thead ].unallocated = unallocated;
5563 ptr = (thead_t *) xmalloc (sizeof (thead_t));
5567 alloc_counts[ (int)alloc_type_thead ].total_alloc++;
5568 *ptr = initial_thead;
5572 /* Free scoping information. */
5578 alloc_counts[ (int)alloc_type_thead ].total_free++;
5580 #ifndef MALLOC_CHECK
5581 ptr->free = (thead_t *) alloc_counts[ (int)alloc_type_thead ].free_list.f_thead;
5582 alloc_counts[ (int)alloc_type_thead ].free_list.f_thead = ptr;
5585 xfree ((PTR_T) ptr);
5590 #endif /* MIPS_DEBUGGING_INFO */
5593 /* Output an error message and exit */
5597 fatal VPROTO((const char *format, ...))
5599 #ifndef ANSI_PROTOTYPES
5604 VA_START (ap, format);
5606 #ifndef ANSI_PROTOTYPES
5607 format = va_arg (ap, char *);
5610 if (line_number > 0)
5611 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5613 fprintf (stderr, "%s:", progname);
5615 vfprintf (stderr, format, ap);
5617 fprintf (stderr, "\n");
5618 if (line_number > 0)
5619 fprintf (stderr, "line:\t%s\n", cur_line_start);
5627 error VPROTO((const char *format, ...))
5629 #ifndef ANSI_PROTOTYPES
5634 VA_START (ap, format);
5636 #ifndef ANSI_PROTOTYPES
5637 format = va_arg (ap, char *);
5640 if (line_number > 0)
5641 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
5643 fprintf (stderr, "%s:", progname);
5645 vfprintf (stderr, format, ap);
5646 fprintf (stderr, "\n");
5647 if (line_number > 0)
5648 fprintf (stderr, "line:\t%s\n", cur_line_start);
5656 /* More 'friendly' abort that prints the line and file.
5657 config.h can #define abort fancy_abort if you like that sort of thing. */
5662 fatal ("Internal abort.");
5666 /* When `malloc.c' is compiled with `rcheck' defined,
5667 it calls this function to report clobberage. */
5676 /* Same as `malloc' but report error if no memory available. */
5682 register PTR_T value = malloc (size);
5684 fatal ("Virtual memory exhausted.");
5688 fputs ("\tmalloc\tptr = ", stderr);
5689 fprintf (stderr, HOST_PTR_PRINTF, value);
5690 fprintf (stderr, ", size = %10lu\n", (unsigned long) size);
5696 /* Same as `calloc' but report error if no memory available. */
5699 xcalloc (size1, size2)
5700 Size_t size1, size2;
5702 register PTR_T value = calloc (size1, size2);
5704 fatal ("Virtual memory exhausted.");
5708 fputs ("\tcalloc\tptr = ", stderr);
5709 fprintf (stderr, HOST_PTR_PRINTF, value);
5710 fprintf (stderr, ", size1 = %10lu, size2 = %10lu [%lu]\n",
5711 (unsigned long) size1, (unsigned long) size2,
5712 (unsigned long) size1*size2);
5718 /* Same as `realloc' but report error if no memory available. */
5721 xrealloc (ptr, size)
5725 register PTR_T result = realloc (ptr, size);
5727 fatal ("Virtual memory exhausted.");
5731 fputs ("\trealloc\tptr = ", stderr);
5732 fprintf (stderr, HOST_PTR_PRINTF, result);
5733 fprintf (stderr, ", size = %10lu, orig = ", size);
5734 fprintf (stderr, HOST_PTR_PRINTF, ptr);
5735 fputs ("\n", stderr);
5747 fputs ("\tfree\tptr = ", stderr);
5748 fprintf (stderr, HOST_PTR_PRINTF, ptr);
5749 fputs ("\n", stderr);
5756 /* Define our own index/rindex, since the local and global symbol
5757 structures as defined by MIPS has an 'index' field. */
5760 local_index (str, sentinel)
5766 for ( ; (ch = *str) != sentinel; str++)
5776 local_rindex (str, sentinel)
5781 const char *ret = (const char *) 0;
5783 for ( ; (ch = *str) != '\0'; str++)