1 /* Update the symbol table (the .T file) in a ECOFF object to
2 contain debugging information specified by the GNU compiler
3 in the form of comments (the mips assembler does not support
4 assembly access to debug information).
5 Copyright (C) 1991, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
6 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
7 Free Software Foundation, Inc.
8 Contributed by Michael Meissner (meissner@cygnus.com).
10 This file is part of GCC.
12 GCC is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free
14 Software Foundation; either version 3, or (at your option) any later
17 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18 WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 You should have received a copy of the GNU General Public License
23 along with GCC; see the file COPYING3. If not see
24 <http://www.gnu.org/licenses/>. */
27 /* Here is a brief description of the MIPS ECOFF symbol table. The
28 MIPS symbol table has the following pieces:
34 +-- Dense number table
42 +-- Relative file descriptors
54 The symbolic header points to each of the other tables, and also
55 contains the number of entries. It also contains a magic number
56 and MIPS compiler version number, such as 2.0.
58 The auxiliary table is a series of 32 bit integers, that are
59 referenced as needed from the local symbol table. Unlike standard
60 COFF, the aux. information does not follow the symbol that uses
61 it, but rather is a separate table. In theory, this would allow
62 the MIPS compilers to collapse duplicate aux. entries, but I've not
63 noticed this happening with the 1.31 compiler suite. The different
64 types of aux. entries are:
66 1) dnLow: Low bound on array dimension.
68 2) dnHigh: High bound on array dimension.
70 3) isym: Index to the local symbol which is the start of the
71 function for the end of function first aux. entry.
73 4) width: Width of structures and bitfields.
75 5) count: Count of ranges for variant part.
77 6) rndx: A relative index into the symbol table. The relative
78 index field has two parts: rfd which is a pointer into the
79 relative file index table or ST_RFDESCAPE which says the next
80 aux. entry is the file number, and index: which is the pointer
81 into the local symbol within a given file table. This is for
82 things like references to types defined in another file.
84 7) Type information: This is like the COFF type bits, except it
85 is 32 bits instead of 16; they still have room to add new
86 basic types; and they can handle more than 6 levels of array,
87 pointer, function, etc. Each type information field contains
88 the following structure members:
90 a) fBitfield: a bit that says this is a bitfield, and the
91 size in bits follows as the next aux. entry.
93 b) continued: a bit that says the next aux. entry is a
94 continuation of the current type information (in case
95 there are more than 6 levels of array/ptr/function).
97 c) bt: an integer containing the base type before adding
98 array, pointer, function, etc. qualifiers. The
99 current base types that I have documentation for are:
102 btAdr -- address - integer same size as ptr
104 btUChar -- unsigned character
106 btUShort -- unsigned short
108 btUInt -- unsigned int
110 btULong -- unsigned long
111 btFloat -- float (real)
112 btDouble -- Double (real)
113 btStruct -- Structure (Record)
114 btUnion -- Union (variant)
116 btTypedef -- defined via a typedef isymRef
117 btRange -- subrange of int
119 btComplex -- fortran complex
120 btDComplex -- fortran double complex
121 btIndirect -- forward or unnamed typedef
122 btFixedDec -- Fixed Decimal
123 btFloatDec -- Float Decimal
124 btString -- Varying Length Character String
125 btBit -- Aligned Bit String
127 btVoid -- Void (MIPS cc revision >= 2.00)
129 d) tq0 - tq5: type qualifier fields as needed. The
130 current type qualifier fields I have documentation for
133 tqNil -- no more qualifiers
137 tqFar -- 8086 far pointers
141 The dense number table is used in the front ends, and disappears by
142 the time the .o is created.
144 With the 1.31 compiler suite, the optimization symbols don't seem
145 to be used as far as I can tell.
147 The linker is the first entity that creates the relative file
148 descriptor table, and I believe it is used so that the individual
149 file table pointers don't have to be rewritten when the objects are
150 merged together into the program file.
152 Unlike COFF, the basic symbol & string tables are split into
153 external and local symbols/strings. The relocation information
154 only goes off of the external symbol table, and the debug
155 information only goes off of the internal symbol table. The
156 external symbols can have links to an appropriate file index and
157 symbol within the file to give it the appropriate type information.
158 Because of this, the external symbols are actually larger than the
159 internal symbols (to contain the link information), and contain the
160 local symbol structure as a member, though this member is not the
161 first member of the external symbol structure (!). I suspect this
162 split is to make strip easier to deal with.
164 Each file table has offsets for where the line numbers, local
165 strings, local symbols, and procedure table starts from within the
166 global tables, and the indices are reset to 0 for each of those
169 The procedure table contains the binary equivalents of the .ent
170 (start of the function address), .frame (what register is the
171 virtual frame pointer, constant offset from the register to obtain
172 the VFP, and what register holds the return address), .mask/.fmask
173 (bitmask of saved registers, and where the first register is stored
174 relative to the VFP) assembler directives. It also contains the
175 low and high bounds of the line numbers if debugging is turned on.
177 The line number table is a compressed form of the normal COFF line
178 table. Each line number entry is either 1 or 3 bytes long, and
179 contains a signed delta from the previous line, and an unsigned
180 count of the number of instructions this statement takes.
182 The local symbol table contains the following fields:
184 1) iss: index to the local string table giving the name of the
187 2) value: value of the symbol (address, register number, etc.).
189 3) st: symbol type. The current symbol types are:
191 stNil -- Nuthin' special
192 stGlobal -- external symbol
194 stParam -- procedure argument
195 stLocal -- local variable
197 stProc -- External Procedure
198 stBlock -- beginning of block
199 stEnd -- end (of anything)
200 stMember -- member (of anything)
201 stTypedef -- type definition
203 stRegReloc -- register relocation
204 stForward -- forwarding address
205 stStaticProc -- Static procedure
208 4) sc: storage class. The current storage classes are:
210 scText -- text symbol
211 scData -- initialized data symbol
212 scBss -- un-initialized data symbol
213 scRegister -- value of symbol is register number
214 scAbs -- value of symbol is absolute
215 scUndefined -- who knows?
216 scCdbLocal -- variable's value is IN se->va.??
217 scBits -- this is a bit field
218 scCdbSystem -- value is IN debugger's address space
219 scRegImage -- register value saved on stack
220 scInfo -- symbol contains debugger information
221 scUserStruct -- addr in struct user for current process
222 scSData -- load time only small data
223 scSBss -- load time only small common
224 scRData -- load time only read only data
225 scVar -- Var parameter (fortranpascal)
226 scCommon -- common variable
227 scSCommon -- small common
228 scVarRegister -- Var parameter in a register
229 scVariant -- Variant record
230 scSUndefined -- small undefined(external) data
231 scInit -- .init section symbol
233 5) index: pointer to a local symbol or aux. entry.
237 For the following program:
242 printf("Hello World!\n");
246 Mips-tdump produces the following information:
251 timestamp 645311799, Wed Jun 13 17:16:39 1990
252 symbolic header offset 284
253 symbolic header size 96
257 Symbolic header, magic number = 0x7009, vstamp = 1.31:
259 Info Offset Number Bytes
260 ==== ====== ====== =====
262 Line numbers 380 4 4 [13]
264 Procedures Tables 384 1 52
265 Local Symbols 436 16 192
266 Optimization Symbols 0 0 0
267 Auxiliary Symbols 628 39 156
268 Local Strings 784 80 80
269 External Strings 864 144 144
270 File Tables 1008 2 144
272 External Symbols 1152 20 320
276 Name index = 1 Readin = No
277 Merge = No Endian = LITTLE
278 Debug level = G2 Language = C
281 Info Start Number Size Offset
282 ==== ===== ====== ==== ======
283 Local strings 0 15 15 784
284 Local symbols 0 6 72 436
285 Line numbers 0 13 13 380
286 Optimization symbols 0 0 0 0
287 Procedures 0 1 52 384
288 Auxiliary symbols 0 14 56 628
289 Relative Files 0 0 0 0
291 There are 6 local symbols, starting at 436
293 Symbol# 0: "hello2.c"
296 Storage class = Text Index = 6
297 Symbol type = File Value = 0
303 Storage class = Text Index = 12
304 Symbol type = Proc Value = 0
309 Storage class = Text Index = 4
310 Symbol type = Block Value = 8
315 Storage class = Text Index = 2
316 Symbol type = End Value = 28
321 Storage class = Text Index = 1
322 Symbol type = End Value = 52
324 Symbol# 5: "hello2.c"
327 Storage class = Text Index = 0
328 Symbol type = End Value = 0
330 There are 14 auxiliary table entries, starting at 628.
332 * #0 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
333 * #1 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
334 * #2 8, [ 8/ 0], [ 2 0:0 0:0:0:0:0:0]
335 * #3 16, [ 16/ 0], [ 4 0:0 0:0:0:0:0:0]
336 * #4 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
337 * #5 32, [ 32/ 0], [ 8 0:0 0:0:0:0:0:0]
338 * #6 40, [ 40/ 0], [10 0:0 0:0:0:0:0:0]
339 * #7 44, [ 44/ 0], [11 0:0 0:0:0:0:0:0]
340 * #8 12, [ 12/ 0], [ 3 0:0 0:0:0:0:0:0]
341 * #9 20, [ 20/ 0], [ 5 0:0 0:0:0:0:0:0]
342 * #10 28, [ 28/ 0], [ 7 0:0 0:0:0:0:0:0]
343 * #11 36, [ 36/ 0], [ 9 0:0 0:0:0:0:0:0]
344 #12 5, [ 5/ 0], [ 1 1:0 0:0:0:0:0:0]
345 #13 24, [ 24/ 0], [ 6 0:0 0:0:0:0:0:0]
347 There are 1 procedure descriptor entries, starting at 0.
349 Procedure descriptor 0:
350 Name index = 10 Name = "main"
351 .mask 0x80000000,-4 .fmask 0x00000000,0
353 Opt. start = -1 Symbols start = 1
354 First line # = 3 Last line # = 6
355 Line Offset = 0 Address = 0x00000000
357 There are 4 bytes holding line numbers, starting at 380.
358 Line 3, delta 0, count 2
359 Line 4, delta 1, count 3
360 Line 5, delta 1, count 2
361 Line 6, delta 1, count 6
363 File #1, "/usr/include/stdio.h"
365 Name index = 1 Readin = No
366 Merge = Yes Endian = LITTLE
367 Debug level = G2 Language = C
370 Info Start Number Size Offset
371 ==== ===== ====== ==== ======
372 Local strings 15 65 65 799
373 Local symbols 6 10 120 508
374 Line numbers 0 0 0 380
375 Optimization symbols 0 0 0 0
377 Auxiliary symbols 14 25 100 684
378 Relative Files 0 0 0 0
380 There are 10 local symbols, starting at 442
382 Symbol# 0: "/usr/include/stdio.h"
385 Storage class = Text Index = 10
386 Symbol type = File Value = 0
391 Storage class = Info Index = 9
392 Symbol type = Block Value = 20
397 Storage class = Info Index = 4
398 Symbol type = Member Value = 0
403 Storage class = Info Index = 15
404 Symbol type = Member Value = 32
409 Storage class = Info Index = 16
410 Symbol type = Member Value = 64
415 Storage class = Info Index = 4
416 Symbol type = Member Value = 96
421 Storage class = Info Index = 3
422 Symbol type = Member Value = 128
427 Storage class = Info Index = 2
428 Symbol type = Member Value = 144
433 Storage class = Info Index = 1
434 Symbol type = End Value = 0
436 Symbol# 9: "/usr/include/stdio.h"
439 Storage class = Text Index = 0
440 Symbol type = End Value = 0
442 There are 25 auxiliary table entries, starting at 642.
444 * #14 -1, [4095/1048575], [63 1:1 f:f:f:f:f:f]
445 #15 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
446 #16 65544, [ 8/ 16], [ 2 0:0 1:0:0:0:0:0]
447 * #17 196656, [ 48/ 48], [12 0:0 3:0:0:0:0:0]
448 * #18 8191, [4095/ 1], [63 1:1 0:0:0:0:f:1]
449 * #19 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
450 * #20 20479, [4095/ 4], [63 1:1 0:0:0:0:f:4]
451 * #21 1, [ 1/ 0], [ 0 1:0 0:0:0:0:0:0]
452 * #22 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
453 * #23 2, [ 2/ 0], [ 0 0:1 0:0:0:0:0:0]
454 * #24 160, [ 160/ 0], [40 0:0 0:0:0:0:0:0]
455 * #25 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
456 * #26 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
457 * #27 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
458 * #28 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
459 * #29 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
460 * #30 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
461 * #31 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
462 * #32 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
463 * #33 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
464 * #34 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
465 * #35 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
466 * #36 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
467 * #37 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
468 * #38 0, [ 0/ 0], [ 0 0:0 0:0:0:0:0:0]
470 There are 0 procedure descriptor entries, starting at 1.
472 There are 20 external symbols, starting at 1152
475 Type = array [3 {160}] of struct _iobuf { ifd = 1, index = 1 }
476 String index = 0 Ifd = 1
477 Storage class = Nil Index = 17
478 Symbol type = Global Value = 60
481 String index = 5 Ifd = 1
482 Storage class = Nil Index = 1048575
483 Symbol type = Proc Value = 0
486 String index = 11 Ifd = 1
487 Storage class = Nil Index = 1048575
488 Symbol type = Proc Value = 0
491 String index = 18 Ifd = 1
492 Storage class = Nil Index = 1048575
493 Symbol type = Proc Value = 0
496 String index = 26 Ifd = 1
497 Storage class = Nil Index = 1048575
498 Symbol type = Proc Value = 0
501 String index = 32 Ifd = 1
502 Storage class = Nil Index = 1048575
503 Symbol type = Proc Value = 0
506 String index = 40 Ifd = 1
507 Storage class = Nil Index = 1048575
508 Symbol type = Proc Value = 0
511 String index = 46 Ifd = 1
512 Storage class = Nil Index = 1048575
513 Symbol type = Proc Value = 0
516 String index = 53 Ifd = 1
517 Storage class = Nil Index = 1048575
518 Symbol type = Proc Value = 0
520 Symbol# 9: "setbuffer"
521 String index = 60 Ifd = 1
522 Storage class = Nil Index = 1048575
523 Symbol type = Proc Value = 0
525 Symbol# 10: "setlinebuf"
526 String index = 70 Ifd = 1
527 Storage class = Nil Index = 1048575
528 Symbol type = Proc Value = 0
531 String index = 81 Ifd = 1
532 Storage class = Nil Index = 1048575
533 Symbol type = Proc Value = 0
536 String index = 87 Ifd = 1
537 Storage class = Nil Index = 1048575
538 Symbol type = Proc Value = 0
540 Symbol# 13: "ctermid"
541 String index = 92 Ifd = 1
542 Storage class = Nil Index = 1048575
543 Symbol type = Proc Value = 0
545 Symbol# 14: "cuserid"
546 String index = 100 Ifd = 1
547 Storage class = Nil Index = 1048575
548 Symbol type = Proc Value = 0
550 Symbol# 15: "tempnam"
551 String index = 108 Ifd = 1
552 Storage class = Nil Index = 1048575
553 Symbol type = Proc Value = 0
556 String index = 116 Ifd = 1
557 Storage class = Nil Index = 1048575
558 Symbol type = Proc Value = 0
560 Symbol# 17: "sprintf"
561 String index = 123 Ifd = 1
562 Storage class = Nil Index = 1048575
563 Symbol type = Proc Value = 0
567 String index = 131 Ifd = 0
568 Storage class = Text Index = 1
569 Symbol type = Proc Value = 0
572 String index = 136 Ifd = 0
573 Storage class = Undefined Index = 1048575
574 Symbol type = Proc Value = 0
576 The following auxiliary table entries were unused:
580 #3 16 0x00000010 short
582 #5 32 0x00000020 long
583 #6 40 0x00000028 float
584 #7 44 0x0000002c double
585 #8 12 0x0000000c unsigned char
586 #9 20 0x00000014 unsigned short
587 #10 28 0x0000001c unsigned int
588 #11 36 0x00000024 unsigned long
589 #14 0 0x00000000 void
590 #15 24 0x00000018 int
591 #19 32 0x00000020 long
592 #20 40 0x00000028 float
593 #21 44 0x0000002c double
594 #22 12 0x0000000c unsigned char
595 #23 20 0x00000014 unsigned short
596 #24 28 0x0000001c unsigned int
597 #25 36 0x00000024 unsigned long
598 #26 48 0x00000030 struct no name { ifd = -1, index = 1048575 }
608 /* Include getopt.h for the sake of getopt_long. */
611 /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for
612 mips-tdump.c to print them out.
614 These must match the corresponding definitions in gdb/mipsread.c.
615 Unfortunately, gcc and gdb do not currently share any directories. */
617 #define CODE_MASK 0x8F300
618 #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
619 #define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
620 #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
622 /* The following might be called from obstack or malloc,
623 so they can't be static. */
625 extern void pfatal_with_name (const char *) ATTRIBUTE_NORETURN
;
626 extern void botch (const char *) ATTRIBUTE_NORETURN
;
628 extern void fatal (const char *format
, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN
;
629 extern void error (const char *format
, ...) ATTRIBUTE_PRINTF_1
;
631 /* The local and global symbols have a field index, so undo any defines
632 of index -> strchr. */
639 #define IS_ASM_IDENT(ch) \
640 (ISIDNUM (ch) || (ch) == '.' || (ch) == '$')
643 /* Redefinition of storage classes as an enumeration for better
647 sc_Nil
= scNil
, /* no storage class */
648 sc_Text
= scText
, /* text symbol */
649 sc_Data
= scData
, /* initialized data symbol */
650 sc_Bss
= scBss
, /* un-initialized data symbol */
651 sc_Register
= scRegister
, /* value of symbol is register number */
652 sc_Abs
= scAbs
, /* value of symbol is absolute */
653 sc_Undefined
= scUndefined
, /* who knows? */
654 sc_CdbLocal
= scCdbLocal
, /* variable's value is IN se->va.?? */
655 sc_Bits
= scBits
, /* this is a bit field */
656 sc_CdbSystem
= scCdbSystem
, /* value is IN CDB's address space */
657 sc_RegImage
= scRegImage
, /* register value saved on stack */
658 sc_Info
= scInfo
, /* symbol contains debugger information */
659 sc_UserStruct
= scUserStruct
, /* addr in struct user for current process */
660 sc_SData
= scSData
, /* load time only small data */
661 sc_SBss
= scSBss
, /* load time only small common */
662 sc_RData
= scRData
, /* load time only read only data */
663 sc_Var
= scVar
, /* Var parameter (fortran,pascal) */
664 sc_Common
= scCommon
, /* common variable */
665 sc_SCommon
= scSCommon
, /* small common */
666 sc_VarRegister
= scVarRegister
, /* Var parameter in a register */
667 sc_Variant
= scVariant
, /* Variant record */
668 sc_SUndefined
= scSUndefined
, /* small undefined(external) data */
669 sc_Init
= scInit
, /* .init section symbol */
670 sc_Max
= scMax
/* Max storage class+1 */
673 /* Redefinition of symbol type. */
676 st_Nil
= stNil
, /* Nuthin' special */
677 st_Global
= stGlobal
, /* external symbol */
678 st_Static
= stStatic
, /* static */
679 st_Param
= stParam
, /* procedure argument */
680 st_Local
= stLocal
, /* local variable */
681 st_Label
= stLabel
, /* label */
682 st_Proc
= stProc
, /* " " Procedure */
683 st_Block
= stBlock
, /* beginning of block */
684 st_End
= stEnd
, /* end (of anything) */
685 st_Member
= stMember
, /* member (of anything - struct/union/enum */
686 st_Typedef
= stTypedef
, /* type definition */
687 st_File
= stFile
, /* file name */
688 st_RegReloc
= stRegReloc
, /* register relocation */
689 st_Forward
= stForward
, /* forwarding address */
690 st_StaticProc
= stStaticProc
, /* load time only static procs */
691 st_Constant
= stConstant
, /* const */
692 st_Str
= stStr
, /* string */
693 st_Number
= stNumber
, /* pure number (i.e. 4 NOR 2+2) */
694 st_Expr
= stExpr
, /* 2+2 vs. 4 */
695 st_Type
= stType
, /* post-coercion SER */
696 st_Max
= stMax
/* max type+1 */
699 /* Redefinition of type qualifiers. */
702 tq_Nil
= tqNil
, /* bt is what you see */
703 tq_Ptr
= tqPtr
, /* pointer */
704 tq_Proc
= tqProc
, /* procedure */
705 tq_Array
= tqArray
, /* duh */
706 tq_Far
= tqFar
, /* longer addressing - 8086/8 land */
707 tq_Vol
= tqVol
, /* volatile */
708 tq_Max
= tqMax
/* Max type qualifier+1 */
711 /* Redefinition of basic types. */
714 bt_Nil
= btNil
, /* undefined */
715 bt_Adr
= btAdr
, /* address - integer same size as pointer */
716 bt_Char
= btChar
, /* character */
717 bt_UChar
= btUChar
, /* unsigned character */
718 bt_Short
= btShort
, /* short */
719 bt_UShort
= btUShort
, /* unsigned short */
720 bt_Int
= btInt
, /* int */
721 bt_UInt
= btUInt
, /* unsigned int */
722 bt_Long
= btLong
, /* long */
723 bt_ULong
= btULong
, /* unsigned long */
724 bt_Float
= btFloat
, /* float (real) */
725 bt_Double
= btDouble
, /* Double (real) */
726 bt_Struct
= btStruct
, /* Structure (Record) */
727 bt_Union
= btUnion
, /* Union (variant) */
728 bt_Enum
= btEnum
, /* Enumerated */
729 bt_Typedef
= btTypedef
, /* defined via a typedef, isymRef points */
730 bt_Range
= btRange
, /* subrange of int */
731 bt_Set
= btSet
, /* pascal sets */
732 bt_Complex
= btComplex
, /* fortran complex */
733 bt_DComplex
= btDComplex
, /* fortran double complex */
734 bt_Indirect
= btIndirect
, /* forward or unnamed typedef */
735 bt_FixedDec
= btFixedDec
, /* Fixed Decimal */
736 bt_FloatDec
= btFloatDec
, /* Float Decimal */
737 bt_String
= btString
, /* Varying Length Character String */
738 bt_Bit
= btBit
, /* Aligned Bit String */
739 bt_Picture
= btPicture
, /* Picture */
742 bt_Void
= btVoid
, /* Void */
744 #define bt_Void bt_Nil
747 bt_Max
= btMax
/* Max basic type+1 */
752 /* Basic COFF storage classes. */
784 /* Regular COFF fundamental type. */
785 typedef enum coff_type
{
805 /* Regular COFF derived types. */
806 typedef enum coff_dt
{
814 #define N_BTMASK 017 /* bitmask to isolate basic type */
815 #define N_TMASK 003 /* bitmask to isolate derived type */
816 #define N_BT_SHIFT 4 /* # bits to shift past basic type */
817 #define N_TQ_SHIFT 2 /* # bits to shift derived types */
818 #define N_TQ 6 /* # of type qualifiers */
820 /* States for whether to hash type or not. */
821 typedef enum hash_state
{
822 hash_no
= 0, /* don't hash type */
823 hash_yes
= 1, /* ok to hash type, or use previous hash */
824 hash_record
= 2 /* ok to record hash, but don't use prev. */
828 /* Types of different sized allocation requests. */
830 alloc_type_none
, /* dummy value */
831 alloc_type_scope
, /* nested scopes linked list */
832 alloc_type_vlinks
, /* glue linking pages in varray */
833 alloc_type_shash
, /* string hash element */
834 alloc_type_thash
, /* type hash element */
835 alloc_type_tag
, /* struct/union/tag element */
836 alloc_type_forward
, /* element to hold unknown tag */
837 alloc_type_thead
, /* head of type hash list */
838 alloc_type_varray
, /* general varray allocation */
839 alloc_type_last
/* last+1 element for array bounds */
843 #define WORD_ALIGN(x) (((x) + (sizeof (long) - 1)) & ~ (sizeof (long) - 1))
844 #define DWORD_ALIGN(x) (((x) + 7) & ~7)
847 /* Structures to provide n-number of virtual arrays, each of which can
848 grow linearly, and which are written in the object file as sequential
849 pages. On systems with a BSD malloc that define USE_MALLOC, the
850 MAX_CLUSTER_PAGES should be 1 less than a power of two, since malloc
851 adds its overhead, and rounds up to the next power of 2. Pages are
852 linked together via a linked list. */
855 #define PAGE_SIZE 32768 /* size of varray pages */
858 #define PAGE_USIZE ((size_t) PAGE_SIZE)
861 #ifndef MAX_CLUSTER_PAGES /* # pages to get from system */
862 #ifndef USE_MALLOC /* in one memory request */
863 #define MAX_CLUSTER_PAGES 64
865 #define MAX_CLUSTER_PAGES 63
870 /* Linked list connecting separate page allocations. */
871 typedef struct vlinks
{
872 struct vlinks
*prev
; /* previous set of pages */
873 struct vlinks
*next
; /* next set of pages */
874 union page
*datum
; /* start of page */
875 unsigned long start_index
; /* starting index # of page */
879 /* Virtual array header. */
880 typedef struct varray
{
881 vlinks_t
*first
; /* first page link */
882 vlinks_t
*last
; /* last page link */
883 unsigned long num_allocated
; /* # objects allocated */
884 unsigned short object_size
; /* size in bytes of each object */
885 unsigned short objects_per_page
; /* # objects that can fit on a page */
886 unsigned short objects_last_page
; /* # objects allocated on last page */
890 #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
892 #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
895 #define INIT_VARRAY(type) { /* macro to initialize a varray */ \
896 (vlinks_t *) 0, /* first */ \
897 (vlinks_t *) 0, /* last */ \
898 0, /* num_allocated */ \
899 sizeof (type), /* object_size */ \
900 OBJECTS_PER_PAGE (type), /* objects_per_page */ \
901 OBJECTS_PER_PAGE (type), /* objects_last_page */ \
904 #define INITIALIZE_VARRAY(x,type) \
906 (x)->object_size = sizeof (type); \
907 (x)->objects_per_page = OBJECTS_PER_PAGE (type); \
908 (x)->objects_last_page = OBJECTS_PER_PAGE (type); \
911 /* Master type for indexes within the symbol table. */
912 typedef unsigned long symint_t
;
915 /* Linked list support for nested scopes (file, block, structure, etc.). */
916 typedef struct scope
{
917 struct scope
*prev
; /* previous scope level */
918 struct scope
*free
; /* free list pointer */
919 SYMR
*lsym
; /* pointer to local symbol node */
920 symint_t lnumber
; /* lsym index */
921 st_t type
; /* type of the node */
925 /* Forward reference list for tags referenced, but not yet defined. */
926 typedef struct forward
{
927 struct forward
*next
; /* next forward reference */
928 struct forward
*free
; /* free list pointer */
929 AUXU
*ifd_ptr
; /* pointer to store file index */
930 AUXU
*index_ptr
; /* pointer to store symbol index */
931 AUXU
*type_ptr
; /* pointer to munge type info */
935 /* Linked list support for tags. The first tag in the list is always
936 the current tag for that block. */
938 struct tag
*free
; /* free list pointer */
939 struct shash
*hash_ptr
; /* pointer to the hash table head */
940 struct tag
*same_name
; /* tag with same name in outer scope */
941 struct tag
*same_block
; /* next tag defined in the same block. */
942 struct forward
*forward_ref
; /* list of forward references */
943 bt_t basic_type
; /* bt_Struct, bt_Union, or bt_Enum */
944 symint_t ifd
; /* file # tag defined in */
945 symint_t indx
; /* index within file's local symbols */
949 /* Head of a block's linked list of tags. */
950 typedef struct thead
{
951 struct thead
*prev
; /* previous block */
952 struct thead
*free
; /* free list pointer */
953 struct tag
*first_tag
; /* first tag in block defined */
957 /* Union containing pointers to each the small structures which are freed up. */
958 typedef union small_free
{
959 scope_t
*f_scope
; /* scope structure */
960 thead_t
*f_thead
; /* tag head structure */
961 tag_t
*f_tag
; /* tag element structure */
962 forward_t
*f_forward
; /* forward tag reference */
966 /* String hash table support. The size of the hash table must fit
969 #define SHASH_SIZE 511
971 #define HASH_LEN_MAX ((1 << 12) - 1) /* Max length we can store */
973 typedef struct shash
{
974 struct shash
*next
; /* next hash value */
975 char *string
; /* string we are hashing */
976 symint_t len
; /* string length */
977 symint_t indx
; /* index within string table */
978 EXTR
*esym_ptr
; /* global symbol pointer */
979 SYMR
*sym_ptr
; /* local symbol pointer */
980 SYMR
*end_ptr
; /* symbol pointer to end block */
981 tag_t
*tag_ptr
; /* tag pointer */
982 PDR
*proc_ptr
; /* procedure descriptor pointer */
986 /* Type hash table support. The size of the hash table must fit
987 within a page with the other extended file descriptor information.
988 Because unique types which are hashed are fewer in number than
989 strings, we use a smaller hash value. */
991 #define THASH_SIZE 55
993 typedef struct thash
{
994 struct thash
*next
; /* next hash value */
995 AUXU type
; /* type we are hashing */
996 symint_t indx
; /* index within string table */
1000 /* Extended file descriptor that contains all of the support necessary
1001 to add things to each file separately. */
1002 typedef struct efdr
{
1003 FDR fdr
; /* File header to be written out */
1004 FDR
*orig_fdr
; /* original file header */
1005 char *name
; /* filename */
1006 int name_len
; /* length of the filename */
1007 symint_t void_type
; /* aux. pointer to 'void' type */
1008 symint_t int_type
; /* aux. pointer to 'int' type */
1009 scope_t
*cur_scope
; /* current nested scopes */
1010 symint_t file_index
; /* current file number */
1011 int nested_scopes
; /* # nested scopes */
1012 varray_t strings
; /* local strings */
1013 varray_t symbols
; /* local symbols */
1014 varray_t procs
; /* procedures */
1015 varray_t aux_syms
; /* auxiliary symbols */
1016 struct efdr
*next_file
; /* next file descriptor */
1017 /* string/type hash tables */
1018 shash_t
**shash_head
; /* string hash table */
1019 thash_t
*thash_head
[THASH_SIZE
];
1022 /* Pre-initialized extended file structure. */
1023 static int init_file_initialized
= 0;
1024 static efdr_t init_file
;
1026 static efdr_t
*first_file
; /* first file descriptor */
1027 static efdr_t
**last_file_ptr
= &first_file
; /* file descriptor tail */
1030 /* Union of various things that are held in pages. */
1031 typedef union page
{
1032 char byte
[ PAGE_SIZE
];
1033 unsigned char ubyte
[ PAGE_SIZE
];
1034 efdr_t file
[ PAGE_SIZE
/ sizeof (efdr_t
) ];
1035 FDR ofile
[ PAGE_SIZE
/ sizeof (FDR
) ];
1036 PDR proc
[ PAGE_SIZE
/ sizeof (PDR
) ];
1037 SYMR sym
[ PAGE_SIZE
/ sizeof (SYMR
) ];
1038 EXTR esym
[ PAGE_SIZE
/ sizeof (EXTR
) ];
1039 AUXU aux
[ PAGE_SIZE
/ sizeof (AUXU
) ];
1040 DNR dense
[ PAGE_SIZE
/ sizeof (DNR
) ];
1041 scope_t scope
[ PAGE_SIZE
/ sizeof (scope_t
) ];
1042 vlinks_t vlinks
[ PAGE_SIZE
/ sizeof (vlinks_t
) ];
1043 shash_t shash
[ PAGE_SIZE
/ sizeof (shash_t
) ];
1044 thash_t thash
[ PAGE_SIZE
/ sizeof (thash_t
) ];
1045 tag_t tag
[ PAGE_SIZE
/ sizeof (tag_t
) ];
1046 forward_t forward
[ PAGE_SIZE
/ sizeof (forward_t
) ];
1047 thead_t thead
[ PAGE_SIZE
/ sizeof (thead_t
) ];
1051 /* Structure holding allocation information for small sized structures. */
1052 typedef struct alloc_info
{
1053 const char *alloc_name
; /* name of this allocation type (must be first) */
1054 page_t
*cur_page
; /* current page being allocated from */
1055 small_free_t free_list
; /* current free list if any */
1056 int unallocated
; /* number of elements unallocated on page */
1057 int total_alloc
; /* total number of allocations */
1058 int total_free
; /* total number of frees */
1059 int total_pages
; /* total number of pages allocated */
1062 /* Type information collected together. */
1063 typedef struct type_info
{
1064 bt_t basic_type
; /* basic type */
1065 coff_type_t orig_type
; /* original COFF-based type */
1066 int num_tq
; /* # type qualifiers */
1067 int num_dims
; /* # dimensions */
1068 int num_sizes
; /* # sizes */
1069 int extra_sizes
; /* # extra sizes not tied with dims */
1070 tag_t
* tag_ptr
; /* tag pointer */
1071 int bitfield
; /* symbol is a bitfield */
1072 int unknown_tag
; /* this is an unknown tag */
1073 tq_t type_qualifiers
[N_TQ
]; /* type qualifiers (ptr, func, array)*/
1074 symint_t dimensions
[N_TQ
]; /* dimensions for each array */
1075 symint_t sizes
[N_TQ
+2]; /* sizes of each array slice + size of
1076 struct/union/enum + bitfield size */
1079 /* Pre-initialized type_info struct. */
1080 static type_info_t type_info_init
= {
1081 bt_Nil
, /* basic type */
1082 T_NULL
, /* original COFF-based type */
1083 0, /* # type qualifiers */
1084 0, /* # dimensions */
1086 0, /* sizes not tied with dims */
1087 NULL
, /* ptr to tag */
1089 0, /* unknown tag */
1090 { /* type qualifiers */
1119 /* Global virtual arrays & hash table for external strings as well as
1120 for the tags table and global tables for file descriptors, and
1123 static varray_t file_desc
= INIT_VARRAY (efdr_t
);
1124 static varray_t dense_num
= INIT_VARRAY (DNR
);
1125 static varray_t tag_strings
= INIT_VARRAY (char);
1126 static varray_t ext_strings
= INIT_VARRAY (char);
1127 static varray_t ext_symbols
= INIT_VARRAY (EXTR
);
1129 static shash_t
*orig_str_hash
[SHASH_SIZE
];
1130 static shash_t
*ext_str_hash
[SHASH_SIZE
];
1131 static shash_t
*tag_hash
[SHASH_SIZE
];
1133 /* Static types for int and void. Also, remember the last function's
1134 type (which is set up when we encounter the declaration for the
1135 function, and used when the end block for the function is emitted. */
1137 static type_info_t int_type_info
;
1138 static type_info_t void_type_info
;
1139 static type_info_t last_func_type_info
;
1140 static EXTR
*last_func_eptr
;
1143 /* Convert COFF basic type to ECOFF basic type. The T_NULL type
1144 really should use bt_Void, but this causes the current ecoff GDB to
1145 issue unsupported type messages, and the Ultrix 4.00 dbx (aka MIPS
1146 2.0) doesn't understand it, even though the compiler generates it.
1147 Maybe this will be fixed in 2.10 or 2.20 of the MIPS compiler
1148 suite, but for now go with what works. */
1150 static const bt_t map_coff_types
[ (int) T_MAX
] = {
1151 bt_Nil
, /* T_NULL */
1153 bt_Char
, /* T_CHAR */
1154 bt_Short
, /* T_SHORT */
1156 bt_Long
, /* T_LONG */
1157 bt_Float
, /* T_FLOAT */
1158 bt_Double
, /* T_DOUBLE */
1159 bt_Struct
, /* T_STRUCT */
1160 bt_Union
, /* T_UNION */
1161 bt_Enum
, /* T_ENUM */
1162 bt_Enum
, /* T_MOE */
1163 bt_UChar
, /* T_UCHAR */
1164 bt_UShort
, /* T_USHORT */
1165 bt_UInt
, /* T_UINT */
1166 bt_ULong
/* T_ULONG */
1169 /* Convert COFF storage class to ECOFF storage class. */
1170 static const sc_t map_coff_storage
[ (int) C_MAX
] = {
1171 sc_Nil
, /* 0: C_NULL */
1172 sc_Abs
, /* 1: C_AUTO auto var */
1173 sc_Undefined
, /* 2: C_EXT external */
1174 sc_Data
, /* 3: C_STAT static */
1175 sc_Register
, /* 4: C_REG register */
1176 sc_Undefined
, /* 5: C_EXTDEF ??? */
1177 sc_Text
, /* 6: C_LABEL label */
1178 sc_Text
, /* 7: C_ULABEL user label */
1179 sc_Info
, /* 8: C_MOS member of struct */
1180 sc_Abs
, /* 9: C_ARG argument */
1181 sc_Info
, /* 10: C_STRTAG struct tag */
1182 sc_Info
, /* 11: C_MOU member of union */
1183 sc_Info
, /* 12: C_UNTAG union tag */
1184 sc_Info
, /* 13: C_TPDEF typedef */
1185 sc_Data
, /* 14: C_USTATIC ??? */
1186 sc_Info
, /* 15: C_ENTAG enum tag */
1187 sc_Info
, /* 16: C_MOE member of enum */
1188 sc_Register
, /* 17: C_REGPARM register parameter */
1189 sc_Bits
, /* 18; C_FIELD bitfield */
1271 sc_Text
, /* 100: C_BLOCK block start/end */
1272 sc_Text
, /* 101: C_FCN function start/end */
1273 sc_Info
, /* 102: C_EOS end of struct/union/enum */
1274 sc_Nil
, /* 103: C_FILE file start */
1275 sc_Nil
, /* 104: C_LINE line number */
1276 sc_Nil
, /* 105: C_ALIAS combined type info */
1277 sc_Nil
, /* 106: C_HIDDEN ??? */
1280 /* Convert COFF storage class to ECOFF symbol type. */
1281 static const st_t map_coff_sym_type
[ (int) C_MAX
] = {
1282 st_Nil
, /* 0: C_NULL */
1283 st_Local
, /* 1: C_AUTO auto var */
1284 st_Global
, /* 2: C_EXT external */
1285 st_Static
, /* 3: C_STAT static */
1286 st_Local
, /* 4: C_REG register */
1287 st_Global
, /* 5: C_EXTDEF ??? */
1288 st_Label
, /* 6: C_LABEL label */
1289 st_Label
, /* 7: C_ULABEL user label */
1290 st_Member
, /* 8: C_MOS member of struct */
1291 st_Param
, /* 9: C_ARG argument */
1292 st_Block
, /* 10: C_STRTAG struct tag */
1293 st_Member
, /* 11: C_MOU member of union */
1294 st_Block
, /* 12: C_UNTAG union tag */
1295 st_Typedef
, /* 13: C_TPDEF typedef */
1296 st_Static
, /* 14: C_USTATIC ??? */
1297 st_Block
, /* 15: C_ENTAG enum tag */
1298 st_Member
, /* 16: C_MOE member of enum */
1299 st_Param
, /* 17: C_REGPARM register parameter */
1300 st_Member
, /* 18; C_FIELD bitfield */
1382 st_Block
, /* 100: C_BLOCK block start/end */
1383 st_Proc
, /* 101: C_FCN function start/end */
1384 st_End
, /* 102: C_EOS end of struct/union/enum */
1385 st_File
, /* 103: C_FILE file start */
1386 st_Nil
, /* 104: C_LINE line number */
1387 st_Nil
, /* 105: C_ALIAS combined type info */
1388 st_Nil
, /* 106: C_HIDDEN ??? */
1391 /* Map COFF derived types to ECOFF type qualifiers. */
1392 static const tq_t map_coff_derived_type
[ (int) DT_MAX
] = {
1393 tq_Nil
, /* 0: DT_NON no more qualifiers */
1394 tq_Ptr
, /* 1: DT_PTR pointer */
1395 tq_Proc
, /* 2: DT_FCN function */
1396 tq_Array
, /* 3: DT_ARY array */
1400 /* Keep track of different sized allocation requests. */
1401 static alloc_info_t alloc_counts
[ (int) alloc_type_last
];
1404 /* Pointers and such to the original symbol table that is read in. */
1405 static struct filehdr orig_file_header
; /* global object file header */
1407 static HDRR orig_sym_hdr
; /* symbolic header on input */
1408 static char *orig_linenum
; /* line numbers */
1409 static DNR
*orig_dense
; /* dense numbers */
1410 static PDR
*orig_procs
; /* procedures */
1411 static SYMR
*orig_local_syms
; /* local symbols */
1412 static OPTR
*orig_opt_syms
; /* optimization symbols */
1413 static AUXU
*orig_aux_syms
; /* auxiliary symbols */
1414 static char *orig_local_strs
; /* local strings */
1415 static char *orig_ext_strs
; /* external strings */
1416 static FDR
*orig_files
; /* file descriptors */
1417 static symint_t
*orig_rfds
; /* relative file desc's */
1418 static EXTR
*orig_ext_syms
; /* external symbols */
1420 /* Macros to convert an index into a given object within the original
1422 #define CHECK(num,max,str) \
1423 (((unsigned long) num > (unsigned long) max) ? out_of_bounds (num, max, str, __LINE__) : 0)
1425 #define ORIG_LINENUM(indx) (CHECK ((indx), orig_sym_hdr.cbLine, "line#"), (indx) + orig_linenum)
1426 #define ORIG_DENSE(indx) (CHECK ((indx), orig_sym_hdr.idnMax, "dense"), (indx) + orig_dense)
1427 #define ORIG_PROCS(indx) (CHECK ((indx), orig_sym_hdr.ipdMax, "procs"), (indx) + orig_procs)
1428 #define ORIG_FILES(indx) (CHECK ((indx), orig_sym_hdr.ifdMax, "funcs"), (indx) + orig_files)
1429 #define ORIG_LSYMS(indx) (CHECK ((indx), orig_sym_hdr.isymMax, "lsyms"), (indx) + orig_local_syms)
1430 #define ORIG_LSTRS(indx) (CHECK ((indx), orig_sym_hdr.issMax, "lstrs"), (indx) + orig_local_strs)
1431 #define ORIG_ESYMS(indx) (CHECK ((indx), orig_sym_hdr.iextMax, "esyms"), (indx) + orig_ext_syms)
1432 #define ORIG_ESTRS(indx) (CHECK ((indx), orig_sym_hdr.issExtMax, "estrs"), (indx) + orig_ext_strs)
1433 #define ORIG_OPT(indx) (CHECK ((indx), orig_sym_hdr.ioptMax, "opt"), (indx) + orig_opt_syms)
1434 #define ORIG_AUX(indx) (CHECK ((indx), orig_sym_hdr.iauxMax, "aux"), (indx) + orig_aux_syms)
1435 #define ORIG_RFDS(indx) (CHECK ((indx), orig_sym_hdr.crfd, "rfds"), (indx) + orig_rfds)
1437 /* Various other statics. */
1438 static HDRR symbolic_header
; /* symbolic header */
1439 static efdr_t
*cur_file_ptr
= (efdr_t
*) 0; /* current file desc. header */
1440 static PDR
*cur_proc_ptr
= (PDR
*) 0; /* current procedure header */
1441 static SYMR
*cur_oproc_begin
= (SYMR
*) 0; /* original proc. sym begin info */
1442 static SYMR
*cur_oproc_end
= (SYMR
*) 0; /* original proc. sym end info */
1443 static PDR
*cur_oproc_ptr
= (PDR
*) 0; /* current original procedure*/
1444 static thead_t
*cur_tag_head
= (thead_t
*) 0;/* current tag head */
1445 static unsigned long file_offset
= 0; /* current file offset */
1446 static unsigned long max_file_offset
= 0; /* maximum file offset */
1447 static FILE *object_stream
= (FILE *) 0; /* file desc. to output .o */
1448 static FILE *obj_in_stream
= (FILE *) 0; /* file desc. to input .o */
1449 static const char *progname
= (const char *) 0;/* program name for errors */
1450 static const char *input_name
= "stdin"; /* name of input file */
1451 static char *object_name
= (char *) 0; /* tmp. name of object file */
1452 static char *obj_in_name
= (char *) 0; /* name of input object file */
1453 static char *cur_line_start
= (char *) 0; /* current line read in */
1454 static char *cur_line_ptr
= (char *) 0; /* ptr within current line */
1455 static unsigned cur_line_nbytes
= 0; /* # bytes for current line */
1456 static unsigned cur_line_alloc
= 0; /* # bytes total in buffer */
1457 static long line_number
= 0; /* current input line number */
1458 static int debug
= 0; /* trace functions */
1459 static int version
= 0; /* print version # */
1460 static int verbose
= 0;
1461 static int had_errors
= 0; /* != 0 if errors were found */
1462 static int rename_output
= 0; /* != 0 if rename output file*/
1463 static int delete_input
= 0; /* != 0 if delete input after done */
1464 static int stabs_seen
= 0; /* != 0 if stabs have been seen */
1467 /* Pseudo symbol to use when putting stabs into the symbol table. */
1468 #ifndef STABS_SYMBOL
1469 #define STABS_SYMBOL "@stabs"
1472 static const char stabs_symbol
[] = STABS_SYMBOL
;
1475 /* Forward reference for functions. See the definition for more details. */
1477 static int out_of_bounds (symint_t
, symint_t
, const char *, int);
1478 static shash_t
*hash_string (const char *, ptrdiff_t, shash_t
**, symint_t
*);
1479 static symint_t
add_string (varray_t
*, shash_t
**, const char *, const char *,
1481 static symint_t
add_local_symbol (const char *, const char *, st_t
, sc_t
,
1482 symint_t
, symint_t
);
1483 static symint_t
add_ext_symbol (EXTR
*, int);
1484 static symint_t
add_aux_sym_symint (symint_t
);
1485 static symint_t
add_aux_sym_rndx (int, symint_t
);
1486 static symint_t
add_aux_sym_tir (type_info_t
*, hash_state_t
, thash_t
**);
1487 static tag_t
* get_tag (const char *, const char *, symint_t
, bt_t
);
1488 static void add_unknown_tag (tag_t
*);
1489 static void add_procedure (const char *, const char *);
1490 static void initialize_init_file (void);
1491 static void add_file (const char *, const char *);
1492 static void add_bytes (varray_t
*, char *, size_t);
1493 static void add_varray_page (varray_t
*);
1494 static void update_headers (void);
1495 static void write_varray (varray_t
*, off_t
, const char *);
1496 static void write_object (void);
1497 static const char *st_to_string (st_t
);
1498 static const char *sc_to_string (sc_t
);
1499 static char *read_line (void);
1500 static void parse_input (void);
1501 static void mark_stabs (const char *);
1502 static void parse_begin (const char *);
1503 static void parse_bend (const char *);
1504 static void parse_def (const char *);
1505 static void parse_end (const char *);
1506 static void parse_ent (const char *);
1507 static void parse_file (const char *);
1508 static void parse_stabs_common (const char *, const char *, const char *);
1509 static void parse_stabs (const char *);
1510 static void parse_stabn (const char *);
1511 static page_t
*read_seek (size_t, off_t
, const char *);
1512 static void copy_object (void);
1514 static void catch_signal (int) ATTRIBUTE_NORETURN
;
1515 static page_t
*allocate_page (void);
1516 static page_t
*allocate_multiple_pages (size_t);
1517 static void free_multiple_pages (page_t
*, size_t);
1519 #ifndef MALLOC_CHECK
1520 static page_t
*allocate_cluster (size_t);
1523 static forward_t
*allocate_forward (void);
1524 static scope_t
*allocate_scope (void);
1525 static shash_t
*allocate_shash (void);
1526 static tag_t
*allocate_tag (void);
1527 static thash_t
*allocate_thash (void);
1528 static thead_t
*allocate_thead (void);
1529 static vlinks_t
*allocate_vlinks (void);
1531 static void free_forward (forward_t
*);
1532 static void free_scope (scope_t
*);
1533 static void free_tag (tag_t
*);
1534 static void free_thead (thead_t
*);
1536 extern char *optarg
;
1540 /* List of assembler pseudo ops and beginning sequences that need
1541 special actions. Someday, this should be a hash table, and such,
1542 but for now a linear list of names and calls to memcmp will
1545 typedef struct _pseudo_ops
{
1546 const char *const name
; /* pseudo-op in ascii */
1547 const int len
; /* length of name to compare */
1548 void (*const func
) (const char *); /* function to handle line */
1551 static const pseudo_ops_t pseudo_ops
[] = {
1552 { "#.def", sizeof("#.def")-1, parse_def
},
1553 { "#.begin", sizeof("#.begin")-1, parse_begin
},
1554 { "#.bend", sizeof("#.bend")-1, parse_bend
},
1555 { ".end", sizeof(".end")-1, parse_end
},
1556 { ".ent", sizeof(".ent")-1, parse_ent
},
1557 { ".file", sizeof(".file")-1, parse_file
},
1558 { "#.stabs", sizeof("#.stabs")-1, parse_stabs
},
1559 { "#.stabn", sizeof("#.stabn")-1, parse_stabn
},
1560 { ".stabs", sizeof(".stabs")-1, parse_stabs
},
1561 { ".stabn", sizeof(".stabn")-1, parse_stabn
},
1562 { "#@stabs", sizeof("#@stabs")-1, mark_stabs
},
1566 /* Command line options for getopt_long. */
1568 static const struct option options
[] =
1570 { "version", 0, 0, 'V' },
1571 { "verbose", 0, 0, 'v' },
1575 /* Add a page to a varray object. */
1578 add_varray_page (varray_t
*vp
)
1580 vlinks_t
*new_links
= allocate_vlinks ();
1583 if (vp
->object_size
> 1)
1584 new_links
->datum
= xcalloc (1, vp
->object_size
);
1587 new_links
->datum
= allocate_page ();
1589 alloc_counts
[ (int) alloc_type_varray
].total_alloc
++;
1590 alloc_counts
[ (int) alloc_type_varray
].total_pages
++;
1592 new_links
->start_index
= vp
->num_allocated
;
1593 vp
->objects_last_page
= 0;
1595 if (vp
->first
== (vlinks_t
*) 0) /* first allocation? */
1596 vp
->first
= vp
->last
= new_links
;
1598 { /* 2nd or greater allocation */
1599 new_links
->prev
= vp
->last
;
1600 vp
->last
->next
= new_links
;
1601 vp
->last
= new_links
;
1606 /* Compute hash code (from tree.c) */
1611 hash_string (const char *text
, ptrdiff_t hash_len
, shash_t
**hash_tbl
,
1612 symint_t
*ret_hash_index
)
1617 int first_ch
= *text
;
1620 for (i
= 0; i
< hash_len
; i
++)
1621 hi
= ((hi
& 0x003fffff) * 613) + (text
[i
] & 0xff);
1623 hi
&= (1 << HASHBITS
) - 1;
1626 if (ret_hash_index
!= (symint_t
*) 0)
1627 *ret_hash_index
= hi
;
1629 for (ptr
= hash_tbl
[hi
]; ptr
!= (shash_t
*) 0; ptr
= ptr
->next
)
1630 if ((symint_t
) hash_len
== ptr
->len
1631 && first_ch
== ptr
->string
[0]
1632 && memcmp (text
, ptr
->string
, hash_len
) == 0)
1639 /* Add a string (and null pad) to one of the string tables. A
1640 consequence of hashing strings, is that we don't let strings cross
1641 page boundaries. The extra nulls will be ignored. VP is a string
1642 virtual array, HASH_TBL a pointer to the hash table, the string
1643 starts at START and the position one byte after the string is given
1644 with END_P1, the resulting hash pointer is returned in RET_HASH. */
1647 add_string (varray_t
*vp
, shash_t
**hash_tbl
, const char *start
,
1648 const char *end_p1
, shash_t
**ret_hash
)
1650 ptrdiff_t len
= end_p1
- start
;
1654 if (len
>= (ptrdiff_t) PAGE_USIZE
)
1655 fatal ("string too big (%ld bytes)", (long) len
);
1657 hash_ptr
= hash_string (start
, len
, hash_tbl
, &hi
);
1658 if (hash_ptr
== (shash_t
*) 0)
1662 if (vp
->objects_last_page
+ len
>= (long) PAGE_USIZE
)
1665 = ((vp
->num_allocated
+ PAGE_USIZE
- 1) / PAGE_USIZE
) * PAGE_USIZE
;
1666 add_varray_page (vp
);
1669 hash_ptr
= allocate_shash ();
1670 hash_ptr
->next
= hash_tbl
[hi
];
1671 hash_tbl
[hi
] = hash_ptr
;
1673 hash_ptr
->len
= len
;
1674 hash_ptr
->indx
= vp
->num_allocated
;
1675 hash_ptr
->string
= p
= & vp
->last
->datum
->byte
[ vp
->objects_last_page
];
1677 vp
->objects_last_page
+= len
+1;
1678 vp
->num_allocated
+= len
+1;
1686 if (ret_hash
!= (shash_t
**) 0)
1687 *ret_hash
= hash_ptr
;
1689 return hash_ptr
->indx
;
1693 /* Add a local symbol. The symbol string starts at STR_START and the
1694 first byte after it is marked by STR_END_P1. The symbol has type
1695 TYPE and storage class STORAGE and value VALUE. INDX is an index
1696 to local/aux. symbols. */
1699 add_local_symbol (const char *str_start
, const char *str_end_p1
, st_t type
,
1700 sc_t storage
, symint_t value
, symint_t indx
)
1708 varray_t
*vp
= &cur_file_ptr
->symbols
;
1709 int scope_delta
= 0;
1710 shash_t
*hash_ptr
= (shash_t
*) 0;
1712 if (vp
->objects_last_page
== vp
->objects_per_page
)
1713 add_varray_page (vp
);
1715 psym
= &vp
->last
->datum
->sym
[ vp
->objects_last_page
++ ];
1717 psym
->value
= value
;
1718 psym
->st
= (unsigned) type
;
1719 psym
->sc
= (unsigned) storage
;
1721 psym
->iss
= (str_start
== (const char *) 0)
1723 : add_string (&cur_file_ptr
->strings
,
1724 &cur_file_ptr
->shash_head
[0],
1729 ret
= vp
->num_allocated
++;
1731 if (MIPS_IS_STAB (psym
))
1734 /* Save the symbol within the hash table if this is a static
1735 item, and it has a name. */
1736 if (hash_ptr
!= (shash_t
*) 0
1737 && (type
== st_Global
|| type
== st_Static
|| type
== st_Label
1738 || type
== st_Proc
|| type
== st_StaticProc
))
1739 hash_ptr
->sym_ptr
= psym
;
1741 /* push or pop a scope if appropriate. */
1747 case st_File
: /* beginning of file */
1748 case st_Proc
: /* procedure */
1749 case st_StaticProc
: /* static procedure */
1750 case st_Block
: /* begin scope */
1751 pscope
= allocate_scope ();
1752 pscope
->prev
= cur_file_ptr
->cur_scope
;
1753 pscope
->lsym
= psym
;
1754 pscope
->lnumber
= ret
;
1755 pscope
->type
= type
;
1756 cur_file_ptr
->cur_scope
= pscope
;
1758 if (type
!= st_File
)
1761 /* For every block type except file, struct, union, or
1762 enumeration blocks, push a level on the tag stack. We omit
1763 file types, so that tags can span file boundaries. */
1764 if (type
!= st_File
&& storage
!= sc_Info
)
1766 ptag_head
= allocate_thead ();
1767 ptag_head
->first_tag
= 0;
1768 ptag_head
->prev
= cur_tag_head
;
1769 cur_tag_head
= ptag_head
;
1774 pscope
= cur_file_ptr
->cur_scope
;
1775 if (pscope
== (scope_t
*) 0)
1776 error ("internal error, too many st_End's");
1780 st_t begin_type
= (st_t
) pscope
->lsym
->st
;
1782 if (begin_type
!= st_File
)
1785 /* Except for file, structure, union, or enumeration end
1786 blocks remove all tags created within this scope. */
1787 if (begin_type
!= st_File
&& storage
!= sc_Info
)
1789 ptag_head
= cur_tag_head
;
1790 cur_tag_head
= ptag_head
->prev
;
1792 for (ptag
= ptag_head
->first_tag
;
1793 ptag
!= (tag_t
*) 0;
1796 if (ptag
->forward_ref
!= (forward_t
*) 0)
1797 add_unknown_tag (ptag
);
1799 ptag_next
= ptag
->same_block
;
1800 ptag
->hash_ptr
->tag_ptr
= ptag
->same_name
;
1804 free_thead (ptag_head
);
1807 cur_file_ptr
->cur_scope
= pscope
->prev
;
1808 psym
->index
= pscope
->lnumber
; /* blk end gets begin sym # */
1810 if (storage
!= sc_Info
)
1811 psym
->iss
= pscope
->lsym
->iss
; /* blk end gets same name */
1813 if (begin_type
== st_File
|| begin_type
== st_Block
)
1814 pscope
->lsym
->index
= ret
+1; /* block begin gets next sym # */
1816 /* Functions push two or more aux words as follows:
1817 1st word: index+1 of the end symbol
1818 2nd word: type of the function (plus any aux words needed).
1819 Also, tie the external pointer back to the function begin symbol. */
1823 pscope
->lsym
->index
= add_aux_sym_symint (ret
+1);
1824 type
= add_aux_sym_tir (&last_func_type_info
,
1826 &cur_file_ptr
->thash_head
[0]);
1829 last_func_eptr
->ifd
= cur_file_ptr
->file_index
;
1831 /* The index for an external st_Proc symbol is the index
1832 of the st_Proc symbol in the local symbol table. */
1833 last_func_eptr
->asym
.index
= psym
->index
;
1837 free_scope (pscope
);
1841 cur_file_ptr
->nested_scopes
+= scope_delta
;
1843 if (debug
&& type
!= st_File
1844 && (debug
> 2 || type
== st_Block
|| type
== st_End
1845 || type
== st_Proc
|| type
== st_StaticProc
))
1847 const char *sc_str
= sc_to_string (storage
);
1848 const char *st_str
= st_to_string (type
);
1849 int depth
= cur_file_ptr
->nested_scopes
+ (scope_delta
< 0);
1852 "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
1853 value
, depth
, sc_str
);
1855 if (str_start
&& str_end_p1
- str_start
> 0)
1856 fprintf (stderr
, " st= %-11s name= %.*s\n",
1857 st_str
, (int) (str_end_p1
- str_start
), str_start
);
1860 size_t len
= strlen (st_str
);
1861 fprintf (stderr
, " st= %.*s\n", (int) (len
-1), st_str
);
1869 /* Add an external symbol with symbol pointer ESYM and file index
1873 add_ext_symbol (EXTR
*esym
, int ifd
)
1875 const char *str_start
; /* first byte in string */
1876 const char *str_end_p1
; /* first byte after string */
1878 varray_t
*vp
= &ext_symbols
;
1879 shash_t
*hash_ptr
= (shash_t
*) 0;
1881 str_start
= ORIG_ESTRS (esym
->asym
.iss
);
1882 str_end_p1
= str_start
+ strlen (str_start
);
1886 long value
= esym
->asym
.value
;
1887 const char *sc_str
= sc_to_string ((sc_t
) esym
->asym
.sc
);
1888 const char *st_str
= st_to_string ((st_t
) esym
->asym
.st
);
1891 "\tesym\tv= %10ld, ifd= %2d, sc= %-12s",
1892 value
, ifd
, sc_str
);
1894 if (str_start
&& str_end_p1
- str_start
> 0)
1895 fprintf (stderr
, " st= %-11s name= %.*s\n",
1896 st_str
, (int) (str_end_p1
- str_start
), str_start
);
1898 fprintf (stderr
, " st= %s\n", st_str
);
1901 if (vp
->objects_last_page
== vp
->objects_per_page
)
1902 add_varray_page (vp
);
1904 psym
= &vp
->last
->datum
->esym
[ vp
->objects_last_page
++ ];
1908 psym
->asym
.index
= indexNil
;
1909 psym
->asym
.iss
= (str_start
== (const char *) 0)
1911 : add_string (&ext_strings
,
1917 hash_ptr
->esym_ptr
= psym
;
1918 return vp
->num_allocated
++;
1922 /* Add an auxiliary symbol (passing a symint). */
1925 add_aux_sym_symint (symint_t aux_word
)
1928 efdr_t
*file_ptr
= cur_file_ptr
;
1929 varray_t
*vp
= &file_ptr
->aux_syms
;
1931 if (vp
->objects_last_page
== vp
->objects_per_page
)
1932 add_varray_page (vp
);
1934 aux_ptr
= &vp
->last
->datum
->aux
[ vp
->objects_last_page
++ ];
1935 aux_ptr
->isym
= aux_word
;
1937 return vp
->num_allocated
++;
1941 /* Add an auxiliary symbol (passing a file/symbol index combo). */
1944 add_aux_sym_rndx (int file_index
, symint_t sym_index
)
1947 efdr_t
*file_ptr
= cur_file_ptr
;
1948 varray_t
*vp
= &file_ptr
->aux_syms
;
1950 if (vp
->objects_last_page
== vp
->objects_per_page
)
1951 add_varray_page (vp
);
1953 aux_ptr
= &vp
->last
->datum
->aux
[ vp
->objects_last_page
++ ];
1954 aux_ptr
->rndx
.rfd
= file_index
;
1955 aux_ptr
->rndx
.index
= sym_index
;
1957 return vp
->num_allocated
++;
1961 /* Add an auxiliary symbol (passing the basic type and possibly
1962 type qualifiers). */
1965 add_aux_sym_tir (type_info_t
*t
, hash_state_t state
, thash_t
**hash_tbl
)
1968 efdr_t
*file_ptr
= cur_file_ptr
;
1969 varray_t
*vp
= &file_ptr
->aux_syms
;
1970 static AUXU init_aux
;
1976 aux
.ti
.bt
= (int) t
->basic_type
;
1977 aux
.ti
.continued
= 0;
1978 aux
.ti
.fBitfield
= t
->bitfield
;
1980 aux
.ti
.tq0
= (int) t
->type_qualifiers
[0];
1981 aux
.ti
.tq1
= (int) t
->type_qualifiers
[1];
1982 aux
.ti
.tq2
= (int) t
->type_qualifiers
[2];
1983 aux
.ti
.tq3
= (int) t
->type_qualifiers
[3];
1984 aux
.ti
.tq4
= (int) t
->type_qualifiers
[4];
1985 aux
.ti
.tq5
= (int) t
->type_qualifiers
[5];
1988 /* For anything that adds additional information, we must not hash,
1989 so check here, and reset our state. */
1991 if (state
!= hash_no
1992 && (t
->type_qualifiers
[0] == tq_Array
1993 || t
->type_qualifiers
[1] == tq_Array
1994 || t
->type_qualifiers
[2] == tq_Array
1995 || t
->type_qualifiers
[3] == tq_Array
1996 || t
->type_qualifiers
[4] == tq_Array
1997 || t
->type_qualifiers
[5] == tq_Array
1998 || t
->basic_type
== bt_Struct
1999 || t
->basic_type
== bt_Union
2000 || t
->basic_type
== bt_Enum
2002 || t
->num_dims
> 0))
2005 /* See if we can hash this type, and save some space, but some types
2006 can't be hashed (because they contain arrays or continuations),
2007 and others can be put into the hash list, but cannot use existing
2008 types because other aux entries precede this one. */
2010 if (state
!= hash_no
)
2015 hi
= aux
.isym
& ((1 << HASHBITS
) - 1);
2018 for (hash_ptr
= hash_tbl
[hi
];
2019 hash_ptr
!= (thash_t
*) 0;
2020 hash_ptr
= hash_ptr
->next
)
2022 if (aux
.isym
== hash_ptr
->type
.isym
)
2026 if (hash_ptr
!= (thash_t
*) 0 && state
== hash_yes
)
2027 return hash_ptr
->indx
;
2029 if (hash_ptr
== (thash_t
*) 0)
2031 hash_ptr
= allocate_thash ();
2032 hash_ptr
->next
= hash_tbl
[hi
];
2033 hash_ptr
->type
= aux
;
2034 hash_ptr
->indx
= vp
->num_allocated
;
2035 hash_tbl
[hi
] = hash_ptr
;
2039 /* Everything is set up, add the aux symbol. */
2040 if (vp
->objects_last_page
== vp
->objects_per_page
)
2041 add_varray_page (vp
);
2043 aux_ptr
= &vp
->last
->datum
->aux
[ vp
->objects_last_page
++ ];
2046 ret
= vp
->num_allocated
++;
2048 /* Add bitfield length if it exists.
2050 NOTE: Mips documentation claims bitfield goes at the end of the
2051 AUX record, but the DECstation compiler emits it here.
2052 (This would only make a difference for enum bitfields.)
2054 Also note: We use the last size given since gcc may emit 2
2055 for an enum bitfield. */
2058 (void) add_aux_sym_symint ((symint_t
) t
->sizes
[t
->num_sizes
-1]);
2061 /* Add tag information if needed. Structure, union, and enum
2062 references add 2 aux symbols: a [file index, symbol index]
2063 pointer to the structure type, and the current file index. */
2065 if (t
->basic_type
== bt_Struct
2066 || t
->basic_type
== bt_Union
2067 || t
->basic_type
== bt_Enum
)
2069 symint_t file_index
= t
->tag_ptr
->ifd
;
2070 symint_t sym_index
= t
->tag_ptr
->indx
;
2074 (void) add_aux_sym_rndx (ST_RFDESCAPE
, sym_index
);
2075 (void) add_aux_sym_symint ((symint_t
)-1);
2077 else if (sym_index
!= indexNil
)
2079 (void) add_aux_sym_rndx (ST_RFDESCAPE
, sym_index
);
2080 (void) add_aux_sym_symint (file_index
);
2084 forward_t
*forward_ref
= allocate_forward ();
2086 forward_ref
->type_ptr
= aux_ptr
;
2087 forward_ref
->next
= t
->tag_ptr
->forward_ref
;
2088 t
->tag_ptr
->forward_ref
= forward_ref
;
2090 (void) add_aux_sym_rndx (ST_RFDESCAPE
, sym_index
);
2091 forward_ref
->index_ptr
2092 = &vp
->last
->datum
->aux
[ vp
->objects_last_page
- 1];
2094 (void) add_aux_sym_symint (file_index
);
2095 forward_ref
->ifd_ptr
2096 = &vp
->last
->datum
->aux
[ vp
->objects_last_page
- 1];
2100 /* Add information about array bounds if they exist. */
2101 for (i
= 0; i
< t
->num_dims
; i
++)
2103 (void) add_aux_sym_rndx (ST_RFDESCAPE
,
2104 cur_file_ptr
->int_type
);
2106 (void) add_aux_sym_symint (cur_file_ptr
->file_index
); /* file index*/
2107 (void) add_aux_sym_symint ((symint_t
) 0); /* low bound */
2108 (void) add_aux_sym_symint (t
->dimensions
[i
] - 1); /* high bound*/
2109 (void) add_aux_sym_symint ((t
->dimensions
[i
] == 0) /* stride */
2111 : (t
->sizes
[i
] * 8) / t
->dimensions
[i
]);
2114 /* NOTE: Mips documentation claims that the bitfield width goes here.
2115 But it needs to be emitted earlier. */
2121 /* Add a tag to the tag table (unless it already exists). */
2124 get_tag (const char *tag_start
, /* 1st byte of tag name */
2125 const char *tag_end_p1
, /* 1st byte after tag name */
2126 symint_t indx
, /* index of tag start block */
2127 bt_t basic_type
) /* bt_Struct, bt_Union, or bt_Enum */
2132 hash_ptr
= hash_string (tag_start
,
2133 tag_end_p1
- tag_start
,
2137 if (hash_ptr
!= (shash_t
*) 0
2138 && hash_ptr
->tag_ptr
!= (tag_t
*) 0)
2140 tag_ptr
= hash_ptr
->tag_ptr
;
2141 if (indx
!= indexNil
)
2143 tag_ptr
->basic_type
= basic_type
;
2144 tag_ptr
->ifd
= cur_file_ptr
->file_index
;
2145 tag_ptr
->indx
= indx
;
2150 (void) add_string (&tag_strings
,
2156 tag_ptr
= allocate_tag ();
2157 tag_ptr
->forward_ref
= (forward_t
*) 0;
2158 tag_ptr
->hash_ptr
= hash_ptr
;
2159 tag_ptr
->same_name
= hash_ptr
->tag_ptr
;
2160 tag_ptr
->basic_type
= basic_type
;
2161 tag_ptr
->indx
= indx
;
2162 tag_ptr
->ifd
= (indx
== indexNil
2163 ? (symint_t
) -1 : cur_file_ptr
->file_index
);
2164 tag_ptr
->same_block
= cur_tag_head
->first_tag
;
2166 cur_tag_head
->first_tag
= tag_ptr
;
2167 hash_ptr
->tag_ptr
= tag_ptr
;
2173 /* Add an unknown {struct, union, enum} tag. */
2176 add_unknown_tag (tag_t
*ptag
)
2178 shash_t
*hash_ptr
= ptag
->hash_ptr
;
2179 char *name_start
= hash_ptr
->string
;
2180 char *name_end_p1
= name_start
+ hash_ptr
->len
;
2181 forward_t
*f_next
= ptag
->forward_ref
;
2184 int file_index
= cur_file_ptr
->file_index
;
2188 const char *agg_type
= "{unknown aggregate type}";
2189 switch (ptag
->basic_type
)
2191 case bt_Struct
: agg_type
= "struct"; break;
2192 case bt_Union
: agg_type
= "union"; break;
2193 case bt_Enum
: agg_type
= "enum"; break;
2197 fprintf (stderr
, "unknown %s %.*s found\n",
2198 agg_type
, (int) hash_ptr
->len
, name_start
);
2201 sym_index
= add_local_symbol (name_start
,
2208 (void) add_local_symbol (name_start
,
2215 while (f_next
!= (forward_t
*) 0)
2218 f_next
= f_next
->next
;
2220 f_cur
->ifd_ptr
->isym
= file_index
;
2221 f_cur
->index_ptr
->rndx
.index
= sym_index
;
2223 free_forward (f_cur
);
2230 /* Add a procedure to the current file's list of procedures, and record
2231 this is the current procedure. If the assembler created a PDR for
2232 this procedure, use that to initialize the current PDR. */
2235 add_procedure (const char *func_start
, /* 1st byte of func name */
2236 const char *func_end_p1
) /* 1st byte after func name */
2239 efdr_t
*file_ptr
= cur_file_ptr
;
2240 varray_t
*vp
= &file_ptr
->procs
;
2242 st_t proc_type
= st_Proc
;
2243 shash_t
*shash_ptr
= hash_string (func_start
,
2244 func_end_p1
- func_start
,
2249 fputc ('\n', stderr
);
2251 if (vp
->objects_last_page
== vp
->objects_per_page
)
2252 add_varray_page (vp
);
2254 cur_proc_ptr
= new_proc_ptr
= &vp
->last
->datum
->proc
[ vp
->objects_last_page
++ ];
2256 vp
->num_allocated
++;
2259 /* Did the assembler create this procedure? If so, get the PDR information. */
2260 cur_oproc_ptr
= (PDR
*) 0;
2261 if (shash_ptr
!= (shash_t
*) 0)
2263 PDR
*old_proc_ptr
= shash_ptr
->proc_ptr
;
2264 SYMR
*sym_ptr
= shash_ptr
->sym_ptr
;
2266 if (old_proc_ptr
!= (PDR
*) 0
2267 && sym_ptr
!= (SYMR
*) 0
2268 && ((st_t
) sym_ptr
->st
== st_Proc
|| (st_t
) sym_ptr
->st
== st_StaticProc
))
2270 cur_oproc_begin
= sym_ptr
;
2271 cur_oproc_end
= shash_ptr
->end_ptr
;
2272 value
= sym_ptr
->value
;
2274 cur_oproc_ptr
= old_proc_ptr
;
2275 proc_type
= (st_t
) sym_ptr
->st
;
2276 *new_proc_ptr
= *old_proc_ptr
; /* initialize */
2280 if (cur_oproc_ptr
== (PDR
*) 0)
2281 error ("did not find a PDR block for %.*s",
2282 (int) (func_end_p1
- func_start
), func_start
);
2284 /* Determine the start of symbols. */
2285 new_proc_ptr
->isym
= file_ptr
->symbols
.num_allocated
;
2287 /* Push the start of the function. */
2288 (void) add_local_symbol (func_start
, func_end_p1
,
2295 /* Initialize the init_file structure. */
2298 initialize_init_file (void)
2305 memset (&init_file
, 0, sizeof (init_file
));
2307 init_file
.fdr
.lang
= langC
;
2308 init_file
.fdr
.fMerge
= 1;
2309 init_file
.fdr
.glevel
= GLEVEL_2
;
2311 /* mips-tfile doesn't attempt to perform byte swapping and always writes
2312 out integers in its native ordering. For cross-compilers, this need
2313 not be the same as either the host or the target. The simplest thing
2314 to do is skip the configury and perform an introspective test. */
2315 /* ??? Despite the name, mips-tfile is currently only used on alpha/Tru64
2316 and would/may require significant work to be used in cross-compiler
2317 configurations, so we could simply admit defeat and hard code this as
2318 little-endian, i.e. init_file.fdr.fBigendian = 0. */
2320 if (endian_test
.c
[3])
2321 init_file
.fdr
.fBigendian
= 1;
2323 INITIALIZE_VARRAY (&init_file
.strings
, char);
2324 INITIALIZE_VARRAY (&init_file
.symbols
, SYMR
);
2325 INITIALIZE_VARRAY (&init_file
.procs
, PDR
);
2326 INITIALIZE_VARRAY (&init_file
.aux_syms
, AUXU
);
2328 init_file_initialized
= 1;
2331 /* Add a new filename, and set up all of the file relative
2332 virtual arrays (strings, symbols, aux syms, etc.). Record
2333 where the current file structure lives. */
2336 add_file (const char *file_start
, /* first byte in string */
2337 const char *file_end_p1
) /* first byte after string */
2339 static char zero_bytes
[2] = { '\0', '\0' };
2341 ptrdiff_t len
= file_end_p1
- file_start
;
2342 int first_ch
= *file_start
;
2346 fprintf (stderr
, "\tfile\t%.*s\n", (int) len
, file_start
);
2348 /* See if the file has already been created. */
2349 for (file_ptr
= first_file
;
2350 file_ptr
!= (efdr_t
*) 0;
2351 file_ptr
= file_ptr
->next_file
)
2353 if (first_ch
== file_ptr
->name
[0]
2354 && file_ptr
->name
[len
] == '\0'
2355 && memcmp (file_start
, file_ptr
->name
, len
) == 0)
2357 cur_file_ptr
= file_ptr
;
2362 /* If this is a new file, create it. */
2363 if (file_ptr
== (efdr_t
*) 0)
2365 if (file_desc
.objects_last_page
== file_desc
.objects_per_page
)
2366 add_varray_page (&file_desc
);
2368 if (! init_file_initialized
)
2369 initialize_init_file ();
2371 file_ptr
= cur_file_ptr
2372 = &file_desc
.last
->datum
->file
[ file_desc
.objects_last_page
++ ];
2373 *file_ptr
= init_file
;
2375 file_ptr
->file_index
= file_desc
.num_allocated
++;
2377 /* Allocate the string hash table. */
2378 file_ptr
->shash_head
= (shash_t
**) allocate_page ();
2380 /* Make sure 0 byte in string table is null */
2381 add_string (&file_ptr
->strings
,
2382 &file_ptr
->shash_head
[0],
2387 if (file_end_p1
- file_start
> (long) PAGE_USIZE
-2)
2388 fatal ("filename goes over one page boundary");
2390 /* Push the start of the filename. We assume that the filename
2391 will be stored at string offset 1. */
2392 (void) add_local_symbol (file_start
, file_end_p1
, st_File
, sc_Text
,
2393 (symint_t
) 0, (symint_t
) 0);
2394 file_ptr
->fdr
.rss
= 1;
2395 file_ptr
->name
= &file_ptr
->strings
.last
->datum
->byte
[1];
2396 file_ptr
->name_len
= file_end_p1
- file_start
;
2398 /* Update the linked list of file descriptors. */
2399 *last_file_ptr
= file_ptr
;
2400 last_file_ptr
= &file_ptr
->next_file
;
2402 /* Add void & int types to the file (void should be first to catch
2403 errant 0's within the index fields). */
2404 file_ptr
->void_type
= add_aux_sym_tir (&void_type_info
,
2406 &cur_file_ptr
->thash_head
[0]);
2408 file_ptr
->int_type
= add_aux_sym_tir (&int_type_info
,
2410 &cur_file_ptr
->thash_head
[0]);
2415 /* Add a stream of random bytes to a varray. */
2418 add_bytes (varray_t
*vp
, /* virtual array to add too */
2419 char *input_ptr
, /* start of the bytes */
2420 size_t nitems
) /* # items to move */
2428 if (vp
->objects_last_page
>= vp
->objects_per_page
)
2429 add_varray_page (vp
);
2431 ptr
= &vp
->last
->datum
->byte
[ vp
->objects_last_page
* vp
->object_size
];
2432 move_items
= vp
->objects_per_page
- vp
->objects_last_page
;
2433 if (move_items
> nitems
)
2434 move_items
= nitems
;
2436 move_bytes
= move_items
* vp
->object_size
;
2437 nitems
-= move_items
;
2439 if (move_bytes
>= 32)
2441 (void) memcpy (ptr
, input_ptr
, move_bytes
);
2442 input_ptr
+= move_bytes
;
2446 while (move_bytes
-- > 0)
2447 *ptr
++ = *input_ptr
++;
2453 /* Convert storage class to string. */
2456 sc_to_string (sc_t storage_class
)
2458 switch (storage_class
)
2460 case sc_Nil
: return "Nil,";
2461 case sc_Text
: return "Text,";
2462 case sc_Data
: return "Data,";
2463 case sc_Bss
: return "Bss,";
2464 case sc_Register
: return "Register,";
2465 case sc_Abs
: return "Abs,";
2466 case sc_Undefined
: return "Undefined,";
2467 case sc_CdbLocal
: return "CdbLocal,";
2468 case sc_Bits
: return "Bits,";
2469 case sc_CdbSystem
: return "CdbSystem,";
2470 case sc_RegImage
: return "RegImage,";
2471 case sc_Info
: return "Info,";
2472 case sc_UserStruct
: return "UserStruct,";
2473 case sc_SData
: return "SData,";
2474 case sc_SBss
: return "SBss,";
2475 case sc_RData
: return "RData,";
2476 case sc_Var
: return "Var,";
2477 case sc_Common
: return "Common,";
2478 case sc_SCommon
: return "SCommon,";
2479 case sc_VarRegister
: return "VarRegister,";
2480 case sc_Variant
: return "Variant,";
2481 case sc_SUndefined
: return "SUndefined,";
2482 case sc_Init
: return "Init,";
2483 case sc_Max
: return "Max,";
2490 /* Convert symbol type to string. */
2493 st_to_string (st_t symbol_type
)
2495 switch (symbol_type
)
2497 case st_Nil
: return "Nil,";
2498 case st_Global
: return "Global,";
2499 case st_Static
: return "Static,";
2500 case st_Param
: return "Param,";
2501 case st_Local
: return "Local,";
2502 case st_Label
: return "Label,";
2503 case st_Proc
: return "Proc,";
2504 case st_Block
: return "Block,";
2505 case st_End
: return "End,";
2506 case st_Member
: return "Member,";
2507 case st_Typedef
: return "Typedef,";
2508 case st_File
: return "File,";
2509 case st_RegReloc
: return "RegReloc,";
2510 case st_Forward
: return "Forward,";
2511 case st_StaticProc
: return "StaticProc,";
2512 case st_Constant
: return "Constant,";
2513 case st_Str
: return "String,";
2514 case st_Number
: return "Number,";
2515 case st_Expr
: return "Expr,";
2516 case st_Type
: return "Type,";
2517 case st_Max
: return "Max,";
2524 /* Read a line from standard input, and return the start of the buffer
2525 (which is grows if the line is too big). We split lines at the
2526 semi-colon, and return each logical line independently. */
2531 static int line_split_p
= 0;
2537 if (cur_line_start
== (char *) 0)
2538 { /* allocate initial page */
2539 cur_line_start
= (char *) allocate_page ();
2540 cur_line_alloc
= PAGE_SIZE
;
2547 cur_line_nbytes
= 0;
2549 for (ptr
= cur_line_start
; (ch
= getchar ()) != EOF
; *ptr
++ = ch
)
2551 if (++cur_line_nbytes
>= cur_line_alloc
-1)
2553 int num_pages
= cur_line_alloc
/ PAGE_SIZE
;
2554 char *old_buffer
= cur_line_start
;
2556 cur_line_alloc
+= PAGE_SIZE
;
2557 cur_line_start
= (char *) allocate_multiple_pages (num_pages
+1);
2558 memcpy (cur_line_start
, old_buffer
, num_pages
* PAGE_SIZE
);
2560 ptr
= cur_line_start
+ cur_line_nbytes
- 1;
2567 cur_line_ptr
= cur_line_start
;
2568 return cur_line_ptr
;
2571 else if (ch
== '\0')
2572 error ("null character found in input");
2574 else if (!comment_p
)
2577 string_p
= !string_p
;
2582 else if (ch
== ';' && !string_p
)
2587 cur_line_ptr
= cur_line_start
;
2588 return cur_line_ptr
;
2594 pfatal_with_name (input_name
);
2596 cur_line_ptr
= (char *) 0;
2601 /* Parse #.begin directives which have a label as the first argument
2602 which gives the location of the start of the block. */
2605 parse_begin (const char *start
)
2607 const char *end_p1
; /* end of label */
2609 shash_t
*hash_ptr
; /* hash pointer to lookup label */
2611 if (cur_file_ptr
== (efdr_t
*) 0)
2613 error ("#.begin directive without a preceding .file directive");
2617 if (cur_proc_ptr
== (PDR
*) 0)
2619 error ("#.begin directive without a preceding .ent directive");
2623 for (end_p1
= start
; (ch
= *end_p1
) != '\0' && !ISSPACE (ch
); end_p1
++)
2626 hash_ptr
= hash_string (start
,
2631 if (hash_ptr
== (shash_t
*) 0)
2633 error ("label %.*s not found for #.begin",
2634 (int) (end_p1
- start
), start
);
2638 if (cur_oproc_begin
== (SYMR
*) 0)
2640 error ("procedure table %.*s not found for #.begin",
2641 (int) (end_p1
- start
), start
);
2645 (void) add_local_symbol ((const char *) 0, (const char *) 0,
2647 (symint_t
) hash_ptr
->sym_ptr
->value
- cur_oproc_begin
->value
,
2652 /* Parse #.bend directives which have a label as the first argument
2653 which gives the location of the end of the block. */
2656 parse_bend (const char *start
)
2658 const char *end_p1
; /* end of label */
2660 shash_t
*hash_ptr
; /* hash pointer to lookup label */
2662 if (cur_file_ptr
== (efdr_t
*) 0)
2664 error ("#.begin directive without a preceding .file directive");
2668 if (cur_proc_ptr
== (PDR
*) 0)
2670 error ("#.bend directive without a preceding .ent directive");
2674 for (end_p1
= start
; (ch
= *end_p1
) != '\0' && !ISSPACE (ch
); end_p1
++)
2677 hash_ptr
= hash_string (start
,
2682 if (hash_ptr
== (shash_t
*) 0)
2684 error ("label %.*s not found for #.bend", (int) (end_p1
- start
), start
);
2688 if (cur_oproc_begin
== (SYMR
*) 0)
2690 error ("procedure table %.*s not found for #.bend",
2691 (int) (end_p1
- start
), start
);
2695 (void) add_local_symbol ((const char *) 0, (const char *) 0,
2697 (symint_t
) hash_ptr
->sym_ptr
->value
- cur_oproc_begin
->value
,
2702 /* Parse #.def directives, which are contain standard COFF subdirectives
2703 to describe the debugging format. These subdirectives include:
2705 .scl specify storage class
2706 .val specify a value
2707 .endef specify end of COFF directives
2708 .type specify the type
2709 .size specify the size of an array
2710 .dim specify an array dimension
2711 .tag specify a tag for a struct, union, or enum. */
2714 parse_def (const char *name_start
)
2716 const char *dir_start
; /* start of current directive*/
2717 const char *dir_end_p1
; /* end+1 of current directive*/
2718 const char *arg_start
; /* start of current argument */
2719 const char *arg_end_p1
; /* end+1 of current argument */
2720 const char *name_end_p1
; /* end+1 of label */
2721 const char *tag_start
= 0; /* start of tag name */
2722 const char *tag_end_p1
= 0; /* end+1 of tag name */
2723 sc_t storage_class
= sc_Nil
;
2724 st_t symbol_type
= st_Nil
;
2726 EXTR
*eptr
= (EXTR
*) 0; /* ext. sym equivalent to def*/
2727 int is_function
= 0; /* != 0 if function */
2729 symint_t indx
= cur_file_ptr
->void_type
;
2731 symint_t arg_number
;
2732 symint_t temp_array
[ N_TQ
];
2737 static int inside_enumeration
= 0; /* is this an enumeration? */
2740 /* Initialize the type information. */
2744 /* Search for the end of the name being defined. */
2745 /* Allow spaces and such in names for G++ templates, which produce stabs
2748 #.def SMANIP<long unsigned int>; .scl 10; .type 0x8; .size 8; .endef */
2750 for (name_end_p1
= name_start
; (ch
= *name_end_p1
) != ';' && ch
!= '\0'; name_end_p1
++)
2755 error_line
= __LINE__
;
2759 /* Parse the remaining subdirectives now. */
2760 dir_start
= name_end_p1
+1;
2763 while ((ch
= *dir_start
) == ' ' || ch
== '\t')
2768 error_line
= __LINE__
;
2773 if (dir_start
[1] == 'e'
2774 && memcmp (dir_start
, ".endef", sizeof (".endef")-1) == 0)
2777 /* Pick up the subdirective now. */
2778 for (dir_end_p1
= dir_start
+1;
2779 (ch
= *dir_end_p1
) != ' ' && ch
!= '\t';
2782 if (ch
== '\0' || ISSPACE (ch
))
2784 error_line
= __LINE__
;
2789 /* Pick up the subdirective argument now. */
2790 arg_was_number
= arg_number
= 0;
2792 arg_start
= dir_end_p1
+1;
2794 while (ch
== ' ' || ch
== '\t')
2797 if (ISDIGIT (ch
) || ch
== '-' || ch
== '+')
2800 arg_number
= strtol (arg_start
, (char **) &arg_end_p1
, 0);
2801 /* It's only a number if followed by ';' or ','. */
2802 if (arg_end_p1
!= arg_start
&& (((ch2
= *arg_end_p1
) == ';') || ch2
== ','))
2806 else if (ch
== '\0' || ISSPACE (ch
))
2808 error_line
= __LINE__
;
2812 if (!arg_was_number
)
2814 /* Allow spaces and such in names for G++ templates. */
2815 for (arg_end_p1
= arg_start
+1;
2816 (ch
= *arg_end_p1
) != ';' && ch
!= '\0';
2822 error_line
= __LINE__
;
2827 /* Classify the directives now. */
2828 len
= dir_end_p1
- dir_start
;
2829 switch (dir_start
[1])
2832 error_line
= __LINE__
;
2836 if (len
== sizeof (".dim")-1
2837 && memcmp (dir_start
, ".dim", sizeof (".dim")-1) == 0
2840 symint_t
*t_ptr
= &temp_array
[ N_TQ
-1 ];
2842 *t_ptr
= arg_number
;
2843 while (*arg_end_p1
== ',' && arg_was_number
)
2845 arg_start
= arg_end_p1
+1;
2847 while (ch
== ' ' || ch
== '\t')
2851 if (ISDIGIT (ch
) || ch
== '-' || ch
== '+')
2854 arg_number
= strtol (arg_start
, (char **) &arg_end_p1
, 0);
2855 if (arg_end_p1
!= arg_start
&& (((ch2
= *arg_end_p1
) == ';') || ch2
== ','))
2858 if (t_ptr
== &temp_array
[0])
2860 error_line
= __LINE__
;
2864 *--t_ptr
= arg_number
;
2868 /* Reverse order of dimensions. */
2869 while (t_ptr
<= &temp_array
[ N_TQ
-1 ])
2871 if (t
.num_dims
>= N_TQ
-1)
2873 error_line
= __LINE__
;
2877 t
.dimensions
[ t
.num_dims
++ ] = *t_ptr
++;
2883 error_line
= __LINE__
;
2889 if (len
== sizeof (".scl")-1
2890 && memcmp (dir_start
, ".scl", sizeof (".scl")-1) == 0
2892 && arg_number
< ((symint_t
) C_MAX
))
2894 /* If the symbol is a static or external, we have
2895 already gotten the appropriate type and class, so
2896 make sure we don't override those values. This is
2897 needed because there are some type and classes that
2898 are not in COFF, such as short data, etc. */
2899 if (symbol_type
== st_Nil
)
2901 symbol_type
= map_coff_sym_type
[arg_number
];
2902 storage_class
= map_coff_storage
[arg_number
];
2907 else if (len
== sizeof (".size")-1
2908 && memcmp (dir_start
, ".size", sizeof (".size")-1) == 0
2911 symint_t
*t_ptr
= &temp_array
[ N_TQ
-1 ];
2913 *t_ptr
= arg_number
;
2914 while (*arg_end_p1
== ',' && arg_was_number
)
2916 arg_start
= arg_end_p1
+1;
2918 while (ch
== ' ' || ch
== '\t')
2922 if (ISDIGIT (ch
) || ch
== '-' || ch
== '+')
2925 arg_number
= strtol (arg_start
, (char **) &arg_end_p1
, 0);
2926 if (arg_end_p1
!= arg_start
&& (((ch2
= *arg_end_p1
) == ';') || ch2
== ','))
2929 if (t_ptr
== &temp_array
[0])
2931 error_line
= __LINE__
;
2935 *--t_ptr
= arg_number
;
2939 /* Reverse order of sizes. */
2940 while (t_ptr
<= &temp_array
[ N_TQ
-1 ])
2942 if (t
.num_sizes
>= N_TQ
-1)
2944 error_line
= __LINE__
;
2948 t
.sizes
[ t
.num_sizes
++ ] = *t_ptr
++;
2955 error_line
= __LINE__
;
2961 if (len
== sizeof (".type")-1
2962 && memcmp (dir_start
, ".type", sizeof (".type")-1) == 0
2965 tq_t
*tq_ptr
= &t
.type_qualifiers
[0];
2967 t
.orig_type
= (coff_type_t
) (arg_number
& N_BTMASK
);
2968 t
.basic_type
= map_coff_types
[(int) t
.orig_type
];
2969 for (i
= N_TQ
-1; i
>= 0; i
--)
2971 int dt
= (arg_number
>> ((i
* N_TQ_SHIFT
) + N_BT_SHIFT
)
2974 if (dt
!= (int) DT_NON
)
2975 *tq_ptr
++ = map_coff_derived_type
[dt
];
2978 /* If this is a function, ignore it, so that we don't get
2979 two entries (one from the .ent, and one for the .def
2980 that precedes it). Save the type information so that
2981 the end block can properly add it after the begin block
2982 index. For MIPS knows what reason, we must strip off
2983 the function type at this point. */
2984 if (tq_ptr
!= &t
.type_qualifiers
[0] && tq_ptr
[-1] == tq_Proc
)
2987 tq_ptr
[-1] = tq_Nil
;
2993 else if (len
== sizeof (".tag")-1
2994 && memcmp (dir_start
, ".tag", sizeof (".tag")-1) == 0)
2996 tag_start
= arg_start
;
2997 tag_end_p1
= arg_end_p1
;
3003 error_line
= __LINE__
;
3009 if (len
== sizeof (".val")-1
3010 && memcmp (dir_start
, ".val", sizeof (".val")-1) == 0)
3015 /* If the value is not an integer value, it must be the
3016 name of a static or global item. Look up the name in
3017 the original symbol table to pick up the storage
3018 class, symbol type, etc. */
3021 shash_t
*orig_hash_ptr
; /* hash within orig sym table*/
3022 shash_t
*ext_hash_ptr
; /* hash within ext. sym table*/
3024 ext_hash_ptr
= hash_string (arg_start
,
3025 arg_end_p1
- arg_start
,
3029 if (ext_hash_ptr
!= (shash_t
*) 0
3030 && ext_hash_ptr
->esym_ptr
!= (EXTR
*) 0)
3031 eptr
= ext_hash_ptr
->esym_ptr
;
3033 orig_hash_ptr
= hash_string (arg_start
,
3034 arg_end_p1
- arg_start
,
3038 if ((orig_hash_ptr
== (shash_t
*) 0
3039 || orig_hash_ptr
->sym_ptr
== (SYMR
*) 0)
3040 && eptr
== (EXTR
*) 0)
3042 fprintf (stderr
, "warning, %.*s not found in original or external symbol tables, value defaults to 0\n",
3043 (int) (arg_end_p1
- arg_start
),
3049 SYMR
*ptr
= (orig_hash_ptr
!= (shash_t
*) 0
3050 && orig_hash_ptr
->sym_ptr
!= (SYMR
*) 0)
3051 ? orig_hash_ptr
->sym_ptr
3054 symbol_type
= (st_t
) ptr
->st
;
3055 storage_class
= (sc_t
) ptr
->sc
;
3063 error_line
= __LINE__
;
3068 /* Set up to find next directive. */
3069 dir_start
= arg_end_p1
+ 1;
3073 if (storage_class
== sc_Bits
)
3083 int num_real_sizes
= t
.num_sizes
- t
.extra_sizes
;
3084 int diff
= t
.num_dims
- num_real_sizes
;
3085 int i
= t
.num_dims
- 1;
3088 if (num_real_sizes
!= 1 || diff
< 0)
3090 error_line
= __LINE__
;
3094 /* If this is an array, make sure the same number of dimensions
3095 and sizes were passed, creating extra sizes for multiply
3096 dimensioned arrays if not passed. */
3100 for (j
= ARRAY_SIZE (t
.sizes
) - 1; j
>= 0; j
--)
3101 t
.sizes
[ j
] = ((j
-diff
) >= 0) ? t
.sizes
[ j
-diff
] : 0;
3103 t
.num_sizes
= i
+ 1;
3104 for ( i
--; i
>= 0; i
-- )
3106 if (t
.dimensions
[ i
+1 ])
3107 t
.sizes
[ i
] = t
.sizes
[ i
+1 ] / t
.dimensions
[ i
+1 ];
3109 t
.sizes
[ i
] = t
.sizes
[ i
+1 ];
3114 /* Except for enumeration members & begin/ending of scopes, put the
3115 type word in the aux. symbol table. */
3117 if (symbol_type
== st_Block
|| symbol_type
== st_End
)
3120 else if (inside_enumeration
)
3121 indx
= cur_file_ptr
->void_type
;
3125 if (t
.basic_type
== bt_Struct
3126 || t
.basic_type
== bt_Union
3127 || t
.basic_type
== bt_Enum
)
3129 if (tag_start
== (char *) 0)
3131 error ("no tag specified for %.*s",
3132 (int) (name_end_p1
- name_start
),
3137 t
.tag_ptr
= get_tag (tag_start
, tag_end_p1
, (symint_t
) indexNil
,
3143 last_func_type_info
= t
;
3144 last_func_eptr
= eptr
;
3148 indx
= add_aux_sym_tir (&t
,
3150 &cur_file_ptr
->thash_head
[0]);
3154 /* If this is an external or static symbol, update the appropriate
3157 if (eptr
!= (EXTR
*) 0
3158 && (eptr
->asym
.index
== indexNil
|| cur_proc_ptr
== (PDR
*) 0))
3160 eptr
->ifd
= cur_file_ptr
->file_index
;
3161 eptr
->asym
.index
= indx
;
3165 /* Do any last minute adjustments that are necessary. */
3166 switch (symbol_type
)
3172 /* For the beginning of structs, unions, and enumerations, the
3173 size info needs to be passed in the value field. */
3176 if (t
.num_sizes
- t
.num_dims
- t
.extra_sizes
!= 1)
3178 error_line
= __LINE__
;
3185 inside_enumeration
= (t
.orig_type
== T_ENUM
);
3189 /* For the end of structs, unions, and enumerations, omit the
3190 name which is always ".eos". This needs to be done last, so
3191 that any error reporting above gives the correct name. */
3194 name_start
= name_end_p1
= 0;
3195 value
= inside_enumeration
= 0;
3199 /* Members of structures and unions that aren't bitfields, need
3200 to adjust the value from a byte offset to a bit offset.
3201 Members of enumerations do not have the value adjusted, and
3202 can be distinguished by indx == indexNil. For enumerations,
3203 update the maximum enumeration value. */
3206 if (!t
.bitfield
&& !inside_enumeration
)
3213 /* Add the symbol, except for global symbols outside of functions,
3214 for which the external symbol table is fine enough. */
3216 if (eptr
== (EXTR
*) 0
3217 || eptr
->asym
.st
== (int) st_Nil
3218 || cur_proc_ptr
!= (PDR
*) 0)
3220 symint_t isym
= add_local_symbol (name_start
, name_end_p1
,
3221 symbol_type
, storage_class
,
3225 /* Deal with struct, union, and enum tags. */
3226 if (symbol_type
== st_Block
)
3228 /* Create or update the tag information. */
3229 tag_t
*tag_ptr
= get_tag (name_start
,
3234 /* If there are any forward references, fill in the appropriate
3235 file and symbol indexes. */
3237 symint_t file_index
= cur_file_ptr
->file_index
;
3238 forward_t
*f_next
= tag_ptr
->forward_ref
;
3241 while (f_next
!= (forward_t
*) 0)
3244 f_next
= f_next
->next
;
3246 f_cur
->ifd_ptr
->isym
= file_index
;
3247 f_cur
->index_ptr
->rndx
.index
= isym
;
3249 free_forward (f_cur
);
3252 tag_ptr
->forward_ref
= (forward_t
*) 0;
3259 /* Error return, issue message. */
3262 error ("compiler error, badly formed #.def (internal line # = %d)", error_line
);
3264 error ("compiler error, badly formed #.def");
3270 /* Parse .end directives. */
3273 parse_end (const char *start
)
3275 const char *start_func
, *end_func_p1
;
3280 if (cur_file_ptr
== (efdr_t
*) 0)
3282 error (".end directive without a preceding .file directive");
3286 if (cur_proc_ptr
== (PDR
*) 0)
3288 error (".end directive without a preceding .ent directive");
3292 /* Get the function name, skipping whitespace. */
3293 for (start_func
= start
; ISSPACE ((unsigned char)*start_func
); start_func
++)
3297 if (!IS_ASM_IDENT (ch
))
3299 error (".end directive has no name");
3303 for (end_func_p1
= start_func
; IS_ASM_IDENT (ch
); ch
= *++end_func_p1
)
3307 /* Get the value field for creating the end from the original object
3308 file (which we find by locating the procedure start, and using the
3309 pointer to the end+1 block and backing up. The index points to a
3310 two word aux. symbol, whose first word is the index of the end
3311 symbol, and the second word is the type of the function return
3314 orig_fdr
= cur_file_ptr
->orig_fdr
;
3316 if (orig_fdr
!= (FDR
*) 0 && cur_oproc_end
!= (SYMR
*) 0)
3317 value
= cur_oproc_end
->value
;
3320 error ("cannot find .end block for %.*s",
3321 (int) (end_func_p1
- start_func
), start_func
);
3323 (void) add_local_symbol (start_func
, end_func_p1
,
3328 cur_proc_ptr
= cur_oproc_ptr
= (PDR
*) 0;
3332 /* Parse .ent directives. */
3335 parse_ent (const char *start
)
3337 const char *start_func
, *end_func_p1
;
3340 if (cur_file_ptr
== (efdr_t
*) 0)
3342 error (".ent directive without a preceding .file directive");
3346 if (cur_proc_ptr
!= (PDR
*) 0)
3348 error ("second .ent directive found before .end directive");
3352 for (start_func
= start
; ISSPACE ((unsigned char)*start_func
); start_func
++)
3356 if (!IS_ASM_IDENT (ch
))
3358 error (".ent directive has no name");
3362 for (end_func_p1
= start_func
; IS_ASM_IDENT (ch
); ch
= *++end_func_p1
)
3365 (void) add_procedure (start_func
, end_func_p1
);
3369 /* Parse .file directives. */
3372 parse_file (const char *start
)
3375 char *start_name
, *end_name_p1
;
3377 (void) strtol (start
, &p
, 0);
3379 || (start_name
= strchr (p
, '"')) == (char *) 0
3380 || (end_name_p1
= strrchr (++start_name
, '"')) == (char *) 0)
3382 error ("invalid .file directive");
3386 if (cur_proc_ptr
!= (PDR
*) 0)
3388 error ("no way to handle .file within .ent/.end section");
3392 add_file (start_name
, end_name_p1
);
3396 /* Make sure the @stabs symbol is emitted. */
3399 mark_stabs (const char *start ATTRIBUTE_UNUSED
)
3403 /* Add a dummy @stabs symbol. */
3405 (void) add_local_symbol (stabs_symbol
,
3406 stabs_symbol
+ sizeof (stabs_symbol
),
3407 (st_t
) stNil
, (sc_t
) scInfo
, -1,
3408 MIPS_MARK_STAB (0));
3414 /* Parse .stabs directives.
3416 .stabs directives have five fields:
3417 "string" a string, encoding the type information.
3418 code a numeric code, defined in <stab.h>
3420 0 a zero or line number
3421 value a numeric value or an address.
3423 If the value is relocatable, we transform this into:
3424 iss points as an index into string space
3425 value value from lookup of the name
3426 st st from lookup of the name
3427 sc sc from lookup of the name
3428 index code|CODE_MASK
3430 If the value is not relocatable, we transform this into:
3431 iss points as an index into string space
3435 index code|CODE_MASK
3437 .stabn directives have four fields (string is null):
3438 code a numeric code, defined in <stab.h>
3440 0 a zero or a line number
3441 value a numeric value or an address. */
3444 parse_stabs_common (const char *string_start
, /* start of string or NULL */
3445 const char *string_end
, /* end+1 of string or NULL */
3446 const char *rest
) /* rest of the directive. */
3448 efdr_t
*save_file_ptr
= cur_file_ptr
;
3456 if (stabs_seen
== 0)
3459 /* Read code from stabs. */
3460 if (!ISDIGIT (*rest
))
3462 error ("invalid .stabs/.stabn directive, code is non-numeric");
3466 code
= strtol (rest
, &p
, 0);
3468 /* Line number stabs are handled differently, since they have two values,
3469 the line number and the address of the label. We use the index field
3470 (aka code) to hold the line number, and the value field to hold the
3471 address. The symbol type is st_Label, which should be different from
3472 the other stabs, so that gdb can recognize it. */
3474 if (code
== (int) N_SLINE
)
3476 SYMR
*sym_ptr
, dummy_symr
;
3480 if (p
[0] != ',' || p
[1] != '0' || p
[2] != ',' || !ISDIGIT (p
[3]))
3482 error ("invalid line number .stabs/.stabn directive");
3486 code
= strtol (p
+3, &p
, 0);
3488 if (p
[-1] != ',' || ISDIGIT (ch
) || !IS_ASM_IDENT (ch
))
3490 error ("invalid line number .stabs/.stabn directive");
3494 dummy_symr
.index
= code
;
3495 if (dummy_symr
.index
!= code
)
3497 error ("line number (%lu) for .stabs/.stabn directive cannot fit in index field (20 bits)",
3503 shash_ptr
= hash_string (p
,
3508 if (shash_ptr
== (shash_t
*) 0
3509 || (sym_ptr
= shash_ptr
->sym_ptr
) == (SYMR
*) 0)
3511 error ("invalid .stabs/.stabn directive, value not found");
3515 if ((st_t
) sym_ptr
->st
!= st_Label
)
3517 error ("invalid line number .stabs/.stabn directive");
3522 sc
= (sc_t
) sym_ptr
->sc
;
3523 value
= sym_ptr
->value
;
3527 /* Skip ,<num>,<num>, */
3530 for (; ISDIGIT (*p
); p
++)
3534 for (; ISDIGIT (*p
); p
++)
3539 if (!IS_ASM_IDENT (ch
) && ch
!= '-')
3542 error ("invalid .stabs/.stabn directive, bad character");
3546 if (ISDIGIT (ch
) || ch
== '-')
3550 value
= strtol (p
, &p
, 0);
3553 error ("invalid .stabs/.stabn directive, stuff after numeric value");
3557 else if (!IS_ASM_IDENT (ch
))
3559 error ("invalid .stabs/.stabn directive, bad character");
3566 const char *start
, *end_p1
;
3569 if ((end_p1
= strchr (start
, '+')) == (char *) 0)
3571 if ((end_p1
= strchr (start
, '-')) == (char *) 0)
3572 end_p1
= start
+ strlen (start
) - 1;
3575 shash_ptr
= hash_string (start
,
3580 if (shash_ptr
== (shash_t
*) 0
3581 || (sym_ptr
= shash_ptr
->sym_ptr
) == (SYMR
*) 0)
3583 shash_ptr
= hash_string (start
,
3588 if (shash_ptr
== (shash_t
*) 0
3589 || shash_ptr
->esym_ptr
== (EXTR
*) 0)
3591 error ("invalid .stabs/.stabn directive, value not found");
3595 sym_ptr
= &(shash_ptr
->esym_ptr
->asym
);
3598 /* Traditionally, N_LBRAC and N_RBRAC are *not* relocated. */
3599 if (code
== (int) N_LBRAC
|| code
== (int) N_RBRAC
)
3606 sc
= (sc_t
) sym_ptr
->sc
;
3607 st
= (st_t
) sym_ptr
->st
;
3609 value
= sym_ptr
->value
;
3614 if (((!ISDIGIT (*end_p1
)) && (*end_p1
!= '-'))
3615 || ((ch
!= '+') && (ch
!= '-')))
3617 error ("invalid .stabs/.stabn directive, badly formed value");
3621 value
+= strtol (end_p1
, &p
, 0);
3623 value
-= strtol (end_p1
, &p
, 0);
3627 error ("invalid .stabs/.stabn directive, stuff after numeric value");
3632 code
= MIPS_MARK_STAB (code
);
3635 (void) add_local_symbol (string_start
, string_end
, st
, sc
, value
, code
);
3636 /* Restore normal file type. */
3637 cur_file_ptr
= save_file_ptr
;
3642 parse_stabs (const char *start
)
3644 const char *end
= strchr (start
+1, '"');
3646 if (*start
!= '"' || end
== (const char *) 0 || end
[1] != ',')
3648 error ("invalid .stabs directive, no string");
3652 parse_stabs_common (start
+1, end
, end
+2);
3657 parse_stabn (const char *start
)
3659 parse_stabs_common ((const char *) 0, (const char *) 0, start
);
3663 /* Parse the input file, and write the lines to the output file
3676 fprintf (stderr
, "\tinput\n");
3678 /* Add a dummy scope block around the entire compilation unit for
3679 structures defined outside of blocks. */
3680 ptag_head
= allocate_thead ();
3681 ptag_head
->first_tag
= 0;
3682 ptag_head
->prev
= cur_tag_head
;
3683 cur_tag_head
= ptag_head
;
3685 while ((p
= read_line ()) != (char *) 0)
3687 /* Skip leading blanks. */
3688 while (ISSPACE ((unsigned char)*p
))
3691 /* See if it's a directive we handle. If so, dispatch handler. */
3692 for (i
= 0; i
< ARRAY_SIZE (pseudo_ops
); i
++)
3693 if (memcmp (p
, pseudo_ops
[i
].name
, pseudo_ops
[i
].len
) == 0
3694 && ISSPACE ((unsigned char)(p
[pseudo_ops
[i
].len
])))
3696 p
+= pseudo_ops
[i
].len
; /* skip to first argument */
3697 while (ISSPACE ((unsigned char)*p
))
3700 (*pseudo_ops
[i
].func
)( p
);
3705 /* Process any tags at global level. */
3706 ptag_head
= cur_tag_head
;
3707 cur_tag_head
= ptag_head
->prev
;
3709 for (ptag
= ptag_head
->first_tag
;
3710 ptag
!= (tag_t
*) 0;
3713 if (ptag
->forward_ref
!= (forward_t
*) 0)
3714 add_unknown_tag (ptag
);
3716 ptag_next
= ptag
->same_block
;
3717 ptag
->hash_ptr
->tag_ptr
= ptag
->same_name
;
3721 free_thead (ptag_head
);
3726 /* Update the global headers with the final offsets in preparation
3727 to write out the .T file. */
3730 update_headers (void)
3735 /* Set up the symbolic header. */
3736 file_offset
= sizeof (symbolic_header
) + orig_file_header
.f_symptr
;
3737 symbolic_header
.magic
= orig_sym_hdr
.magic
;
3738 symbolic_header
.vstamp
= orig_sym_hdr
.vstamp
;
3740 /* Set up global counts. */
3741 symbolic_header
.issExtMax
= ext_strings
.num_allocated
;
3742 symbolic_header
.idnMax
= dense_num
.num_allocated
;
3743 symbolic_header
.ifdMax
= file_desc
.num_allocated
;
3744 symbolic_header
.iextMax
= ext_symbols
.num_allocated
;
3745 symbolic_header
.ilineMax
= orig_sym_hdr
.ilineMax
;
3746 symbolic_header
.ioptMax
= orig_sym_hdr
.ioptMax
;
3747 symbolic_header
.cbLine
= orig_sym_hdr
.cbLine
;
3748 symbolic_header
.crfd
= orig_sym_hdr
.crfd
;
3751 /* Loop through each file, figuring out how many local syms,
3752 line numbers, etc. there are. Also, put out end symbol
3753 for the filename. */
3755 for (file_ptr
= first_file
;
3756 file_ptr
!= (efdr_t
*) 0;
3757 file_ptr
= file_ptr
->next_file
)
3762 FDR
*fd_ptr
= file_ptr
->orig_fdr
;
3764 cur_file_ptr
= file_ptr
;
3766 /* Copy st_Static symbols from the original local symbol table if
3767 they did not get added to the new local symbol table.
3768 This happens with stabs-in-ecoff or if the source file is
3769 compiled without debugging. */
3770 sym_start
= ORIG_LSYMS (fd_ptr
->isymBase
);
3771 sym_end_p1
= sym_start
+ fd_ptr
->csym
;
3772 for (sym
= sym_start
; sym
< sym_end_p1
; sym
++)
3774 if ((st_t
) sym
->st
== st_Static
)
3776 char *str
= ORIG_LSTRS (fd_ptr
->issBase
+ sym
->iss
);
3777 size_t len
= strlen (str
);
3780 /* Ignore internal labels. */
3781 if (str
[0] == '$' && str
[1] == 'L')
3783 hash_ptr
= hash_string (str
,
3785 &file_ptr
->shash_head
[0],
3787 if (hash_ptr
== (shash_t
*) 0)
3789 (void) add_local_symbol (str
, str
+ len
,
3790 (st_t
) sym
->st
, (sc_t
) sym
->sc
,
3791 (symint_t
) sym
->value
,
3792 (symint_t
) indexNil
);
3796 (void) add_local_symbol ((const char *) 0, (const char *) 0,
3801 file_ptr
->fdr
.cpd
= file_ptr
->procs
.num_allocated
;
3802 file_ptr
->fdr
.ipdFirst
= symbolic_header
.ipdMax
;
3803 symbolic_header
.ipdMax
+= file_ptr
->fdr
.cpd
;
3805 file_ptr
->fdr
.csym
= file_ptr
->symbols
.num_allocated
;
3806 file_ptr
->fdr
.isymBase
= symbolic_header
.isymMax
;
3807 symbolic_header
.isymMax
+= file_ptr
->fdr
.csym
;
3809 file_ptr
->fdr
.caux
= file_ptr
->aux_syms
.num_allocated
;
3810 file_ptr
->fdr
.iauxBase
= symbolic_header
.iauxMax
;
3811 symbolic_header
.iauxMax
+= file_ptr
->fdr
.caux
;
3813 file_ptr
->fdr
.cbSs
= file_ptr
->strings
.num_allocated
;
3814 file_ptr
->fdr
.issBase
= symbolic_header
.issMax
;
3815 symbolic_header
.issMax
+= file_ptr
->fdr
.cbSs
;
3818 /* Align ecoff symbol tables to avoid OSF1/1.3 nm complaints. */
3819 #define ALIGN_SYMTABLE_OFFSET(OFFSET) (((OFFSET) + 7) & ~7)
3821 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3822 i
= WORD_ALIGN (symbolic_header
.cbLine
); /* line numbers */
3825 symbolic_header
.cbLineOffset
= file_offset
;
3827 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3830 i
= symbolic_header
.ioptMax
; /* optimization symbols */
3833 symbolic_header
.cbOptOffset
= file_offset
;
3834 file_offset
+= i
* sizeof (OPTR
);
3835 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3838 i
= symbolic_header
.idnMax
; /* dense numbers */
3841 symbolic_header
.cbDnOffset
= file_offset
;
3842 file_offset
+= i
* sizeof (DNR
);
3843 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3846 i
= symbolic_header
.ipdMax
; /* procedure tables */
3849 symbolic_header
.cbPdOffset
= file_offset
;
3850 file_offset
+= i
* sizeof (PDR
);
3851 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3854 i
= symbolic_header
.isymMax
; /* local symbols */
3857 symbolic_header
.cbSymOffset
= file_offset
;
3858 file_offset
+= i
* sizeof (SYMR
);
3859 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3862 i
= symbolic_header
.iauxMax
; /* aux syms. */
3865 symbolic_header
.cbAuxOffset
= file_offset
;
3866 file_offset
+= i
* sizeof (TIR
);
3867 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3870 i
= WORD_ALIGN (symbolic_header
.issMax
); /* local strings */
3873 symbolic_header
.cbSsOffset
= file_offset
;
3875 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3878 i
= WORD_ALIGN (symbolic_header
.issExtMax
); /* external strings */
3881 symbolic_header
.cbSsExtOffset
= file_offset
;
3883 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3886 i
= symbolic_header
.ifdMax
; /* file tables */
3889 symbolic_header
.cbFdOffset
= file_offset
;
3890 file_offset
+= i
* sizeof (FDR
);
3891 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3894 i
= symbolic_header
.crfd
; /* relative file descriptors */
3897 symbolic_header
.cbRfdOffset
= file_offset
;
3898 file_offset
+= i
* sizeof (symint_t
);
3899 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3902 i
= symbolic_header
.iextMax
; /* external symbols */
3905 symbolic_header
.cbExtOffset
= file_offset
;
3906 file_offset
+= i
* sizeof (EXTR
);
3907 file_offset
= ALIGN_SYMTABLE_OFFSET (file_offset
);
3912 /* Write out a varray at a given location. */
3915 write_varray (varray_t
*vp
, /* virtual array */
3916 off_t offset
, /* offset to write varray to */
3917 const char *str
) /* string to print out when tracing */
3919 int num_write
, sys_write
;
3922 if (vp
->num_allocated
== 0)
3926 fprintf (stderr
, "\twarray\tvp = " HOST_PTR_PRINTF
3927 ", offset = %7lu, size = %7lu, %s\n",
3928 (void *) vp
, (unsigned long) offset
,
3929 vp
->num_allocated
* vp
->object_size
, str
);
3931 if (file_offset
!= (unsigned long) offset
3932 && fseek (object_stream
, (long) offset
, SEEK_SET
) < 0)
3933 pfatal_with_name (object_name
);
3935 for (ptr
= vp
->first
; ptr
!= (vlinks_t
*) 0; ptr
= ptr
->next
)
3937 num_write
= (ptr
->next
== (vlinks_t
*) 0)
3938 ? vp
->objects_last_page
* vp
->object_size
3939 : vp
->objects_per_page
* vp
->object_size
;
3941 sys_write
= fwrite (ptr
->datum
, 1, num_write
, object_stream
);
3943 pfatal_with_name (object_name
);
3945 else if (sys_write
!= num_write
)
3946 fatal ("wrote %d bytes to %s, system returned %d",
3951 file_offset
+= num_write
;
3956 /* Write out the symbol table in the object file. */
3966 fprintf (stderr
, "\n\twrite\tvp = " HOST_PTR_PRINTF
3967 ", offset = %7u, size = %7lu, %s\n",
3968 (void *) &symbolic_header
, 0,
3969 (unsigned long) sizeof (symbolic_header
), "symbolic header");
3971 sys_write
= fwrite (&symbolic_header
,
3973 sizeof (symbolic_header
),
3977 pfatal_with_name (object_name
);
3979 else if (sys_write
!= sizeof (symbolic_header
))
3980 fatal ("wrote %d bytes to %s, system returned %d",
3981 (int) sizeof (symbolic_header
),
3986 file_offset
= sizeof (symbolic_header
) + orig_file_header
.f_symptr
;
3988 if (symbolic_header
.cbLine
> 0) /* line numbers */
3992 if (file_offset
!= (unsigned long) symbolic_header
.cbLineOffset
3993 && fseek (object_stream
, symbolic_header
.cbLineOffset
, SEEK_SET
) != 0)
3994 pfatal_with_name (object_name
);
3997 fprintf (stderr
, "\twrite\tvp = " HOST_PTR_PRINTF
3998 ", offset = %7lu, size = %7lu, %s\n",
3999 (void *) &orig_linenum
, (long) symbolic_header
.cbLineOffset
,
4000 (long) symbolic_header
.cbLine
, "Line numbers");
4002 sys_write
= fwrite (orig_linenum
,
4004 symbolic_header
.cbLine
,
4008 pfatal_with_name (object_name
);
4010 else if (sys_write
!= symbolic_header
.cbLine
)
4011 fatal ("wrote %ld bytes to %s, system returned %ld",
4012 (long) symbolic_header
.cbLine
,
4016 file_offset
= symbolic_header
.cbLineOffset
+ symbolic_header
.cbLine
;
4019 if (symbolic_header
.ioptMax
> 0) /* optimization symbols */
4022 long num_write
= symbolic_header
.ioptMax
* sizeof (OPTR
);
4024 if (file_offset
!= (unsigned long) symbolic_header
.cbOptOffset
4025 && fseek (object_stream
, symbolic_header
.cbOptOffset
, SEEK_SET
) != 0)
4026 pfatal_with_name (object_name
);
4029 fprintf (stderr
, "\twrite\tvp = " HOST_PTR_PRINTF
4030 ", offset = %7lu, size = %7lu, %s\n",
4031 (void *) &orig_opt_syms
, (long) symbolic_header
.cbOptOffset
,
4032 num_write
, "Optimizer symbols");
4034 sys_write
= fwrite (orig_opt_syms
,
4040 pfatal_with_name (object_name
);
4042 else if (sys_write
!= num_write
)
4043 fatal ("wrote %ld bytes to %s, system returned %ld",
4048 file_offset
= symbolic_header
.cbOptOffset
+ num_write
;
4051 if (symbolic_header
.idnMax
> 0) /* dense numbers */
4052 write_varray (&dense_num
, (off_t
) symbolic_header
.cbDnOffset
, "Dense numbers");
4054 if (symbolic_header
.ipdMax
> 0) /* procedure tables */
4056 offset
= symbolic_header
.cbPdOffset
;
4057 for (file_ptr
= first_file
;
4058 file_ptr
!= (efdr_t
*) 0;
4059 file_ptr
= file_ptr
->next_file
)
4061 write_varray (&file_ptr
->procs
, offset
, "Procedure tables");
4062 offset
= file_offset
;
4066 if (symbolic_header
.isymMax
> 0) /* local symbols */
4068 offset
= symbolic_header
.cbSymOffset
;
4069 for (file_ptr
= first_file
;
4070 file_ptr
!= (efdr_t
*) 0;
4071 file_ptr
= file_ptr
->next_file
)
4073 write_varray (&file_ptr
->symbols
, offset
, "Local symbols");
4074 offset
= file_offset
;
4078 if (symbolic_header
.iauxMax
> 0) /* aux symbols */
4080 offset
= symbolic_header
.cbAuxOffset
;
4081 for (file_ptr
= first_file
;
4082 file_ptr
!= (efdr_t
*) 0;
4083 file_ptr
= file_ptr
->next_file
)
4085 write_varray (&file_ptr
->aux_syms
, offset
, "Aux. symbols");
4086 offset
= file_offset
;
4090 if (symbolic_header
.issMax
> 0) /* local strings */
4092 offset
= symbolic_header
.cbSsOffset
;
4093 for (file_ptr
= first_file
;
4094 file_ptr
!= (efdr_t
*) 0;
4095 file_ptr
= file_ptr
->next_file
)
4097 write_varray (&file_ptr
->strings
, offset
, "Local strings");
4098 offset
= file_offset
;
4102 if (symbolic_header
.issExtMax
> 0) /* external strings */
4103 write_varray (&ext_strings
, symbolic_header
.cbSsExtOffset
, "External strings");
4105 if (symbolic_header
.ifdMax
> 0) /* file tables */
4107 offset
= symbolic_header
.cbFdOffset
;
4108 if (file_offset
!= (unsigned long) offset
4109 && fseek (object_stream
, (long) offset
, SEEK_SET
) < 0)
4110 pfatal_with_name (object_name
);
4112 file_offset
= offset
;
4113 for (file_ptr
= first_file
;
4114 file_ptr
!= (efdr_t
*) 0;
4115 file_ptr
= file_ptr
->next_file
)
4118 fprintf (stderr
, "\twrite\tvp = " HOST_PTR_PRINTF
4119 ", offset = %7lu, size = %7lu, %s\n",
4120 (void *) &file_ptr
->fdr
, file_offset
,
4121 (unsigned long) sizeof (FDR
), "File header");
4123 sys_write
= fwrite (&file_ptr
->fdr
,
4129 pfatal_with_name (object_name
);
4131 else if (sys_write
!= sizeof (FDR
))
4132 fatal ("wrote %d bytes to %s, system returned %d",
4137 file_offset
= offset
+= sizeof (FDR
);
4141 if (symbolic_header
.crfd
> 0) /* relative file descriptors */
4144 symint_t num_write
= symbolic_header
.crfd
* sizeof (symint_t
);
4146 if (file_offset
!= (unsigned long) symbolic_header
.cbRfdOffset
4147 && fseek (object_stream
, symbolic_header
.cbRfdOffset
, SEEK_SET
) != 0)
4148 pfatal_with_name (object_name
);
4151 fprintf (stderr
, "\twrite\tvp = " HOST_PTR_PRINTF
4152 ", offset = %7lu, size = %7lu, %s\n",
4153 (void *) &orig_rfds
, (long) symbolic_header
.cbRfdOffset
,
4154 num_write
, "Relative file descriptors");
4156 sys_write
= fwrite (orig_rfds
,
4162 pfatal_with_name (object_name
);
4164 else if (sys_write
!= (long) num_write
)
4165 fatal ("wrote %lu bytes to %s, system returned %ld",
4170 file_offset
= symbolic_header
.cbRfdOffset
+ num_write
;
4173 if (symbolic_header
.issExtMax
> 0) /* external symbols */
4174 write_varray (&ext_symbols
, (off_t
) symbolic_header
.cbExtOffset
, "External symbols");
4176 if (fclose (object_stream
) != 0)
4177 pfatal_with_name (object_name
);
4181 /* Read some bytes at a specified location, and return a pointer. */
4184 read_seek (size_t size
, /* # bytes to read */
4185 off_t offset
, /* offset to read at */
4186 const char *str
) /* name for tracing */
4191 if (size
== 0) /* nothing to read */
4192 return (page_t
*) 0;
4196 "\trseek\tsize = %7lu, offset = %7lu, currently at %7lu, %s\n",
4197 (unsigned long) size
, (unsigned long) offset
, file_offset
, str
);
4199 #ifndef MALLOC_CHECK
4200 ptr
= allocate_multiple_pages ((size
+ PAGE_USIZE
- 1) / PAGE_USIZE
);
4202 ptr
= xcalloc (1, size
);
4205 /* If we need to seek, and the distance is nearby, just do some reads,
4206 to speed things up. */
4207 if (file_offset
!= (unsigned long) offset
)
4209 symint_t difference
= offset
- file_offset
;
4213 char small_buffer
[8];
4215 sys_read
= fread (small_buffer
, 1, difference
, obj_in_stream
);
4217 pfatal_with_name (obj_in_name
);
4219 if ((symint_t
) sys_read
!= difference
)
4220 fatal ("wanted to read %lu bytes from %s, system returned %ld",
4221 (unsigned long) size
,
4225 else if (fseek (obj_in_stream
, offset
, SEEK_SET
) < 0)
4226 pfatal_with_name (obj_in_name
);
4229 sys_read
= fread (ptr
, 1, size
, obj_in_stream
);
4231 pfatal_with_name (obj_in_name
);
4233 if (sys_read
!= (long) size
)
4234 fatal ("wanted to read %lu bytes from %s, system returned %ld",
4235 (unsigned long) size
,
4239 file_offset
= offset
+ size
;
4241 if (file_offset
> max_file_offset
)
4242 max_file_offset
= file_offset
;
4248 /* Read the existing object file (and copy to the output object file
4249 if it is different from the input object file), and remove the old
4255 char buffer
[ PAGE_SIZE
];
4262 int *remap_file_number
;
4263 struct stat stat_buf
;
4266 fprintf (stderr
, "\tcopy\n");
4268 if (fstat (fileno (obj_in_stream
), &stat_buf
) != 0
4269 || fseek (obj_in_stream
, 0L, SEEK_SET
) != 0)
4270 pfatal_with_name (obj_in_name
);
4272 sys_read
= fread (&orig_file_header
,
4274 sizeof (struct filehdr
),
4278 pfatal_with_name (obj_in_name
);
4280 else if (sys_read
== 0 && feof (obj_in_stream
))
4281 return; /* create a .T file sans file header */
4283 else if (sys_read
< (int) sizeof (struct filehdr
))
4284 fatal ("wanted to read %d bytes from %s, system returned %d",
4285 (int) sizeof (struct filehdr
),
4290 if (orig_file_header
.f_nsyms
!= sizeof (HDRR
))
4291 fatal ("%s symbolic header wrong size (%ld bytes, should be %ld)",
4292 input_name
, (long) orig_file_header
.f_nsyms
, (long) sizeof (HDRR
));
4295 /* Read in the current symbolic header. */
4296 if (fseek (obj_in_stream
, (long) orig_file_header
.f_symptr
, SEEK_SET
) != 0)
4297 pfatal_with_name (input_name
);
4299 sys_read
= fread (&orig_sym_hdr
,
4301 sizeof (orig_sym_hdr
),
4305 pfatal_with_name (object_name
);
4307 else if (sys_read
< (int) sizeof (struct filehdr
))
4308 fatal ("wanted to read %d bytes from %s, system returned %d",
4309 (int) sizeof (struct filehdr
),
4314 /* Read in each of the sections if they exist in the object file.
4315 We read things in the order the mips assembler creates the
4316 sections, so in theory no extra seeks are done.
4318 For simplicity sake, round each read up to a page boundary,
4319 we may want to revisit this later.... */
4321 file_offset
= orig_file_header
.f_symptr
+ sizeof (struct filehdr
);
4323 if (orig_sym_hdr
.cbLine
> 0) /* line numbers */
4324 orig_linenum
= (char *) read_seek (orig_sym_hdr
.cbLine
,
4325 orig_sym_hdr
.cbLineOffset
,
4328 if (orig_sym_hdr
.ipdMax
> 0) /* procedure tables */
4329 orig_procs
= (PDR
*) read_seek (orig_sym_hdr
.ipdMax
* sizeof (PDR
),
4330 orig_sym_hdr
.cbPdOffset
,
4331 "Procedure tables");
4333 if (orig_sym_hdr
.isymMax
> 0) /* local symbols */
4334 orig_local_syms
= (SYMR
*) read_seek (orig_sym_hdr
.isymMax
* sizeof (SYMR
),
4335 orig_sym_hdr
.cbSymOffset
,
4338 if (orig_sym_hdr
.iauxMax
> 0) /* aux symbols */
4339 orig_aux_syms
= (AUXU
*) read_seek (orig_sym_hdr
.iauxMax
* sizeof (AUXU
),
4340 orig_sym_hdr
.cbAuxOffset
,
4343 if (orig_sym_hdr
.issMax
> 0) /* local strings */
4344 orig_local_strs
= (char *) read_seek (orig_sym_hdr
.issMax
,
4345 orig_sym_hdr
.cbSsOffset
,
4348 if (orig_sym_hdr
.issExtMax
> 0) /* external strings */
4349 orig_ext_strs
= (char *) read_seek (orig_sym_hdr
.issExtMax
,
4350 orig_sym_hdr
.cbSsExtOffset
,
4351 "External strings");
4353 if (orig_sym_hdr
.ifdMax
> 0) /* file tables */
4354 orig_files
= (FDR
*) read_seek (orig_sym_hdr
.ifdMax
* sizeof (FDR
),
4355 orig_sym_hdr
.cbFdOffset
,
4358 if (orig_sym_hdr
.crfd
> 0) /* relative file descriptors */
4359 orig_rfds
= (symint_t
*) read_seek (orig_sym_hdr
.crfd
* sizeof (symint_t
),
4360 orig_sym_hdr
.cbRfdOffset
,
4361 "Relative file descriptors");
4363 if (orig_sym_hdr
.issExtMax
> 0) /* external symbols */
4364 orig_ext_syms
= (EXTR
*) read_seek (orig_sym_hdr
.iextMax
* sizeof (EXTR
),
4365 orig_sym_hdr
.cbExtOffset
,
4366 "External symbols");
4368 if (orig_sym_hdr
.idnMax
> 0) /* dense numbers */
4370 orig_dense
= (DNR
*) read_seek (orig_sym_hdr
.idnMax
* sizeof (DNR
),
4371 orig_sym_hdr
.cbDnOffset
,
4374 add_bytes (&dense_num
, (char *) orig_dense
, orig_sym_hdr
.idnMax
);
4377 if (orig_sym_hdr
.ioptMax
> 0) /* opt symbols */
4378 orig_opt_syms
= (OPTR
*) read_seek (orig_sym_hdr
.ioptMax
* sizeof (OPTR
),
4379 orig_sym_hdr
.cbOptOffset
,
4380 "Optimizer symbols");
4384 /* The symbol table should be last. */
4385 if (max_file_offset
!= (unsigned long) stat_buf
.st_size
)
4386 fatal ("symbol table is not last (symbol table ends at %ld, .o ends at %ld",
4388 (long) stat_buf
.st_size
);
4391 /* If the first original file descriptor is a dummy which the assembler
4392 put out, but there are no symbols in it, skip it now. */
4393 if (orig_sym_hdr
.ifdMax
> 1
4394 && orig_files
->csym
== 2
4395 && orig_files
->caux
== 0)
4397 char *filename
= orig_local_strs
+ (orig_files
->issBase
+ orig_files
->rss
);
4398 char *suffix
= strrchr (filename
, '.');
4400 if (suffix
!= (char *) 0 && strcmp (suffix
, ".s") == 0)
4405 /* Create array to map original file numbers to the new file numbers
4406 (in case there are duplicate filenames, we collapse them into one
4407 file section, the MIPS assembler may or may not collapse them). */
4409 remap_file_number
= (int *) alloca (sizeof (int) * orig_sym_hdr
.ifdMax
);
4411 for (fd
= delete_ifd
; fd
< orig_sym_hdr
.ifdMax
; fd
++)
4413 FDR
*fd_ptr
= ORIG_FILES (fd
);
4414 char *filename
= ORIG_LSTRS (fd_ptr
->issBase
+ fd_ptr
->rss
);
4416 /* file support itself. */
4417 add_file (filename
, filename
+ strlen (filename
));
4418 remap_file_number
[fd
] = cur_file_ptr
->file_index
;
4421 if (delete_ifd
> 0) /* just in case */
4422 remap_file_number
[0] = remap_file_number
[1];
4425 /* Loop, adding each of the external symbols. These must be in
4426 order or otherwise we would have to change the relocation
4427 entries. We don't just call add_bytes, because we need to have
4428 the names put into the external hash table. We set the type to
4429 'void' for now, and parse_def will fill in the correct type if it
4430 is in the symbol table. We must add the external symbols before
4431 the locals, since the locals do lookups against the externals. */
4434 fprintf (stderr
, "\tehash\n");
4436 for (es
= 0; es
< orig_sym_hdr
.iextMax
; es
++)
4438 EXTR
*eptr
= orig_ext_syms
+ es
;
4439 int ifd
= eptr
->ifd
;
4441 (void) add_ext_symbol (eptr
, ((long) ifd
< orig_sym_hdr
.ifdMax
)
4442 ? remap_file_number
[ ifd
] : ifd
);
4446 /* For each of the files in the object file, copy the symbols, and such
4447 into the varrays for the new object file. */
4449 for (fd
= delete_ifd
; fd
< orig_sym_hdr
.ifdMax
; fd
++)
4451 FDR
*fd_ptr
= ORIG_FILES (fd
);
4452 char *filename
= ORIG_LSTRS (fd_ptr
->issBase
+ fd_ptr
->rss
);
4460 /* file support itself. */
4461 add_file (filename
, filename
+ strlen (filename
));
4462 cur_file_ptr
->orig_fdr
= fd_ptr
;
4464 /* Copy stuff that's just passed through (such as line #'s) */
4465 cur_file_ptr
->fdr
.adr
= fd_ptr
->adr
;
4466 cur_file_ptr
->fdr
.ilineBase
= fd_ptr
->ilineBase
;
4467 cur_file_ptr
->fdr
.cline
= fd_ptr
->cline
;
4468 cur_file_ptr
->fdr
.rfdBase
= fd_ptr
->rfdBase
;
4469 cur_file_ptr
->fdr
.crfd
= fd_ptr
->crfd
;
4470 cur_file_ptr
->fdr
.cbLineOffset
= fd_ptr
->cbLineOffset
;
4471 cur_file_ptr
->fdr
.cbLine
= fd_ptr
->cbLine
;
4472 cur_file_ptr
->fdr
.fMerge
= fd_ptr
->fMerge
;
4473 cur_file_ptr
->fdr
.fReadin
= fd_ptr
->fReadin
;
4474 cur_file_ptr
->fdr
.glevel
= fd_ptr
->glevel
;
4477 fprintf (stderr
, "\thash\tstart, filename %s\n", filename
);
4479 /* For each of the static and global symbols defined, add them
4480 to the hash table of original symbols, so we can look up
4483 sym_start
= ORIG_LSYMS (fd_ptr
->isymBase
);
4484 sym_end_p1
= sym_start
+ fd_ptr
->csym
;
4485 for (sym
= sym_start
; sym
< sym_end_p1
; sym
++)
4487 switch ((st_t
) sym
->st
)
4498 auto symint_t hash_index
;
4499 char *str
= ORIG_LSTRS (fd_ptr
->issBase
+ sym
->iss
);
4500 size_t len
= strlen (str
);
4501 shash_t
*shash_ptr
= hash_string (str
,
4506 if (shash_ptr
!= (shash_t
*) 0)
4507 error ("internal error, %s is already in original symbol table", str
);
4511 shash_ptr
= allocate_shash ();
4512 shash_ptr
->next
= orig_str_hash
[hash_index
];
4513 orig_str_hash
[hash_index
] = shash_ptr
;
4515 shash_ptr
->len
= len
;
4516 shash_ptr
->indx
= indexNil
;
4517 shash_ptr
->string
= str
;
4518 shash_ptr
->sym_ptr
= sym
;
4524 if ((sc_t
) sym
->sc
== sc_Text
)
4526 char *str
= ORIG_LSTRS (fd_ptr
->issBase
+ sym
->iss
);
4530 size_t len
= strlen (str
);
4531 shash_t
*shash_ptr
= hash_string (str
,
4536 if (shash_ptr
!= (shash_t
*) 0)
4537 shash_ptr
->end_ptr
= sym
;
4547 fprintf (stderr
, "\thash\tdone, filename %s\n", filename
);
4548 fprintf (stderr
, "\tproc\tstart, filename %s\n", filename
);
4551 /* Go through each of the procedures in this file, and add the
4552 procedure pointer to the hash entry for the given name. */
4554 proc_start
= ORIG_PROCS (fd_ptr
->ipdFirst
);
4555 proc_end_p1
= proc_start
+ fd_ptr
->cpd
;
4556 for (proc
= proc_start
; proc
< proc_end_p1
; proc
++)
4558 SYMR
*proc_sym
= ORIG_LSYMS (fd_ptr
->isymBase
+ proc
->isym
);
4559 char *str
= ORIG_LSTRS (fd_ptr
->issBase
+ proc_sym
->iss
);
4560 size_t len
= strlen (str
);
4561 shash_t
*shash_ptr
= hash_string (str
,
4566 if (shash_ptr
== (shash_t
*) 0)
4567 error ("internal error, function %s is not in original symbol table", str
);
4570 shash_ptr
->proc_ptr
= proc
;
4574 fprintf (stderr
, "\tproc\tdone, filename %s\n", filename
);
4577 cur_file_ptr
= first_file
;
4580 /* Copy all of the object file up to the symbol table. Originally
4581 we were going to use ftruncate, but that doesn't seem to work
4582 on Ultrix 3.1.... */
4584 if (fseek (obj_in_stream
, (long) 0, SEEK_SET
) != 0)
4585 pfatal_with_name (obj_in_name
);
4587 if (fseek (object_stream
, (long) 0, SEEK_SET
) != 0)
4588 pfatal_with_name (object_name
);
4590 for (remaining
= orig_file_header
.f_symptr
;
4592 remaining
-= num_write
)
4595 = (remaining
<= (int) sizeof (buffer
))
4596 ? remaining
: (int) sizeof (buffer
);
4597 sys_read
= fread (buffer
, 1, num_write
, obj_in_stream
);
4599 pfatal_with_name (obj_in_name
);
4601 else if (sys_read
!= num_write
)
4602 fatal ("wanted to read %d bytes from %s, system returned %d",
4607 sys_write
= fwrite (buffer
, 1, num_write
, object_stream
);
4609 pfatal_with_name (object_name
);
4611 else if (sys_write
!= num_write
)
4612 fatal ("wrote %d bytes to %s, system returned %d",
4620 /* Ye olde main program. */
4622 extern int main (int, char **);
4625 main (int argc
, char **argv
)
4632 progname
= lbasename (argv
[0]);
4634 (void) signal (SIGSEGV
, catch_signal
);
4635 (void) signal (SIGBUS
, catch_signal
);
4636 (void) signal (SIGABRT
, catch_signal
);
4639 if (sizeof (efdr_t
) > PAGE_USIZE
)
4640 fatal ("efdr_t has a sizeof %d bytes, when it should be less than %d",
4641 (int) sizeof (efdr_t
),
4644 if (sizeof (page_t
) != PAGE_USIZE
)
4645 fatal ("page_t has a sizeof %d bytes, when it should be %d",
4646 (int) sizeof (page_t
),
4651 alloc_counts
[ alloc_type_none
].alloc_name
= "none";
4652 alloc_counts
[ alloc_type_scope
].alloc_name
= "scope";
4653 alloc_counts
[ alloc_type_vlinks
].alloc_name
= "vlinks";
4654 alloc_counts
[ alloc_type_shash
].alloc_name
= "shash";
4655 alloc_counts
[ alloc_type_thash
].alloc_name
= "thash";
4656 alloc_counts
[ alloc_type_tag
].alloc_name
= "tag";
4657 alloc_counts
[ alloc_type_forward
].alloc_name
= "forward";
4658 alloc_counts
[ alloc_type_thead
].alloc_name
= "thead";
4659 alloc_counts
[ alloc_type_varray
].alloc_name
= "varray";
4661 int_type_info
= type_info_init
;
4662 int_type_info
.basic_type
= bt_Int
;
4664 void_type_info
= type_info_init
;
4665 void_type_info
.basic_type
= bt_Void
;
4667 while ((option
= getopt_long (argc
, argv
, "d:i:I:o:v", options
, NULL
)) != -1)
4675 debug
= strtol (optarg
, &num_end
, 0);
4676 if ((unsigned) debug
> 4 || num_end
== optarg
)
4682 if (rename_output
|| obj_in_name
!= (char *) 0)
4687 /* Fall through to 'i' case. */
4690 if (obj_in_name
== (char *) 0)
4692 obj_in_name
= optarg
;
4700 if (object_name
== (char *) 0)
4701 object_name
= optarg
;
4717 printf (_("mips-tfile %s%s\n"), pkgversion_string
, version_string
);
4718 fputs ("Copyright (C) 2011 Free Software Foundation, Inc.\n", stdout
);
4719 fputs (_("This is free software; see the source for copying conditions. There is NO\n\
4720 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
4725 if (obj_in_name
== (char *) 0 && optind
<= argc
- 2)
4726 obj_in_name
= argv
[--argc
];
4728 if (object_name
== (char *) 0 && optind
<= argc
- 2)
4729 object_name
= argv
[--argc
];
4731 /* If there is an output name, but no input name use
4732 the same file for both, deleting the name between
4733 opening it for input and opening it for output. */
4734 if (obj_in_name
== (char *) 0 && object_name
!= (char *) 0)
4736 obj_in_name
= object_name
;
4740 if (optind
!= argc
- 1)
4743 if (verbose
|| had_errors
)
4744 fprintf (stderr
, _("mips-tfile (GCC) %s\n"), version_string
);
4746 if (object_name
== (char *) 0 || had_errors
)
4748 fprintf (stderr
, _("Calling Sequence:\n"));
4749 fprintf (stderr
, _("\tmips-tfile [-d <num>] [-v] [-i <o-in-file>] -o <o-out-file> <s-file> (or)\n"));
4750 fprintf (stderr
, _("\tmips-tfile [-d <num>] [-v] [-I <o-in-file>] -o <o-out-file> <s-file> (or)\n"));
4751 fprintf (stderr
, _("\tmips-tfile [-d <num>] [-v] <s-file> <o-in-file> <o-out-file>\n"));
4752 fprintf (stderr
, "\n");
4753 fprintf (stderr
, _("Debug levels are:\n"));
4754 fprintf (stderr
, _(" 1\tGeneral debug + trace functions/blocks.\n"));
4755 fprintf (stderr
, _(" 2\tDebug level 1 + trace externals.\n"));
4756 fprintf (stderr
, _(" 3\tDebug level 2 + trace all symbols.\n"));
4757 fprintf (stderr
, _(" 4\tDebug level 3 + trace memory allocations.\n"));
4761 if (obj_in_name
== (char *) 0)
4762 obj_in_name
= object_name
;
4764 if (rename_output
&& rename (object_name
, obj_in_name
) != 0)
4766 char *buffer
= (char *) allocate_multiple_pages (4);
4772 /* Rename failed, copy input file */
4773 in_fd
= open (object_name
, O_RDONLY
, 0666);
4775 pfatal_with_name (object_name
);
4777 out_fd
= open (obj_in_name
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0666);
4779 pfatal_with_name (obj_in_name
);
4781 while ((len
= read (in_fd
, buffer
, 4*PAGE_SIZE
)) > 0)
4783 len2
= write (out_fd
, buffer
, len
);
4785 pfatal_with_name (object_name
);
4788 fatal ("wrote %d bytes to %s, expected to write %d", len2
, obj_in_name
, len
);
4791 free_multiple_pages ((page_t
*) buffer
, 4);
4794 pfatal_with_name (object_name
);
4796 if (close (in_fd
) < 0)
4797 pfatal_with_name (object_name
);
4799 if (close (out_fd
) < 0)
4800 pfatal_with_name (obj_in_name
);
4803 /* Must open input before output, since the output may be the same file, and
4804 we need to get the input handle before truncating it. */
4805 obj_in_stream
= fopen (obj_in_name
, "r");
4806 if (obj_in_stream
== (FILE *) 0)
4807 pfatal_with_name (obj_in_name
);
4809 if (delete_input
&& unlink (obj_in_name
) != 0)
4810 pfatal_with_name (obj_in_name
);
4812 object_stream
= fopen (object_name
, "w");
4813 if (object_stream
== (FILE *) 0)
4814 pfatal_with_name (object_name
);
4816 if (strcmp (argv
[optind
], "-") != 0)
4818 input_name
= argv
[optind
];
4819 if (freopen (argv
[optind
], "r", stdin
) != stdin
)
4820 pfatal_with_name (argv
[optind
]);
4823 copy_object (); /* scan & copy object file */
4824 parse_input (); /* scan all of input */
4826 update_headers (); /* write out tfile */
4831 fprintf (stderr
, "\n\tAllocation summary:\n\n");
4832 for (i
= (int) alloc_type_none
; i
< (int) alloc_type_last
; i
++)
4833 if (alloc_counts
[i
].total_alloc
)
4836 "\t%s\t%5d allocation(s), %5d free(s), %2d page(s)\n",
4837 alloc_counts
[i
].alloc_name
,
4838 alloc_counts
[i
].total_alloc
,
4839 alloc_counts
[i
].total_free
,
4840 alloc_counts
[i
].total_pages
);
4844 return (had_errors
) ? 1 : 0;
4848 /* Catch a signal and exit without dumping core. */
4851 catch_signal (int signum
)
4853 (void) signal (signum
, SIG_DFL
); /* just in case... */
4854 fatal ("%s", strsignal (signum
));
4857 /* Print a fatal error message. NAME is the text.
4858 Also include a system error message based on `errno'. */
4861 pfatal_with_name (const char *msg
)
4863 int save_errno
= errno
; /* just in case.... */
4864 if (line_number
> 0)
4865 fprintf (stderr
, "%s, %s:%ld ", progname
, input_name
, line_number
);
4867 fprintf (stderr
, "%s:", progname
);
4871 fprintf (stderr
, "[errno = 0] %s\n", msg
);
4879 /* Procedure to die with an out of bounds error message. It has
4880 type int, so it can be used with an ?: expression within the
4881 ORIG_xxx macros, but the function never returns. */
4884 out_of_bounds (symint_t indx
, /* index that is out of bounds */
4885 symint_t max
, /* maximum index */
4886 const char *str
, /* string to print out */
4887 int prog_line
) /* line number within mips-tfile.c */
4889 if (indx
< max
) /* just in case */
4892 fprintf (stderr
, "%s, %s:%ld index %lu is out of bounds for %s, max is %lu, mips-tfile.c line# %d\n",
4893 progname
, input_name
, line_number
, indx
, str
, max
, prog_line
);
4896 return 0; /* turn off warning messages */
4900 /* Allocate a cluster of pages. USE_MALLOC says that malloc does not
4901 like sbrk's behind its back (or sbrk isn't available). If we use
4902 sbrk, we assume it gives us zeroed pages. */
4904 #ifndef MALLOC_CHECK
4908 allocate_cluster (size_t npages
)
4910 page_t
*value
= xcalloc (npages
, PAGE_USIZE
);
4913 fprintf (stderr
, "\talloc\tnpages = %d, value = 0x%.8x\n", npages
, value
);
4918 #else /* USE_MALLOC */
4921 allocate_cluster (size_t npages
)
4923 page_t
*ptr
= (page_t
*) sbrk (0); /* current sbreak */
4924 unsigned long offset
= ((unsigned long) ptr
) & (PAGE_SIZE
- 1);
4926 if (offset
!= 0) /* align to a page boundary */
4928 if (sbrk (PAGE_USIZE
- offset
) == (char *)-1)
4929 pfatal_with_name ("allocate_cluster");
4931 ptr
= (page_t
*) (((char *) ptr
) + PAGE_SIZE
- offset
);
4934 if (sbrk (npages
* PAGE_USIZE
) == (char *) -1)
4935 pfatal_with_name ("allocate_cluster");
4938 fprintf (stderr
, "\talloc\tnpages = %lu, value = " HOST_PTR_PRINTF
"\n",
4939 (unsigned long) npages
, (void *) ptr
);
4944 #endif /* USE_MALLOC */
4947 static page_t
*cluster_ptr
= NULL
;
4948 static unsigned pages_left
= 0;
4950 #endif /* MALLOC_CHECK */
4953 /* Allocate some pages (which is initialized to 0). */
4956 allocate_multiple_pages (size_t npages
)
4958 #ifndef MALLOC_CHECK
4959 if (pages_left
== 0 && npages
< MAX_CLUSTER_PAGES
)
4961 pages_left
= MAX_CLUSTER_PAGES
;
4962 cluster_ptr
= allocate_cluster (MAX_CLUSTER_PAGES
);
4965 if (npages
<= pages_left
)
4967 page_t
*ptr
= cluster_ptr
;
4968 cluster_ptr
+= npages
;
4969 pages_left
-= npages
;
4973 return allocate_cluster (npages
);
4975 #else /* MALLOC_CHECK */
4976 return xcalloc (npages
, PAGE_SIZE
);
4978 #endif /* MALLOC_CHECK */
4982 /* Release some pages. */
4985 free_multiple_pages (page_t
*page_ptr
, size_t npages
)
4987 #ifndef MALLOC_CHECK
4988 if (pages_left
== 0)
4990 cluster_ptr
= page_ptr
;
4991 pages_left
= npages
;
4994 else if ((page_ptr
+ npages
) == cluster_ptr
)
4996 cluster_ptr
-= npages
;
4997 pages_left
+= npages
;
5000 /* otherwise the page is not freed. If more than call is
5001 done, we probably should worry about it, but at present,
5002 the free pages is done right after an allocate. */
5004 #else /* MALLOC_CHECK */
5007 #endif /* MALLOC_CHECK */
5011 /* Allocate one page (which is initialized to 0). */
5014 allocate_page (void)
5016 #ifndef MALLOC_CHECK
5017 if (pages_left
== 0)
5019 pages_left
= MAX_CLUSTER_PAGES
;
5020 cluster_ptr
= allocate_cluster (MAX_CLUSTER_PAGES
);
5024 return cluster_ptr
++;
5026 #else /* MALLOC_CHECK */
5027 return xcalloc (1, PAGE_SIZE
);
5029 #endif /* MALLOC_CHECK */
5033 /* Allocate scoping information. */
5036 allocate_scope (void)
5039 static scope_t initial_scope
;
5041 #ifndef MALLOC_CHECK
5042 ptr
= alloc_counts
[ (int) alloc_type_scope
].free_list
.f_scope
;
5043 if (ptr
!= (scope_t
*) 0)
5044 alloc_counts
[ (int) alloc_type_scope
].free_list
.f_scope
= ptr
->free
;
5048 int unallocated
= alloc_counts
[ (int) alloc_type_scope
].unallocated
;
5049 page_t
*cur_page
= alloc_counts
[ (int) alloc_type_scope
].cur_page
;
5051 if (unallocated
== 0)
5053 unallocated
= PAGE_SIZE
/ sizeof (scope_t
);
5054 alloc_counts
[ (int) alloc_type_scope
].cur_page
= cur_page
= allocate_page ();
5055 alloc_counts
[ (int) alloc_type_scope
].total_pages
++;
5058 ptr
= &cur_page
->scope
[ --unallocated
];
5059 alloc_counts
[ (int) alloc_type_scope
].unallocated
= unallocated
;
5063 ptr
= xmalloc (sizeof (scope_t
));
5067 alloc_counts
[ (int) alloc_type_scope
].total_alloc
++;
5068 *ptr
= initial_scope
;
5072 /* Free scoping information. */
5075 free_scope (scope_t
*ptr
)
5077 alloc_counts
[ (int) alloc_type_scope
].total_free
++;
5079 #ifndef MALLOC_CHECK
5080 ptr
->free
= alloc_counts
[ (int) alloc_type_scope
].free_list
.f_scope
;
5081 alloc_counts
[ (int) alloc_type_scope
].free_list
.f_scope
= ptr
;
5090 /* Allocate links for pages in a virtual array. */
5093 allocate_vlinks (void)
5096 static vlinks_t initial_vlinks
;
5098 #ifndef MALLOC_CHECK
5099 int unallocated
= alloc_counts
[ (int) alloc_type_vlinks
].unallocated
;
5100 page_t
*cur_page
= alloc_counts
[ (int) alloc_type_vlinks
].cur_page
;
5102 if (unallocated
== 0)
5104 unallocated
= PAGE_SIZE
/ sizeof (vlinks_t
);
5105 alloc_counts
[ (int) alloc_type_vlinks
].cur_page
= cur_page
= allocate_page ();
5106 alloc_counts
[ (int) alloc_type_vlinks
].total_pages
++;
5109 ptr
= &cur_page
->vlinks
[ --unallocated
];
5110 alloc_counts
[ (int) alloc_type_vlinks
].unallocated
= unallocated
;
5113 ptr
= xmalloc (sizeof (vlinks_t
));
5117 alloc_counts
[ (int) alloc_type_vlinks
].total_alloc
++;
5118 *ptr
= initial_vlinks
;
5123 /* Allocate string hash buckets. */
5126 allocate_shash (void)
5129 static shash_t initial_shash
;
5131 #ifndef MALLOC_CHECK
5132 int unallocated
= alloc_counts
[ (int) alloc_type_shash
].unallocated
;
5133 page_t
*cur_page
= alloc_counts
[ (int) alloc_type_shash
].cur_page
;
5135 if (unallocated
== 0)
5137 unallocated
= PAGE_SIZE
/ sizeof (shash_t
);
5138 alloc_counts
[ (int) alloc_type_shash
].cur_page
= cur_page
= allocate_page ();
5139 alloc_counts
[ (int) alloc_type_shash
].total_pages
++;
5142 ptr
= &cur_page
->shash
[ --unallocated
];
5143 alloc_counts
[ (int) alloc_type_shash
].unallocated
= unallocated
;
5146 ptr
= xmalloc (sizeof (shash_t
));
5150 alloc_counts
[ (int) alloc_type_shash
].total_alloc
++;
5151 *ptr
= initial_shash
;
5156 /* Allocate type hash buckets. */
5159 allocate_thash (void)
5162 static thash_t initial_thash
;
5164 #ifndef MALLOC_CHECK
5165 int unallocated
= alloc_counts
[ (int) alloc_type_thash
].unallocated
;
5166 page_t
*cur_page
= alloc_counts
[ (int) alloc_type_thash
].cur_page
;
5168 if (unallocated
== 0)
5170 unallocated
= PAGE_SIZE
/ sizeof (thash_t
);
5171 alloc_counts
[ (int) alloc_type_thash
].cur_page
= cur_page
= allocate_page ();
5172 alloc_counts
[ (int) alloc_type_thash
].total_pages
++;
5175 ptr
= &cur_page
->thash
[ --unallocated
];
5176 alloc_counts
[ (int) alloc_type_thash
].unallocated
= unallocated
;
5179 ptr
= xmalloc (sizeof (thash_t
));
5183 alloc_counts
[ (int) alloc_type_thash
].total_alloc
++;
5184 *ptr
= initial_thash
;
5189 /* Allocate structure, union, or enum tag information. */
5195 static tag_t initial_tag
;
5197 #ifndef MALLOC_CHECK
5198 ptr
= alloc_counts
[ (int) alloc_type_tag
].free_list
.f_tag
;
5199 if (ptr
!= (tag_t
*) 0)
5200 alloc_counts
[ (int) alloc_type_tag
].free_list
.f_tag
= ptr
->free
;
5204 int unallocated
= alloc_counts
[ (int) alloc_type_tag
].unallocated
;
5205 page_t
*cur_page
= alloc_counts
[ (int) alloc_type_tag
].cur_page
;
5207 if (unallocated
== 0)
5209 unallocated
= PAGE_SIZE
/ sizeof (tag_t
);
5210 alloc_counts
[ (int) alloc_type_tag
].cur_page
= cur_page
= allocate_page ();
5211 alloc_counts
[ (int) alloc_type_tag
].total_pages
++;
5214 ptr
= &cur_page
->tag
[ --unallocated
];
5215 alloc_counts
[ (int) alloc_type_tag
].unallocated
= unallocated
;
5219 ptr
= xmalloc (sizeof (tag_t
));
5223 alloc_counts
[ (int) alloc_type_tag
].total_alloc
++;
5228 /* Free scoping information. */
5231 free_tag (tag_t
*ptr
)
5233 alloc_counts
[ (int) alloc_type_tag
].total_free
++;
5235 #ifndef MALLOC_CHECK
5236 ptr
->free
= alloc_counts
[ (int) alloc_type_tag
].free_list
.f_tag
;
5237 alloc_counts
[ (int) alloc_type_tag
].free_list
.f_tag
= ptr
;
5246 /* Allocate forward reference to a yet unknown tag. */
5249 allocate_forward (void)
5252 static forward_t initial_forward
;
5254 #ifndef MALLOC_CHECK
5255 ptr
= alloc_counts
[ (int) alloc_type_forward
].free_list
.f_forward
;
5256 if (ptr
!= (forward_t
*) 0)
5257 alloc_counts
[ (int) alloc_type_forward
].free_list
.f_forward
= ptr
->free
;
5261 int unallocated
= alloc_counts
[ (int) alloc_type_forward
].unallocated
;
5262 page_t
*cur_page
= alloc_counts
[ (int) alloc_type_forward
].cur_page
;
5264 if (unallocated
== 0)
5266 unallocated
= PAGE_SIZE
/ sizeof (forward_t
);
5267 alloc_counts
[ (int) alloc_type_forward
].cur_page
= cur_page
= allocate_page ();
5268 alloc_counts
[ (int) alloc_type_forward
].total_pages
++;
5271 ptr
= &cur_page
->forward
[ --unallocated
];
5272 alloc_counts
[ (int) alloc_type_forward
].unallocated
= unallocated
;
5276 ptr
= xmalloc (sizeof (forward_t
));
5280 alloc_counts
[ (int) alloc_type_forward
].total_alloc
++;
5281 *ptr
= initial_forward
;
5285 /* Free scoping information. */
5288 free_forward (forward_t
*ptr
)
5290 alloc_counts
[ (int) alloc_type_forward
].total_free
++;
5292 #ifndef MALLOC_CHECK
5293 ptr
->free
= alloc_counts
[ (int) alloc_type_forward
].free_list
.f_forward
;
5294 alloc_counts
[ (int) alloc_type_forward
].free_list
.f_forward
= ptr
;
5303 /* Allocate head of type hash list. */
5306 allocate_thead (void)
5309 static thead_t initial_thead
;
5311 #ifndef MALLOC_CHECK
5312 ptr
= alloc_counts
[ (int) alloc_type_thead
].free_list
.f_thead
;
5313 if (ptr
!= (thead_t
*) 0)
5314 alloc_counts
[ (int) alloc_type_thead
].free_list
.f_thead
= ptr
->free
;
5318 int unallocated
= alloc_counts
[ (int) alloc_type_thead
].unallocated
;
5319 page_t
*cur_page
= alloc_counts
[ (int) alloc_type_thead
].cur_page
;
5321 if (unallocated
== 0)
5323 unallocated
= PAGE_SIZE
/ sizeof (thead_t
);
5324 alloc_counts
[ (int) alloc_type_thead
].cur_page
= cur_page
= allocate_page ();
5325 alloc_counts
[ (int) alloc_type_thead
].total_pages
++;
5328 ptr
= &cur_page
->thead
[ --unallocated
];
5329 alloc_counts
[ (int) alloc_type_thead
].unallocated
= unallocated
;
5333 ptr
= xmalloc (sizeof (thead_t
));
5337 alloc_counts
[ (int) alloc_type_thead
].total_alloc
++;
5338 *ptr
= initial_thead
;
5342 /* Free scoping information. */
5345 free_thead (thead_t
*ptr
)
5347 alloc_counts
[ (int) alloc_type_thead
].total_free
++;
5349 #ifndef MALLOC_CHECK
5350 ptr
->free
= (thead_t
*) alloc_counts
[ (int) alloc_type_thead
].free_list
.f_thead
;
5351 alloc_counts
[ (int) alloc_type_thead
].free_list
.f_thead
= ptr
;
5359 /* Output an error message and exit. */
5362 fatal (const char *format
, ...)
5366 va_start (ap
, format
);
5368 if (line_number
> 0)
5369 fprintf (stderr
, "%s, %s:%ld ", progname
, input_name
, line_number
);
5371 fprintf (stderr
, "%s:", progname
);
5373 vfprintf (stderr
, format
, ap
);
5375 fprintf (stderr
, "\n");
5376 if (line_number
> 0)
5377 fprintf (stderr
, "line:\t%s\n", cur_line_start
);
5383 error (const char *format
, ...)
5387 va_start (ap
, format
);
5389 if (line_number
> 0)
5390 fprintf (stderr
, "%s, %s:%ld ", progname
, input_name
, line_number
);
5392 fprintf (stderr
, "%s:", progname
);
5394 vfprintf (stderr
, format
, ap
);
5395 fprintf (stderr
, "\n");
5396 if (line_number
> 0)
5397 fprintf (stderr
, "line:\t%s\n", cur_line_start
);
5403 /* More 'friendly' abort that prints the line and file. */
5406 fancy_abort (const char *file
, int line
, const char *func
)
5408 fatal ("abort in %s, at %s:%d", func
, file
, line
);
5412 /* When `malloc.c' is compiled with `rcheck' defined,
5413 it calls this function to report clobberage. */
5416 botch (const char *s
)