1 /* Update the symbol table (the .T file) in a MIPS object to
2 contain debugging information specified by the GNU compiler
3 in the form of comments (the mips assembler does not support
4 assembly access to debug information).
5 Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
6 Contributed by Michael Meissner, meissner@osf.org
8 This file is part of GNU CC.
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 /* Here is a brief description of the MIPS ECOFF symbol table. The
26 MIPS symbol table has the following pieces:
32 +-- Dense number table
40 +-- Relative file descriptors
52 The symbolic header points to each of the other tables, and also
53 contains the number of entries. It also contains a magic number
54 and MIPS compiler version number, such as 2.0.
56 The auxiliary table is a series of 32 bit integers, that are
57 referenced as needed from the local symbol table. Unlike standard
58 COFF, the aux. information does not follow the symbol that uses
59 it, but rather is a separate table. In theory, this would allow
60 the MIPS compilers to collapse duplicate aux. entries, but I've not
61 noticed this happening with the 1.31 compiler suite. The different
62 types of aux. entries are:
64 1) dnLow: Low bound on array dimension.
66 2) dnHigh: High bound on array dimension.
68 3) isym: Index to the local symbol which is the start of the
69 function for the end of function first aux. entry.
71 4) width: Width of structures and bitfields.
73 5) count: Count of ranges for variant part.
75 6) rndx: A relative index into the symbol table. The relative
76 index field has two parts: rfd which is a pointer into the
77 relative file index table or ST_RFDESCAPE which says the next
78 aux. entry is the file number, and index: which is the pointer
79 into the local symbol within a given file table. This is for
80 things like references to types defined in another file.
82 7) Type information: This is like the COFF type bits, except it
83 is 32 bits instead of 16; they still have room to add new
84 basic types; and they can handle more than 6 levels of array,
85 pointer, function, etc. Each type information field contains
86 the following structure members:
88 a) fBitfield: a bit that says this is a bitfield, and the
89 size in bits follows as the next aux. entry.
91 b) continued: a bit that says the next aux. entry is a
92 continuation of the current type information (in case
93 there are more than 6 levels of array/ptr/function).
95 c) bt: an integer containing the base type before adding
96 array, pointer, function, etc. qualifiers. The
97 current base types that I have documentation for are:
100 btAdr -- address - integer same size as ptr
102 btUChar -- unsigned character
104 btUShort -- unsigned short
106 btUInt -- unsigned int
108 btULong -- unsigned long
109 btFloat -- float (real)
110 btDouble -- Double (real)
111 btStruct -- Structure (Record)
112 btUnion -- Union (variant)
114 btTypedef -- defined via a typedef isymRef
115 btRange -- subrange of int
117 btComplex -- fortran complex
118 btDComplex -- fortran double complex
119 btIndirect -- forward or unnamed typedef
120 btFixedDec -- Fixed Decimal
121 btFloatDec -- Float Decimal
122 btString -- Varying Length Character String
123 btBit -- Aligned Bit String
125 btVoid -- Void (MIPS cc revision >= 2.00)
127 d) tq0 - tq5: type qualifier fields as needed. The
128 current type qualifier fields I have documentation for
131 tqNil -- no more qualifiers
135 tqFar -- 8086 far pointers
139 The dense number table is used in the front ends, and disappears by
140 the time the .o is created.
142 With the 1.31 compiler suite, the optimization symbols don't seem
143 to be used as far as I can tell.
145 The linker is the first entity that creates the relative file
146 descriptor table, and I believe it is used so that the individual
147 file table pointers don't have to be rewritten when the objects are
148 merged together into the program file.
150 Unlike COFF, the basic symbol & string tables are split into
151 external and local symbols/strings. The relocation information
152 only goes off of the external symbol table, and the debug
153 information only goes off of the internal symbol table. The
154 external symbols can have links to an appropriate file index and
155 symbol within the file to give it the appropriate type information.
156 Because of this, the external symbols are actually larger than the
157 internal symbols (to contain the link information), and contain the
158 local symbol structure as a member, though this member is not the
159 first member of the external symbol structure (!). I suspect this
160 split is to make strip easier to deal with.
162 Each file table has offsets for where the line numbers, local
163 strings, local symbols, and procedure table starts from within the
164 global tables, and the indexs are reset to 0 for each of those
167 The procedure table contains the binary equivalents of the .ent
168 (start of the function address), .frame (what register is the
169 virtual frame pointer, constant offset from the register to obtain
170 the VFP, and what register holds the return address), .mask/.fmask
171 (bitmask of saved registers, and where the first register is stored
172 relative to the VFP) assembler directives. It also contains the
173 low and high bounds of the line numbers if debugging is turned on.
175 The line number table is a compressed form of the normal COFF line
176 table. Each line number entry is either 1 or 3 bytes long, and
177 contains a signed delta from the previous line, and an unsigned
178 count of the number of instructions this statement takes.
180 The local symbol table contains the following fields:
182 1) iss: index to the local string table giving the name of the
185 2) value: value of the symbol (address, register number, etc.).
187 3) st: symbol type. The current symbol types are:
189 stNil -- Nuthin' special
190 stGlobal -- external symbol
192 stParam -- procedure argument
193 stLocal -- local variable
195 stProc -- External Procedure
196 stBlock -- beginning of block
197 stEnd -- end (of anything)
198 stMember -- member (of anything)
199 stTypedef -- type definition
201 stRegReloc -- register relocation
202 stForward -- forwarding address
203 stStaticProc -- Static procedure
206 4) sc: storage class. The current storage classes are:
208 scText -- text symbol
209 scData -- initialized data symbol
210 scBss -- un-initialized data symbol
211 scRegister -- value of symbol is register number
212 scAbs -- value of symbol is absolute
213 scUndefined -- who knows?
214 scCdbLocal -- variable's value is IN se->va.??
215 scBits -- this is a bit field
216 scCdbSystem -- value is IN debugger's address space
217 scRegImage -- register value saved on stack
218 scInfo -- symbol contains debugger information
219 scUserStruct -- addr in struct user for current process
220 scSData -- load time only small data
221 scSBss -- load time only small common
222 scRData -- load time only read only data
223 scVar -- Var parameter (fortranpascal)
224 scCommon -- common variable
225 scSCommon -- small common
226 scVarRegister -- Var parameter in a register
227 scVariant -- Variant record
228 scSUndefined -- small undefined(external) data
229 scInit -- .init section symbol
231 5) index: pointer to a local symbol or aux. entry.
235 For the following program:
240 printf("Hello World!\n");
244 Mips-tdump produces the following information:
249 timestamp 645311799, Wed Jun 13 17:16:39 1990
250 symbolic header offset 284
251 symbolic header size 96
255 Symbolic header, magic number = 0x7009, vstamp = 1.31:
257 Info Offset Number Bytes
258 ==== ====== ====== =====
260 Line numbers 380 4 4 [13]
262 Procedures Tables 384 1 52
263 Local Symbols 436 16 192
264 Optimization Symbols 0 0 0
265 Auxiliary Symbols 628 39 156
266 Local Strings 784 80 80
267 External Strings 864 144 144
268 File Tables 1008 2 144
270 External Symbols 1152 20 320
274 Name index = 1 Readin = No
275 Merge = No Endian = LITTLE
276 Debug level = G2 Language = C
279 Info Start Number Size Offset
280 ==== ===== ====== ==== ======
281 Local strings 0 15 15 784
282 Local symbols 0 6 72 436
283 Line numbers 0 13 13 380
284 Optimization symbols 0 0 0 0
285 Procedures 0 1 52 384
286 Auxiliary symbols 0 14 56 628
287 Relative Files 0 0 0 0
289 There are 6 local symbols, starting at 436
291 Symbol# 0: "hello2.c"
294 Storage class = Text Index = 6
295 Symbol type = File Value = 0
301 Storage class = Text Index = 12
302 Symbol type = Proc Value = 0
307 Storage class = Text Index = 4
308 Symbol type = Block Value = 8
313 Storage class = Text Index = 2
314 Symbol type = End Value = 28
319 Storage class = Text Index = 1
320 Symbol type = End Value = 52
322 Symbol# 5: "hello2.c"
325 Storage class = Text Index = 0
326 Symbol type = End Value = 0
328 There are 14 auxiliary table entries, starting at 628.
330 * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
331 * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
332 * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0]
333 * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0]
334 * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
335 * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0]
336 * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0]
337 * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0]
338 * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0]
339 * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0]
340 * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0]
341 * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0]
342 #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0]
343 #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
345 There are 1 procedure descriptor entries, starting at 0.
347 Procedure descriptor 0:
348 Name index = 10 Name = "main"
349 .mask 0x80000000,-4 .fmask 0x00000000,0
351 Opt. start = -1 Symbols start = 1
352 First line # = 3 Last line # = 6
353 Line Offset = 0 Address = 0x00000000
355 There are 4 bytes holding line numbers, starting at 380.
356 Line 3, delta 0, count 2
357 Line 4, delta 1, count 3
358 Line 5, delta 1, count 2
359 Line 6, delta 1, count 6
361 File #1, "/usr/include/stdio.h"
363 Name index = 1 Readin = No
364 Merge = Yes Endian = LITTLE
365 Debug level = G2 Language = C
368 Info Start Number Size Offset
369 ==== ===== ====== ==== ======
370 Local strings 15 65 65 799
371 Local symbols 6 10 120 508
372 Line numbers 0 0 0 380
373 Optimization symbols 0 0 0 0
375 Auxiliary symbols 14 25 100 684
376 Relative Files 0 0 0 0
378 There are 10 local symbols, starting at 442
380 Symbol# 0: "/usr/include/stdio.h"
383 Storage class = Text Index = 10
384 Symbol type = File Value = 0
389 Storage class = Info Index = 9
390 Symbol type = Block Value = 20
395 Storage class = Info Index = 4
396 Symbol type = Member Value = 0
401 Storage class = Info Index = 15
402 Symbol type = Member Value = 32
407 Storage class = Info Index = 16
408 Symbol type = Member Value = 64
413 Storage class = Info Index = 4
414 Symbol type = Member Value = 96
419 Storage class = Info Index = 3
420 Symbol type = Member Value = 128
425 Storage class = Info Index = 2
426 Symbol type = Member Value = 144
431 Storage class = Info Index = 1
432 Symbol type = End Value = 0
434 Symbol# 9: "/usr/include/stdio.h"
437 Storage class = Text Index = 0
438 Symbol type = End Value = 0
440 There are 25 auxiliary table entries, starting at 642.
442 * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
443 #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
444 #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
445 * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0]
446 * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1]
447 * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
448 * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4]
449 * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
450 * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
451 * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0]
452 * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0]
453 * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
454 * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
455 * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
456 * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
457 * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
458 * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
459 * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
460 * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
461 * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
462 * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
463 * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
464 * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
465 * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
466 * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
468 There are 0 procedure descriptor entries, starting at 1.
470 There are 20 external symbols, starting at 1152
473 Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
474 String index = 0 Ifd = 1
475 Storage class = Nil Index = 17
476 Symbol type = Global Value = 60
479 String index = 5 Ifd = 1
480 Storage class = Nil Index = 1048575
481 Symbol type = Proc Value = 0
484 String index = 11 Ifd = 1
485 Storage class = Nil Index = 1048575
486 Symbol type = Proc Value = 0
489 String index = 18 Ifd = 1
490 Storage class = Nil Index = 1048575
491 Symbol type = Proc Value = 0
494 String index = 26 Ifd = 1
495 Storage class = Nil Index = 1048575
496 Symbol type = Proc Value = 0
499 String index = 32 Ifd = 1
500 Storage class = Nil Index = 1048575
501 Symbol type = Proc Value = 0
504 String index = 40 Ifd = 1
505 Storage class = Nil Index = 1048575
506 Symbol type = Proc Value = 0
509 String index = 46 Ifd = 1
510 Storage class = Nil Index = 1048575
511 Symbol type = Proc Value = 0
514 String index = 53 Ifd = 1
515 Storage class = Nil Index = 1048575
516 Symbol type = Proc Value = 0
518 Symbol# 9: "setbuffer"
519 String index = 60 Ifd = 1
520 Storage class = Nil Index = 1048575
521 Symbol type = Proc Value = 0
523 Symbol# 10: "setlinebuf"
524 String index = 70 Ifd = 1
525 Storage class = Nil Index = 1048575
526 Symbol type = Proc Value = 0
529 String index = 81 Ifd = 1
530 Storage class = Nil Index = 1048575
531 Symbol type = Proc Value = 0
534 String index = 87 Ifd = 1
535 Storage class = Nil Index = 1048575
536 Symbol type = Proc Value = 0
538 Symbol# 13: "ctermid"
539 String index = 92 Ifd = 1
540 Storage class = Nil Index = 1048575
541 Symbol type = Proc Value = 0
543 Symbol# 14: "cuserid"
544 String index = 100 Ifd = 1
545 Storage class = Nil Index = 1048575
546 Symbol type = Proc Value = 0
548 Symbol# 15: "tempnam"
549 String index = 108 Ifd = 1
550 Storage class = Nil Index = 1048575
551 Symbol type = Proc Value = 0
554 String index = 116 Ifd = 1
555 Storage class = Nil Index = 1048575
556 Symbol type = Proc Value = 0
558 Symbol# 17: "sprintf"
559 String index = 123 Ifd = 1
560 Storage class = Nil Index = 1048575
561 Symbol type = Proc Value = 0
565 String index = 131 Ifd = 0
566 Storage class = Text Index = 1
567 Symbol type = Proc Value = 0
570 String index = 136 Ifd = 0
571 Storage class = Undefined Index = 1048575
572 Symbol type = Proc Value = 0
574 The following auxiliary table entries were unused:
578 #3 16 0x00000010 short
580 #5 32 0x00000020 long
581 #6 40 0x00000028 float
582 #7 44 0x0000002c double
583 #8 12 0x0000000c unsigned char
584 #9 20 0x00000014 unsigned short
585 #10 28 0x0000001c unsigned int
586 #11 36 0x00000024 unsigned long
587 #14 0 0x00000000 void
588 #15 24 0x00000018 int
589 #19 32 0x00000020 long
590 #20 40 0x00000028 float
591 #21 44 0x0000002c double
592 #22 12 0x0000000c unsigned char
593 #23 20 0x00000014 unsigned short
594 #24 28 0x0000001c unsigned int
595 #25 36 0x00000024 unsigned long
596 #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 }
604 #include "gvarargs.h"
619 typedef const void *CPTR_T
;
621 #define VPROTO(ARGS) ARGS
622 #define VA_START(va_list,var) va_start(va_list,var)
625 #if defined(_STDIO_H_) || defined(__STDIO_H__) /* Ultrix 4.0, SGI */
627 typedef void *CPTR_T
;
630 typedef char *PTR_T
; /* Ultrix 3.1 */
631 typedef char *CPTR_T
;
634 #define __proto(x) ()
636 #define VPROTO(ARGS) (va_alist) va_dcl
637 #define VA_START(va_list,var) va_start(va_list)
640 /* Do to size_t being defined in sys/types.h and different
641 in stddef.h, we have to do this by hand..... Note, these
642 types are correct for MIPS based systems, and may not be
643 correct for other systems. Ultrix 4.0 and Silicon Graphics
644 have this fixed, but since the following is correct, and
645 the fact that including stddef.h gets you GCC's version
646 instead of the standard one it's not worth it to fix it. */
648 #if defined(__OSF1__) || defined(__OSF__) || defined(__osf__)
649 #define Size_t long unsigned int
651 #define Size_t unsigned int
653 #define Ptrdiff_t long
655 /* The following might be called from obstack or malloc,
656 so they can't be static. */
658 extern void pfatal_with_name
660 extern void fancy_abort
__proto((void));
661 void botch
__proto((const char *));
662 extern PTR_T xmalloc
__proto((Size_t
));
663 extern PTR_T xcalloc
__proto((Size_t
, Size_t
));
664 extern PTR_T xrealloc
__proto((PTR_T
, Size_t
));
665 extern void xfree
__proto((PTR_T
));
668 extern void fatal
__proto((char *format
, ...));
669 extern void error
__proto((char *format
, ...));
671 /* We must not provide any prototype here, even if ANSI C. */
672 extern void fatal
__proto(());
673 extern void error
__proto(());
677 #ifndef MIPS_DEBUGGING_INFO
679 static int line_number
;
680 static int cur_line_start
;
682 static int had_errors
;
683 static char *progname
;
684 static char *input_name
;
689 fprintf (stderr
, "Mips-tfile should only be run on a MIPS computer!\n");
693 #else /* MIPS_DEBUGGING defined */
695 /* The local and global symbols have a field index, so undo any defines
696 of index -> strchr and rindex -> strrchr. */
701 #include <sys/types.h>
707 #include <sys/stat.h>
709 #ifndef CROSS_COMPILE
712 #include "mips/a.out.h"
713 #endif /* CROSS_COMPILE */
715 #if defined (USG) || defined (NO_STAB_H)
716 #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */
718 #include <stab.h> /* On BSD, use the system's stab.h. */
722 #define STAB_CODE_TYPE enum __stab_debug_code
724 #define STAB_CODE_TYPE int
741 extern int errno
; /* MIPS errno.h doesn't declare this */
750 #define IS_ASM_IDENT(ch) \
751 (isalnum (ch) || (ch) == '_' || (ch) == '.' || (ch) == '$')
754 /* Redefinition of of storage classes as an enumeration for better
758 sc_Nil
= scNil
, /* no storage class */
759 sc_Text
= scText
, /* text symbol */
760 sc_Data
= scData
, /* initialized data symbol */
761 sc_Bss
= scBss
, /* un-initialized data symbol */
762 sc_Register
= scRegister
, /* value of symbol is register number */
763 sc_Abs
= scAbs
, /* value of symbol is absolute */
764 sc_Undefined
= scUndefined
, /* who knows? */
765 sc_CdbLocal
= scCdbLocal
, /* variable's value is IN se->va.?? */
766 sc_Bits
= scBits
, /* this is a bit field */
767 sc_CdbSystem
= scCdbSystem
, /* value is IN CDB's address space */
768 sc_RegImage
= scRegImage
, /* register value saved on stack */
769 sc_Info
= scInfo
, /* symbol contains debugger information */
770 sc_UserStruct
= scUserStruct
, /* addr in struct user for current process */
771 sc_SData
= scSData
, /* load time only small data */
772 sc_SBss
= scSBss
, /* load time only small common */
773 sc_RData
= scRData
, /* load time only read only data */
774 sc_Var
= scVar
, /* Var parameter (fortran,pascal) */
775 sc_Common
= scCommon
, /* common variable */
776 sc_SCommon
= scSCommon
, /* small common */
777 sc_VarRegister
= scVarRegister
, /* Var parameter in a register */
778 sc_Variant
= scVariant
, /* Variant record */
779 sc_SUndefined
= scSUndefined
, /* small undefined(external) data */
780 sc_Init
= scInit
, /* .init section symbol */
781 sc_Max
= scMax
/* Max storage class+1 */
784 /* Redefinition of symbol type. */
787 st_Nil
= stNil
, /* Nuthin' special */
788 st_Global
= stGlobal
, /* external symbol */
789 st_Static
= stStatic
, /* static */
790 st_Param
= stParam
, /* procedure argument */
791 st_Local
= stLocal
, /* local variable */
792 st_Label
= stLabel
, /* label */
793 st_Proc
= stProc
, /* " " Procedure */
794 st_Block
= stBlock
, /* beginning of block */
795 st_End
= stEnd
, /* end (of anything) */
796 st_Member
= stMember
, /* member (of anything - struct/union/enum */
797 st_Typedef
= stTypedef
, /* type definition */
798 st_File
= stFile
, /* file name */
799 st_RegReloc
= stRegReloc
, /* register relocation */
800 st_Forward
= stForward
, /* forwarding address */
801 st_StaticProc
= stStaticProc
, /* load time only static procs */
802 st_Constant
= stConstant
, /* const */
803 st_Str
= stStr
, /* string */
804 st_Number
= stNumber
, /* pure number (ie. 4 NOR 2+2) */
805 st_Expr
= stExpr
, /* 2+2 vs. 4 */
806 st_Type
= stType
, /* post-coercion SER */
807 st_Max
= stMax
/* max type+1 */
810 /* Redefinition of type qualifiers. */
813 tq_Nil
= tqNil
, /* bt is what you see */
814 tq_Ptr
= tqPtr
, /* pointer */
815 tq_Proc
= tqProc
, /* procedure */
816 tq_Array
= tqArray
, /* duh */
817 tq_Far
= tqFar
, /* longer addressing - 8086/8 land */
818 tq_Vol
= tqVol
, /* volatile */
819 tq_Max
= tqMax
/* Max type qualifier+1 */
822 /* Redefinition of basic types. */
825 bt_Nil
= btNil
, /* undefined */
826 bt_Adr
= btAdr
, /* address - integer same size as pointer */
827 bt_Char
= btChar
, /* character */
828 bt_UChar
= btUChar
, /* unsigned character */
829 bt_Short
= btShort
, /* short */
830 bt_UShort
= btUShort
, /* unsigned short */
831 bt_Int
= btInt
, /* int */
832 bt_UInt
= btUInt
, /* unsigned int */
833 bt_Long
= btLong
, /* long */
834 bt_ULong
= btULong
, /* unsigned long */
835 bt_Float
= btFloat
, /* float (real) */
836 bt_Double
= btDouble
, /* Double (real) */
837 bt_Struct
= btStruct
, /* Structure (Record) */
838 bt_Union
= btUnion
, /* Union (variant) */
839 bt_Enum
= btEnum
, /* Enumerated */
840 bt_Typedef
= btTypedef
, /* defined via a typedef, isymRef points */
841 bt_Range
= btRange
, /* subrange of int */
842 bt_Set
= btSet
, /* pascal sets */
843 bt_Complex
= btComplex
, /* fortran complex */
844 bt_DComplex
= btDComplex
, /* fortran double complex */
845 bt_Indirect
= btIndirect
, /* forward or unnamed typedef */
846 bt_FixedDec
= btFixedDec
, /* Fixed Decimal */
847 bt_FloatDec
= btFloatDec
, /* Float Decimal */
848 bt_String
= btString
, /* Varying Length Character String */
849 bt_Bit
= btBit
, /* Aligned Bit String */
850 bt_Picture
= btPicture
, /* Picture */
853 bt_Void
= btVoid
, /* Void */
855 #define bt_Void bt_Nil
858 bt_Max
= btMax
/* Max basic type+1 */
863 /* Basic COFF storage classes. */
895 /* Regular COFF fundamental type. */
896 typedef enum coff_type
{
916 /* Regular COFF derived types. */
917 typedef enum coff_dt
{
925 #define N_BTMASK 017 /* bitmask to isolate basic type */
926 #define N_TMASK 003 /* bitmask to isolate derived type */
927 #define N_BT_SHIFT 4 /* # bits to shift past basic type */
928 #define N_TQ_SHIFT 2 /* # bits to shift derived types */
929 #define N_TQ 6 /* # of type qualifiers */
931 /* States for whether to hash type or not. */
932 typedef enum hash_state
{
933 hash_no
= 0, /* don't hash type */
934 hash_yes
= 1, /* ok to hash type, or use previous hash */
935 hash_record
= 2 /* ok to record hash, but don't use prev. */
939 /* Types of different sized allocation requests. */
941 alloc_type_none
, /* dummy value */
942 alloc_type_scope
, /* nested scopes linked list */
943 alloc_type_vlinks
, /* glue linking pages in varray */
944 alloc_type_shash
, /* string hash element */
945 alloc_type_thash
, /* type hash element */
946 alloc_type_tag
, /* struct/union/tag element */
947 alloc_type_forward
, /* element to hold unknown tag */
948 alloc_type_thead
, /* head of type hash list */
949 alloc_type_varray
, /* general varray allocation */
950 alloc_type_last
/* last+1 element for array bounds */
954 #define WORD_ALIGN(x) (((x) + (sizeof (long) - 1)) & ~ (sizeof (long) - 1))
955 #define DWORD_ALIGN(x) (((x) + 7) & ~7)
958 /* Structures to provide n-number of virtual arrays, each of which can
959 grow linearly, and which are written in the object file as sequential
960 pages. On systems with a BSD malloc that define USE_MALLOC, the
961 MAX_CLUSTER_PAGES should be 1 less than a power of two, since malloc
962 adds it's overhead, and rounds up to the next power of 2. Pages are
963 linked together via a linked list.
965 If PAGE_SIZE is > 4096, the string length in the shash_t structure
966 can't be represented (assuming there are strings > 4096 bytes). */
969 #define PAGE_SIZE 4096 /* size of varray pages */
972 #define PAGE_USIZE ((Size_t)PAGE_SIZE)
975 #ifndef MAX_CLUSTER_PAGES /* # pages to get from system */
976 #ifndef USE_MALLOC /* in one memory request */
977 #define MAX_CLUSTER_PAGES 64
979 #define MAX_CLUSTER_PAGES 63
984 /* Linked list connecting separate page allocations. */
985 typedef struct vlinks
{
986 struct vlinks
*prev
; /* previous set of pages */
987 struct vlinks
*next
; /* next set of pages */
988 union page
*datum
; /* start of page */
989 unsigned long start_index
; /* starting index # of page */
993 /* Virtual array header. */
994 typedef struct varray
{
995 vlinks_t
*first
; /* first page link */
996 vlinks_t
*last
; /* last page link */
997 unsigned long num_allocated
; /* # objects allocated */
998 unsigned short object_size
; /* size in bytes of each object */
999 unsigned short objects_per_page
; /* # objects that can fit on a page */
1000 unsigned short objects_last_page
; /* # objects allocated on last page */
1003 #ifndef MALLOC_CHECK
1004 #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
1006 #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
1009 #define INIT_VARRAY(type) { /* macro to initialize a varray */ \
1010 (vlinks_t *)0, /* first */ \
1011 (vlinks_t *)0, /* last */ \
1012 0, /* num_allocated */ \
1013 sizeof (type), /* object_size */ \
1014 OBJECTS_PER_PAGE (type), /* objects_per_page */ \
1015 OBJECTS_PER_PAGE (type), /* objects_last_page */ \
1018 /* Master type for indexes within the symbol table. */
1019 typedef unsigned long symint_t
;
1022 /* Linked list support for nested scopes (file, block, structure, etc.). */
1023 typedef struct scope
{
1024 struct scope
*prev
; /* previous scope level */
1025 struct scope
*free
; /* free list pointer */
1026 SYMR
*lsym
; /* pointer to local symbol node */
1027 symint_t lnumber
; /* lsym index */
1028 st_t type
; /* type of the node */
1032 /* Forward reference list for tags referenced, but not yet defined. */
1033 typedef struct forward
{
1034 struct forward
*next
; /* next forward reference */
1035 struct forward
*free
; /* free list pointer */
1036 AUXU
*ifd_ptr
; /* pointer to store file index */
1037 AUXU
*index_ptr
; /* pointer to store symbol index */
1038 AUXU
*type_ptr
; /* pointer to munge type info */
1042 /* Linked list support for tags. The first tag in the list is always
1043 the current tag for that block. */
1044 typedef struct tag
{
1045 struct tag
*free
; /* free list pointer */
1046 struct shash
*hash_ptr
; /* pointer to the hash table head */
1047 struct tag
*same_name
; /* tag with same name in outer scope */
1048 struct tag
*same_block
; /* next tag defined in the same block. */
1049 struct forward
*forward_ref
; /* list of forward references */
1050 bt_t basic_type
; /* bt_Struct, bt_Union, or bt_Enum */
1051 symint_t ifd
; /* file # tag defined in */
1052 symint_t indx
; /* index within file's local symbols */
1056 /* Head of a block's linked list of tags. */
1057 typedef struct thead
{
1058 struct thead
*prev
; /* previous block */
1059 struct thead
*free
; /* free list pointer */
1060 struct tag
*first_tag
; /* first tag in block defined */
1064 /* Union containing pointers to each the small structures which are freed up. */
1065 typedef union small_free
{
1066 scope_t
*f_scope
; /* scope structure */
1067 thead_t
*f_thead
; /* tag head structure */
1068 tag_t
*f_tag
; /* tag element structure */
1069 forward_t
*f_forward
; /* forward tag reference */
1073 /* String hash table support. The size of the hash table must fit
1077 #define SHASH_SIZE 1009
1080 #define HASH_LEN_MAX ((1 << 12) - 1) /* Max length we can store */
1082 typedef struct shash
{
1083 struct shash
*next
; /* next hash value */
1084 char *string
; /* string we are hashing */
1085 symint_t len
; /* string length */
1086 symint_t indx
; /* index within string table */
1087 EXTR
*esym_ptr
; /* global symbol pointer */
1088 SYMR
*sym_ptr
; /* local symbol pointer */
1089 SYMR
*end_ptr
; /* symbol pointer to end block */
1090 tag_t
*tag_ptr
; /* tag pointer */
1091 PDR
*proc_ptr
; /* procedure descriptor pointer */
1095 /* Type hash table support. The size of the hash table must fit
1096 within a page with the other extended file descriptor information.
1097 Because unique types which are hashed are fewer in number than
1098 strings, we use a smaller hash value. */
1101 #define THASH_SIZE 113
1104 typedef struct thash
{
1105 struct thash
*next
; /* next hash value */
1106 AUXU type
; /* type we are hashing */
1107 symint_t indx
; /* index within string table */
1111 /* Extended file descriptor that contains all of the support necessary
1112 to add things to each file separately. */
1113 typedef struct efdr
{
1114 FDR fdr
; /* File header to be written out */
1115 FDR
*orig_fdr
; /* original file header */
1116 char *name
; /* filename */
1117 int name_len
; /* length of the filename */
1118 symint_t void_type
; /* aux. pointer to 'void' type */
1119 symint_t int_type
; /* aux. pointer to 'int' type */
1120 scope_t
*cur_scope
; /* current nested scopes */
1121 symint_t file_index
; /* current file number */
1122 int nested_scopes
; /* # nested scopes */
1123 varray_t strings
; /* local strings */
1124 varray_t symbols
; /* local symbols */
1125 varray_t procs
; /* procedures */
1126 varray_t aux_syms
; /* auxiliary symbols */
1127 struct efdr
*next_file
; /* next file descriptor */
1128 /* string/type hash tables */
1129 shash_t
**shash_head
; /* string hash table */
1130 thash_t
*thash_head
[THASH_SIZE
];
1133 /* Pre-initialized extended file structure. */
1134 static efdr_t init_file
=
1136 { /* FDR structure */
1137 0, /* adr: memory address of beginning of file */
1138 0, /* rss: file name (of source, if known) */
1139 0, /* issBase: file's string space */
1140 0, /* cbSs: number of bytes in the ss */
1141 0, /* isymBase: beginning of symbols */
1142 0, /* csym: count file's of symbols */
1143 0, /* ilineBase: file's line symbols */
1144 0, /* cline: count of file's line symbols */
1145 0, /* ioptBase: file's optimization entries */
1146 0, /* copt: count of file's optimization entries */
1147 0, /* ipdFirst: start of procedures for this file */
1148 0, /* cpd: count of procedures for this file */
1149 0, /* iauxBase: file's auxiliary entries */
1150 0, /* caux: count of file's auxiliary entries */
1151 0, /* rfdBase: index into the file indirect table */
1152 0, /* crfd: count file indirect entries */
1153 langC
, /* lang: language for this file */
1154 1, /* fMerge: whether this file can be merged */
1155 0, /* fReadin: true if read in (not just created) */
1156 #if BYTES_BIG_ENDIAN
1157 1, /* fBigendian: if 1, compiled on big endian machine */
1159 0, /* fBigendian: if 1, compiled on big endian machine */
1161 GLEVEL_2
, /* glevel: level this file was compiled with */
1162 0, /* reserved: reserved for future use */
1163 0, /* cbLineOffset: byte offset from header for this file ln's */
1164 0, /* cbLine: size of lines for this file */
1167 (FDR
*)0, /* orig_fdr: original file header pointer */
1168 (char *)0, /* name: pointer to filename */
1169 0, /* name_len: length of filename */
1170 0, /* void_type: ptr to aux node for void type */
1171 0, /* int_type: ptr to aux node for int type */
1172 (scope_t
*)0, /* cur_scope: current scope being processed */
1173 0, /* file_index: current file # */
1174 0, /* nested_scopes: # nested scopes */
1175 INIT_VARRAY (char), /* strings: local string varray */
1176 INIT_VARRAY (SYMR
), /* symbols: local symbols varray */
1177 INIT_VARRAY (PDR
), /* procs: procedure varray */
1178 INIT_VARRAY (AUXU
), /* aux_syms: auxiliary symbols varray */
1180 (struct efdr
*)0, /* next_file: next file structure */
1182 (shash_t
**)0, /* shash_head: string hash table */
1183 { 0 }, /* thash_head: type hash table */
1187 static efdr_t
*first_file
; /* first file descriptor */
1188 static efdr_t
**last_file_ptr
= &first_file
; /* file descriptor tail */
1191 /* Union of various things that are held in pages. */
1192 typedef union page
{
1193 char byte
[ PAGE_SIZE
];
1194 unsigned char ubyte
[ PAGE_SIZE
];
1195 efdr_t file
[ PAGE_SIZE
/ sizeof (efdr_t
) ];
1196 FDR ofile
[ PAGE_SIZE
/ sizeof (FDR
) ];
1197 PDR proc
[ PAGE_SIZE
/ sizeof (PDR
) ];
1198 SYMR sym
[ PAGE_SIZE
/ sizeof (SYMR
) ];
1199 EXTR esym
[ PAGE_SIZE
/ sizeof (EXTR
) ];
1200 AUXU aux
[ PAGE_SIZE
/ sizeof (AUXU
) ];
1201 DNR dense
[ PAGE_SIZE
/ sizeof (DNR
) ];
1202 scope_t scope
[ PAGE_SIZE
/ sizeof (scope_t
) ];
1203 vlinks_t vlinks
[ PAGE_SIZE
/ sizeof (vlinks_t
) ];
1204 shash_t shash
[ PAGE_SIZE
/ sizeof (shash_t
) ];
1205 thash_t thash
[ PAGE_SIZE
/ sizeof (thash_t
) ];
1206 tag_t tag
[ PAGE_SIZE
/ sizeof (tag_t
) ];
1207 forward_t forward
[ PAGE_SIZE
/ sizeof (forward_t
) ];
1208 thead_t thead
[ PAGE_SIZE
/ sizeof (thead_t
) ];
1212 /* Structure holding allocation information for small sized structures. */
1213 typedef struct alloc_info
{
1214 char *alloc_name
; /* name of this allocation type (must be first) */
1215 page_t
*cur_page
; /* current page being allocated from */
1216 small_free_t free_list
; /* current free list if any */
1217 int unallocated
; /* number of elements unallocated on page */
1218 int total_alloc
; /* total number of allocations */
1219 int total_free
; /* total number of frees */
1220 int total_pages
; /* total number of pages allocated */
1223 /* Type information collected together. */
1224 typedef struct type_info
{
1225 bt_t basic_type
; /* basic type */
1226 coff_type_t orig_type
; /* original COFF-based type */
1227 int num_tq
; /* # type qualifiers */
1228 int num_dims
; /* # dimensions */
1229 int num_sizes
; /* # sizes */
1230 int extra_sizes
; /* # extra sizes not tied with dims */
1231 tag_t
* tag_ptr
; /* tag pointer */
1232 int bitfield
; /* symbol is a bitfield */
1233 int unknown_tag
; /* this is an unknown tag */
1234 tq_t type_qualifiers
[N_TQ
]; /* type qualifiers (ptr, func, array)*/
1235 symint_t dimensions
[N_TQ
]; /* dimensions for each array */
1236 symint_t sizes
[N_TQ
+2]; /* sizes of each array slice + size of
1237 struct/union/enum + bitfield size */
1240 /* Pre-initialized type_info struct. */
1241 static type_info_t type_info_init
= {
1242 bt_Nil
, /* basic type */
1243 T_NULL
, /* original COFF-based type */
1244 0, /* # type qualifiers */
1245 0, /* # dimensions */
1247 0, /* sizes not tied with dims */
1248 NULL
, /* ptr to tag */
1250 0, /* unknown tag */
1251 { /* type qualifiers */
1280 /* Global virtual arrays & hash table for external strings as well as
1281 for the tags table and global tables for file descriptors, and
1284 static varray_t file_desc
= INIT_VARRAY (efdr_t
);
1285 static varray_t dense_num
= INIT_VARRAY (DNR
);
1286 static varray_t tag_strings
= INIT_VARRAY (char);
1287 static varray_t ext_strings
= INIT_VARRAY (char);
1288 static varray_t ext_symbols
= INIT_VARRAY (EXTR
);
1290 static shash_t
*orig_str_hash
[SHASH_SIZE
];
1291 static shash_t
*ext_str_hash
[SHASH_SIZE
];
1292 static shash_t
*tag_hash
[SHASH_SIZE
];
1294 /* Static types for int and void. Also, remember the last function's
1295 type (which is set up when we encounter the declaration for the
1296 function, and used when the end block for the function is emitted. */
1298 static type_info_t int_type_info
;
1299 static type_info_t void_type_info
;
1300 static type_info_t last_func_type_info
;
1301 static EXTR
*last_func_eptr
;
1304 /* Convert COFF basic type to ECOFF basic type. The T_NULL type
1305 really should use bt_Void, but this causes the current ecoff GDB to
1306 issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
1307 2.0) doesn't understand it, even though the compiler generates it.
1308 Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
1309 suite, but for now go with what works. */
1311 static bt_t map_coff_types
[ (int)T_MAX
] = {
1312 bt_Nil
, /* T_NULL */
1314 bt_Char
, /* T_CHAR */
1315 bt_Short
, /* T_SHORT */
1317 bt_Long
, /* T_LONG */
1318 bt_Float
, /* T_FLOAT */
1319 bt_Double
, /* T_DOUBLE */
1320 bt_Struct
, /* T_STRUCT */
1321 bt_Union
, /* T_UNION */
1322 bt_Enum
, /* T_ENUM */
1323 bt_Enum
, /* T_MOE */
1324 bt_UChar
, /* T_UCHAR */
1325 bt_UShort
, /* T_USHORT */
1326 bt_UInt
, /* T_UINT */
1327 bt_ULong
/* T_ULONG */
1330 /* Convert COFF storage class to ECOFF storage class. */
1331 static sc_t map_coff_storage
[ (int)C_MAX
] = {
1332 sc_Nil
, /* 0: C_NULL */
1333 sc_Abs
, /* 1: C_AUTO auto var */
1334 sc_Undefined
, /* 2: C_EXT external */
1335 sc_Data
, /* 3: C_STAT static */
1336 sc_Register
, /* 4: C_REG register */
1337 sc_Undefined
, /* 5: C_EXTDEF ??? */
1338 sc_Text
, /* 6: C_LABEL label */
1339 sc_Text
, /* 7: C_ULABEL user label */
1340 sc_Info
, /* 8: C_MOS member of struct */
1341 sc_Abs
, /* 9: C_ARG argument */
1342 sc_Info
, /* 10: C_STRTAG struct tag */
1343 sc_Info
, /* 11: C_MOU member of union */
1344 sc_Info
, /* 12: C_UNTAG union tag */
1345 sc_Info
, /* 13: C_TPDEF typedef */
1346 sc_Data
, /* 14: C_USTATIC ??? */
1347 sc_Info
, /* 15: C_ENTAG enum tag */
1348 sc_Info
, /* 16: C_MOE member of enum */
1349 sc_Register
, /* 17: C_REGPARM register parameter */
1350 sc_Bits
, /* 18; C_FIELD bitfield */
1432 sc_Text
, /* 100: C_BLOCK block start/end */
1433 sc_Text
, /* 101: C_FCN function start/end */
1434 sc_Info
, /* 102: C_EOS end of struct/union/enum */
1435 sc_Nil
, /* 103: C_FILE file start */
1436 sc_Nil
, /* 104: C_LINE line number */
1437 sc_Nil
, /* 105: C_ALIAS combined type info */
1438 sc_Nil
, /* 106: C_HIDDEN ??? */
1441 /* Convert COFF storage class to ECOFF symbol type. */
1442 static st_t map_coff_sym_type
[ (int)C_MAX
] = {
1443 st_Nil
, /* 0: C_NULL */
1444 st_Local
, /* 1: C_AUTO auto var */
1445 st_Global
, /* 2: C_EXT external */
1446 st_Static
, /* 3: C_STAT static */
1447 st_Local
, /* 4: C_REG register */
1448 st_Global
, /* 5: C_EXTDEF ??? */
1449 st_Label
, /* 6: C_LABEL label */
1450 st_Label
, /* 7: C_ULABEL user label */
1451 st_Member
, /* 8: C_MOS member of struct */
1452 st_Param
, /* 9: C_ARG argument */
1453 st_Block
, /* 10: C_STRTAG struct tag */
1454 st_Member
, /* 11: C_MOU member of union */
1455 st_Block
, /* 12: C_UNTAG union tag */
1456 st_Typedef
, /* 13: C_TPDEF typedef */
1457 st_Static
, /* 14: C_USTATIC ??? */
1458 st_Block
, /* 15: C_ENTAG enum tag */
1459 st_Member
, /* 16: C_MOE member of enum */
1460 st_Param
, /* 17: C_REGPARM register parameter */
1461 st_Member
, /* 18; C_FIELD bitfield */
1543 st_Block
, /* 100: C_BLOCK block start/end */
1544 st_Proc
, /* 101: C_FCN function start/end */
1545 st_End
, /* 102: C_EOS end of struct/union/enum */
1546 st_File
, /* 103: C_FILE file start */
1547 st_Nil
, /* 104: C_LINE line number */
1548 st_Nil
, /* 105: C_ALIAS combined type info */
1549 st_Nil
, /* 106: C_HIDDEN ??? */
1552 /* Map COFF derived types to ECOFF type qualifiers. */
1553 static tq_t map_coff_derived_type
[ (int)DT_MAX
] = {
1554 tq_Nil
, /* 0: DT_NON no more qualifiers */
1555 tq_Ptr
, /* 1: DT_PTR pointer */
1556 tq_Proc
, /* 2: DT_FCN function */
1557 tq_Array
, /* 3: DT_ARY array */
1561 /* Keep track of different sized allocation requests. */
1562 static alloc_info_t alloc_counts
[ (int)alloc_type_last
];
1565 /* Pointers and such to the original symbol table that is read in. */
1566 static struct filehdr orig_file_header
; /* global object file header */
1568 static HDRR orig_sym_hdr
; /* symbolic header on input */
1569 static char *orig_linenum
; /* line numbers */
1570 static DNR
*orig_dense
; /* dense numbers */
1571 static PDR
*orig_procs
; /* procedures */
1572 static SYMR
*orig_local_syms
; /* local symbols */
1573 static OPTR
*orig_opt_syms
; /* optimization symbols */
1574 static AUXU
*orig_aux_syms
; /* auxiliary symbols */
1575 static char *orig_local_strs
; /* local strings */
1576 static char *orig_ext_strs
; /* external strings */
1577 static FDR
*orig_files
; /* file descriptors */
1578 static symint_t
*orig_rfds
; /* relative file desc's */
1579 static EXTR
*orig_ext_syms
; /* external symbols */
1581 /* Macros to convert an index into a given object within the original
1583 #define CHECK(num,max,str) \
1584 (((unsigned long)num > (unsigned long)max) ? out_of_bounds (num, max, str, __LINE__) : 0)
1586 #define ORIG_LINENUM(indx) (CHECK ((indx), orig_sym_hdr.cbLine, "line#"), (indx) + orig_linenum)
1587 #define ORIG_DENSE(indx) (CHECK ((indx), orig_sym_hdr.idnMax, "dense"), (indx) + orig_dense)
1588 #define ORIG_PROCS(indx) (CHECK ((indx), orig_sym_hdr.ipdMax, "procs"), (indx) + orig_procs)
1589 #define ORIG_FILES(indx) (CHECK ((indx), orig_sym_hdr.ifdMax, "funcs"), (indx) + orig_files)
1590 #define ORIG_LSYMS(indx) (CHECK ((indx), orig_sym_hdr.isymMax, "lsyms"), (indx) + orig_local_syms)
1591 #define ORIG_LSTRS(indx) (CHECK ((indx), orig_sym_hdr.issMax, "lstrs"), (indx) + orig_local_strs)
1592 #define ORIG_ESYMS(indx) (CHECK ((indx), orig_sym_hdr.iextMax, "esyms"), (indx) + orig_ext_syms)
1593 #define ORIG_ESTRS(indx) (CHECK ((indx), orig_sym_hdr.issExtMax, "estrs"), (indx) + orig_ext_strs)
1594 #define ORIG_OPT(indx) (CHECK ((indx), orig_sym_hdr.ioptMax, "opt"), (indx) + orig_opt_syms)
1595 #define ORIG_AUX(indx) (CHECK ((indx), orig_sym_hdr.iauxMax, "aux"), (indx) + orig_aux_syms)
1596 #define ORIG_RFDS(indx) (CHECK ((indx), orig_sym_hdr.crfd, "rfds"), (indx) + orig_rfds)
1598 /* Various other statics. */
1599 static HDRR symbolic_header
; /* symbolic header */
1600 static efdr_t
*cur_file_ptr
= (efdr_t
*) 0; /* current file desc. header */
1601 static PDR
*cur_proc_ptr
= (PDR
*) 0; /* current procedure header */
1602 static SYMR
*cur_oproc_begin
= (SYMR
*) 0; /* original proc. sym begin info */
1603 static SYMR
*cur_oproc_end
= (SYMR
*) 0; /* original proc. sym end info */
1604 static PDR
*cur_oproc_ptr
= (PDR
*) 0; /* current original procedure*/
1605 static thead_t
*cur_tag_head
= (thead_t
*)0; /* current tag head */
1606 static long file_offset
= 0; /* current file offset */
1607 static long max_file_offset
= 0; /* maximum file offset */
1608 static FILE *object_stream
= (FILE *)0; /* file desc. to output .o */
1609 static FILE *obj_in_stream
= (FILE *)0; /* file desc. to input .o */
1610 static char *progname
= (char *)0; /* program name for errors */
1611 static char *input_name
= "stdin"; /* name of input file */
1612 static char *object_name
= (char *)0; /* tmp. name of object file */
1613 static char *obj_in_name
= (char *)0; /* name of input object file */
1614 static char *cur_line_start
= (char *)0; /* current line read in */
1615 static char *cur_line_ptr
= (char *)0; /* ptr within current line */
1616 static unsigned cur_line_nbytes
= 0; /* # bytes for current line */
1617 static unsigned cur_line_alloc
= 0; /* # bytes total in buffer */
1618 static long line_number
= 0; /* current input line number */
1619 static int debug
= 0; /* trace functions */
1620 static int version
= 0; /* print version # */
1621 static int had_errors
= 0; /* != 0 if errors were found */
1622 static int rename_output
= 0; /* != 0 if rename output file*/
1623 static int delete_input
= 0; /* != 0 if delete input after done */
1624 static int stabs_seen
= 0; /* != 0 if stabs have been seen */
1627 /* Pseudo symbol to use when putting stabs into the symbol table. */
1628 #ifndef STABS_SYMBOL
1629 #define STABS_SYMBOL "@stabs"
1632 static char stabs_symbol
[] = STABS_SYMBOL
;
1635 /* Forward reference for functions. See the definition for more details. */
1638 #define STATIC static
1641 STATIC
int out_of_bounds
__proto((symint_t
, symint_t
, const char *, int));
1643 STATIC shash_t
*hash_string
__proto((const char *,
1648 STATIC symint_t add_string
__proto((varray_t
*,
1654 STATIC symint_t add_local_symbol
1655 __proto((const char *,
1662 STATIC symint_t add_ext_symbol
__proto((const char *,
1670 STATIC symint_t add_aux_sym_symint
1671 __proto((symint_t
));
1673 STATIC symint_t add_aux_sym_rndx
1674 __proto((int, symint_t
));
1676 STATIC symint_t add_aux_sym_tir
__proto((type_info_t
*,
1680 STATIC tag_t
* get_tag
__proto((const char *,
1685 STATIC
void add_unknown_tag
__proto((tag_t
*));
1687 STATIC
void add_procedure
__proto((const char *,
1690 STATIC
void add_file
__proto((const char *,
1693 STATIC
void add_bytes
__proto((varray_t
*,
1697 STATIC
void add_varray_page
__proto((varray_t
*));
1699 STATIC
void update_headers
__proto((void));
1701 STATIC
void write_varray
__proto((varray_t
*, off_t
, const char *));
1702 STATIC
void write_object
__proto((void));
1703 STATIC
char *st_to_string
__proto((st_t
));
1704 STATIC
char *sc_to_string
__proto((sc_t
));
1705 STATIC
char *read_line
__proto((void));
1706 STATIC
void parse_input
__proto((void));
1707 STATIC
void mark_stabs
__proto((const char *));
1708 STATIC
void parse_begin
__proto((const char *));
1709 STATIC
void parse_bend
__proto((const char *));
1710 STATIC
void parse_def
__proto((const char *));
1711 STATIC
void parse_end
__proto((const char *));
1712 STATIC
void parse_ent
__proto((const char *));
1713 STATIC
void parse_file
__proto((const char *));
1714 STATIC
void parse_stabs_common
1715 __proto((const char *, const char *, const char *));
1716 STATIC
void parse_stabs
__proto((const char *));
1717 STATIC
void parse_stabn
__proto((const char *));
1718 STATIC page_t
*read_seek
__proto((Size_t
, off_t
, const char *));
1719 STATIC
void copy_object
__proto((void));
1721 STATIC
void catch_signal
__proto((int));
1722 STATIC page_t
*allocate_page
__proto((void));
1724 STATIC page_t
*allocate_multiple_pages
1727 STATIC
void free_multiple_pages
1728 __proto((page_t
*, Size_t
));
1730 #ifndef MALLOC_CHECK
1731 STATIC page_t
*allocate_cluster
1735 STATIC forward_t
*allocate_forward
__proto((void));
1736 STATIC scope_t
*allocate_scope
__proto((void));
1737 STATIC shash_t
*allocate_shash
__proto((void));
1738 STATIC tag_t
*allocate_tag
__proto((void));
1739 STATIC thash_t
*allocate_thash
__proto((void));
1740 STATIC thead_t
*allocate_thead
__proto((void));
1741 STATIC vlinks_t
*allocate_vlinks
__proto((void));
1743 STATIC
void free_forward
__proto((forward_t
*));
1744 STATIC
void free_scope
__proto((scope_t
*));
1745 STATIC
void free_tag
__proto((tag_t
*));
1746 STATIC
void free_thead
__proto((thead_t
*));
1748 STATIC
char *local_index
__proto((const char *, int));
1749 STATIC
char *local_rindex
__proto((const char *, int));
1752 extern char *sbrk
__proto((int));
1753 extern PTR_T malloc
__proto((Size_t
));
1754 extern PTR_T calloc
__proto((Size_t
, Size_t
));
1755 extern PTR_T realloc
__proto((PTR_T
, Size_t
));
1756 extern void free
__proto((PTR_T
));
1758 extern char *mktemp
__proto((char *));
1759 extern long strtol
__proto((const char *, char **, int));
1761 extern char *optarg
;
1764 extern char *version_string
;
1765 #ifndef NO_SYS_SIGLIST
1766 #ifndef DONT_DECLARE_SYS_SIGLIST
1767 extern char *sys_siglist
[NSIG
+ 1];
1771 #ifndef SEEK_SET /* Symbolic constants for the "fseek" function: */
1772 #define SEEK_SET 0 /* Set file pointer to offset */
1773 #define SEEK_CUR 1 /* Set file pointer to its current value plus offset */
1774 #define SEEK_END 2 /* Set file pointer to the size of the file plus offset */
1778 /* List of assembler pseudo ops and beginning sequences that need
1779 special actions. Someday, this should be a hash table, and such,
1780 but for now a linear list of names and calls to memcmp will
1783 typedef struct _pseudo_ops
{
1784 const char *name
; /* pseudo-op in ascii */
1785 int len
; /* length of name to compare */
1786 void (*func
) __proto((const char *)); /* function to handle line */
1789 static pseudo_ops_t pseudo_ops
[] = {
1790 { "#.def", sizeof("#.def")-1, parse_def
},
1791 { "#.begin", sizeof("#.begin")-1, parse_begin
},
1792 { "#.bend", sizeof("#.bend")-1, parse_bend
},
1793 { ".end", sizeof(".end")-1, parse_end
},
1794 { ".ent", sizeof(".ent")-1, parse_ent
},
1795 { ".file", sizeof(".file")-1, parse_file
},
1796 { "#.stabs", sizeof("#.stabs")-1, parse_stabs
},
1797 { "#.stabn", sizeof("#.stabn")-1, parse_stabn
},
1798 { ".stabs", sizeof(".stabs")-1, parse_stabs
},
1799 { ".stabn", sizeof(".stabn")-1, parse_stabn
},
1800 { "#@stabs", sizeof("#@stabs")-1, mark_stabs
},
1804 /* Add a page to a varray object. */
1807 add_varray_page (vp
)
1808 varray_t
*vp
; /* varray to add page to */
1810 vlinks_t
*new_links
= allocate_vlinks ();
1813 if (vp
->object_size
> 1)
1814 new_links
->datum
= (page_t
*) xcalloc (1, vp
->object_size
);
1817 new_links
->datum
= allocate_page ();
1819 alloc_counts
[ (int)alloc_type_varray
].total_alloc
++;
1820 alloc_counts
[ (int)alloc_type_varray
].total_pages
++;
1822 new_links
->start_index
= vp
->num_allocated
;
1823 vp
->objects_last_page
= 0;
1825 if (vp
->first
== (vlinks_t
*)0) /* first allocation? */
1826 vp
->first
= vp
->last
= new_links
;
1828 { /* 2nd or greater allocation */
1829 new_links
->prev
= vp
->last
;
1830 vp
->last
->next
= new_links
;
1831 vp
->last
= new_links
;
1836 /* Compute hash code (from tree.c) */
1841 hash_string (text
, hash_len
, hash_tbl
, ret_hash_index
)
1842 const char *text
; /* ptr to text to hash */
1843 Ptrdiff_t hash_len
; /* length of the text */
1844 shash_t
**hash_tbl
; /* hash table */
1845 symint_t
*ret_hash_index
; /* ptr to store hash index */
1847 register unsigned long hi
;
1848 register Ptrdiff_t i
;
1849 register shash_t
*ptr
;
1850 register int first_ch
= *text
;
1853 for (i
= 0; i
< hash_len
; i
++)
1854 hi
= ((hi
& 0x003fffff) * 613) + (text
[i
] & 0xff);
1856 hi
&= (1 << HASHBITS
) - 1;
1859 if (ret_hash_index
!= (symint_t
*)0)
1860 *ret_hash_index
= hi
;
1862 for (ptr
= hash_tbl
[hi
]; ptr
!= (shash_t
*)0; ptr
= ptr
->next
)
1863 if (hash_len
== ptr
->len
1864 && first_ch
== ptr
->string
[0]
1865 && memcmp ((CPTR_T
) text
, (CPTR_T
) ptr
->string
, hash_len
) == 0)
1872 /* Add a string (and null pad) to one of the string tables. A
1873 consequence of hashing strings, is that we don't let strings
1874 cross page boundaries. The extra nulls will be ignored. */
1877 add_string (vp
, hash_tbl
, start
, end_p1
, ret_hash
)
1878 varray_t
*vp
; /* string virtual array */
1879 shash_t
**hash_tbl
; /* ptr to hash table */
1880 const char *start
; /* 1st byte in string */
1881 const char *end_p1
; /* 1st byte after string */
1882 shash_t
**ret_hash
; /* return hash pointer */
1884 register Ptrdiff_t len
= end_p1
- start
;
1885 register shash_t
*hash_ptr
;
1888 if (len
>= PAGE_USIZE
)
1889 fatal ("String too big (%ld bytes)", (long) len
);
1891 hash_ptr
= hash_string (start
, len
, hash_tbl
, &hi
);
1892 if (hash_ptr
== (shash_t
*)0)
1896 if (vp
->objects_last_page
+ len
>= PAGE_USIZE
)
1899 ((vp
->num_allocated
+ PAGE_USIZE
- 1) / PAGE_USIZE
) * PAGE_USIZE
;
1900 add_varray_page (vp
);
1903 hash_ptr
= allocate_shash ();
1904 hash_ptr
->next
= hash_tbl
[hi
];
1905 hash_tbl
[hi
] = hash_ptr
;
1907 hash_ptr
->len
= len
;
1908 hash_ptr
->indx
= vp
->num_allocated
;
1909 hash_ptr
->string
= p
= & vp
->last
->datum
->byte
[ vp
->objects_last_page
];
1911 vp
->objects_last_page
+= len
+1;
1912 vp
->num_allocated
+= len
+1;
1920 if (ret_hash
!= (shash_t
**)0)
1921 *ret_hash
= hash_ptr
;
1923 return hash_ptr
->indx
;
1927 /* Add a local symbol. */
1930 add_local_symbol (str_start
, str_end_p1
, type
, storage
, value
, indx
)
1931 const char *str_start
; /* first byte in string */
1932 const char *str_end_p1
; /* first byte after string */
1933 st_t type
; /* symbol type */
1934 sc_t storage
; /* storage class */
1935 symint_t value
; /* value of symbol */
1936 symint_t indx
; /* index to local/aux. syms */
1938 register symint_t ret
;
1939 register SYMR
*psym
;
1940 register scope_t
*pscope
;
1941 register thead_t
*ptag_head
;
1942 register tag_t
*ptag
;
1943 register tag_t
*ptag_next
;
1944 register varray_t
*vp
= &cur_file_ptr
->symbols
;
1945 register int scope_delta
= 0;
1946 shash_t
*hash_ptr
= (shash_t
*)0;
1948 if (vp
->objects_last_page
== vp
->objects_per_page
)
1949 add_varray_page (vp
);
1951 psym
= &vp
->last
->datum
->sym
[ vp
->objects_last_page
++ ];
1953 psym
->value
= value
;
1954 psym
->st
= (unsigned) type
;
1955 psym
->sc
= (unsigned) storage
;
1957 psym
->iss
= (str_start
== (const char *)0)
1959 : add_string (&cur_file_ptr
->strings
,
1960 &cur_file_ptr
->shash_head
[0],
1965 ret
= vp
->num_allocated
++;
1967 if (MIPS_IS_STAB(psym
))
1970 /* Save the symbol within the hash table if this is a static
1971 item, and it has a name. */
1972 if (hash_ptr
!= (shash_t
*)0
1973 && (type
== st_Global
|| type
== st_Static
|| type
== st_Label
1974 || type
== st_Proc
|| type
== st_StaticProc
))
1975 hash_ptr
->sym_ptr
= psym
;
1977 /* push or pop a scope if appropriate. */
1983 case st_File
: /* beginning of file */
1984 case st_Proc
: /* procedure */
1985 case st_StaticProc
: /* static procedure */
1986 case st_Block
: /* begin scope */
1987 pscope
= allocate_scope ();
1988 pscope
->prev
= cur_file_ptr
->cur_scope
;
1989 pscope
->lsym
= psym
;
1990 pscope
->lnumber
= ret
;
1991 pscope
->type
= type
;
1992 cur_file_ptr
->cur_scope
= pscope
;
1994 if (type
!= st_File
)
1997 /* For every block type except file, struct, union, or
1998 enumeration blocks, push a level on the tag stack. We omit
1999 file types, so that tags can span file boundaries. */
2000 if (type
!= st_File
&& storage
!= sc_Info
)
2002 ptag_head
= allocate_thead ();
2003 ptag_head
->first_tag
= 0;
2004 ptag_head
->prev
= cur_tag_head
;
2005 cur_tag_head
= ptag_head
;
2010 pscope
= cur_file_ptr
->cur_scope
;
2011 if (pscope
== (scope_t
*)0)
2012 error ("internal error, too many st_End's");
2016 st_t begin_type
= (st_t
) pscope
->lsym
->st
;
2018 if (begin_type
!= st_File
)
2021 /* Except for file, structure, union, or enumeration end
2022 blocks remove all tags created within this scope. */
2023 if (begin_type
!= st_File
&& storage
!= sc_Info
)
2025 ptag_head
= cur_tag_head
;
2026 cur_tag_head
= ptag_head
->prev
;
2028 for (ptag
= ptag_head
->first_tag
;
2032 if (ptag
->forward_ref
!= (forward_t
*)0)
2033 add_unknown_tag (ptag
);
2035 ptag_next
= ptag
->same_block
;
2036 ptag
->hash_ptr
->tag_ptr
= ptag
->same_name
;
2040 free_thead (ptag_head
);
2043 cur_file_ptr
->cur_scope
= pscope
->prev
;
2044 psym
->index
= pscope
->lnumber
; /* blk end gets begin sym # */
2046 if (storage
!= sc_Info
)
2047 psym
->iss
= pscope
->lsym
->iss
; /* blk end gets same name */
2049 if (begin_type
== st_File
|| begin_type
== st_Block
)
2050 pscope
->lsym
->index
= ret
+1; /* block begin gets next sym # */
2052 /* Functions push two or more aux words as follows:
2053 1st word: index+1 of the end symbol
2054 2nd word: type of the function (plus any aux words needed).
2055 Also, tie the external pointer back to the function begin symbol. */
2059 pscope
->lsym
->index
= add_aux_sym_symint (ret
+1);
2060 type
= add_aux_sym_tir (&last_func_type_info
,
2062 &cur_file_ptr
->thash_head
[0]);
2065 last_func_eptr
->ifd
= cur_file_ptr
->file_index
;
2067 /* The index for an external st_Proc symbol is the index
2068 of the st_Proc symbol in the local symbol table. */
2069 last_func_eptr
->asym
.index
= psym
->index
;
2073 free_scope (pscope
);
2077 cur_file_ptr
->nested_scopes
+= scope_delta
;
2079 if (debug
&& type
!= st_File
2080 && (debug
> 2 || type
== st_Block
|| type
== st_End
2081 || type
== st_Proc
|| type
== st_StaticProc
))
2083 char *sc_str
= sc_to_string (storage
);
2084 char *st_str
= st_to_string (type
);
2085 int depth
= cur_file_ptr
->nested_scopes
+ (scope_delta
< 0);
2088 "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
2089 value
, depth
, sc_str
);
2091 if (str_start
&& str_end_p1
- str_start
> 0)
2092 fprintf (stderr
, " st= %-11s name= %.*s\n", st_str
, str_end_p1
- str_start
, str_start
);
2095 Size_t len
= strlen (st_str
);
2096 fprintf (stderr
, " st= %.*s\n", len
-1, st_str
);
2104 /* Add an external symbol. */
2107 add_ext_symbol (str_start
, str_end_p1
, type
, storage
, value
, indx
, ifd
)
2108 const char *str_start
; /* first byte in string */
2109 const char *str_end_p1
; /* first byte after string */
2110 st_t type
; /* symbol type */
2111 sc_t storage
; /* storage class */
2112 long value
; /* value of symbol */
2113 symint_t indx
; /* index to local/aux. syms */
2114 int ifd
; /* file index */
2116 register EXTR
*psym
;
2117 register varray_t
*vp
= &ext_symbols
;
2118 shash_t
*hash_ptr
= (shash_t
*)0;
2122 char *sc_str
= sc_to_string (storage
);
2123 char *st_str
= st_to_string (type
);
2126 "\tesym\tv= %10ld, ifd= %2d, sc= %-12s",
2127 value
, ifd
, sc_str
);
2129 if (str_start
&& str_end_p1
- str_start
> 0)
2130 fprintf (stderr
, " st= %-11s name= %.*s\n", st_str
, str_end_p1
- str_start
, str_start
);
2132 fprintf (stderr
, " st= %s\n", st_str
);
2135 if (vp
->objects_last_page
== vp
->objects_per_page
)
2136 add_varray_page (vp
);
2138 psym
= &vp
->last
->datum
->esym
[ vp
->objects_last_page
++ ];
2141 psym
->asym
.value
= value
;
2142 psym
->asym
.st
= (unsigned) type
;
2143 psym
->asym
.sc
= (unsigned) storage
;
2144 psym
->asym
.index
= indx
;
2145 psym
->asym
.iss
= (str_start
== (const char *)0)
2147 : add_string (&ext_strings
,
2153 hash_ptr
->esym_ptr
= psym
;
2154 return vp
->num_allocated
++;
2158 /* Add an auxiliary symbol (passing a symint). */
2161 add_aux_sym_symint (aux_word
)
2162 symint_t aux_word
; /* auxiliary information word */
2164 register AUXU
*aux_ptr
;
2165 register efdr_t
*file_ptr
= cur_file_ptr
;
2166 register varray_t
*vp
= &file_ptr
->aux_syms
;
2168 if (vp
->objects_last_page
== vp
->objects_per_page
)
2169 add_varray_page (vp
);
2171 aux_ptr
= &vp
->last
->datum
->aux
[ vp
->objects_last_page
++ ];
2172 aux_ptr
->isym
= aux_word
;
2174 return vp
->num_allocated
++;
2178 /* Add an auxiliary symbol (passing a file/symbol index combo). */
2181 add_aux_sym_rndx (file_index
, sym_index
)
2185 register AUXU
*aux_ptr
;
2186 register efdr_t
*file_ptr
= cur_file_ptr
;
2187 register varray_t
*vp
= &file_ptr
->aux_syms
;
2189 if (vp
->objects_last_page
== vp
->objects_per_page
)
2190 add_varray_page (vp
);
2192 aux_ptr
= &vp
->last
->datum
->aux
[ vp
->objects_last_page
++ ];
2193 aux_ptr
->rndx
.rfd
= file_index
;
2194 aux_ptr
->rndx
.index
= sym_index
;
2196 return vp
->num_allocated
++;
2200 /* Add an auxiliary symbol (passing the basic type and possibly
2201 type qualifiers). */
2204 add_aux_sym_tir (t
, state
, hash_tbl
)
2205 type_info_t
*t
; /* current type information */
2206 hash_state_t state
; /* whether to hash type or not */
2207 thash_t
**hash_tbl
; /* pointer to hash table to use */
2209 register AUXU
*aux_ptr
;
2210 register efdr_t
*file_ptr
= cur_file_ptr
;
2211 register varray_t
*vp
= &file_ptr
->aux_syms
;
2212 static AUXU init_aux
;
2218 aux
.ti
.bt
= (int) t
->basic_type
;
2219 aux
.ti
.continued
= 0;
2220 aux
.ti
.fBitfield
= t
->bitfield
;
2222 aux
.ti
.tq0
= (int) t
->type_qualifiers
[0];
2223 aux
.ti
.tq1
= (int) t
->type_qualifiers
[1];
2224 aux
.ti
.tq2
= (int) t
->type_qualifiers
[2];
2225 aux
.ti
.tq3
= (int) t
->type_qualifiers
[3];
2226 aux
.ti
.tq4
= (int) t
->type_qualifiers
[4];
2227 aux
.ti
.tq5
= (int) t
->type_qualifiers
[5];
2230 /* For anything that adds additional information, we must not hash,
2231 so check here, and reset our state. */
2233 if (state
!= hash_no
2234 && (t
->type_qualifiers
[0] == tq_Array
2235 || t
->type_qualifiers
[1] == tq_Array
2236 || t
->type_qualifiers
[2] == tq_Array
2237 || t
->type_qualifiers
[3] == tq_Array
2238 || t
->type_qualifiers
[4] == tq_Array
2239 || t
->type_qualifiers
[5] == tq_Array
2240 || t
->basic_type
== bt_Struct
2241 || t
->basic_type
== bt_Union
2242 || t
->basic_type
== bt_Enum
2244 || t
->num_dims
> 0))
2247 /* See if we can hash this type, and save some space, but some types
2248 can't be hashed (because they contain arrays or continuations),
2249 and others can be put into the hash list, but cannot use existing
2250 types because other aux entries precede this one. */
2252 if (state
!= hash_no
)
2254 register thash_t
*hash_ptr
;
2255 register symint_t hi
;
2257 hi
= aux
.isym
& ((1 << HASHBITS
) - 1);
2260 for (hash_ptr
= hash_tbl
[hi
];
2261 hash_ptr
!= (thash_t
*)0;
2262 hash_ptr
= hash_ptr
->next
)
2264 if (aux
.isym
== hash_ptr
->type
.isym
)
2268 if (hash_ptr
!= (thash_t
*)0 && state
== hash_yes
)
2269 return hash_ptr
->indx
;
2271 if (hash_ptr
== (thash_t
*)0)
2273 hash_ptr
= allocate_thash ();
2274 hash_ptr
->next
= hash_tbl
[hi
];
2275 hash_ptr
->type
= aux
;
2276 hash_ptr
->indx
= vp
->num_allocated
;
2277 hash_tbl
[hi
] = hash_ptr
;
2281 /* Everything is set up, add the aux symbol. */
2282 if (vp
->objects_last_page
== vp
->objects_per_page
)
2283 add_varray_page (vp
);
2285 aux_ptr
= &vp
->last
->datum
->aux
[ vp
->objects_last_page
++ ];
2288 ret
= vp
->num_allocated
++;
2290 /* Add bitfield length if it exists.
2292 NOTE: Mips documentation claims bitfield goes at the end of the
2293 AUX record, but the DECstation compiler emits it here.
2294 (This would only make a difference for enum bitfields.)
2296 Also note: We use the last size given since gcc may emit 2
2297 for an enum bitfield. */
2300 (void) add_aux_sym_symint ((symint_t
)t
->sizes
[t
->num_sizes
-1]);
2303 /* Add tag information if needed. Structure, union, and enum
2304 references add 2 aux symbols: a [file index, symbol index]
2305 pointer to the structure type, and the current file index. */
2307 if (t
->basic_type
== bt_Struct
2308 || t
->basic_type
== bt_Union
2309 || t
->basic_type
== bt_Enum
)
2311 register symint_t file_index
= t
->tag_ptr
->ifd
;
2312 register symint_t sym_index
= t
->tag_ptr
->indx
;
2316 (void) add_aux_sym_rndx (ST_RFDESCAPE
, sym_index
);
2317 (void) add_aux_sym_symint ((symint_t
)-1);
2319 else if (sym_index
!= indexNil
)
2321 (void) add_aux_sym_rndx (ST_RFDESCAPE
, sym_index
);
2322 (void) add_aux_sym_symint (file_index
);
2326 register forward_t
*forward_ref
= allocate_forward ();
2328 forward_ref
->type_ptr
= aux_ptr
;
2329 forward_ref
->next
= t
->tag_ptr
->forward_ref
;
2330 t
->tag_ptr
->forward_ref
= forward_ref
;
2332 (void) add_aux_sym_rndx (ST_RFDESCAPE
, sym_index
);
2333 forward_ref
->index_ptr
2334 = &vp
->last
->datum
->aux
[ vp
->objects_last_page
- 1];
2336 (void) add_aux_sym_symint (file_index
);
2337 forward_ref
->ifd_ptr
2338 = &vp
->last
->datum
->aux
[ vp
->objects_last_page
- 1];
2342 /* Add information about array bounds if they exist. */
2343 for (i
= 0; i
< t
->num_dims
; i
++)
2345 (void) add_aux_sym_rndx (ST_RFDESCAPE
,
2346 cur_file_ptr
->int_type
);
2348 (void) add_aux_sym_symint (cur_file_ptr
->file_index
); /* file index*/
2349 (void) add_aux_sym_symint ((symint_t
)0); /* low bound */
2350 (void) add_aux_sym_symint (t
->dimensions
[i
] - 1); /* high bound*/
2351 (void) add_aux_sym_symint ((t
->dimensions
[i
] == 0) /* stride */
2353 : (t
->sizes
[i
] * 8) / t
->dimensions
[i
]);
2356 /* NOTE: Mips documentation claism that the bitfield width goes here.
2357 But it needs to be emitted earlier. */
2363 /* Add a tag to the tag table (unless it already exists). */
2366 get_tag (tag_start
, tag_end_p1
, indx
, basic_type
)
2367 const char *tag_start
; /* 1st byte of tag name */
2368 const char *tag_end_p1
; /* 1st byte after tag name */
2369 symint_t indx
; /* index of tag start block */
2370 bt_t basic_type
; /* bt_Struct, bt_Union, or bt_Enum */
2374 hash_ptr
= hash_string (tag_start
,
2375 tag_end_p1
- tag_start
,
2379 if (hash_ptr
!= (shash_t
*)0
2380 && hash_ptr
->tag_ptr
!= (tag_t
*)0)
2382 tag_ptr
= hash_ptr
->tag_ptr
;
2383 if (indx
!= indexNil
)
2385 tag_ptr
->basic_type
= basic_type
;
2386 tag_ptr
->ifd
= cur_file_ptr
->file_index
;
2387 tag_ptr
->indx
= indx
;
2392 (void) add_string (&tag_strings
,
2398 tag_ptr
= allocate_tag ();
2399 tag_ptr
->forward_ref
= (forward_t
*) 0;
2400 tag_ptr
->hash_ptr
= hash_ptr
;
2401 tag_ptr
->same_name
= hash_ptr
->tag_ptr
;
2402 tag_ptr
->basic_type
= basic_type
;
2403 tag_ptr
->indx
= indx
;
2404 tag_ptr
->ifd
= (indx
== indexNil
) ? -1 : cur_file_ptr
->file_index
;
2405 tag_ptr
->same_block
= cur_tag_head
->first_tag
;
2407 cur_tag_head
->first_tag
= tag_ptr
;
2408 hash_ptr
->tag_ptr
= tag_ptr
;
2414 /* Add an unknown {struct, union, enum} tag. */
2417 add_unknown_tag (ptag
)
2418 tag_t
*ptag
; /* pointer to tag information */
2420 shash_t
*hash_ptr
= ptag
->hash_ptr
;
2421 char *name_start
= hash_ptr
->string
;
2422 char *name_end_p1
= name_start
+ hash_ptr
->len
;
2423 forward_t
*f_next
= ptag
->forward_ref
;
2426 int file_index
= cur_file_ptr
->file_index
;
2430 char *agg_type
= "{unknown aggregate type}";
2431 switch (ptag
->basic_type
)
2433 case bt_Struct
: agg_type
= "struct"; break;
2434 case bt_Union
: agg_type
= "union"; break;
2435 case bt_Enum
: agg_type
= "enum"; break;
2439 fprintf (stderr
, "unknown %s %.*s found\n", agg_type
,
2440 hash_ptr
->len
, name_start
);
2443 sym_index
= add_local_symbol (name_start
,
2450 (void) add_local_symbol (name_start
,
2457 while (f_next
!= (forward_t
*)0)
2460 f_next
= f_next
->next
;
2462 f_cur
->ifd_ptr
->isym
= file_index
;
2463 f_cur
->index_ptr
->rndx
.index
= sym_index
;
2465 free_forward (f_cur
);
2472 /* Add a procedure to the current file's list of procedures, and record
2473 this is the current procedure. If the assembler created a PDR for
2474 this procedure, use that to initialize the current PDR. */
2477 add_procedure (func_start
, func_end_p1
)
2478 const char *func_start
; /* 1st byte of func name */
2479 const char *func_end_p1
; /* 1st byte after func name */
2481 register PDR
*new_proc_ptr
;
2482 register efdr_t
*file_ptr
= cur_file_ptr
;
2483 register varray_t
*vp
= &file_ptr
->procs
;
2484 register symint_t value
= 0;
2485 register st_t proc_type
= st_Proc
;
2486 register shash_t
*shash_ptr
= hash_string (func_start
,
2487 func_end_p1
- func_start
,
2492 fputc ('\n', stderr
);
2494 if (vp
->objects_last_page
== vp
->objects_per_page
)
2495 add_varray_page (vp
);
2497 cur_proc_ptr
= new_proc_ptr
= &vp
->last
->datum
->proc
[ vp
->objects_last_page
++ ];
2499 vp
->num_allocated
++;
2502 /* Did the assembler create this procedure? If so, get the PDR information. */
2503 cur_oproc_ptr
= (PDR
*)0;
2504 if (shash_ptr
!= (shash_t
*)0)
2506 register PDR
*old_proc_ptr
= shash_ptr
->proc_ptr
;
2507 register SYMR
*sym_ptr
= shash_ptr
->sym_ptr
;
2509 if (old_proc_ptr
!= (PDR
*)0
2510 && sym_ptr
!= (SYMR
*)0
2511 && ((st_t
)sym_ptr
->st
== st_Proc
|| (st_t
)sym_ptr
->st
== st_StaticProc
))
2513 cur_oproc_begin
= sym_ptr
;
2514 cur_oproc_end
= shash_ptr
->end_ptr
;
2515 value
= sym_ptr
->value
;
2517 cur_oproc_ptr
= old_proc_ptr
;
2518 proc_type
= (st_t
)sym_ptr
->st
;
2519 *new_proc_ptr
= *old_proc_ptr
; /* initialize */
2523 if (cur_oproc_ptr
== (PDR
*)0)
2524 error ("Did not find a PDR block for %.*s", func_end_p1
- func_start
, func_start
);
2526 /* Determine the start of symbols. */
2527 new_proc_ptr
->isym
= file_ptr
->symbols
.num_allocated
;
2529 /* Push the start of the function. */
2530 (void) add_local_symbol (func_start
, func_end_p1
,
2537 /* Add a new filename, and set up all of the file relative
2538 virtual arrays (strings, symbols, aux syms, etc.). Record
2539 where the current file structure lives. */
2542 add_file (file_start
, file_end_p1
)
2543 const char *file_start
; /* first byte in string */
2544 const char *file_end_p1
; /* first byte after string */
2546 static char zero_bytes
[2] = { '\0', '\0' };
2548 register Ptrdiff_t len
= file_end_p1
- file_start
;
2549 register int first_ch
= *file_start
;
2550 register efdr_t
*file_ptr
;
2553 fprintf (stderr
, "\tfile\t%.*s\n", len
, file_start
);
2555 /* See if the file has already been created. */
2556 for (file_ptr
= first_file
;
2557 file_ptr
!= (efdr_t
*)0;
2558 file_ptr
= file_ptr
->next_file
)
2560 if (first_ch
== file_ptr
->name
[0]
2561 && file_ptr
->name
[len
] == '\0'
2562 && memcmp ((CPTR_T
) file_start
, (CPTR_T
) file_ptr
->name
, len
) == 0)
2564 cur_file_ptr
= file_ptr
;
2569 /* If this is a new file, create it. */
2570 if (file_ptr
== (efdr_t
*)0)
2572 if (file_desc
.objects_last_page
== file_desc
.objects_per_page
)
2573 add_varray_page (&file_desc
);
2575 file_ptr
= cur_file_ptr
=
2576 &file_desc
.last
->datum
->file
[ file_desc
.objects_last_page
++ ];
2577 *file_ptr
= init_file
;
2579 file_ptr
->file_index
= file_desc
.num_allocated
++;
2581 /* Allocate the string hash table. */
2582 file_ptr
->shash_head
= (shash_t
**) allocate_page ();
2584 /* Make sure 0 byte in string table is null */
2585 add_string (&file_ptr
->strings
,
2586 &file_ptr
->shash_head
[0],
2591 if (file_end_p1
- file_start
> PAGE_USIZE
-2)
2592 fatal ("Filename goes over one page boundary.");
2594 /* Push the start of the filename. We assume that the filename
2595 will be stored at string offset 1. */
2596 (void) add_local_symbol (file_start
, file_end_p1
, st_File
, sc_Text
,
2597 (symint_t
)0, (symint_t
)0);
2598 file_ptr
->fdr
.rss
= 1;
2599 file_ptr
->name
= &file_ptr
->strings
.last
->datum
->byte
[1];
2600 file_ptr
->name_len
= file_end_p1
- file_start
;
2602 /* Update the linked list of file descriptors. */
2603 *last_file_ptr
= file_ptr
;
2604 last_file_ptr
= &file_ptr
->next_file
;
2606 /* Add void & int types to the file (void should be first to catch
2607 errant 0's within the index fields). */
2608 file_ptr
->void_type
= add_aux_sym_tir (&void_type_info
,
2610 &cur_file_ptr
->thash_head
[0]);
2612 file_ptr
->int_type
= add_aux_sym_tir (&int_type_info
,
2614 &cur_file_ptr
->thash_head
[0]);
2619 /* Add a stream of random bytes to a varray. */
2622 add_bytes (vp
, input_ptr
, nitems
)
2623 varray_t
*vp
; /* virtual array to add too */
2624 char *input_ptr
; /* start of the bytes */
2625 Size_t nitems
; /* # items to move */
2627 register Size_t move_items
;
2628 register Size_t move_bytes
;
2633 if (vp
->objects_last_page
>= vp
->objects_per_page
)
2634 add_varray_page (vp
);
2636 ptr
= &vp
->last
->datum
->byte
[ vp
->objects_last_page
* vp
->object_size
];
2637 move_items
= vp
->objects_per_page
- vp
->objects_last_page
;
2638 if (move_items
> nitems
)
2639 move_items
= nitems
;
2641 move_bytes
= move_items
* vp
->object_size
;
2642 nitems
-= move_items
;
2644 if (move_bytes
>= 32)
2646 (void) memcpy ((PTR_T
) ptr
, (CPTR_T
) input_ptr
, move_bytes
);
2647 input_ptr
+= move_bytes
;
2651 while (move_bytes
-- > 0)
2652 *ptr
++ = *input_ptr
++;
2658 /* Convert storage class to string. */
2661 sc_to_string(storage_class
)
2664 switch(storage_class
)
2666 case sc_Nil
: return "Nil,";
2667 case sc_Text
: return "Text,";
2668 case sc_Data
: return "Data,";
2669 case sc_Bss
: return "Bss,";
2670 case sc_Register
: return "Register,";
2671 case sc_Abs
: return "Abs,";
2672 case sc_Undefined
: return "Undefined,";
2673 case sc_CdbLocal
: return "CdbLocal,";
2674 case sc_Bits
: return "Bits,";
2675 case sc_CdbSystem
: return "CdbSystem,";
2676 case sc_RegImage
: return "RegImage,";
2677 case sc_Info
: return "Info,";
2678 case sc_UserStruct
: return "UserStruct,";
2679 case sc_SData
: return "SData,";
2680 case sc_SBss
: return "SBss,";
2681 case sc_RData
: return "RData,";
2682 case sc_Var
: return "Var,";
2683 case sc_Common
: return "Common,";
2684 case sc_SCommon
: return "SCommon,";
2685 case sc_VarRegister
: return "VarRegister,";
2686 case sc_Variant
: return "Variant,";
2687 case sc_SUndefined
: return "SUndefined,";
2688 case sc_Init
: return "Init,";
2689 case sc_Max
: return "Max,";
2696 /* Convert symbol type to string. */
2699 st_to_string(symbol_type
)
2704 case st_Nil
: return "Nil,";
2705 case st_Global
: return "Global,";
2706 case st_Static
: return "Static,";
2707 case st_Param
: return "Param,";
2708 case st_Local
: return "Local,";
2709 case st_Label
: return "Label,";
2710 case st_Proc
: return "Proc,";
2711 case st_Block
: return "Block,";
2712 case st_End
: return "End,";
2713 case st_Member
: return "Member,";
2714 case st_Typedef
: return "Typedef,";
2715 case st_File
: return "File,";
2716 case st_RegReloc
: return "RegReloc,";
2717 case st_Forward
: return "Forward,";
2718 case st_StaticProc
: return "StaticProc,";
2719 case st_Constant
: return "Constant,";
2720 case st_Str
: return "String,";
2721 case st_Number
: return "Number,";
2722 case st_Expr
: return "Expr,";
2723 case st_Type
: return "Type,";
2724 case st_Max
: return "Max,";
2731 /* Read a line from standard input, and return the start of the buffer
2732 (which is grows if the line is too big). We split lines at the
2733 semi-colon, and return each logical line independently. */
2736 read_line
__proto((void))
2738 static int line_split_p
= 0;
2739 register int string_p
= 0;
2740 register int comment_p
= 0;
2744 if (cur_line_start
== (char *)0)
2745 { /* allocate initial page */
2746 cur_line_start
= (char *) allocate_page ();
2747 cur_line_alloc
= PAGE_SIZE
;
2754 cur_line_nbytes
= 0;
2756 for (ptr
= cur_line_start
; (ch
= getchar ()) != EOF
; *ptr
++ = ch
)
2758 if (++cur_line_nbytes
>= cur_line_alloc
-1)
2760 register int num_pages
= cur_line_alloc
/ PAGE_SIZE
;
2761 register char *old_buffer
= cur_line_start
;
2763 cur_line_alloc
+= PAGE_SIZE
;
2764 cur_line_start
= (char *) allocate_multiple_pages (num_pages
+1);
2765 memcpy (cur_line_start
, old_buffer
, num_pages
* PAGE_SIZE
);
2767 ptr
= cur_line_start
+ cur_line_nbytes
- 1;
2774 cur_line_ptr
= cur_line_start
;
2775 return cur_line_ptr
;
2778 else if (ch
== '\0')
2779 error ("Null character found in input");
2781 else if (!comment_p
)
2784 string_p
= !string_p
;
2789 else if (ch
== ';' && !string_p
)
2794 cur_line_ptr
= cur_line_start
;
2795 return cur_line_ptr
;
2801 pfatal_with_name (input_name
);
2803 cur_line_ptr
= (char *)0;
2808 /* Parse #.begin directives which have a label as the first argument
2809 which gives the location of the start of the block. */
2813 const char *start
; /* start of directive */
2815 const char *end_p1
; /* end of label */
2817 shash_t
*hash_ptr
; /* hash pointer to lookup label */
2819 if (cur_file_ptr
== (efdr_t
*)0)
2821 error ("#.begin directive without a preceding .file directive");
2825 if (cur_proc_ptr
== (PDR
*)0)
2827 error ("#.begin directive without a preceding .ent directive");
2831 for (end_p1
= start
; (ch
= *end_p1
) != '\0' && !isspace (ch
); end_p1
++)
2834 hash_ptr
= hash_string (start
,
2839 if (hash_ptr
== (shash_t
*)0)
2841 error ("Label %.*s not found for #.begin", end_p1
- start
, start
);
2845 if (cur_oproc_begin
== (SYMR
*)0)
2847 error ("Procedure table %.*s not found for #.begin", end_p1
- start
, start
);
2851 (void) add_local_symbol ((const char *)0, (const char *)0,
2853 (symint_t
)hash_ptr
->sym_ptr
->value
- cur_oproc_begin
->value
,
2858 /* Parse #.bend directives which have a label as the first argument
2859 which gives the location of the end of the block. */
2863 const char *start
; /* start of directive */
2865 const char *end_p1
; /* end of label */
2867 shash_t
*hash_ptr
; /* hash pointer to lookup label */
2869 if (cur_file_ptr
== (efdr_t
*)0)
2871 error ("#.begin directive without a preceding .file directive");
2875 if (cur_proc_ptr
== (PDR
*)0)
2877 error ("#.bend directive without a preceding .ent directive");
2881 for (end_p1
= start
; (ch
= *end_p1
) != '\0' && !isspace (ch
); end_p1
++)
2884 hash_ptr
= hash_string (start
,
2889 if (hash_ptr
== (shash_t
*)0)
2891 error ("Label %.*s not found for #.bend", end_p1
- start
, start
);
2895 if (cur_oproc_begin
== (SYMR
*)0)
2897 error ("Procedure table %.*s not found for #.bend", end_p1
- start
, start
);
2901 (void) add_local_symbol ((const char *)0, (const char *)0,
2903 (symint_t
)hash_ptr
->sym_ptr
->value
- cur_oproc_begin
->value
,
2908 /* Parse #.def directives, which are contain standard COFF subdirectives
2909 to describe the debugging format. These subdirectives include:
2911 .scl specify storage class
2912 .val specify a value
2913 .endef specify end of COFF directives
2914 .type specify the type
2915 .size specify the size of an array
2916 .dim specify an array dimension
2917 .tag specify a tag for a struct, union, or enum. */
2920 parse_def (name_start
)
2921 const char *name_start
; /* start of directive */
2923 const char *dir_start
; /* start of current directive*/
2924 const char *dir_end_p1
; /* end+1 of current directive*/
2925 const char *arg_start
; /* start of current argument */
2926 const char *arg_end_p1
; /* end+1 of current argument */
2927 const char *name_end_p1
; /* end+1 of label */
2928 const char *tag_start
= (const char *)0; /* start of tag name */
2929 const char *tag_end_p1
= (const char *)0; /* end+1 of tag name */
2930 sc_t storage_class
= sc_Nil
;
2931 st_t symbol_type
= st_Nil
;
2933 EXTR
*eptr
= (EXTR
*)0; /* ext. sym equivalent to def*/
2934 int is_function
= 0; /* != 0 if function */
2936 symint_t indx
= cur_file_ptr
->void_type
;
2938 symint_t arg_number
;
2939 symint_t temp_array
[ N_TQ
];
2944 static int inside_enumeration
= 0; /* is this an enumeration? */
2947 /* Initialize the type information. */
2951 /* Search for the end of the name being defined. */
2952 /* Allow spaces and such in names for G++ templates, which produce stabs
2955 #.def SMANIP<long unsigned int>; .scl 10; .type 0x8; .size 8; .endef */
2957 for (name_end_p1
= name_start
; (ch
= *name_end_p1
) != ';' && ch
!= '\0'; name_end_p1
++)
2962 error_line
= __LINE__
;
2967 /* Parse the remaining subdirectives now. */
2968 dir_start
= name_end_p1
+1;
2971 while ((ch
= *dir_start
) == ' ' || ch
== '\t')
2976 error_line
= __LINE__
;
2982 if (dir_start
[1] == 'e'
2983 && memcmp (dir_start
, ".endef", sizeof (".endef")-1) == 0)
2986 /* Pick up the subdirective now */
2987 for (dir_end_p1
= dir_start
+1;
2988 (ch
= *dir_end_p1
) != ' ' && ch
!= '\t';
2991 if (ch
== '\0' || isspace (ch
))
2993 error_line
= __LINE__
;
2999 /* Pick up the subdirective argument now. */
3000 arg_was_number
= arg_number
= 0;
3001 arg_end_p1
= (const char *)0;
3002 arg_start
= dir_end_p1
+1;
3004 while (ch
== ' ' || ch
== '\t')
3007 if (isdigit (ch
) || ch
== '-' || ch
== '+')
3010 arg_number
= strtol (arg_start
, (char **) &arg_end_p1
, 0);
3011 if (arg_end_p1
!= arg_start
|| (ch2
= *arg_end_p1
!= ';') || ch2
!= ',')
3015 else if (ch
== '\0' || isspace (ch
))
3017 error_line
= __LINE__
;
3022 if (!arg_was_number
)
3024 /* Allow spaces and such in names for G++ templates. */
3025 for (arg_end_p1
= arg_start
+1;
3026 (ch
= *arg_end_p1
) != ';' && ch
!= '\0';
3032 error_line
= __LINE__
;
3038 /* Classify the directives now. */
3039 len
= dir_end_p1
- dir_start
;
3040 switch (dir_start
[1])
3043 error_line
= __LINE__
;
3048 if (len
== sizeof (".dim")-1
3049 && memcmp (dir_start
, ".dim", sizeof (".dim")-1) == 0
3052 symint_t
*t_ptr
= &temp_array
[ N_TQ
-1 ];
3054 *t_ptr
= arg_number
;
3055 while (*arg_end_p1
== ',' && arg_was_number
)
3057 arg_start
= arg_end_p1
+1;
3059 while (ch
== ' ' || ch
== '\t')
3063 if (isdigit (ch
) || ch
== '-' || ch
== '+')
3066 arg_number
= strtol (arg_start
, (char **) &arg_end_p1
, 0);
3067 if (arg_end_p1
!= arg_start
|| (ch2
= *arg_end_p1
!= ';') || ch2
!= ',')
3070 if (t_ptr
== &temp_array
[0])
3072 error_line
= __LINE__
;
3077 *--t_ptr
= arg_number
;
3081 /* Reverse order of dimensions. */
3082 while (t_ptr
<= &temp_array
[ N_TQ
-1 ])
3084 if (t
.num_dims
>= N_TQ
-1)
3086 error_line
= __LINE__
;
3091 t
.dimensions
[ t
.num_dims
++ ] = *t_ptr
++;
3097 error_line
= __LINE__
;
3104 if (len
== sizeof (".scl")-1
3105 && memcmp (dir_start
, ".scl", sizeof (".scl")-1) == 0
3107 && arg_number
< ((symint_t
) C_MAX
))
3109 /* If the symbol is a static or external, we have
3110 already gotten the appropriate type and class, so
3111 make sure we don't override those values. This is
3112 needed because there are some type and classes that
3113 are not in COFF, such as short data, etc. */
3114 if (symbol_type
== st_Nil
)
3116 symbol_type
= map_coff_sym_type
[arg_number
];
3117 storage_class
= map_coff_storage
[arg_number
];
3122 else if (len
== sizeof (".size")-1
3123 && memcmp (dir_start
, ".size", sizeof (".size")-1) == 0
3126 symint_t
*t_ptr
= &temp_array
[ N_TQ
-1 ];
3128 *t_ptr
= arg_number
;
3129 while (*arg_end_p1
== ',' && arg_was_number
)
3131 arg_start
= arg_end_p1
+1;
3133 while (ch
== ' ' || ch
== '\t')
3137 if (isdigit (ch
) || ch
== '-' || ch
== '+')
3140 arg_number
= strtol (arg_start
, (char **) &arg_end_p1
, 0);
3141 if (arg_end_p1
!= arg_start
|| (ch2
= *arg_end_p1
!= ';') || ch2
!= ',')
3144 if (t_ptr
== &temp_array
[0])
3146 error_line
= __LINE__
;
3151 *--t_ptr
= arg_number
;
3155 /* Reverse order of sizes. */
3156 while (t_ptr
<= &temp_array
[ N_TQ
-1 ])
3158 if (t
.num_sizes
>= N_TQ
-1)
3160 error_line
= __LINE__
;
3165 t
.sizes
[ t
.num_sizes
++ ] = *t_ptr
++;
3172 error_line
= __LINE__
;
3179 if (len
== sizeof (".type")-1
3180 && memcmp (dir_start
, ".type", sizeof (".type")-1) == 0
3183 tq_t
*tq_ptr
= &t
.type_qualifiers
[0];
3185 t
.orig_type
= (coff_type_t
) (arg_number
& N_BTMASK
);
3186 t
.basic_type
= map_coff_types
[(int)t
.orig_type
];
3187 for (i
= N_TQ
-1; i
>= 0; i
--)
3189 int dt
= (arg_number
>> ((i
* N_TQ_SHIFT
) + N_BT_SHIFT
)
3192 if (dt
!= (int)DT_NON
)
3193 *tq_ptr
++ = map_coff_derived_type
[dt
];
3196 /* If this is a function, ignore it, so that we don't get
3197 two entries (one from the .ent, and one for the .def
3198 that precedes it). Save the type information so that
3199 the end block can properly add it after the begin block
3200 index. For MIPS knows what reason, we must strip off
3201 the function type at this point. */
3202 if (tq_ptr
!= &t
.type_qualifiers
[0] && tq_ptr
[-1] == tq_Proc
)
3205 tq_ptr
[-1] = tq_Nil
;
3211 else if (len
== sizeof (".tag")-1
3212 && memcmp (dir_start
, ".tag", sizeof (".tag")-1) == 0)
3214 tag_start
= arg_start
;
3215 tag_end_p1
= arg_end_p1
;
3221 error_line
= __LINE__
;
3228 if (len
== sizeof (".val")-1
3229 && memcmp (dir_start
, ".val", sizeof (".val")-1) == 0)
3234 /* If the value is not an integer value, it must be the
3235 name of a static or global item. Look up the name in
3236 the original symbol table to pick up the storage
3237 class, symbol type, etc. */
3240 shash_t
*orig_hash_ptr
; /* hash within orig sym table*/
3241 shash_t
*ext_hash_ptr
; /* hash within ext. sym table*/
3243 ext_hash_ptr
= hash_string (arg_start
,
3244 arg_end_p1
- arg_start
,
3248 if (ext_hash_ptr
!= (shash_t
*)0
3249 && ext_hash_ptr
->esym_ptr
!= (EXTR
*)0)
3250 eptr
= ext_hash_ptr
->esym_ptr
;
3252 orig_hash_ptr
= hash_string (arg_start
,
3253 arg_end_p1
- arg_start
,
3257 if ((orig_hash_ptr
== (shash_t
*)0
3258 || orig_hash_ptr
->sym_ptr
== (SYMR
*)0)
3259 && eptr
== (EXTR
*)0)
3261 fprintf (stderr
, "warning, %.*s not found in original or external symbol tables, value defaults to 0\n",
3262 arg_end_p1
- arg_start
,
3268 SYMR
*ptr
= (orig_hash_ptr
!= (shash_t
*)0
3269 && orig_hash_ptr
->sym_ptr
!= (SYMR
*)0)
3270 ? orig_hash_ptr
->sym_ptr
3273 symbol_type
= (st_t
) ptr
->st
;
3274 storage_class
= (sc_t
) ptr
->sc
;
3282 error_line
= __LINE__
;
3288 /* Set up to find next directive. */
3289 dir_start
= arg_end_p1
+ 1;
3293 t
.extra_sizes
= (tag_start
!= (char *)0);
3296 int diff
= t
.num_dims
- t
.num_sizes
;
3297 int i
= t
.num_dims
- 1;
3300 if (t
.num_sizes
!= 1 || diff
< 0)
3302 error_line
= __LINE__
;
3307 /* If this is an array, make sure the same number of dimensions
3308 and sizes were passed, creating extra sizes for multiply
3309 dimensioned arrays if not passed. */
3314 for (j
= (sizeof (t
.sizes
) / sizeof (t
.sizes
[0])) - 1; j
>= 0; j
--)
3315 t
.sizes
[ j
] = ((j
-diff
) >= 0) ? t
.sizes
[ j
-diff
] : 0;
3317 t
.num_sizes
= i
+ 1;
3318 for ( i
--; i
>= 0; i
-- )
3320 if (t
.dimensions
[ i
+1 ])
3321 t
.sizes
[ i
] = t
.sizes
[ i
+1 ] / t
.dimensions
[ i
+1 ];
3323 t
.sizes
[ i
] = t
.sizes
[ i
+1 ];
3328 else if (symbol_type
== st_Member
&& t
.num_sizes
- t
.extra_sizes
== 1)
3329 { /* Is this a bitfield? This is indicated by a structure memeber
3330 having a size field that isn't an array. */
3336 /* Except for enumeration members & begin/ending of scopes, put the
3337 type word in the aux. symbol table. */
3339 if (symbol_type
== st_Block
|| symbol_type
== st_End
)
3342 else if (inside_enumeration
)
3343 indx
= cur_file_ptr
->void_type
;
3347 if (t
.basic_type
== bt_Struct
3348 || t
.basic_type
== bt_Union
3349 || t
.basic_type
== bt_Enum
)
3351 if (tag_start
== (char *)0)
3353 error ("No tag specified for %.*s",
3354 name_end_p1
- name_start
,
3359 t
.tag_ptr
= get_tag (tag_start
, tag_end_p1
, (symint_t
)indexNil
,
3365 last_func_type_info
= t
;
3366 last_func_eptr
= eptr
;
3370 indx
= add_aux_sym_tir (&t
,
3372 &cur_file_ptr
->thash_head
[0]);
3376 /* If this is an external or static symbol, update the appropriate
3379 if (eptr
!= (EXTR
*)0
3380 && (eptr
->asym
.index
== indexNil
|| cur_proc_ptr
== (PDR
*)0))
3382 eptr
->ifd
= cur_file_ptr
->file_index
;
3383 eptr
->asym
.index
= indx
;
3387 /* Do any last minute adjustments that are necessary. */
3388 switch (symbol_type
)
3394 /* For the beginning of structs, unions, and enumerations, the
3395 size info needs to be passed in the value field. */
3398 if (t
.num_sizes
- t
.num_dims
- t
.extra_sizes
!= 1)
3400 error_line
= __LINE__
;
3408 inside_enumeration
= (t
.orig_type
== T_ENUM
);
3412 /* For the end of structs, unions, and enumerations, omit the
3413 name which is always ".eos". This needs to be done last, so
3414 that any error reporting above gives the correct name. */
3417 name_start
= name_end_p1
= (const char *)0;
3418 value
= inside_enumeration
= 0;
3422 /* Members of structures and unions that aren't bitfields, need
3423 to adjust the value from a byte offset to a bit offset.
3424 Members of enumerations do not have the value adjusted, and
3425 can be distinguished by indx == indexNil. For enumerations,
3426 update the maximum enumeration value. */
3429 if (!t
.bitfield
&& !inside_enumeration
)
3436 /* Add the symbol, except for global symbols outside of functions,
3437 for which the external symbol table is fine enough. */
3439 if (eptr
== (EXTR
*)0
3440 || eptr
->asym
.st
== (int)st_Nil
3441 || cur_proc_ptr
!= (PDR
*)0)
3443 symint_t isym
= add_local_symbol (name_start
, name_end_p1
,
3444 symbol_type
, storage_class
,
3448 /* deal with struct, union, and enum tags. */
3449 if (symbol_type
== st_Block
)
3451 /* Create or update the tag information. */
3452 tag_t
*tag_ptr
= get_tag (name_start
,
3457 /* If there are any forward references, fill in the appropriate
3458 file and symbol indexes. */
3460 symint_t file_index
= cur_file_ptr
->file_index
;
3461 forward_t
*f_next
= tag_ptr
->forward_ref
;
3464 while (f_next
!= (forward_t
*)0)
3467 f_next
= f_next
->next
;
3469 f_cur
->ifd_ptr
->isym
= file_index
;
3470 f_cur
->index_ptr
->rndx
.index
= isym
;
3472 free_forward (f_cur
);
3475 tag_ptr
->forward_ref
= (forward_t
*)0;
3482 /* Error return, issue message. */
3485 error ("compiler error, badly formed #.def (internal line # = %d)", error_line
);
3487 error ("compiler error, badly formed #.def");
3493 /* Parse .end directives. */
3497 const char *start
; /* start of directive */
3499 register const char *start_func
, *end_func_p1
;
3501 register symint_t value
;
3502 register FDR
*orig_fdr
;
3504 if (cur_file_ptr
== (efdr_t
*)0)
3506 error (".end directive without a preceding .file directive");
3510 if (cur_proc_ptr
== (PDR
*)0)
3512 error (".end directive without a preceding .ent directive");
3516 /* Get the function name, skipping whitespace. */
3517 for (start_func
= start
; isspace (*start_func
); start_func
++)
3521 if (!IS_ASM_IDENT (ch
))
3523 error (".end directive has no name");
3527 for (end_func_p1
= start_func
; IS_ASM_IDENT (ch
); ch
= *++end_func_p1
)
3531 /* Get the value field for creating the end from the original object
3532 file (which we find by locating the procedure start, and using the
3533 pointer to the end+1 block and backing up. The index points to a
3534 two word aux. symbol, whose first word is the index of the end
3535 symbol, and the second word is the type of the function return
3538 orig_fdr
= cur_file_ptr
->orig_fdr
;
3540 if (orig_fdr
!= (FDR
*)0 && cur_oproc_end
!= (SYMR
*)0)
3541 value
= cur_oproc_end
->value
;
3544 error ("Cannot find .end block for %.*s", end_func_p1
- start_func
, start_func
);
3546 (void) add_local_symbol (start_func
, end_func_p1
,
3551 cur_proc_ptr
= cur_oproc_ptr
= (PDR
*)0;
3555 /* Parse .ent directives. */
3559 const char *start
; /* start of directive */
3561 register const char *start_func
, *end_func_p1
;
3564 if (cur_file_ptr
== (efdr_t
*)0)
3566 error (".ent directive without a preceding .file directive");
3570 if (cur_proc_ptr
!= (PDR
*)0)
3572 error ("second .ent directive found before .end directive");
3576 for (start_func
= start
; isspace (*start_func
); start_func
++)
3580 if (!IS_ASM_IDENT (ch
))
3582 error (".ent directive has no name");
3586 for (end_func_p1
= start_func
; IS_ASM_IDENT (ch
); ch
= *++end_func_p1
)
3589 (void) add_procedure (start_func
, end_func_p1
);
3593 /* Parse .file directives. */
3597 const char *start
; /* start of directive */
3600 register char *start_name
, *end_name_p1
;
3602 (void) strtol (start
, &p
, 0);
3604 || (start_name
= local_index (p
, '"')) == (char *)0
3605 || (end_name_p1
= local_rindex (++start_name
, '"')) == (char *)0)
3607 error ("Invalid .file directive");
3611 if (cur_proc_ptr
!= (PDR
*)0)
3613 error ("No way to handle .file within .ent/.end section");
3617 add_file (start_name
, end_name_p1
);
3621 /* Make sure the @stabs symbol is emitted. */
3625 const char *start
; /* Start of directive (ignored) */
3629 /* Add a dummy @stabs dymbol. */
3631 (void) add_local_symbol (stabs_symbol
,
3632 stabs_symbol
+ sizeof (stabs_symbol
),
3633 stNil
, scInfo
, -1, MIPS_MARK_STAB(0));
3639 /* Parse .stabs directives.
3641 .stabs directives have five fields:
3642 "string" a string, encoding the type information.
3643 code a numeric code, defined in <stab.h>
3645 0 a zero or line number
3646 value a numeric value or an address.
3648 If the value is relocatable, we transform this into:
3649 iss points as an index into string space
3650 value value from lookup of the name
3651 st st from lookup of the name
3652 sc sc from lookup of the name
3653 index code|CODE_MASK
3655 If the value is not relocatable, we transform this into:
3656 iss points as an index into string space
3660 index code|CODE_MASK
3662 .stabn directives have four fields (string is null):
3663 code a numeric code, defined in <stab.h>
3665 0 a zero or a line number
3666 value a numeric value or an address. */
3669 parse_stabs_common (string_start
, string_end
, rest
)
3670 const char *string_start
; /* start of string or NULL */
3671 const char *string_end
; /* end+1 of string or NULL */
3672 const char *rest
; /* rest of the directive. */
3674 efdr_t
*save_file_ptr
= cur_file_ptr
;
3682 if (stabs_seen
== 0)
3685 /* Read code from stabs. */
3686 if (!isdigit (*rest
))
3688 error ("Invalid .stabs/.stabn directive, code is non-numeric");
3692 code
= strtol (rest
, &p
, 0);
3694 /* Line number stabs are handled differently, since they have two values,
3695 the line number and the address of the label. We use the index field
3696 (aka code) to hold the line number, and the value field to hold the
3697 address. The symbol type is st_Label, which should be different from
3698 the other stabs, so that gdb can recognize it. */
3700 if (code
== (int)N_SLINE
)
3702 SYMR
*sym_ptr
, dummy_symr
;
3706 if (p
[0] != ',' || p
[1] != '0' || p
[2] != ',' || !isdigit (p
[3]))
3708 error ("Invalid line number .stabs/.stabn directive");
3712 code
= strtol (p
+3, &p
, 0);
3714 if (p
[-1] != ',' || isdigit (ch
) || !IS_ASM_IDENT (ch
))
3716 error ("Invalid line number .stabs/.stabn directive");
3720 dummy_symr
.index
= code
;
3721 if (dummy_symr
.index
!= code
)
3723 error ("Line number (%d) for .stabs/.stabn directive cannot fit in index field (20 bits)",
3729 shash_ptr
= hash_string (p
,
3734 if (shash_ptr
== (shash_t
*)0
3735 || (sym_ptr
= shash_ptr
->sym_ptr
) == (SYMR
*)0)
3737 error ("Invalid .stabs/.stabn directive, value not found");
3741 if ((st_t
) sym_ptr
->st
!= st_Label
)
3743 error ("Invalid line number .stabs/.stabn directive");
3748 sc
= (sc_t
) sym_ptr
->sc
;
3749 value
= sym_ptr
->value
;
3753 /* Skip ,<num>,<num>, */
3756 for (; isdigit (*p
); p
++)
3760 for (; isdigit (*p
); p
++)
3765 if (!IS_ASM_IDENT (ch
) && ch
!= '-')
3768 error ("Invalid .stabs/.stabn directive, bad character");
3772 if (isdigit (ch
) || ch
== '-')
3776 value
= strtol (p
, &p
, 0);
3779 error ("Invalid .stabs/.stabn directive, stuff after numeric value");
3783 else if (!IS_ASM_IDENT (ch
))
3785 error ("Invalid .stabs/.stabn directive, bad character");
3792 const char *start
, *end_p1
;
3795 if ((end_p1
= strchr (start
, '+')) == (char *)0)
3797 if ((end_p1
= strchr (start
, '-')) == (char *)0)
3798 end_p1
= start
+ strlen(start
) - 1;
3801 shash_ptr
= hash_string (start
,
3806 if (shash_ptr
== (shash_t
*)0
3807 || (sym_ptr
= shash_ptr
->sym_ptr
) == (SYMR
*)0)
3809 shash_ptr
= hash_string (start
,
3814 if (shash_ptr
== (shash_t
*)0
3815 || shash_ptr
->esym_ptr
== (EXTR
*)0)
3817 error ("Invalid .stabs/.stabn directive, value not found");
3821 sym_ptr
= &(shash_ptr
->esym_ptr
->asym
);
3824 /* Traditionally, N_LBRAC and N_RBRAC are *not* relocated. */
3825 if (code
== (int)N_LBRAC
|| code
== (int)N_RBRAC
)
3832 sc
= (sc_t
) sym_ptr
->sc
;
3833 st
= (st_t
) sym_ptr
->st
;
3835 value
= sym_ptr
->value
;
3840 if (((!isdigit (*end_p1
)) && (*end_p1
!= '-'))
3841 || ((ch
!= '+') && (ch
!= '-')))
3843 error ("Invalid .stabs/.stabn directive, badly formed value");
3847 value
+= strtol (end_p1
, &p
, 0);
3849 value
-= strtol (end_p1
, &p
, 0);
3853 error ("Invalid .stabs/.stabn directive, stuff after numeric value");
3858 code
= MIPS_MARK_STAB(code
);
3861 (void) add_local_symbol (string_start
, string_end
, st
, sc
, value
, code
);
3862 /* Restore normal file type. */
3863 cur_file_ptr
= save_file_ptr
;
3869 const char *start
; /* start of directive */
3871 const char *end
= local_index (start
+1, '"');
3873 if (*start
!= '"' || end
== (const char *)0 || end
[1] != ',')
3875 error ("Invalid .stabs directive, no string");
3879 parse_stabs_common (start
+1, end
, end
+2);
3885 const char *start
; /* start of directive */
3887 parse_stabs_common ((const char *)0, (const char *)0, start
);
3891 /* Parse the input file, and write the lines to the output file
3895 parse_input
__proto((void))
3899 register thead_t
*ptag_head
;
3900 register tag_t
*ptag
;
3901 register tag_t
*ptag_next
;
3904 fprintf (stderr
, "\tinput\n");
3906 /* Add a dummy scope block around the entire compilation unit for
3907 structures defined outside of blocks. */
3908 ptag_head
= allocate_thead ();
3909 ptag_head
->first_tag
= 0;
3910 ptag_head
->prev
= cur_tag_head
;
3911 cur_tag_head
= ptag_head
;
3913 while ((p
= read_line ()) != (char *)0)
3915 /* Skip leading blanks */
3916 while (isspace (*p
))
3919 /* See if it's a directive we handle. If so, dispatch handler. */
3920 for (i
= 0; i
< sizeof (pseudo_ops
) / sizeof (pseudo_ops
[0]); i
++)
3921 if (memcmp (p
, pseudo_ops
[i
].name
, pseudo_ops
[i
].len
) == 0
3922 && isspace (p
[pseudo_ops
[i
].len
]))
3924 p
+= pseudo_ops
[i
].len
; /* skip to first argument */
3925 while (isspace (*p
))
3928 (*pseudo_ops
[i
].func
)( p
);
3933 /* Process any tags at global level. */
3934 ptag_head
= cur_tag_head
;
3935 cur_tag_head
= ptag_head
->prev
;
3937 for (ptag
= ptag_head
->first_tag
;
3941 if (ptag
->forward_ref
!= (forward_t
*)0)
3942 add_unknown_tag (ptag
);
3944 ptag_next
= ptag
->same_block
;
3945 ptag
->hash_ptr
->tag_ptr
= ptag
->same_name
;
3949 free_thead (ptag_head
);
3954 /* Update the global headers with the final offsets in preparation
3955 to write out the .T file. */
3958 update_headers
__proto((void))
3960 register symint_t i
;
3961 register efdr_t
*file_ptr
;
3963 /* Set up the symbolic header. */
3964 file_offset
= sizeof (symbolic_header
) + orig_file_header
.f_symptr
;
3965 symbolic_header
.magic
= orig_sym_hdr
.magic
;
3966 symbolic_header
.vstamp
= orig_sym_hdr
.vstamp
;
3968 /* Set up global counts. */
3969 symbolic_header
.issExtMax
= ext_strings
.num_allocated
;
3970 symbolic_header
.idnMax
= dense_num
.num_allocated
;
3971 symbolic_header
.ifdMax
= file_desc
.num_allocated
;
3972 symbolic_header
.iextMax
= ext_symbols
.num_allocated
;
3973 symbolic_header
.ilineMax
= orig_sym_hdr
.ilineMax
;
3974 symbolic_header
.ioptMax
= orig_sym_hdr
.ioptMax
;
3975 symbolic_header
.cbLine
= orig_sym_hdr
.cbLine
;
3976 symbolic_header
.crfd
= orig_sym_hdr
.crfd
;
3979 /* Loop through each file, figuring out how many local syms,
3980 line numbers, etc. there are. Also, put out end symbol
3981 for the filename. */
3983 for (file_ptr
= first_file
;
3984 file_ptr
!= (efdr_t
*)0;
3985 file_ptr
= file_ptr
->next_file
)
3987 cur_file_ptr
= file_ptr
;
3988 (void) add_local_symbol ((const char *)0, (const char *)0,
3993 file_ptr
->fdr
.cpd
= file_ptr
->procs
.num_allocated
;
3994 file_ptr
->fdr
.ipdFirst
= symbolic_header
.ipdMax
;
3995 symbolic_header
.ipdMax
+= file_ptr
->fdr
.cpd
;
3997 file_ptr
->fdr
.csym
= file_ptr
->symbols
.num_allocated
;
3998 file_ptr
->fdr
.isymBase
= symbolic_header
.isymMax
;
3999 symbolic_header
.isymMax
+= file_ptr
->fdr
.csym
;
4001 file_ptr
->fdr
.caux
= file_ptr
->aux_syms
.num_allocated
;
4002 file_ptr
->fdr
.iauxBase
= symbolic_header
.iauxMax
;
4003 symbolic_header
.iauxMax
+= file_ptr
->fdr
.caux
;
4005 file_ptr
->fdr
.cbSs
= file_ptr
->strings
.num_allocated
;
4006 file_ptr
->fdr
.issBase
= symbolic_header
.issMax
;
4007 symbolic_header
.issMax
+= file_ptr
->fdr
.cbSs
;
4011 i
= WORD_ALIGN (symbolic_header
.cbLine
); /* line numbers */
4014 symbolic_header
.cbLineOffset
= file_offset
;
4018 i
= symbolic_header
.ioptMax
; /* optimization symbols */
4021 symbolic_header
.cbOptOffset
= file_offset
;
4022 file_offset
+= i
* sizeof (OPTR
);
4025 i
= symbolic_header
.idnMax
; /* dense numbers */
4028 symbolic_header
.cbDnOffset
= file_offset
;
4029 file_offset
+= i
* sizeof (DNR
);
4032 i
= symbolic_header
.ipdMax
; /* procedure tables */
4035 symbolic_header
.cbPdOffset
= file_offset
;
4036 file_offset
+= i
* sizeof (PDR
);
4039 i
= symbolic_header
.isymMax
; /* local symbols */
4042 symbolic_header
.cbSymOffset
= file_offset
;
4043 file_offset
+= i
* sizeof (SYMR
);
4046 i
= symbolic_header
.iauxMax
; /* aux syms. */
4049 symbolic_header
.cbAuxOffset
= file_offset
;
4050 file_offset
+= i
* sizeof (TIR
);
4053 i
= WORD_ALIGN (symbolic_header
.issMax
); /* local strings */
4056 symbolic_header
.cbSsOffset
= file_offset
;
4060 i
= WORD_ALIGN (symbolic_header
.issExtMax
); /* external strings */
4063 symbolic_header
.cbSsExtOffset
= file_offset
;
4067 i
= symbolic_header
.ifdMax
; /* file tables */
4070 symbolic_header
.cbFdOffset
= file_offset
;
4071 file_offset
+= i
* sizeof (FDR
);
4074 i
= symbolic_header
.crfd
; /* relative file descriptors */
4077 symbolic_header
.cbRfdOffset
= file_offset
;
4078 file_offset
+= i
* sizeof (symint_t
);
4081 i
= symbolic_header
.iextMax
; /* external symbols */
4084 symbolic_header
.cbExtOffset
= file_offset
;
4085 file_offset
+= i
* sizeof (EXTR
);
4090 /* Write out a varray at a given location. */
4093 write_varray (vp
, offset
, str
)
4094 varray_t
*vp
; /* virtual array */
4095 off_t offset
; /* offset to write varray to */
4096 const char *str
; /* string to print out when tracing */
4098 int num_write
, sys_write
;
4101 if (vp
->num_allocated
== 0)
4105 fprintf (stderr
, "\twarray\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4106 vp
, offset
, vp
->num_allocated
* vp
->object_size
, str
);
4108 if (file_offset
!= offset
4109 && fseek (object_stream
, (long)offset
, SEEK_SET
) < 0)
4110 pfatal_with_name (object_name
);
4112 for (ptr
= vp
->first
; ptr
!= (vlinks_t
*)0; ptr
= ptr
->next
)
4114 num_write
= (ptr
->next
== (vlinks_t
*)0)
4115 ? vp
->objects_last_page
* vp
->object_size
4116 : vp
->objects_per_page
* vp
->object_size
;
4118 sys_write
= fwrite ((PTR_T
) ptr
->datum
, 1, num_write
, object_stream
);
4120 pfatal_with_name (object_name
);
4122 else if (sys_write
!= num_write
)
4123 fatal ("Wrote %d bytes to %s, system returned %d",
4128 file_offset
+= num_write
;
4133 /* Write out the symbol table in the object file. */
4136 write_object
__proto((void))
4143 fprintf (stderr
, "\n\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4144 (PTR_T
*) &symbolic_header
, 0, sizeof (symbolic_header
),
4147 sys_write
= fwrite ((PTR_T
) &symbolic_header
,
4149 sizeof (symbolic_header
),
4153 pfatal_with_name (object_name
);
4155 else if (sys_write
!= sizeof (symbolic_header
))
4156 fatal ("Wrote %d bytes to %s, system returned %d",
4157 sizeof (symbolic_header
),
4162 file_offset
= sizeof (symbolic_header
) + orig_file_header
.f_symptr
;
4164 if (symbolic_header
.cbLine
> 0) /* line numbers */
4168 if (file_offset
!= symbolic_header
.cbLineOffset
4169 && fseek (object_stream
, symbolic_header
.cbLineOffset
, SEEK_SET
) != 0)
4170 pfatal_with_name (object_name
);
4173 fprintf (stderr
, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4174 (PTR_T
*) &orig_linenum
, symbolic_header
.cbLineOffset
,
4175 symbolic_header
.cbLine
, "Line numbers");
4177 sys_write
= fwrite ((PTR_T
) orig_linenum
,
4179 symbolic_header
.cbLine
,
4183 pfatal_with_name (object_name
);
4185 else if (sys_write
!= symbolic_header
.cbLine
)
4186 fatal ("Wrote %d bytes to %s, system returned %d",
4187 symbolic_header
.cbLine
,
4191 file_offset
= symbolic_header
.cbLineOffset
+ symbolic_header
.cbLine
;
4194 if (symbolic_header
.ioptMax
> 0) /* optimization symbols */
4197 long num_write
= symbolic_header
.ioptMax
* sizeof (OPTR
);
4199 if (file_offset
!= symbolic_header
.cbOptOffset
4200 && fseek (object_stream
, symbolic_header
.cbOptOffset
, SEEK_SET
) != 0)
4201 pfatal_with_name (object_name
);
4204 fprintf (stderr
, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4205 (PTR_T
*) &orig_opt_syms
, symbolic_header
.cbOptOffset
,
4206 num_write
, "Optimizer symbols");
4208 sys_write
= fwrite ((PTR_T
) orig_opt_syms
,
4214 pfatal_with_name (object_name
);
4216 else if (sys_write
!= num_write
)
4217 fatal ("Wrote %d bytes to %s, system returned %d",
4222 file_offset
= symbolic_header
.cbOptOffset
+ num_write
;
4225 if (symbolic_header
.idnMax
> 0) /* dense numbers */
4226 write_varray (&dense_num
, (off_t
)symbolic_header
.cbDnOffset
, "Dense numbers");
4228 if (symbolic_header
.ipdMax
> 0) /* procedure tables */
4230 offset
= symbolic_header
.cbPdOffset
;
4231 for (file_ptr
= first_file
;
4232 file_ptr
!= (efdr_t
*)0;
4233 file_ptr
= file_ptr
->next_file
)
4235 write_varray (&file_ptr
->procs
, offset
, "Procedure tables");
4236 offset
= file_offset
;
4240 if (symbolic_header
.isymMax
> 0) /* local symbols */
4242 offset
= symbolic_header
.cbSymOffset
;
4243 for (file_ptr
= first_file
;
4244 file_ptr
!= (efdr_t
*)0;
4245 file_ptr
= file_ptr
->next_file
)
4247 write_varray (&file_ptr
->symbols
, offset
, "Local symbols");
4248 offset
= file_offset
;
4252 if (symbolic_header
.iauxMax
> 0) /* aux symbols */
4254 offset
= symbolic_header
.cbAuxOffset
;
4255 for (file_ptr
= first_file
;
4256 file_ptr
!= (efdr_t
*)0;
4257 file_ptr
= file_ptr
->next_file
)
4259 write_varray (&file_ptr
->aux_syms
, offset
, "Aux. symbols");
4260 offset
= file_offset
;
4264 if (symbolic_header
.issMax
> 0) /* local strings */
4266 offset
= symbolic_header
.cbSsOffset
;
4267 for (file_ptr
= first_file
;
4268 file_ptr
!= (efdr_t
*)0;
4269 file_ptr
= file_ptr
->next_file
)
4271 write_varray (&file_ptr
->strings
, offset
, "Local strings");
4272 offset
= file_offset
;
4276 if (symbolic_header
.issExtMax
> 0) /* external strings */
4277 write_varray (&ext_strings
, symbolic_header
.cbSsExtOffset
, "External strings");
4279 if (symbolic_header
.ifdMax
> 0) /* file tables */
4281 offset
= symbolic_header
.cbFdOffset
;
4282 if (file_offset
!= offset
4283 && fseek (object_stream
, (long)offset
, SEEK_SET
) < 0)
4284 pfatal_with_name (object_name
);
4286 file_offset
= offset
;
4287 for (file_ptr
= first_file
;
4288 file_ptr
!= (efdr_t
*)0;
4289 file_ptr
= file_ptr
->next_file
)
4292 fprintf (stderr
, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4293 (PTR_T
*) &file_ptr
->fdr
, file_offset
, sizeof (FDR
), "File header");
4295 sys_write
= fwrite (&file_ptr
->fdr
,
4301 pfatal_with_name (object_name
);
4303 else if (sys_write
!= sizeof (FDR
))
4304 fatal ("Wrote %d bytes to %s, system returned %d",
4309 file_offset
= offset
+= sizeof (FDR
);
4313 if (symbolic_header
.crfd
> 0) /* relative file descriptors */
4316 symint_t num_write
= symbolic_header
.crfd
* sizeof (symint_t
);
4318 if (file_offset
!= symbolic_header
.cbRfdOffset
4319 && fseek (object_stream
, symbolic_header
.cbRfdOffset
, SEEK_SET
) != 0)
4320 pfatal_with_name (object_name
);
4323 fprintf (stderr
, "\twrite\tvp = 0x%.8x, offset = %7u, size = %7u, %s\n",
4324 (PTR_T
*) &orig_rfds
, symbolic_header
.cbRfdOffset
,
4325 num_write
, "Relative file descriptors");
4327 sys_write
= fwrite (orig_rfds
,
4333 pfatal_with_name (object_name
);
4335 else if (sys_write
!= num_write
)
4336 fatal ("Wrote %d bytes to %s, system returned %d",
4341 file_offset
= symbolic_header
.cbRfdOffset
+ num_write
;
4344 if (symbolic_header
.issExtMax
> 0) /* external symbols */
4345 write_varray (&ext_symbols
, (off_t
)symbolic_header
.cbExtOffset
, "External symbols");
4347 if (fclose (object_stream
) != 0)
4348 pfatal_with_name (object_name
);
4352 /* Read some bytes at a specified location, and return a pointer. */
4355 read_seek (size
, offset
, str
)
4356 Size_t size
; /* # bytes to read */
4357 off_t offset
; /* offset to read at */
4358 const char *str
; /* name for tracing */
4363 if (size
== 0) /* nothing to read */
4367 fprintf (stderr
, "\trseek\tsize = %7u, offset = %7u, currently at %7u, %s\n",
4368 size
, offset
, file_offset
, str
);
4370 #ifndef MALLOC_CHECK
4371 ptr
= allocate_multiple_pages ((size
+ PAGE_USIZE
- 1) / PAGE_USIZE
);
4373 ptr
= (page_t
*) xcalloc (1, size
);
4376 /* If we need to seek, and the distance is nearby, just do some reads,
4377 to speed things up. */
4378 if (file_offset
!= offset
)
4380 symint_t difference
= offset
- file_offset
;
4384 char small_buffer
[8];
4386 sys_read
= fread (small_buffer
, 1, difference
, obj_in_stream
);
4388 pfatal_with_name (obj_in_name
);
4390 if (sys_read
!= difference
)
4391 fatal ("Wanted to read %d bytes from %s, system returned %d",
4396 else if (fseek (obj_in_stream
, offset
, SEEK_SET
) < 0)
4397 pfatal_with_name (obj_in_name
);
4400 sys_read
= fread ((PTR_T
)ptr
, 1, size
, obj_in_stream
);
4402 pfatal_with_name (obj_in_name
);
4404 if (sys_read
!= size
)
4405 fatal ("Wanted to read %d bytes from %s, system returned %d",
4410 file_offset
= offset
+ size
;
4412 if (file_offset
> max_file_offset
)
4413 max_file_offset
= file_offset
;
4419 /* Read the existing object file (and copy to the output object file
4420 if it is different from the input object file), and remove the old
4424 copy_object
__proto((void))
4426 char buffer
[ PAGE_SIZE
];
4427 register int sys_read
;
4428 register int remaining
;
4429 register int num_write
;
4430 register int sys_write
;
4431 register int fd
, es
;
4432 register int delete_ifd
= 0;
4433 register int *remap_file_number
;
4434 struct stat stat_buf
;
4437 fprintf (stderr
, "\tcopy\n");
4439 if (fstat (fileno (obj_in_stream
), &stat_buf
) != 0
4440 || fseek (obj_in_stream
, 0L, SEEK_SET
) != 0)
4441 pfatal_with_name (obj_in_name
);
4443 sys_read
= fread ((PTR_T
) &orig_file_header
,
4445 sizeof (struct filehdr
),
4449 pfatal_with_name (obj_in_name
);
4451 else if (sys_read
== 0 && feof (obj_in_stream
))
4452 return; /* create a .T file sans file header */
4454 else if (sys_read
< sizeof (struct filehdr
))
4455 fatal ("Wanted to read %d bytes from %s, system returned %d",
4456 sizeof (struct filehdr
),
4461 if (orig_file_header
.f_nsyms
!= sizeof (HDRR
))
4462 fatal ("%s symbolic header wrong size (%d bytes, should be %d)",
4463 input_name
, orig_file_header
.f_nsyms
, sizeof (HDRR
));
4466 /* Read in the current symbolic header. */
4467 if (fseek (obj_in_stream
, (long) orig_file_header
.f_symptr
, SEEK_SET
) != 0)
4468 pfatal_with_name (input_name
);
4470 sys_read
= fread ((PTR_T
) &orig_sym_hdr
,
4472 sizeof (orig_sym_hdr
),
4476 pfatal_with_name (object_name
);
4478 else if (sys_read
< sizeof (struct filehdr
))
4479 fatal ("Wanted to read %d bytes from %s, system returned %d",
4480 sizeof (struct filehdr
),
4485 /* Read in each of the sections if they exist in the object file.
4486 We read things in in the order the mips assembler creates the
4487 sections, so in theory no extra seeks are done.
4489 For simplicity sake, round each read up to a page boundary,
4490 we may want to revisit this later.... */
4492 file_offset
= orig_file_header
.f_symptr
+ sizeof (struct filehdr
);
4494 if (orig_sym_hdr
.cbLine
> 0) /* line numbers */
4495 orig_linenum
= (char *) read_seek ((Size_t
)orig_sym_hdr
.cbLine
,
4496 orig_sym_hdr
.cbLineOffset
,
4499 if (orig_sym_hdr
.ipdMax
> 0) /* procedure tables */
4500 orig_procs
= (PDR
*) read_seek ((Size_t
)orig_sym_hdr
.ipdMax
* sizeof (PDR
),
4501 orig_sym_hdr
.cbPdOffset
,
4502 "Procedure tables");
4504 if (orig_sym_hdr
.isymMax
> 0) /* local symbols */
4505 orig_local_syms
= (SYMR
*) read_seek ((Size_t
)orig_sym_hdr
.isymMax
* sizeof (SYMR
),
4506 orig_sym_hdr
.cbSymOffset
,
4509 if (orig_sym_hdr
.iauxMax
> 0) /* aux symbols */
4510 orig_aux_syms
= (AUXU
*) read_seek ((Size_t
)orig_sym_hdr
.iauxMax
* sizeof (AUXU
),
4511 orig_sym_hdr
.cbAuxOffset
,
4514 if (orig_sym_hdr
.issMax
> 0) /* local strings */
4515 orig_local_strs
= (char *) read_seek ((Size_t
)orig_sym_hdr
.issMax
,
4516 orig_sym_hdr
.cbSsOffset
,
4519 if (orig_sym_hdr
.issExtMax
> 0) /* external strings */
4520 orig_ext_strs
= (char *) read_seek ((Size_t
)orig_sym_hdr
.issExtMax
,
4521 orig_sym_hdr
.cbSsExtOffset
,
4522 "External strings");
4524 if (orig_sym_hdr
.ifdMax
> 0) /* file tables */
4525 orig_files
= (FDR
*) read_seek ((Size_t
)orig_sym_hdr
.ifdMax
* sizeof (FDR
),
4526 orig_sym_hdr
.cbFdOffset
,
4529 if (orig_sym_hdr
.crfd
> 0) /* relative file descriptors */
4530 orig_rfds
= (symint_t
*) read_seek ((Size_t
)orig_sym_hdr
.crfd
* sizeof (symint_t
),
4531 orig_sym_hdr
.cbRfdOffset
,
4532 "Relative file descriptors");
4534 if (orig_sym_hdr
.issExtMax
> 0) /* external symbols */
4535 orig_ext_syms
= (EXTR
*) read_seek ((Size_t
)orig_sym_hdr
.iextMax
* sizeof (EXTR
),
4536 orig_sym_hdr
.cbExtOffset
,
4537 "External symbols");
4539 if (orig_sym_hdr
.idnMax
> 0) /* dense numbers */
4541 orig_dense
= (DNR
*) read_seek ((Size_t
)orig_sym_hdr
.idnMax
* sizeof (DNR
),
4542 orig_sym_hdr
.cbDnOffset
,
4545 add_bytes (&dense_num
, (char *) orig_dense
, (Size_t
)orig_sym_hdr
.idnMax
);
4548 if (orig_sym_hdr
.ioptMax
> 0) /* opt symbols */
4549 orig_opt_syms
= (OPTR
*) read_seek ((Size_t
)orig_sym_hdr
.ioptMax
* sizeof (OPTR
),
4550 orig_sym_hdr
.cbOptOffset
,
4551 "Optimizer symbols");
4555 /* Abort if the symbol table is not last. */
4556 if (max_file_offset
!= stat_buf
.st_size
)
4557 fatal ("Symbol table is not last (symbol table ends at %ld, .o ends at %ld",
4562 /* If the first original file descriptor is a dummy which the assembler
4563 put out, but there are no symbols in it, skip it now. */
4564 if (orig_sym_hdr
.ifdMax
> 1
4565 && orig_files
->csym
== 2
4566 && orig_files
->caux
== 0)
4568 char *filename
= orig_local_strs
+ (orig_files
->issBase
+ orig_files
->rss
);
4569 char *suffix
= local_rindex (filename
, '.');
4571 if (suffix
!= (char *)0 && strcmp (suffix
, ".s") == 0)
4576 /* Create array to map original file numbers to the new file numbers
4577 (in case there are duplicate filenames, we collapse them into one
4578 file section, the MIPS assembler may or may not collapse them). */
4580 remap_file_number
= (int *) alloca (sizeof (int) * orig_sym_hdr
.ifdMax
);
4582 for (fd
= delete_ifd
; fd
< orig_sym_hdr
.ifdMax
; fd
++)
4584 register FDR
*fd_ptr
= ORIG_FILES (fd
);
4585 register char *filename
= ORIG_LSTRS (fd_ptr
->issBase
+ fd_ptr
->rss
);
4587 /* file support itself. */
4588 add_file (filename
, filename
+ strlen (filename
));
4589 remap_file_number
[fd
] = cur_file_ptr
->file_index
;
4592 if (delete_ifd
> 0) /* just in case */
4593 remap_file_number
[0] = remap_file_number
[1];
4596 /* Loop, adding each of the external symbols. These must be in
4597 order or otherwise we would have to change the relocation
4598 entries. We don't just call add_bytes, because we need to have
4599 the names put into the external hash table. We set the type to
4600 'void' for now, and parse_def will fill in the correct type if it
4601 is in the symbol table. We must add the external symbols before
4602 the locals, since the locals do lookups against the externals. */
4605 fprintf (stderr
, "\tehash\n");
4607 for (es
= 0; es
< orig_sym_hdr
.iextMax
; es
++)
4609 register EXTR
*eptr
= orig_ext_syms
+ es
;
4610 register char *ename
= ORIG_ESTRS (eptr
->asym
.iss
);
4611 register unsigned ifd
= eptr
->ifd
;
4613 (void) add_ext_symbol (ename
,
4614 ename
+ strlen (ename
),
4615 (st_t
) eptr
->asym
.st
,
4616 (sc_t
) eptr
->asym
.sc
,
4618 (symint_t
)((eptr
->asym
.index
== indexNil
) ? indexNil
: 0),
4619 (ifd
< orig_sym_hdr
.ifdMax
) ? remap_file_number
[ ifd
] : ifd
);
4623 /* For each of the files in the object file, copy the symbols, and such
4624 into the varrays for the new object file. */
4626 for (fd
= delete_ifd
; fd
< orig_sym_hdr
.ifdMax
; fd
++)
4628 register FDR
*fd_ptr
= ORIG_FILES (fd
);
4629 register char *filename
= ORIG_LSTRS (fd_ptr
->issBase
+ fd_ptr
->rss
);
4630 register SYMR
*sym_start
;
4632 register SYMR
*sym_end_p1
;
4633 register PDR
*proc_start
;
4635 register PDR
*proc_end_p1
;
4637 /* file support itself. */
4638 add_file (filename
, filename
+ strlen (filename
));
4639 cur_file_ptr
->orig_fdr
= fd_ptr
;
4641 /* Copy stuff that's just passed through (such as line #'s) */
4642 cur_file_ptr
->fdr
.adr
= fd_ptr
->adr
;
4643 cur_file_ptr
->fdr
.ilineBase
= fd_ptr
->ilineBase
;
4644 cur_file_ptr
->fdr
.cline
= fd_ptr
->cline
;
4645 cur_file_ptr
->fdr
.rfdBase
= fd_ptr
->rfdBase
;
4646 cur_file_ptr
->fdr
.crfd
= fd_ptr
->crfd
;
4647 cur_file_ptr
->fdr
.cbLineOffset
= fd_ptr
->cbLineOffset
;
4648 cur_file_ptr
->fdr
.cbLine
= fd_ptr
->cbLine
;
4649 cur_file_ptr
->fdr
.fMerge
= fd_ptr
->fMerge
;
4650 cur_file_ptr
->fdr
.fReadin
= fd_ptr
->fReadin
;
4651 cur_file_ptr
->fdr
.glevel
= fd_ptr
->glevel
;
4654 fprintf (stderr
, "\thash\tstart, filename %s\n", filename
);
4656 /* For each of the static and global symbols defined, add them
4657 to the hash table of original symbols, so we can look up
4660 sym_start
= ORIG_LSYMS (fd_ptr
->isymBase
);
4661 sym_end_p1
= sym_start
+ fd_ptr
->csym
;
4662 for (sym
= sym_start
; sym
< sym_end_p1
; sym
++)
4664 switch ((st_t
) sym
->st
)
4675 auto symint_t hash_index
;
4676 register char *str
= ORIG_LSTRS (fd_ptr
->issBase
+ sym
->iss
);
4677 register Size_t len
= strlen (str
);
4678 register shash_t
*shash_ptr
= hash_string (str
,
4683 if (shash_ptr
!= (shash_t
*)0)
4684 error ("internal error, %s is already in original symbol table", str
);
4688 shash_ptr
= allocate_shash ();
4689 shash_ptr
->next
= orig_str_hash
[hash_index
];
4690 orig_str_hash
[hash_index
] = shash_ptr
;
4692 shash_ptr
->len
= len
;
4693 shash_ptr
->indx
= indexNil
;
4694 shash_ptr
->string
= str
;
4695 shash_ptr
->sym_ptr
= sym
;
4701 if ((sc_t
) sym
->sc
== sc_Text
)
4703 register char *str
= ORIG_LSTRS (fd_ptr
->issBase
+ sym
->iss
);
4707 register Size_t len
= strlen (str
);
4708 register shash_t
*shash_ptr
= hash_string (str
,
4713 if (shash_ptr
!= (shash_t
*)0)
4714 shash_ptr
->end_ptr
= sym
;
4724 fprintf (stderr
, "\thash\tdone, filename %s\n", filename
);
4725 fprintf (stderr
, "\tproc\tstart, filename %s\n", filename
);
4728 /* Go through each of the procedures in this file, and add the
4729 procedure pointer to the hash entry for the given name. */
4731 proc_start
= ORIG_PROCS (fd_ptr
->ipdFirst
);
4732 proc_end_p1
= proc_start
+ fd_ptr
->cpd
;
4733 for (proc
= proc_start
; proc
< proc_end_p1
; proc
++)
4735 register SYMR
*proc_sym
= ORIG_LSYMS (fd_ptr
->isymBase
+ proc
->isym
);
4736 register char *str
= ORIG_LSTRS (fd_ptr
->issBase
+ proc_sym
->iss
);
4737 register Size_t len
= strlen (str
);
4738 register shash_t
*shash_ptr
= hash_string (str
,
4743 if (shash_ptr
== (shash_t
*)0)
4744 error ("internal error, function %s is not in original symbol table", str
);
4747 shash_ptr
->proc_ptr
= proc
;
4751 fprintf (stderr
, "\tproc\tdone, filename %s\n", filename
);
4754 cur_file_ptr
= first_file
;
4757 /* Copy all of the object file up to the symbol table. Originally
4758 we were going to use ftruncate, but that doesn't seem to work
4759 on Ultrix 3.1.... */
4761 if (fseek (obj_in_stream
, (long)0, SEEK_SET
) != 0)
4762 pfatal_with_name (obj_in_name
);
4764 if (fseek (object_stream
, (long)0, SEEK_SET
) != 0)
4765 pfatal_with_name (object_name
);
4767 for (remaining
= orig_file_header
.f_symptr
;
4769 remaining
-= num_write
)
4771 num_write
= (remaining
<= sizeof (buffer
)) ? remaining
: sizeof (buffer
);
4772 sys_read
= fread ((PTR_T
) buffer
, 1, num_write
, obj_in_stream
);
4774 pfatal_with_name (obj_in_name
);
4776 else if (sys_read
!= num_write
)
4777 fatal ("Wanted to read %d bytes from %s, system returned %d",
4782 sys_write
= fwrite (buffer
, 1, num_write
, object_stream
);
4784 pfatal_with_name (object_name
);
4786 else if (sys_write
!= num_write
)
4787 fatal ("Wrote %d bytes to %s, system returned %d",
4795 /* Ye olde main program. */
4803 char *p
= local_rindex (argv
[0], '/');
4808 progname
= (p
!= 0) ? p
+1 : argv
[0];
4810 (void) signal (SIGSEGV
, catch_signal
);
4811 (void) signal (SIGBUS
, catch_signal
);
4812 (void) signal (SIGABRT
, catch_signal
);
4814 #if !defined(__SABER__) && !defined(lint)
4815 if (sizeof (efdr_t
) > PAGE_USIZE
)
4816 fatal ("Efdr_t has a sizeof %d bytes, when it should be less than %d",
4820 if (sizeof (page_t
) != PAGE_USIZE
)
4821 fatal ("Page_t has a sizeof %d bytes, when it should be %d",
4827 alloc_counts
[ alloc_type_none
].alloc_name
= "none";
4828 alloc_counts
[ alloc_type_scope
].alloc_name
= "scope";
4829 alloc_counts
[ alloc_type_vlinks
].alloc_name
= "vlinks";
4830 alloc_counts
[ alloc_type_shash
].alloc_name
= "shash";
4831 alloc_counts
[ alloc_type_thash
].alloc_name
= "thash";
4832 alloc_counts
[ alloc_type_tag
].alloc_name
= "tag";
4833 alloc_counts
[ alloc_type_forward
].alloc_name
= "forward";
4834 alloc_counts
[ alloc_type_thead
].alloc_name
= "thead";
4835 alloc_counts
[ alloc_type_varray
].alloc_name
= "varray";
4837 int_type_info
= type_info_init
;
4838 int_type_info
.basic_type
= bt_Int
;
4840 void_type_info
= type_info_init
;
4841 void_type_info
.basic_type
= bt_Void
;
4843 while ((option
= getopt (argc
, argv
, "d:i:I:o:v")) != EOF
)
4851 debug
= strtol (optarg
, &num_end
, 0);
4852 if ((unsigned)debug
> 4 || num_end
== optarg
)
4858 if (rename_output
|| obj_in_name
!= (char *)0)
4863 /* fall through to 'i' case. */
4866 if (obj_in_name
== (char *)0)
4868 obj_in_name
= optarg
;
4876 if (object_name
== (char *)0)
4877 object_name
= optarg
;
4887 if (obj_in_name
== (char *)0 && optind
<= argc
- 2)
4888 obj_in_name
= argv
[--argc
];
4890 if (object_name
== (char *)0 && optind
<= argc
- 2)
4891 object_name
= argv
[--argc
];
4893 /* If there is an output name, but no input name use
4894 the same file for both, deleting the name between
4895 opening it for input and opening it for output. */
4896 if (obj_in_name
== (char *)0 && object_name
!= (char *)0)
4898 obj_in_name
= object_name
;
4902 if (object_name
== (char *)0 || had_errors
|| optind
!= argc
- 1)
4904 fprintf (stderr
, "Calling Sequence:\n");
4905 fprintf (stderr
, "\tmips-tfile [-d <num>] [-v] [-i <o-in-file>] -o <o-out-file> <s-file> (or)\n");
4906 fprintf (stderr
, "\tmips-tfile [-d <num>] [-v] [-I <o-in-file>] -o <o-out-file> <s-file> (or)\n");
4907 fprintf (stderr
, "\tmips-tfile [-d <num>] [-v] <s-file> <o-in-file> <o-out-file>\n");
4908 fprintf (stderr
, "\n");
4909 fprintf (stderr
, "Debug levels are:\n");
4910 fprintf (stderr
, " 1\tGeneral debug + trace functions/blocks.\n");
4911 fprintf (stderr
, " 2\tDebug level 1 + trace externals.\n");
4912 fprintf (stderr
, " 3\tDebug level 2 + trace all symbols.\n");
4913 fprintf (stderr
, " 4\tDebug level 3 + trace memory allocations.\n");
4920 fprintf (stderr
, "mips-tfile version %s", version_string
);
4921 #ifdef TARGET_VERSION
4924 fputc ('\n', stderr
);
4927 if (obj_in_name
== (char *)0)
4928 obj_in_name
= object_name
;
4930 if (rename_output
&& rename (object_name
, obj_in_name
) != 0)
4932 char *buffer
= (char *) allocate_multiple_pages (4);
4938 /* Rename failed, copy input file */
4939 in_fd
= open (object_name
, O_RDONLY
, 0666);
4941 pfatal_with_name (object_name
);
4943 out_fd
= open (obj_in_name
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
4945 pfatal_with_name (obj_in_name
);
4947 while ((len
= read (in_fd
, buffer
, 4*PAGE_SIZE
)) > 0)
4949 len2
= write (out_fd
, buffer
, len
);
4951 pfatal_with_name (object_name
);
4954 fatal ("wrote %d bytes to %s, expected to write %d", len2
, obj_in_name
, len
);
4957 free_multiple_pages ((page_t
*)buffer
, 4);
4960 pfatal_with_name (object_name
);
4962 if (close (in_fd
) < 0)
4963 pfatal_with_name (object_name
);
4965 if (close (out_fd
) < 0)
4966 pfatal_with_name (obj_in_name
);
4969 /* Must open input before output, since the output may be the same file, and
4970 we need to get the input handle before truncating it. */
4971 obj_in_stream
= fopen (obj_in_name
, "r");
4972 if (obj_in_stream
== (FILE *)0)
4973 pfatal_with_name (obj_in_name
);
4975 if (delete_input
&& unlink (obj_in_name
) != 0)
4976 pfatal_with_name (obj_in_name
);
4978 object_stream
= fopen (object_name
, "w");
4979 if (object_stream
== (FILE *)0)
4980 pfatal_with_name (object_name
);
4982 if (strcmp (argv
[optind
], "-") != 0)
4984 input_name
= argv
[optind
];
4985 if (freopen (argv
[optind
], "r", stdin
) != stdin
)
4986 pfatal_with_name (argv
[optind
]);
4989 copy_object (); /* scan & copy object file */
4990 parse_input (); /* scan all of input */
4992 update_headers (); /* write out tfile */
4997 fprintf (stderr
, "\n\tAllocation summary:\n\n");
4998 for (i
= (int)alloc_type_none
; i
< (int)alloc_type_last
; i
++)
4999 if (alloc_counts
[i
].total_alloc
)
5002 "\t%s\t%5d allocation(s), %5d free(s), %2d page(s)\n",
5003 alloc_counts
[i
].alloc_name
,
5004 alloc_counts
[i
].total_alloc
,
5005 alloc_counts
[i
].total_free
,
5006 alloc_counts
[i
].total_pages
);
5010 return (had_errors
) ? 1 : 0;
5014 /* Catch a signal and exit without dumping core. */
5017 catch_signal (signum
)
5020 (void) signal (signum
, SIG_DFL
); /* just in case... */
5021 #ifdef NO_SYS_SIGLIST
5022 fatal ("caught signal");
5024 fatal (sys_siglist
[signum
]);
5028 /* Print a fatal error message. NAME is the text.
5029 Also include a system error message based on `errno'. */
5032 pfatal_with_name (msg
)
5035 int save_errno
= errno
; /* just in case.... */
5036 if (line_number
> 0)
5037 fprintf (stderr
, "%s, %s:%ld ", progname
, input_name
, line_number
);
5039 fprintf (stderr
, "%s:", progname
);
5043 fprintf (stderr
, "[errno = 0] %s\n", msg
);
5051 /* Procedure to abort with an out of bounds error message. It has
5052 type int, so it can be used with an ?: expression within the
5053 ORIG_xxx macros, but the function never returns. */
5056 out_of_bounds (indx
, max
, str
, prog_line
)
5057 symint_t indx
; /* index that is out of bounds */
5058 symint_t max
; /* maximum index */
5059 const char *str
; /* string to print out */
5060 int prog_line
; /* line number within mips-tfile.c */
5062 if (indx
< max
) /* just in case */
5065 fprintf (stderr
, "%s, %s:%ld index %u is out of bounds for %s, max is %u, mips-tfile.c line# %d\n",
5066 progname
, input_name
, line_number
, indx
, str
, max
, prog_line
);
5069 return 0; /* turn off warning messages */
5073 /* Allocate a cluster of pages. USE_MALLOC says that malloc does not
5074 like sbrk's behind it's back (or sbrk isn't available). If we use
5075 sbrk, we assume it gives us zeroed pages. */
5077 #ifndef MALLOC_CHECK
5081 allocate_cluster (npages
)
5084 register page_t
*value
= (page_t
*) calloc (npages
, PAGE_USIZE
);
5087 fatal ("Virtual memory exhausted.");
5090 fprintf (stderr
, "\talloc\tnpages = %d, value = 0x%.8x\n", npages
, value
);
5095 #else /* USE_MALLOC */
5098 allocate_cluster (npages
)
5101 register page_t
*ptr
= (page_t
*) sbrk (0); /* current sbreak */
5102 unsigned long offset
= ((unsigned long) ptr
) & (PAGE_SIZE
- 1);
5104 if (offset
!= 0) /* align to a page boundary */
5106 if (sbrk (PAGE_USIZE
- offset
) == (char *)-1)
5107 pfatal_with_name ("allocate_cluster");
5109 ptr
= (page_t
*) (((char *)ptr
) + PAGE_SIZE
- offset
);
5112 if (sbrk (npages
* PAGE_USIZE
) == (char *)-1)
5113 pfatal_with_name ("allocate_cluster");
5116 fprintf (stderr
, "\talloc\tnpages = %d, value = 0x%.8x\n", npages
, ptr
);
5121 #endif /* USE_MALLOC */
5124 static page_t
*cluster_ptr
= NULL
;
5125 static unsigned pages_left
= 0;
5127 #endif /* MALLOC_CHECK */
5130 /* Allocate some pages (which is initialized to 0). */
5133 allocate_multiple_pages (npages
)
5136 #ifndef MALLOC_CHECK
5137 if (pages_left
== 0 && npages
< MAX_CLUSTER_PAGES
)
5139 pages_left
= MAX_CLUSTER_PAGES
;
5140 cluster_ptr
= allocate_cluster (MAX_CLUSTER_PAGES
);
5143 if (npages
<= pages_left
)
5145 page_t
*ptr
= cluster_ptr
;
5146 cluster_ptr
+= npages
;
5147 pages_left
-= npages
;
5151 return allocate_cluster (npages
);
5153 #else /* MALLOC_CHECK */
5154 return (page_t
*) xcalloc (npages
, PAGE_SIZE
);
5156 #endif /* MALLOC_CHECK */
5160 /* Release some pages. */
5163 free_multiple_pages (page_ptr
, npages
)
5167 #ifndef MALLOC_CHECK
5168 if (pages_left
== 0)
5170 cluster_ptr
= page_ptr
;
5171 pages_left
= npages
;
5174 else if ((page_ptr
+ npages
) == cluster_ptr
)
5176 cluster_ptr
-= npages
;
5177 pages_left
+= npages
;
5180 /* otherwise the page is not freed. If more than call is
5181 done, we probably should worry about it, but at present,
5182 the free pages is done right after an allocate. */
5184 #else /* MALLOC_CHECK */
5185 free ((char *) page_ptr
);
5187 #endif /* MALLOC_CHECK */
5191 /* Allocate one page (which is initialized to 0). */
5194 allocate_page
__proto((void))
5196 #ifndef MALLOC_CHECK
5197 if (pages_left
== 0)
5199 pages_left
= MAX_CLUSTER_PAGES
;
5200 cluster_ptr
= allocate_cluster (MAX_CLUSTER_PAGES
);
5204 return cluster_ptr
++;
5206 #else /* MALLOC_CHECK */
5207 return (page_t
*) xcalloc (1, PAGE_SIZE
);
5209 #endif /* MALLOC_CHECK */
5213 /* Allocate scoping information. */
5216 allocate_scope
__proto((void))
5218 register scope_t
*ptr
;
5219 static scope_t initial_scope
;
5221 #ifndef MALLOC_CHECK
5222 ptr
= alloc_counts
[ (int)alloc_type_scope
].free_list
.f_scope
;
5223 if (ptr
!= (scope_t
*)0)
5224 alloc_counts
[ (int)alloc_type_scope
].free_list
.f_scope
= ptr
->free
;
5228 register int unallocated
= alloc_counts
[ (int)alloc_type_scope
].unallocated
;
5229 register page_t
*cur_page
= alloc_counts
[ (int)alloc_type_scope
].cur_page
;
5231 if (unallocated
== 0)
5233 unallocated
= PAGE_SIZE
/ sizeof (scope_t
);
5234 alloc_counts
[ (int)alloc_type_scope
].cur_page
= cur_page
= allocate_page ();
5235 alloc_counts
[ (int)alloc_type_scope
].total_pages
++;
5238 ptr
= &cur_page
->scope
[ --unallocated
];
5239 alloc_counts
[ (int)alloc_type_scope
].unallocated
= unallocated
;
5243 ptr
= (scope_t
*) xmalloc (sizeof (scope_t
));
5247 alloc_counts
[ (int)alloc_type_scope
].total_alloc
++;
5248 *ptr
= initial_scope
;
5252 /* Free scoping information. */
5258 alloc_counts
[ (int)alloc_type_scope
].total_free
++;
5260 #ifndef MALLOC_CHECK
5261 ptr
->free
= alloc_counts
[ (int)alloc_type_scope
].free_list
.f_scope
;
5262 alloc_counts
[ (int)alloc_type_scope
].free_list
.f_scope
= ptr
;
5265 xfree ((PTR_T
) ptr
);
5271 /* Allocate links for pages in a virtual array. */
5274 allocate_vlinks
__proto((void))
5276 register vlinks_t
*ptr
;
5277 static vlinks_t initial_vlinks
;
5279 #ifndef MALLOC_CHECK
5280 register int unallocated
= alloc_counts
[ (int)alloc_type_vlinks
].unallocated
;
5281 register page_t
*cur_page
= alloc_counts
[ (int)alloc_type_vlinks
].cur_page
;
5283 if (unallocated
== 0)
5285 unallocated
= PAGE_SIZE
/ sizeof (vlinks_t
);
5286 alloc_counts
[ (int)alloc_type_vlinks
].cur_page
= cur_page
= allocate_page ();
5287 alloc_counts
[ (int)alloc_type_vlinks
].total_pages
++;
5290 ptr
= &cur_page
->vlinks
[ --unallocated
];
5291 alloc_counts
[ (int)alloc_type_vlinks
].unallocated
= unallocated
;
5294 ptr
= (vlinks_t
*) xmalloc (sizeof (vlinks_t
));
5298 alloc_counts
[ (int)alloc_type_vlinks
].total_alloc
++;
5299 *ptr
= initial_vlinks
;
5304 /* Allocate string hash buckets. */
5307 allocate_shash
__proto((void))
5309 register shash_t
*ptr
;
5310 static shash_t initial_shash
;
5312 #ifndef MALLOC_CHECK
5313 register int unallocated
= alloc_counts
[ (int)alloc_type_shash
].unallocated
;
5314 register page_t
*cur_page
= alloc_counts
[ (int)alloc_type_shash
].cur_page
;
5316 if (unallocated
== 0)
5318 unallocated
= PAGE_SIZE
/ sizeof (shash_t
);
5319 alloc_counts
[ (int)alloc_type_shash
].cur_page
= cur_page
= allocate_page ();
5320 alloc_counts
[ (int)alloc_type_shash
].total_pages
++;
5323 ptr
= &cur_page
->shash
[ --unallocated
];
5324 alloc_counts
[ (int)alloc_type_shash
].unallocated
= unallocated
;
5327 ptr
= (shash_t
*) xmalloc (sizeof (shash_t
));
5331 alloc_counts
[ (int)alloc_type_shash
].total_alloc
++;
5332 *ptr
= initial_shash
;
5337 /* Allocate type hash buckets. */
5340 allocate_thash
__proto((void))
5342 register thash_t
*ptr
;
5343 static thash_t initial_thash
;
5345 #ifndef MALLOC_CHECK
5346 register int unallocated
= alloc_counts
[ (int)alloc_type_thash
].unallocated
;
5347 register page_t
*cur_page
= alloc_counts
[ (int)alloc_type_thash
].cur_page
;
5349 if (unallocated
== 0)
5351 unallocated
= PAGE_SIZE
/ sizeof (thash_t
);
5352 alloc_counts
[ (int)alloc_type_thash
].cur_page
= cur_page
= allocate_page ();
5353 alloc_counts
[ (int)alloc_type_thash
].total_pages
++;
5356 ptr
= &cur_page
->thash
[ --unallocated
];
5357 alloc_counts
[ (int)alloc_type_thash
].unallocated
= unallocated
;
5360 ptr
= (thash_t
*) xmalloc (sizeof (thash_t
));
5364 alloc_counts
[ (int)alloc_type_thash
].total_alloc
++;
5365 *ptr
= initial_thash
;
5370 /* Allocate structure, union, or enum tag information. */
5373 allocate_tag
__proto((void))
5375 register tag_t
*ptr
;
5376 static tag_t initial_tag
;
5378 #ifndef MALLOC_CHECK
5379 ptr
= alloc_counts
[ (int)alloc_type_tag
].free_list
.f_tag
;
5380 if (ptr
!= (tag_t
*)0)
5381 alloc_counts
[ (int)alloc_type_tag
].free_list
.f_tag
= ptr
->free
;
5385 register int unallocated
= alloc_counts
[ (int)alloc_type_tag
].unallocated
;
5386 register page_t
*cur_page
= alloc_counts
[ (int)alloc_type_tag
].cur_page
;
5388 if (unallocated
== 0)
5390 unallocated
= PAGE_SIZE
/ sizeof (tag_t
);
5391 alloc_counts
[ (int)alloc_type_tag
].cur_page
= cur_page
= allocate_page ();
5392 alloc_counts
[ (int)alloc_type_tag
].total_pages
++;
5395 ptr
= &cur_page
->tag
[ --unallocated
];
5396 alloc_counts
[ (int)alloc_type_tag
].unallocated
= unallocated
;
5400 ptr
= (tag_t
*) xmalloc (sizeof (tag_t
));
5404 alloc_counts
[ (int)alloc_type_tag
].total_alloc
++;
5409 /* Free scoping information. */
5415 alloc_counts
[ (int)alloc_type_tag
].total_free
++;
5417 #ifndef MALLOC_CHECK
5418 ptr
->free
= alloc_counts
[ (int)alloc_type_tag
].free_list
.f_tag
;
5419 alloc_counts
[ (int)alloc_type_tag
].free_list
.f_tag
= ptr
;
5422 xfree ((PTR_T
) ptr
);
5428 /* Allocate forward reference to a yet unknown tag. */
5431 allocate_forward
__proto((void))
5433 register forward_t
*ptr
;
5434 static forward_t initial_forward
;
5436 #ifndef MALLOC_CHECK
5437 ptr
= alloc_counts
[ (int)alloc_type_forward
].free_list
.f_forward
;
5438 if (ptr
!= (forward_t
*)0)
5439 alloc_counts
[ (int)alloc_type_forward
].free_list
.f_forward
= ptr
->free
;
5443 register int unallocated
= alloc_counts
[ (int)alloc_type_forward
].unallocated
;
5444 register page_t
*cur_page
= alloc_counts
[ (int)alloc_type_forward
].cur_page
;
5446 if (unallocated
== 0)
5448 unallocated
= PAGE_SIZE
/ sizeof (forward_t
);
5449 alloc_counts
[ (int)alloc_type_forward
].cur_page
= cur_page
= allocate_page ();
5450 alloc_counts
[ (int)alloc_type_forward
].total_pages
++;
5453 ptr
= &cur_page
->forward
[ --unallocated
];
5454 alloc_counts
[ (int)alloc_type_forward
].unallocated
= unallocated
;
5458 ptr
= (forward_t
*) xmalloc (sizeof (forward_t
));
5462 alloc_counts
[ (int)alloc_type_forward
].total_alloc
++;
5463 *ptr
= initial_forward
;
5467 /* Free scoping information. */
5473 alloc_counts
[ (int)alloc_type_forward
].total_free
++;
5475 #ifndef MALLOC_CHECK
5476 ptr
->free
= alloc_counts
[ (int)alloc_type_forward
].free_list
.f_forward
;
5477 alloc_counts
[ (int)alloc_type_forward
].free_list
.f_forward
= ptr
;
5480 xfree ((PTR_T
) ptr
);
5486 /* Allocate head of type hash list. */
5489 allocate_thead
__proto((void))
5491 register thead_t
*ptr
;
5492 static thead_t initial_thead
;
5494 #ifndef MALLOC_CHECK
5495 ptr
= alloc_counts
[ (int)alloc_type_thead
].free_list
.f_thead
;
5496 if (ptr
!= (thead_t
*)0)
5497 alloc_counts
[ (int)alloc_type_thead
].free_list
.f_thead
= ptr
->free
;
5501 register int unallocated
= alloc_counts
[ (int)alloc_type_thead
].unallocated
;
5502 register page_t
*cur_page
= alloc_counts
[ (int)alloc_type_thead
].cur_page
;
5504 if (unallocated
== 0)
5506 unallocated
= PAGE_SIZE
/ sizeof (thead_t
);
5507 alloc_counts
[ (int)alloc_type_thead
].cur_page
= cur_page
= allocate_page ();
5508 alloc_counts
[ (int)alloc_type_thead
].total_pages
++;
5511 ptr
= &cur_page
->thead
[ --unallocated
];
5512 alloc_counts
[ (int)alloc_type_thead
].unallocated
= unallocated
;
5516 ptr
= (thead_t
*) xmalloc (sizeof (thead_t
));
5520 alloc_counts
[ (int)alloc_type_thead
].total_alloc
++;
5521 *ptr
= initial_thead
;
5525 /* Free scoping information. */
5531 alloc_counts
[ (int)alloc_type_thead
].total_free
++;
5533 #ifndef MALLOC_CHECK
5534 ptr
->free
= (thead_t
*) alloc_counts
[ (int)alloc_type_thead
].free_list
.f_thead
;
5535 alloc_counts
[ (int)alloc_type_thead
].free_list
.f_thead
= ptr
;
5538 xfree ((PTR_T
) ptr
);
5543 #endif /* MIPS_DEBUGGING_INFO */
5548 /* Output an error message and exit */
5552 fatal
VPROTO((char *format
, ...))
5559 VA_START (ap
, format
);
5562 format
= va_arg (ap
, char*);
5565 if (line_number
> 0)
5566 fprintf (stderr
, "%s, %s:%ld ", progname
, input_name
, line_number
);
5568 fprintf (stderr
, "%s:", progname
);
5570 vfprintf (stderr
, format
, ap
);
5572 fprintf (stderr
, "\n");
5573 if (line_number
> 0)
5574 fprintf (stderr
, "line:\t%s\n", cur_line_start
);
5582 error
VPROTO((char *format
, ...))
5589 VA_START (ap
, format
);
5592 format
= va_arg (ap
, char*);
5595 if (line_number
> 0)
5596 fprintf (stderr
, "%s, %s:%ld ", progname
, input_name
, line_number
);
5598 fprintf (stderr
, "%s:", progname
);
5600 vfprintf (stderr
, format
, ap
);
5601 fprintf (stderr
, "\n");
5602 if (line_number
> 0)
5603 fprintf (stderr
, "line:\t%s\n", cur_line_start
);
5611 #else /* not HAVE_VPRINTF */
5614 fatal (msg
, arg1
, arg2
)
5615 char *msg
, *arg1
, *arg2
;
5617 error (msg
, arg1
, arg2
);
5622 error (msg
, arg1
, arg2
)
5623 char *msg
, *arg1
, *arg2
;
5625 fprintf (stderr
, "%s: ", progname
);
5626 fprintf (stderr
, msg
, arg1
, arg2
);
5627 fprintf (stderr
, "\n");
5630 #endif /* not HAVE_VPRINTF */
5632 /* More 'friendly' abort that prints the line and file.
5633 config.h can #define abort fancy_abort if you like that sort of thing. */
5638 fatal ("Internal abort.");
5642 /* When `malloc.c' is compiled with `rcheck' defined,
5643 it calls this function to report clobberage. */
5652 /* Same as `malloc' but report error if no memory available. */
5658 register PTR_T value
= malloc (size
);
5660 fatal ("Virtual memory exhausted.");
5663 fprintf (stderr
, "\tmalloc\tptr = 0x%.8x, size = %10u\n", value
, size
);
5668 /* Same as `calloc' but report error if no memory available. */
5671 xcalloc (size1
, size2
)
5672 Size_t size1
, size2
;
5674 register PTR_T value
= calloc (size1
, size2
);
5676 fatal ("Virtual memory exhausted.");
5679 fprintf (stderr
, "\tcalloc\tptr = 0x%.8x, size1 = %10u, size2 = %10u [%u]\n",
5680 value
, size1
, size2
, size1
+size2
);
5685 /* Same as `realloc' but report error if no memory available. */
5688 xrealloc (ptr
, size
)
5692 register PTR_T result
= realloc (ptr
, size
);
5694 fatal ("Virtual memory exhausted.");
5697 fprintf (stderr
, "\trealloc\tptr = 0x%.8x, size = %10u, orig = 0x%.8x\n",
5708 fprintf (stderr
, "\tfree\tptr = 0x%.8x\n", ptr
);
5714 /* Define our own index/rindex, since the local and global symbol
5715 structures as defined by MIPS has an 'index' field. */
5718 local_index (str
, sentinel
)
5724 for ( ; (ch
= *str
) != sentinel
; str
++)
5734 local_rindex (str
, sentinel
)
5739 const char *ret
= (const char *)0;
5741 for ( ; (ch
= *str
) != '\0'; str
++)