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, 2012 7 Free Software Foundation, Inc. 8 Contributed by Michael Meissner (meissner@cygnus.com). 9 10 This file is part of GCC. 11 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 15 version. 16 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 20 for more details. 21 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/>. */ 25 26 27 /* Here is a brief description of the MIPS ECOFF symbol table. The 28 MIPS symbol table has the following pieces: 29 30 Symbolic Header 31 | 32 +-- Auxiliary Symbols 33 | 34 +-- Dense number table 35 | 36 +-- Optimizer Symbols 37 | 38 +-- External Strings 39 | 40 +-- External Symbols 41 | 42 +-- Relative file descriptors 43 | 44 +-- File table 45 | 46 +-- Procedure table 47 | 48 +-- Line number table 49 | 50 +-- Local Strings 51 | 52 +-- Local Symbols 53 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. 57 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: 65 66 1) dnLow: Low bound on array dimension. 67 68 2) dnHigh: High bound on array dimension. 69 70 3) isym: Index to the local symbol which is the start of the 71 function for the end of function first aux. entry. 72 73 4) width: Width of structures and bitfields. 74 75 5) count: Count of ranges for variant part. 76 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. 83 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: 89 90 a) fBitfield: a bit that says this is a bitfield, and the 91 size in bits follows as the next aux. entry. 92 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). 96 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: 100 101 btNil -- undefined 102 btAdr -- address - integer same size as ptr 103 btChar -- character 104 btUChar -- unsigned character 105 btShort -- short 106 btUShort -- unsigned short 107 btInt -- int 108 btUInt -- unsigned int 109 btLong -- long 110 btULong -- unsigned long 111 btFloat -- float (real) 112 btDouble -- Double (real) 113 btStruct -- Structure (Record) 114 btUnion -- Union (variant) 115 btEnum -- Enumerated 116 btTypedef -- defined via a typedef isymRef 117 btRange -- subrange of int 118 btSet -- pascal sets 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 126 btPicture -- Picture 127 btVoid -- Void (MIPS cc revision >= 2.00) 128 129 d) tq0 - tq5: type qualifier fields as needed. The 130 current type qualifier fields I have documentation for 131 are: 132 133 tqNil -- no more qualifiers 134 tqPtr -- pointer 135 tqProc -- procedure 136 tqArray -- array 137 tqFar -- 8086 far pointers 138 tqVol -- volatile 139 140 141 The dense number table is used in the front ends, and disappears by 142 the time the .o is created. 143 144 With the 1.31 compiler suite, the optimization symbols don't seem 145 to be used as far as I can tell. 146 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. 151 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. 163 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 167 tables for the file. 168 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. 176 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. 181 182 The local symbol table contains the following fields: 183 184 1) iss: index to the local string table giving the name of the 185 symbol. 186 187 2) value: value of the symbol (address, register number, etc.). 188 189 3) st: symbol type. The current symbol types are: 190 191 stNil -- Nuthin' special 192 stGlobal -- external symbol 193 stStatic -- static 194 stParam -- procedure argument 195 stLocal -- local variable 196 stLabel -- label 197 stProc -- External Procedure 198 stBlock -- beginning of block 199 stEnd -- end (of anything) 200 stMember -- member (of anything) 201 stTypedef -- type definition 202 stFile -- file name 203 stRegReloc -- register relocation 204 stForward -- forwarding address 205 stStaticProc -- Static procedure 206 stConstant -- const 207 208 4) sc: storage class. The current storage classes are: 209 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 232 233 5) index: pointer to a local symbol or aux. entry. 234 235 236 237 For the following program: 238 239 #include <stdio.h> 240 241 main(){ 242 printf("Hello World!\n"); 243 return 0; 244 } 245 246 Mips-tdump produces the following information: 247 248 Global file header: 249 magic number 0x162 250 # sections 2 251 timestamp 645311799, Wed Jun 13 17:16:39 1990 252 symbolic header offset 284 253 symbolic header size 96 254 optional header 56 255 flags 0x0 256 257 Symbolic header, magic number = 0x7009, vstamp = 1.31: 258 259 Info Offset Number Bytes 260 ==== ====== ====== ===== 261 262 Line numbers 380 4 4 [13] 263 Dense numbers 0 0 0 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 271 Relative Files 0 0 0 272 External Symbols 1152 20 320 273 274 File #0, "hello2.c" 275 276 Name index = 1 Readin = No 277 Merge = No Endian = LITTLE 278 Debug level = G2 Language = C 279 Adr = 0x00000000 280 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 290 291 There are 6 local symbols, starting at 436 292 293 Symbol# 0: "hello2.c" 294 End+1 symbol = 6 295 String index = 1 296 Storage class = Text Index = 6 297 Symbol type = File Value = 0 298 299 Symbol# 1: "main" 300 End+1 symbol = 5 301 Type = int 302 String index = 10 303 Storage class = Text Index = 12 304 Symbol type = Proc Value = 0 305 306 Symbol# 2: "" 307 End+1 symbol = 4 308 String index = 0 309 Storage class = Text Index = 4 310 Symbol type = Block Value = 8 311 312 Symbol# 3: "" 313 First symbol = 2 314 String index = 0 315 Storage class = Text Index = 2 316 Symbol type = End Value = 28 317 318 Symbol# 4: "main" 319 First symbol = 1 320 String index = 10 321 Storage class = Text Index = 1 322 Symbol type = End Value = 52 323 324 Symbol# 5: "hello2.c" 325 First symbol = 0 326 String index = 1 327 Storage class = Text Index = 0 328 Symbol type = End Value = 0 329 330 There are 14 auxiliary table entries, starting at 628. 331 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] 346 347 There are 1 procedure descriptor entries, starting at 0. 348 349 Procedure descriptor 0: 350 Name index = 10 Name = "main" 351 .mask 0x80000000,-4 .fmask 0x00000000,0 352 .frame $29,24,$31 353 Opt. start = -1 Symbols start = 1 354 First line # = 3 Last line # = 6 355 Line Offset = 0 Address = 0x00000000 356 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 362 363 File #1, "/usr/include/stdio.h" 364 365 Name index = 1 Readin = No 366 Merge = Yes Endian = LITTLE 367 Debug level = G2 Language = C 368 Adr = 0x00000000 369 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 376 Procedures 1 0 0 436 377 Auxiliary symbols 14 25 100 684 378 Relative Files 0 0 0 0 379 380 There are 10 local symbols, starting at 442 381 382 Symbol# 0: "/usr/include/stdio.h" 383 End+1 symbol = 10 384 String index = 1 385 Storage class = Text Index = 10 386 Symbol type = File Value = 0 387 388 Symbol# 1: "_iobuf" 389 End+1 symbol = 9 390 String index = 22 391 Storage class = Info Index = 9 392 Symbol type = Block Value = 20 393 394 Symbol# 2: "_cnt" 395 Type = int 396 String index = 29 397 Storage class = Info Index = 4 398 Symbol type = Member Value = 0 399 400 Symbol# 3: "_ptr" 401 Type = ptr to char 402 String index = 34 403 Storage class = Info Index = 15 404 Symbol type = Member Value = 32 405 406 Symbol# 4: "_base" 407 Type = ptr to char 408 String index = 39 409 Storage class = Info Index = 16 410 Symbol type = Member Value = 64 411 412 Symbol# 5: "_bufsiz" 413 Type = int 414 String index = 45 415 Storage class = Info Index = 4 416 Symbol type = Member Value = 96 417 418 Symbol# 6: "_flag" 419 Type = short 420 String index = 53 421 Storage class = Info Index = 3 422 Symbol type = Member Value = 128 423 424 Symbol# 7: "_file" 425 Type = char 426 String index = 59 427 Storage class = Info Index = 2 428 Symbol type = Member Value = 144 429 430 Symbol# 8: "" 431 First symbol = 1 432 String index = 0 433 Storage class = Info Index = 1 434 Symbol type = End Value = 0 435 436 Symbol# 9: "/usr/include/stdio.h" 437 First symbol = 0 438 String index = 1 439 Storage class = Text Index = 0 440 Symbol type = End Value = 0 441 442 There are 25 auxiliary table entries, starting at 642. 443 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] 469 470 There are 0 procedure descriptor entries, starting at 1. 471 472 There are 20 external symbols, starting at 1152 473 474 Symbol# 0: "_iob" 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 479 480 Symbol# 1: "fopen" 481 String index = 5 Ifd = 1 482 Storage class = Nil Index = 1048575 483 Symbol type = Proc Value = 0 484 485 Symbol# 2: "fdopen" 486 String index = 11 Ifd = 1 487 Storage class = Nil Index = 1048575 488 Symbol type = Proc Value = 0 489 490 Symbol# 3: "freopen" 491 String index = 18 Ifd = 1 492 Storage class = Nil Index = 1048575 493 Symbol type = Proc Value = 0 494 495 Symbol# 4: "popen" 496 String index = 26 Ifd = 1 497 Storage class = Nil Index = 1048575 498 Symbol type = Proc Value = 0 499 500 Symbol# 5: "tmpfile" 501 String index = 32 Ifd = 1 502 Storage class = Nil Index = 1048575 503 Symbol type = Proc Value = 0 504 505 Symbol# 6: "ftell" 506 String index = 40 Ifd = 1 507 Storage class = Nil Index = 1048575 508 Symbol type = Proc Value = 0 509 510 Symbol# 7: "rewind" 511 String index = 46 Ifd = 1 512 Storage class = Nil Index = 1048575 513 Symbol type = Proc Value = 0 514 515 Symbol# 8: "setbuf" 516 String index = 53 Ifd = 1 517 Storage class = Nil Index = 1048575 518 Symbol type = Proc Value = 0 519 520 Symbol# 9: "setbuffer" 521 String index = 60 Ifd = 1 522 Storage class = Nil Index = 1048575 523 Symbol type = Proc Value = 0 524 525 Symbol# 10: "setlinebuf" 526 String index = 70 Ifd = 1 527 Storage class = Nil Index = 1048575 528 Symbol type = Proc Value = 0 529 530 Symbol# 11: "fgets" 531 String index = 81 Ifd = 1 532 Storage class = Nil Index = 1048575 533 Symbol type = Proc Value = 0 534 535 Symbol# 12: "gets" 536 String index = 87 Ifd = 1 537 Storage class = Nil Index = 1048575 538 Symbol type = Proc Value = 0 539 540 Symbol# 13: "ctermid" 541 String index = 92 Ifd = 1 542 Storage class = Nil Index = 1048575 543 Symbol type = Proc Value = 0 544 545 Symbol# 14: "cuserid" 546 String index = 100 Ifd = 1 547 Storage class = Nil Index = 1048575 548 Symbol type = Proc Value = 0 549 550 Symbol# 15: "tempnam" 551 String index = 108 Ifd = 1 552 Storage class = Nil Index = 1048575 553 Symbol type = Proc Value = 0 554 555 Symbol# 16: "tmpnam" 556 String index = 116 Ifd = 1 557 Storage class = Nil Index = 1048575 558 Symbol type = Proc Value = 0 559 560 Symbol# 17: "sprintf" 561 String index = 123 Ifd = 1 562 Storage class = Nil Index = 1048575 563 Symbol type = Proc Value = 0 564 565 Symbol# 18: "main" 566 Type = int 567 String index = 131 Ifd = 0 568 Storage class = Text Index = 1 569 Symbol type = Proc Value = 0 570 571 Symbol# 19: "printf" 572 String index = 136 Ifd = 0 573 Storage class = Undefined Index = 1048575 574 Symbol type = Proc Value = 0 575 576 The following auxiliary table entries were unused: 577 578 #0 0 0x00000000 void 579 #2 8 0x00000008 char 580 #3 16 0x00000010 short 581 #4 24 0x00000018 int 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 } 599 600 */ 601 602 603 #include "config.h" 604 #include "system.h" 605 #include "version.h" 606 #include "intl.h" 607 608 /* Include getopt.h for the sake of getopt_long. */ 609 #include "getopt.h" 610 611 /* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for 612 mips-tdump.c to print them out. 613 614 These must match the corresponding definitions in gdb/mipsread.c. 615 Unfortunately, gcc and gdb do not currently share any directories. */ 616 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) 621 622 /* The following might be called from obstack or malloc, 623 so they can't be static. */ 624 625 extern void pfatal_with_name (const char *) ATTRIBUTE_NORETURN; 626 extern void botch (const char *) ATTRIBUTE_NORETURN; 627 628 extern void fatal (const char *format, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; 629 extern void error (const char *format, ...) ATTRIBUTE_PRINTF_1; 630 631 /* The local and global symbols have a field index, so undo any defines 632 of index -> strchr. */ 633 634 #undef index 635 636 #include <a.out.h> 637 #include "gstab.h" 638 639 #define IS_ASM_IDENT(ch) \ 640 (ISIDNUM (ch) || (ch) == '.' || (ch) == '$') 641 642 643 /* Redefinition of storage classes as an enumeration for better 644 debugging. */ 645 646 typedef enum sc { 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 */ 671 } sc_t; 672 673 /* Redefinition of symbol type. */ 674 675 typedef enum st { 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 */ 697 } st_t; 698 699 /* Redefinition of type qualifiers. */ 700 701 typedef enum tq { 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 */ 709 } tq_t; 710 711 /* Redefinition of basic types. */ 712 713 typedef enum bt { 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 */ 740 741 #ifdef btVoid 742 bt_Void = btVoid, /* Void */ 743 #else 744 #define bt_Void bt_Nil 745 #endif 746 747 bt_Max = btMax /* Max basic type+1 */ 748 } bt_t; 749 750 751 752 /* Basic COFF storage classes. */ 753 enum coff_storage { 754 C_EFCN = -1, 755 C_NULL = 0, 756 C_AUTO = 1, 757 C_EXT = 2, 758 C_STAT = 3, 759 C_REG = 4, 760 C_EXTDEF = 5, 761 C_LABEL = 6, 762 C_ULABEL = 7, 763 C_MOS = 8, 764 C_ARG = 9, 765 C_STRTAG = 10, 766 C_MOU = 11, 767 C_UNTAG = 12, 768 C_TPDEF = 13, 769 C_USTATIC = 14, 770 C_ENTAG = 15, 771 C_MOE = 16, 772 C_REGPARM = 17, 773 C_FIELD = 18, 774 C_BLOCK = 100, 775 C_FCN = 101, 776 C_EOS = 102, 777 C_FILE = 103, 778 C_LINE = 104, 779 C_ALIAS = 105, 780 C_HIDDEN = 106, 781 C_MAX = 107 782 } coff_storage_t; 783 784 /* Regular COFF fundamental type. */ 785 typedef enum coff_type { 786 T_NULL = 0, 787 T_ARG = 1, 788 T_CHAR = 2, 789 T_SHORT = 3, 790 T_INT = 4, 791 T_LONG = 5, 792 T_FLOAT = 6, 793 T_DOUBLE = 7, 794 T_STRUCT = 8, 795 T_UNION = 9, 796 T_ENUM = 10, 797 T_MOE = 11, 798 T_UCHAR = 12, 799 T_USHORT = 13, 800 T_UINT = 14, 801 T_ULONG = 15, 802 T_MAX = 16 803 } coff_type_t; 804 805 /* Regular COFF derived types. */ 806 typedef enum coff_dt { 807 DT_NON = 0, 808 DT_PTR = 1, 809 DT_FCN = 2, 810 DT_ARY = 3, 811 DT_MAX = 4 812 } coff_dt_t; 813 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 */ 819 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. */ 825 } hash_state_t; 826 827 828 /* Types of different sized allocation requests. */ 829 enum alloc_type { 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 */ 840 }; 841 842 843 #define WORD_ALIGN(x) (((x) + (sizeof (long) - 1)) & ~ (sizeof (long) - 1)) 844 #define DWORD_ALIGN(x) (((x) + 7) & ~7) 845 846 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. */ 853 854 #ifndef PAGE_SIZE 855 #define PAGE_SIZE 32768 /* size of varray pages */ 856 #endif 857 858 #define PAGE_USIZE ((size_t) PAGE_SIZE) 859 860 861 #ifndef MAX_CLUSTER_PAGES /* # pages to get from system */ 862 #ifndef USE_MALLOC /* in one memory request */ 863 #define MAX_CLUSTER_PAGES 64 864 #else 865 #define MAX_CLUSTER_PAGES 63 866 #endif 867 #endif 868 869 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 */ 876 } vlinks_t; 877 878 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 */ 887 } varray_t; 888 889 #ifndef MALLOC_CHECK 890 #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type)) 891 #else 892 #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE) 893 #endif 894 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 */ \ 902 } 903 904 #define INITIALIZE_VARRAY(x,type) \ 905 do { \ 906 (x)->object_size = sizeof (type); \ 907 (x)->objects_per_page = OBJECTS_PER_PAGE (type); \ 908 (x)->objects_last_page = OBJECTS_PER_PAGE (type); \ 909 } while (0) 910 911 /* Master type for indexes within the symbol table. */ 912 typedef unsigned long symint_t; 913 914 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 */ 922 } scope_t; 923 924 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 */ 932 } forward_t; 933 934 935 /* Linked list support for tags. The first tag in the list is always 936 the current tag for that block. */ 937 typedef struct tag { 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 */ 946 } tag_t; 947 948 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 */ 954 } thead_t; 955 956 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 */ 963 } small_free_t; 964 965 966 /* String hash table support. The size of the hash table must fit 967 within a page. */ 968 969 #define SHASH_SIZE 511 970 971 #define HASH_LEN_MAX ((1 << 12) - 1) /* Max length we can store */ 972 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 */ 983 } shash_t; 984 985 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. */ 990 991 #define THASH_SIZE 55 992 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 */ 997 } thash_t; 998 999 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]; 1020 } efdr_t; 1021 1022 /* Pre-initialized extended file structure. */ 1023 static int init_file_initialized = 0; 1024 static efdr_t init_file; 1025 1026 static efdr_t *first_file; /* first file descriptor */ 1027 static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */ 1028 1029 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) ]; 1048 } page_t; 1049 1050 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 */ 1060 } alloc_info_t; 1061 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 */ 1077 } type_info_t; 1078 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 */ 1085 0, /* # sizes */ 1086 0, /* sizes not tied with dims */ 1087 NULL, /* ptr to tag */ 1088 0, /* bitfield */ 1089 0, /* unknown tag */ 1090 { /* type qualifiers */ 1091 tq_Nil, 1092 tq_Nil, 1093 tq_Nil, 1094 tq_Nil, 1095 tq_Nil, 1096 tq_Nil, 1097 }, 1098 { /* dimensions */ 1099 0, 1100 0, 1101 0, 1102 0, 1103 0, 1104 0 1105 }, 1106 { /* sizes */ 1107 0, 1108 0, 1109 0, 1110 0, 1111 0, 1112 0, 1113 0, 1114 0, 1115 }, 1116 }; 1117 1118 1119 /* Global virtual arrays & hash table for external strings as well as 1120 for the tags table and global tables for file descriptors, and 1121 dense numbers. */ 1122 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); 1128 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]; 1132 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. */ 1136 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; 1141 1142 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. */ 1149 1150 static const bt_t map_coff_types[ (int) T_MAX ] = { 1151 bt_Nil, /* T_NULL */ 1152 bt_Nil, /* T_ARG */ 1153 bt_Char, /* T_CHAR */ 1154 bt_Short, /* T_SHORT */ 1155 bt_Int, /* T_INT */ 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 */ 1167 }; 1168 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 */ 1190 sc_Nil, /* 19 */ 1191 sc_Nil, /* 20 */ 1192 sc_Nil, /* 21 */ 1193 sc_Nil, /* 22 */ 1194 sc_Nil, /* 23 */ 1195 sc_Nil, /* 24 */ 1196 sc_Nil, /* 25 */ 1197 sc_Nil, /* 26 */ 1198 sc_Nil, /* 27 */ 1199 sc_Nil, /* 28 */ 1200 sc_Nil, /* 29 */ 1201 sc_Nil, /* 30 */ 1202 sc_Nil, /* 31 */ 1203 sc_Nil, /* 32 */ 1204 sc_Nil, /* 33 */ 1205 sc_Nil, /* 34 */ 1206 sc_Nil, /* 35 */ 1207 sc_Nil, /* 36 */ 1208 sc_Nil, /* 37 */ 1209 sc_Nil, /* 38 */ 1210 sc_Nil, /* 39 */ 1211 sc_Nil, /* 40 */ 1212 sc_Nil, /* 41 */ 1213 sc_Nil, /* 42 */ 1214 sc_Nil, /* 43 */ 1215 sc_Nil, /* 44 */ 1216 sc_Nil, /* 45 */ 1217 sc_Nil, /* 46 */ 1218 sc_Nil, /* 47 */ 1219 sc_Nil, /* 48 */ 1220 sc_Nil, /* 49 */ 1221 sc_Nil, /* 50 */ 1222 sc_Nil, /* 51 */ 1223 sc_Nil, /* 52 */ 1224 sc_Nil, /* 53 */ 1225 sc_Nil, /* 54 */ 1226 sc_Nil, /* 55 */ 1227 sc_Nil, /* 56 */ 1228 sc_Nil, /* 57 */ 1229 sc_Nil, /* 58 */ 1230 sc_Nil, /* 59 */ 1231 sc_Nil, /* 60 */ 1232 sc_Nil, /* 61 */ 1233 sc_Nil, /* 62 */ 1234 sc_Nil, /* 63 */ 1235 sc_Nil, /* 64 */ 1236 sc_Nil, /* 65 */ 1237 sc_Nil, /* 66 */ 1238 sc_Nil, /* 67 */ 1239 sc_Nil, /* 68 */ 1240 sc_Nil, /* 69 */ 1241 sc_Nil, /* 70 */ 1242 sc_Nil, /* 71 */ 1243 sc_Nil, /* 72 */ 1244 sc_Nil, /* 73 */ 1245 sc_Nil, /* 74 */ 1246 sc_Nil, /* 75 */ 1247 sc_Nil, /* 76 */ 1248 sc_Nil, /* 77 */ 1249 sc_Nil, /* 78 */ 1250 sc_Nil, /* 79 */ 1251 sc_Nil, /* 80 */ 1252 sc_Nil, /* 81 */ 1253 sc_Nil, /* 82 */ 1254 sc_Nil, /* 83 */ 1255 sc_Nil, /* 84 */ 1256 sc_Nil, /* 85 */ 1257 sc_Nil, /* 86 */ 1258 sc_Nil, /* 87 */ 1259 sc_Nil, /* 88 */ 1260 sc_Nil, /* 89 */ 1261 sc_Nil, /* 90 */ 1262 sc_Nil, /* 91 */ 1263 sc_Nil, /* 92 */ 1264 sc_Nil, /* 93 */ 1265 sc_Nil, /* 94 */ 1266 sc_Nil, /* 95 */ 1267 sc_Nil, /* 96 */ 1268 sc_Nil, /* 97 */ 1269 sc_Nil, /* 98 */ 1270 sc_Nil, /* 99 */ 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 ??? */ 1278 }; 1279 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 */ 1301 st_Nil, /* 19 */ 1302 st_Nil, /* 20 */ 1303 st_Nil, /* 21 */ 1304 st_Nil, /* 22 */ 1305 st_Nil, /* 23 */ 1306 st_Nil, /* 24 */ 1307 st_Nil, /* 25 */ 1308 st_Nil, /* 26 */ 1309 st_Nil, /* 27 */ 1310 st_Nil, /* 28 */ 1311 st_Nil, /* 29 */ 1312 st_Nil, /* 30 */ 1313 st_Nil, /* 31 */ 1314 st_Nil, /* 32 */ 1315 st_Nil, /* 33 */ 1316 st_Nil, /* 34 */ 1317 st_Nil, /* 35 */ 1318 st_Nil, /* 36 */ 1319 st_Nil, /* 37 */ 1320 st_Nil, /* 38 */ 1321 st_Nil, /* 39 */ 1322 st_Nil, /* 40 */ 1323 st_Nil, /* 41 */ 1324 st_Nil, /* 42 */ 1325 st_Nil, /* 43 */ 1326 st_Nil, /* 44 */ 1327 st_Nil, /* 45 */ 1328 st_Nil, /* 46 */ 1329 st_Nil, /* 47 */ 1330 st_Nil, /* 48 */ 1331 st_Nil, /* 49 */ 1332 st_Nil, /* 50 */ 1333 st_Nil, /* 51 */ 1334 st_Nil, /* 52 */ 1335 st_Nil, /* 53 */ 1336 st_Nil, /* 54 */ 1337 st_Nil, /* 55 */ 1338 st_Nil, /* 56 */ 1339 st_Nil, /* 57 */ 1340 st_Nil, /* 58 */ 1341 st_Nil, /* 59 */ 1342 st_Nil, /* 60 */ 1343 st_Nil, /* 61 */ 1344 st_Nil, /* 62 */ 1345 st_Nil, /* 63 */ 1346 st_Nil, /* 64 */ 1347 st_Nil, /* 65 */ 1348 st_Nil, /* 66 */ 1349 st_Nil, /* 67 */ 1350 st_Nil, /* 68 */ 1351 st_Nil, /* 69 */ 1352 st_Nil, /* 70 */ 1353 st_Nil, /* 71 */ 1354 st_Nil, /* 72 */ 1355 st_Nil, /* 73 */ 1356 st_Nil, /* 74 */ 1357 st_Nil, /* 75 */ 1358 st_Nil, /* 76 */ 1359 st_Nil, /* 77 */ 1360 st_Nil, /* 78 */ 1361 st_Nil, /* 79 */ 1362 st_Nil, /* 80 */ 1363 st_Nil, /* 81 */ 1364 st_Nil, /* 82 */ 1365 st_Nil, /* 83 */ 1366 st_Nil, /* 84 */ 1367 st_Nil, /* 85 */ 1368 st_Nil, /* 86 */ 1369 st_Nil, /* 87 */ 1370 st_Nil, /* 88 */ 1371 st_Nil, /* 89 */ 1372 st_Nil, /* 90 */ 1373 st_Nil, /* 91 */ 1374 st_Nil, /* 92 */ 1375 st_Nil, /* 93 */ 1376 st_Nil, /* 94 */ 1377 st_Nil, /* 95 */ 1378 st_Nil, /* 96 */ 1379 st_Nil, /* 97 */ 1380 st_Nil, /* 98 */ 1381 st_Nil, /* 99 */ 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 ??? */ 1389 }; 1390 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 */ 1397 }; 1398 1399 1400 /* Keep track of different sized allocation requests. */ 1401 static alloc_info_t alloc_counts[ (int) alloc_type_last ]; 1402 1403 1404 /* Pointers and such to the original symbol table that is read in. */ 1405 static struct filehdr orig_file_header; /* global object file header */ 1406 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 */ 1419 1420 /* Macros to convert an index into a given object within the original 1421 symbol table. */ 1422 #define CHECK(num,max,str) \ 1423 (((unsigned long) num > (unsigned long) max) ? out_of_bounds (num, max, str, __LINE__) : 0) 1424 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) 1436 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 */ 1465 1466 1467 /* Pseudo symbol to use when putting stabs into the symbol table. */ 1468 #ifndef STABS_SYMBOL 1469 #define STABS_SYMBOL "@stabs" 1470 #endif 1471 1472 static const char stabs_symbol[] = STABS_SYMBOL; 1473 1474 1475 /* Forward reference for functions. See the definition for more details. */ 1476 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 *, 1480 shash_t **); 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); 1513 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); 1518 1519 #ifndef MALLOC_CHECK 1520 static page_t *allocate_cluster (size_t); 1521 #endif 1522 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); 1530 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 *); 1535 1536 extern char *optarg; 1537 extern int optind; 1538 extern int opterr; 1539 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 1543 do...... */ 1544 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 */ 1549 } pseudo_ops_t; 1550 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 }, 1563 }; 1564 1565 1566 /* Command line options for getopt_long. */ 1567 1568 static const struct option options[] = 1569 { 1570 { "version", 0, 0, 'V' }, 1571 { "verbose", 0, 0, 'v' }, 1572 { 0, 0, 0, 0 } 1573 }; 1574 1575 /* Add a page to a varray object. */ 1576 1577 static void 1578 add_varray_page (varray_t *vp) 1579 { 1580 vlinks_t *new_links = allocate_vlinks (); 1581 1582 #ifdef MALLOC_CHECK 1583 if (vp->object_size > 1) 1584 new_links->datum = xcalloc (1, vp->object_size); 1585 else 1586 #endif 1587 new_links->datum = allocate_page (); 1588 1589 alloc_counts[ (int) alloc_type_varray ].total_alloc++; 1590 alloc_counts[ (int) alloc_type_varray ].total_pages++; 1591 1592 new_links->start_index = vp->num_allocated; 1593 vp->objects_last_page = 0; 1594 1595 if (vp->first == (vlinks_t *) 0) /* first allocation? */ 1596 vp->first = vp->last = new_links; 1597 else 1598 { /* 2nd or greater allocation */ 1599 new_links->prev = vp->last; 1600 vp->last->next = new_links; 1601 vp->last = new_links; 1602 } 1603 } 1604 1605 1606 /* Compute hash code (from tree.c) */ 1607 1608 #define HASHBITS 30 1609 1610 static shash_t * 1611 hash_string (const char *text, ptrdiff_t hash_len, shash_t **hash_tbl, 1612 symint_t *ret_hash_index) 1613 { 1614 unsigned long hi; 1615 ptrdiff_t i; 1616 shash_t *ptr; 1617 int first_ch = *text; 1618 1619 hi = hash_len; 1620 for (i = 0; i < hash_len; i++) 1621 hi = ((hi & 0x003fffff) * 613) + (text[i] & 0xff); 1622 1623 hi &= (1 << HASHBITS) - 1; 1624 hi %= SHASH_SIZE; 1625 1626 if (ret_hash_index != (symint_t *) 0) 1627 *ret_hash_index = hi; 1628 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) 1633 break; 1634 1635 return ptr; 1636 } 1637 1638 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. */ 1645 1646 static symint_t 1647 add_string (varray_t *vp, shash_t **hash_tbl, const char *start, 1648 const char *end_p1, shash_t **ret_hash) 1649 { 1650 ptrdiff_t len = end_p1 - start; 1651 shash_t *hash_ptr; 1652 symint_t hi; 1653 1654 if (len >= (ptrdiff_t) PAGE_USIZE) 1655 fatal ("string too big (%ld bytes)", (long) len); 1656 1657 hash_ptr = hash_string (start, len, hash_tbl, &hi); 1658 if (hash_ptr == (shash_t *) 0) 1659 { 1660 char *p; 1661 1662 if (vp->objects_last_page + len >= (long) PAGE_USIZE) 1663 { 1664 vp->num_allocated 1665 = ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE; 1666 add_varray_page (vp); 1667 } 1668 1669 hash_ptr = allocate_shash (); 1670 hash_ptr->next = hash_tbl[hi]; 1671 hash_tbl[hi] = hash_ptr; 1672 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 ]; 1676 1677 vp->objects_last_page += len+1; 1678 vp->num_allocated += len+1; 1679 1680 while (len-- > 0) 1681 *p++ = *start++; 1682 1683 *p = '\0'; 1684 } 1685 1686 if (ret_hash != (shash_t **) 0) 1687 *ret_hash = hash_ptr; 1688 1689 return hash_ptr->indx; 1690 } 1691 1692 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. */ 1697 1698 static symint_t 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) 1701 { 1702 symint_t ret; 1703 SYMR *psym; 1704 scope_t *pscope; 1705 thead_t *ptag_head; 1706 tag_t *ptag; 1707 tag_t *ptag_next; 1708 varray_t *vp = &cur_file_ptr->symbols; 1709 int scope_delta = 0; 1710 shash_t *hash_ptr = (shash_t *) 0; 1711 1712 if (vp->objects_last_page == vp->objects_per_page) 1713 add_varray_page (vp); 1714 1715 psym = &vp->last->datum->sym[ vp->objects_last_page++ ]; 1716 1717 psym->value = value; 1718 psym->st = (unsigned) type; 1719 psym->sc = (unsigned) storage; 1720 psym->index = indx; 1721 psym->iss = (str_start == (const char *) 0) 1722 ? 0 1723 : add_string (&cur_file_ptr->strings, 1724 &cur_file_ptr->shash_head[0], 1725 str_start, 1726 str_end_p1, 1727 &hash_ptr); 1728 1729 ret = vp->num_allocated++; 1730 1731 if (MIPS_IS_STAB (psym)) 1732 return ret; 1733 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; 1740 1741 /* push or pop a scope if appropriate. */ 1742 switch (type) 1743 { 1744 default: 1745 break; 1746 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; 1757 1758 if (type != st_File) 1759 scope_delta = 1; 1760 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) 1765 { 1766 ptag_head = allocate_thead (); 1767 ptag_head->first_tag = 0; 1768 ptag_head->prev = cur_tag_head; 1769 cur_tag_head = ptag_head; 1770 } 1771 break; 1772 1773 case st_End: 1774 pscope = cur_file_ptr->cur_scope; 1775 if (pscope == (scope_t *) 0) 1776 error ("internal error, too many st_End's"); 1777 1778 else 1779 { 1780 st_t begin_type = (st_t) pscope->lsym->st; 1781 1782 if (begin_type != st_File) 1783 scope_delta = -1; 1784 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) 1788 { 1789 ptag_head = cur_tag_head; 1790 cur_tag_head = ptag_head->prev; 1791 1792 for (ptag = ptag_head->first_tag; 1793 ptag != (tag_t *) 0; 1794 ptag = ptag_next) 1795 { 1796 if (ptag->forward_ref != (forward_t *) 0) 1797 add_unknown_tag (ptag); 1798 1799 ptag_next = ptag->same_block; 1800 ptag->hash_ptr->tag_ptr = ptag->same_name; 1801 free_tag (ptag); 1802 } 1803 1804 free_thead (ptag_head); 1805 } 1806 1807 cur_file_ptr->cur_scope = pscope->prev; 1808 psym->index = pscope->lnumber; /* blk end gets begin sym # */ 1809 1810 if (storage != sc_Info) 1811 psym->iss = pscope->lsym->iss; /* blk end gets same name */ 1812 1813 if (begin_type == st_File || begin_type == st_Block) 1814 pscope->lsym->index = ret+1; /* block begin gets next sym # */ 1815 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. */ 1820 else 1821 { 1822 symint_t type; 1823 pscope->lsym->index = add_aux_sym_symint (ret+1); 1824 type = add_aux_sym_tir (&last_func_type_info, 1825 hash_no, 1826 &cur_file_ptr->thash_head[0]); 1827 if (last_func_eptr) 1828 { 1829 last_func_eptr->ifd = cur_file_ptr->file_index; 1830 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; 1834 } 1835 } 1836 1837 free_scope (pscope); 1838 } 1839 } 1840 1841 cur_file_ptr->nested_scopes += scope_delta; 1842 1843 if (debug && type != st_File 1844 && (debug > 2 || type == st_Block || type == st_End 1845 || type == st_Proc || type == st_StaticProc)) 1846 { 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); 1850 1851 fprintf (stderr, 1852 "\tlsym\tv= %10ld, depth= %2d, sc= %-12s", 1853 value, depth, sc_str); 1854 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); 1858 else 1859 { 1860 size_t len = strlen (st_str); 1861 fprintf (stderr, " st= %.*s\n", (int) (len-1), st_str); 1862 } 1863 } 1864 1865 return ret; 1866 } 1867 1868 1869 /* Add an external symbol with symbol pointer ESYM and file index 1870 IFD. */ 1871 1872 static symint_t 1873 add_ext_symbol (EXTR *esym, int ifd) 1874 { 1875 const char *str_start; /* first byte in string */ 1876 const char *str_end_p1; /* first byte after string */ 1877 EXTR *psym; 1878 varray_t *vp = &ext_symbols; 1879 shash_t *hash_ptr = (shash_t *) 0; 1880 1881 str_start = ORIG_ESTRS (esym->asym.iss); 1882 str_end_p1 = str_start + strlen (str_start); 1883 1884 if (debug > 1) 1885 { 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); 1889 1890 fprintf (stderr, 1891 "\tesym\tv= %10ld, ifd= %2d, sc= %-12s", 1892 value, ifd, sc_str); 1893 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); 1897 else 1898 fprintf (stderr, " st= %s\n", st_str); 1899 } 1900 1901 if (vp->objects_last_page == vp->objects_per_page) 1902 add_varray_page (vp); 1903 1904 psym = &vp->last->datum->esym[ vp->objects_last_page++ ]; 1905 1906 *psym = *esym; 1907 psym->ifd = ifd; 1908 psym->asym.index = indexNil; 1909 psym->asym.iss = (str_start == (const char *) 0) 1910 ? 0 1911 : add_string (&ext_strings, 1912 &ext_str_hash[0], 1913 str_start, 1914 str_end_p1, 1915 &hash_ptr); 1916 1917 hash_ptr->esym_ptr = psym; 1918 return vp->num_allocated++; 1919 } 1920 1921 1922 /* Add an auxiliary symbol (passing a symint). */ 1923 1924 static symint_t 1925 add_aux_sym_symint (symint_t aux_word) 1926 { 1927 AUXU *aux_ptr; 1928 efdr_t *file_ptr = cur_file_ptr; 1929 varray_t *vp = &file_ptr->aux_syms; 1930 1931 if (vp->objects_last_page == vp->objects_per_page) 1932 add_varray_page (vp); 1933 1934 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ]; 1935 aux_ptr->isym = aux_word; 1936 1937 return vp->num_allocated++; 1938 } 1939 1940 1941 /* Add an auxiliary symbol (passing a file/symbol index combo). */ 1942 1943 static symint_t 1944 add_aux_sym_rndx (int file_index, symint_t sym_index) 1945 { 1946 AUXU *aux_ptr; 1947 efdr_t *file_ptr = cur_file_ptr; 1948 varray_t *vp = &file_ptr->aux_syms; 1949 1950 if (vp->objects_last_page == vp->objects_per_page) 1951 add_varray_page (vp); 1952 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; 1956 1957 return vp->num_allocated++; 1958 } 1959 1960 1961 /* Add an auxiliary symbol (passing the basic type and possibly 1962 type qualifiers). */ 1963 1964 static symint_t 1965 add_aux_sym_tir (type_info_t *t, hash_state_t state, thash_t **hash_tbl) 1966 { 1967 AUXU *aux_ptr; 1968 efdr_t *file_ptr = cur_file_ptr; 1969 varray_t *vp = &file_ptr->aux_syms; 1970 static AUXU init_aux; 1971 symint_t ret; 1972 int i; 1973 AUXU aux; 1974 1975 aux = init_aux; 1976 aux.ti.bt = (int) t->basic_type; 1977 aux.ti.continued = 0; 1978 aux.ti.fBitfield = t->bitfield; 1979 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]; 1986 1987 1988 /* For anything that adds additional information, we must not hash, 1989 so check here, and reset our state. */ 1990 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 2001 || t->bitfield 2002 || t->num_dims > 0)) 2003 state = hash_no; 2004 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. */ 2009 2010 if (state != hash_no) 2011 { 2012 thash_t *hash_ptr; 2013 symint_t hi; 2014 2015 hi = aux.isym & ((1 << HASHBITS) - 1); 2016 hi %= THASH_SIZE; 2017 2018 for (hash_ptr = hash_tbl[hi]; 2019 hash_ptr != (thash_t *) 0; 2020 hash_ptr = hash_ptr->next) 2021 { 2022 if (aux.isym == hash_ptr->type.isym) 2023 break; 2024 } 2025 2026 if (hash_ptr != (thash_t *) 0 && state == hash_yes) 2027 return hash_ptr->indx; 2028 2029 if (hash_ptr == (thash_t *) 0) 2030 { 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; 2036 } 2037 } 2038 2039 /* Everything is set up, add the aux symbol. */ 2040 if (vp->objects_last_page == vp->objects_per_page) 2041 add_varray_page (vp); 2042 2043 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ]; 2044 *aux_ptr = aux; 2045 2046 ret = vp->num_allocated++; 2047 2048 /* Add bitfield length if it exists. 2049 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.) 2053 2054 Also note: We use the last size given since gcc may emit 2 2055 for an enum bitfield. */ 2056 2057 if (t->bitfield) 2058 (void) add_aux_sym_symint ((symint_t) t->sizes[t->num_sizes-1]); 2059 2060 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. */ 2064 2065 if (t->basic_type == bt_Struct 2066 || t->basic_type == bt_Union 2067 || t->basic_type == bt_Enum) 2068 { 2069 symint_t file_index = t->tag_ptr->ifd; 2070 symint_t sym_index = t->tag_ptr->indx; 2071 2072 if (t->unknown_tag) 2073 { 2074 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index); 2075 (void) add_aux_sym_symint ((symint_t)-1); 2076 } 2077 else if (sym_index != indexNil) 2078 { 2079 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index); 2080 (void) add_aux_sym_symint (file_index); 2081 } 2082 else 2083 { 2084 forward_t *forward_ref = allocate_forward (); 2085 2086 forward_ref->type_ptr = aux_ptr; 2087 forward_ref->next = t->tag_ptr->forward_ref; 2088 t->tag_ptr->forward_ref = forward_ref; 2089 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]; 2093 2094 (void) add_aux_sym_symint (file_index); 2095 forward_ref->ifd_ptr 2096 = &vp->last->datum->aux[ vp->objects_last_page - 1]; 2097 } 2098 } 2099 2100 /* Add information about array bounds if they exist. */ 2101 for (i = 0; i < t->num_dims; i++) 2102 { 2103 (void) add_aux_sym_rndx (ST_RFDESCAPE, 2104 cur_file_ptr->int_type); 2105 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 */ 2110 ? 0 2111 : (t->sizes[i] * 8) / t->dimensions[i]); 2112 }; 2113 2114 /* NOTE: Mips documentation claims that the bitfield width goes here. 2115 But it needs to be emitted earlier. */ 2116 2117 return ret; 2118 } 2119 2120 2121 /* Add a tag to the tag table (unless it already exists). */ 2122 2123 static tag_t * 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 */ 2128 2129 { 2130 shash_t *hash_ptr; 2131 tag_t *tag_ptr; 2132 hash_ptr = hash_string (tag_start, 2133 tag_end_p1 - tag_start, 2134 &tag_hash[0], 2135 (symint_t *) 0); 2136 2137 if (hash_ptr != (shash_t *) 0 2138 && hash_ptr->tag_ptr != (tag_t *) 0) 2139 { 2140 tag_ptr = hash_ptr->tag_ptr; 2141 if (indx != indexNil) 2142 { 2143 tag_ptr->basic_type = basic_type; 2144 tag_ptr->ifd = cur_file_ptr->file_index; 2145 tag_ptr->indx = indx; 2146 } 2147 return tag_ptr; 2148 } 2149 2150 (void) add_string (&tag_strings, 2151 &tag_hash[0], 2152 tag_start, 2153 tag_end_p1, 2154 &hash_ptr); 2155 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; 2165 2166 cur_tag_head->first_tag = tag_ptr; 2167 hash_ptr->tag_ptr = tag_ptr; 2168 2169 return tag_ptr; 2170 } 2171 2172 2173 /* Add an unknown {struct, union, enum} tag. */ 2174 2175 static void 2176 add_unknown_tag (tag_t *ptag) 2177 { 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; 2182 forward_t *f_cur; 2183 int sym_index; 2184 int file_index = cur_file_ptr->file_index; 2185 2186 if (debug > 1) 2187 { 2188 const char *agg_type = "{unknown aggregate type}"; 2189 switch (ptag->basic_type) 2190 { 2191 case bt_Struct: agg_type = "struct"; break; 2192 case bt_Union: agg_type = "union"; break; 2193 case bt_Enum: agg_type = "enum"; break; 2194 default: break; 2195 } 2196 2197 fprintf (stderr, "unknown %s %.*s found\n", 2198 agg_type, (int) hash_ptr->len, name_start); 2199 } 2200 2201 sym_index = add_local_symbol (name_start, 2202 name_end_p1, 2203 st_Block, 2204 sc_Info, 2205 (symint_t) 0, 2206 (symint_t) 0); 2207 2208 (void) add_local_symbol (name_start, 2209 name_end_p1, 2210 st_End, 2211 sc_Info, 2212 (symint_t) 0, 2213 (symint_t) 0); 2214 2215 while (f_next != (forward_t *) 0) 2216 { 2217 f_cur = f_next; 2218 f_next = f_next->next; 2219 2220 f_cur->ifd_ptr->isym = file_index; 2221 f_cur->index_ptr->rndx.index = sym_index; 2222 2223 free_forward (f_cur); 2224 } 2225 2226 return; 2227 } 2228 2229 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. */ 2233 2234 static void 2235 add_procedure (const char *func_start, /* 1st byte of func name */ 2236 const char *func_end_p1) /* 1st byte after func name */ 2237 { 2238 PDR *new_proc_ptr; 2239 efdr_t *file_ptr = cur_file_ptr; 2240 varray_t *vp = &file_ptr->procs; 2241 symint_t value = 0; 2242 st_t proc_type = st_Proc; 2243 shash_t *shash_ptr = hash_string (func_start, 2244 func_end_p1 - func_start, 2245 &orig_str_hash[0], 2246 (symint_t *) 0); 2247 2248 if (debug) 2249 fputc ('\n', stderr); 2250 2251 if (vp->objects_last_page == vp->objects_per_page) 2252 add_varray_page (vp); 2253 2254 cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[ vp->objects_last_page++ ]; 2255 2256 vp->num_allocated++; 2257 2258 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) 2262 { 2263 PDR *old_proc_ptr = shash_ptr->proc_ptr; 2264 SYMR *sym_ptr = shash_ptr->sym_ptr; 2265 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)) 2269 { 2270 cur_oproc_begin = sym_ptr; 2271 cur_oproc_end = shash_ptr->end_ptr; 2272 value = sym_ptr->value; 2273 2274 cur_oproc_ptr = old_proc_ptr; 2275 proc_type = (st_t) sym_ptr->st; 2276 *new_proc_ptr = *old_proc_ptr; /* initialize */ 2277 } 2278 } 2279 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); 2283 2284 /* Determine the start of symbols. */ 2285 new_proc_ptr->isym = file_ptr->symbols.num_allocated; 2286 2287 /* Push the start of the function. */ 2288 (void) add_local_symbol (func_start, func_end_p1, 2289 proc_type, sc_Text, 2290 value, 2291 (symint_t) 0); 2292 } 2293 2294 2295 /* Initialize the init_file structure. */ 2296 2297 static void 2298 initialize_init_file (void) 2299 { 2300 union { 2301 unsigned char c[4]; 2302 int i; 2303 } endian_test; 2304 2305 memset (&init_file, 0, sizeof (init_file)); 2306 2307 init_file.fdr.lang = langC; 2308 init_file.fdr.fMerge = 1; 2309 init_file.fdr.glevel = GLEVEL_2; 2310 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. */ 2319 endian_test.i = 1; 2320 if (endian_test.c[3]) 2321 init_file.fdr.fBigendian = 1; 2322 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); 2327 2328 init_file_initialized = 1; 2329 } 2330 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. */ 2334 2335 static void 2336 add_file (const char *file_start, /* first byte in string */ 2337 const char *file_end_p1) /* first byte after string */ 2338 { 2339 static char zero_bytes[2] = { '\0', '\0' }; 2340 2341 ptrdiff_t len = file_end_p1 - file_start; 2342 int first_ch = *file_start; 2343 efdr_t *file_ptr; 2344 2345 if (debug) 2346 fprintf (stderr, "\tfile\t%.*s\n", (int) len, file_start); 2347 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) 2352 { 2353 if (first_ch == file_ptr->name[0] 2354 && file_ptr->name[len] == '\0' 2355 && memcmp (file_start, file_ptr->name, len) == 0) 2356 { 2357 cur_file_ptr = file_ptr; 2358 break; 2359 } 2360 } 2361 2362 /* If this is a new file, create it. */ 2363 if (file_ptr == (efdr_t *) 0) 2364 { 2365 if (file_desc.objects_last_page == file_desc.objects_per_page) 2366 add_varray_page (&file_desc); 2367 2368 if (! init_file_initialized) 2369 initialize_init_file (); 2370 2371 file_ptr = cur_file_ptr 2372 = &file_desc.last->datum->file[ file_desc.objects_last_page++ ]; 2373 *file_ptr = init_file; 2374 2375 file_ptr->file_index = file_desc.num_allocated++; 2376 2377 /* Allocate the string hash table. */ 2378 file_ptr->shash_head = (shash_t **) allocate_page (); 2379 2380 /* Make sure 0 byte in string table is null */ 2381 add_string (&file_ptr->strings, 2382 &file_ptr->shash_head[0], 2383 &zero_bytes[0], 2384 &zero_bytes[0], 2385 (shash_t **) 0); 2386 2387 if (file_end_p1 - file_start > (long) PAGE_USIZE-2) 2388 fatal ("filename goes over one page boundary"); 2389 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; 2397 2398 /* Update the linked list of file descriptors. */ 2399 *last_file_ptr = file_ptr; 2400 last_file_ptr = &file_ptr->next_file; 2401 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, 2405 hash_yes, 2406 &cur_file_ptr->thash_head[0]); 2407 2408 file_ptr->int_type = add_aux_sym_tir (&int_type_info, 2409 hash_yes, 2410 &cur_file_ptr->thash_head[0]); 2411 } 2412 } 2413 2414 2415 /* Add a stream of random bytes to a varray. */ 2416 2417 static void 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 */ 2421 { 2422 size_t move_items; 2423 size_t move_bytes; 2424 char *ptr; 2425 2426 while (nitems > 0) 2427 { 2428 if (vp->objects_last_page >= vp->objects_per_page) 2429 add_varray_page (vp); 2430 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; 2435 2436 move_bytes = move_items * vp->object_size; 2437 nitems -= move_items; 2438 2439 if (move_bytes >= 32) 2440 { 2441 (void) memcpy (ptr, input_ptr, move_bytes); 2442 input_ptr += move_bytes; 2443 } 2444 else 2445 { 2446 while (move_bytes-- > 0) 2447 *ptr++ = *input_ptr++; 2448 } 2449 } 2450 } 2451 2452 2453 /* Convert storage class to string. */ 2454 2455 static const char * 2456 sc_to_string (sc_t storage_class) 2457 { 2458 switch (storage_class) 2459 { 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,"; 2484 } 2485 2486 return "???,"; 2487 } 2488 2489 2490 /* Convert symbol type to string. */ 2491 2492 static const char * 2493 st_to_string (st_t symbol_type) 2494 { 2495 switch (symbol_type) 2496 { 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,"; 2518 } 2519 2520 return "???,"; 2521 } 2522 2523 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. */ 2527 2528 static char * 2529 read_line (void) 2530 { 2531 static int line_split_p = 0; 2532 int string_p = 0; 2533 int comment_p = 0; 2534 int ch; 2535 char *ptr; 2536 2537 if (cur_line_start == (char *) 0) 2538 { /* allocate initial page */ 2539 cur_line_start = (char *) allocate_page (); 2540 cur_line_alloc = PAGE_SIZE; 2541 } 2542 2543 if (!line_split_p) 2544 line_number++; 2545 2546 line_split_p = 0; 2547 cur_line_nbytes = 0; 2548 2549 for (ptr = cur_line_start; (ch = getchar ()) != EOF; *ptr++ = ch) 2550 { 2551 if (++cur_line_nbytes >= cur_line_alloc-1) 2552 { 2553 int num_pages = cur_line_alloc / PAGE_SIZE; 2554 char *old_buffer = cur_line_start; 2555 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); 2559 2560 ptr = cur_line_start + cur_line_nbytes - 1; 2561 } 2562 2563 if (ch == '\n') 2564 { 2565 *ptr++ = '\n'; 2566 *ptr = '\0'; 2567 cur_line_ptr = cur_line_start; 2568 return cur_line_ptr; 2569 } 2570 2571 else if (ch == '\0') 2572 error ("null character found in input"); 2573 2574 else if (!comment_p) 2575 { 2576 if (ch == '"') 2577 string_p = !string_p; 2578 2579 else if (ch == '#') 2580 comment_p++; 2581 2582 else if (ch == ';' && !string_p) 2583 { 2584 line_split_p = 1; 2585 *ptr++ = '\n'; 2586 *ptr = '\0'; 2587 cur_line_ptr = cur_line_start; 2588 return cur_line_ptr; 2589 } 2590 } 2591 } 2592 2593 if (ferror (stdin)) 2594 pfatal_with_name (input_name); 2595 2596 cur_line_ptr = (char *) 0; 2597 return (char *) 0; 2598 } 2599 2600 2601 /* Parse #.begin directives which have a label as the first argument 2602 which gives the location of the start of the block. */ 2603 2604 static void 2605 parse_begin (const char *start) 2606 { 2607 const char *end_p1; /* end of label */ 2608 int ch; 2609 shash_t *hash_ptr; /* hash pointer to lookup label */ 2610 2611 if (cur_file_ptr == (efdr_t *) 0) 2612 { 2613 error ("#.begin directive without a preceding .file directive"); 2614 return; 2615 } 2616 2617 if (cur_proc_ptr == (PDR *) 0) 2618 { 2619 error ("#.begin directive without a preceding .ent directive"); 2620 return; 2621 } 2622 2623 for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++) 2624 ; 2625 2626 hash_ptr = hash_string (start, 2627 end_p1 - start, 2628 &orig_str_hash[0], 2629 (symint_t *) 0); 2630 2631 if (hash_ptr == (shash_t *) 0) 2632 { 2633 error ("label %.*s not found for #.begin", 2634 (int) (end_p1 - start), start); 2635 return; 2636 } 2637 2638 if (cur_oproc_begin == (SYMR *) 0) 2639 { 2640 error ("procedure table %.*s not found for #.begin", 2641 (int) (end_p1 - start), start); 2642 return; 2643 } 2644 2645 (void) add_local_symbol ((const char *) 0, (const char *) 0, 2646 st_Block, sc_Text, 2647 (symint_t) hash_ptr->sym_ptr->value - cur_oproc_begin->value, 2648 (symint_t) 0); 2649 } 2650 2651 2652 /* Parse #.bend directives which have a label as the first argument 2653 which gives the location of the end of the block. */ 2654 2655 static void 2656 parse_bend (const char *start) 2657 { 2658 const char *end_p1; /* end of label */ 2659 int ch; 2660 shash_t *hash_ptr; /* hash pointer to lookup label */ 2661 2662 if (cur_file_ptr == (efdr_t *) 0) 2663 { 2664 error ("#.begin directive without a preceding .file directive"); 2665 return; 2666 } 2667 2668 if (cur_proc_ptr == (PDR *) 0) 2669 { 2670 error ("#.bend directive without a preceding .ent directive"); 2671 return; 2672 } 2673 2674 for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++) 2675 ; 2676 2677 hash_ptr = hash_string (start, 2678 end_p1 - start, 2679 &orig_str_hash[0], 2680 (symint_t *) 0); 2681 2682 if (hash_ptr == (shash_t *) 0) 2683 { 2684 error ("label %.*s not found for #.bend", (int) (end_p1 - start), start); 2685 return; 2686 } 2687 2688 if (cur_oproc_begin == (SYMR *) 0) 2689 { 2690 error ("procedure table %.*s not found for #.bend", 2691 (int) (end_p1 - start), start); 2692 return; 2693 } 2694 2695 (void) add_local_symbol ((const char *) 0, (const char *) 0, 2696 st_End, sc_Text, 2697 (symint_t) hash_ptr->sym_ptr->value - cur_oproc_begin->value, 2698 (symint_t) 0); 2699 } 2700 2701 2702 /* Parse #.def directives, which are contain standard COFF subdirectives 2703 to describe the debugging format. These subdirectives include: 2704 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. */ 2712 2713 static void 2714 parse_def (const char *name_start) 2715 { 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; 2725 type_info_t t; 2726 EXTR *eptr = (EXTR *) 0; /* ext. sym equivalent to def*/ 2727 int is_function = 0; /* != 0 if function */ 2728 symint_t value = 0; 2729 symint_t indx = cur_file_ptr->void_type; 2730 int error_line = 0; 2731 symint_t arg_number; 2732 symint_t temp_array[ N_TQ ]; 2733 int arg_was_number; 2734 int ch, i; 2735 ptrdiff_t len; 2736 2737 static int inside_enumeration = 0; /* is this an enumeration? */ 2738 2739 2740 /* Initialize the type information. */ 2741 t = type_info_init; 2742 2743 2744 /* Search for the end of the name being defined. */ 2745 /* Allow spaces and such in names for G++ templates, which produce stabs 2746 that look like: 2747 2748 #.def SMANIP<long unsigned int>; .scl 10; .type 0x8; .size 8; .endef */ 2749 2750 for (name_end_p1 = name_start; (ch = *name_end_p1) != ';' && ch != '\0'; name_end_p1++) 2751 ; 2752 2753 if (ch == '\0') 2754 { 2755 error_line = __LINE__; 2756 goto bomb_out; 2757 } 2758 2759 /* Parse the remaining subdirectives now. */ 2760 dir_start = name_end_p1+1; 2761 for (;;) 2762 { 2763 while ((ch = *dir_start) == ' ' || ch == '\t') 2764 ++dir_start; 2765 2766 if (ch != '.') 2767 { 2768 error_line = __LINE__; 2769 goto bomb_out; 2770 } 2771 2772 /* Are we done? */ 2773 if (dir_start[1] == 'e' 2774 && memcmp (dir_start, ".endef", sizeof (".endef")-1) == 0) 2775 break; 2776 2777 /* Pick up the subdirective now. */ 2778 for (dir_end_p1 = dir_start+1; 2779 (ch = *dir_end_p1) != ' ' && ch != '\t'; 2780 dir_end_p1++) 2781 { 2782 if (ch == '\0' || ISSPACE (ch)) 2783 { 2784 error_line = __LINE__; 2785 goto bomb_out; 2786 } 2787 } 2788 2789 /* Pick up the subdirective argument now. */ 2790 arg_was_number = arg_number = 0; 2791 arg_end_p1 = 0; 2792 arg_start = dir_end_p1+1; 2793 ch = *arg_start; 2794 while (ch == ' ' || ch == '\t') 2795 ch = *++arg_start; 2796 2797 if (ISDIGIT (ch) || ch == '-' || ch == '+') 2798 { 2799 int ch2; 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 == ',')) 2803 arg_was_number++; 2804 } 2805 2806 else if (ch == '\0' || ISSPACE (ch)) 2807 { 2808 error_line = __LINE__; 2809 goto bomb_out; 2810 } 2811 2812 if (!arg_was_number) 2813 { 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'; 2817 arg_end_p1++) 2818 ; 2819 2820 if (ch == '\0') 2821 { 2822 error_line = __LINE__; 2823 goto bomb_out; 2824 } 2825 } 2826 2827 /* Classify the directives now. */ 2828 len = dir_end_p1 - dir_start; 2829 switch (dir_start[1]) 2830 { 2831 default: 2832 error_line = __LINE__; 2833 goto bomb_out; 2834 2835 case 'd': 2836 if (len == sizeof (".dim")-1 2837 && memcmp (dir_start, ".dim", sizeof (".dim")-1) == 0 2838 && arg_was_number) 2839 { 2840 symint_t *t_ptr = &temp_array[ N_TQ-1 ]; 2841 2842 *t_ptr = arg_number; 2843 while (*arg_end_p1 == ',' && arg_was_number) 2844 { 2845 arg_start = arg_end_p1+1; 2846 ch = *arg_start; 2847 while (ch == ' ' || ch == '\t') 2848 ch = *++arg_start; 2849 2850 arg_was_number = 0; 2851 if (ISDIGIT (ch) || ch == '-' || ch == '+') 2852 { 2853 int ch2; 2854 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0); 2855 if (arg_end_p1 != arg_start && (((ch2 = *arg_end_p1) == ';') || ch2 == ',')) 2856 arg_was_number++; 2857 2858 if (t_ptr == &temp_array[0]) 2859 { 2860 error_line = __LINE__; 2861 goto bomb_out; 2862 } 2863 2864 *--t_ptr = arg_number; 2865 } 2866 } 2867 2868 /* Reverse order of dimensions. */ 2869 while (t_ptr <= &temp_array[ N_TQ-1 ]) 2870 { 2871 if (t.num_dims >= N_TQ-1) 2872 { 2873 error_line = __LINE__; 2874 goto bomb_out; 2875 } 2876 2877 t.dimensions[ t.num_dims++ ] = *t_ptr++; 2878 } 2879 break; 2880 } 2881 else 2882 { 2883 error_line = __LINE__; 2884 goto bomb_out; 2885 } 2886 2887 2888 case 's': 2889 if (len == sizeof (".scl")-1 2890 && memcmp (dir_start, ".scl", sizeof (".scl")-1) == 0 2891 && arg_was_number 2892 && arg_number < ((symint_t) C_MAX)) 2893 { 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) 2900 { 2901 symbol_type = map_coff_sym_type[arg_number]; 2902 storage_class = map_coff_storage [arg_number]; 2903 } 2904 break; 2905 } 2906 2907 else if (len == sizeof (".size")-1 2908 && memcmp (dir_start, ".size", sizeof (".size")-1) == 0 2909 && arg_was_number) 2910 { 2911 symint_t *t_ptr = &temp_array[ N_TQ-1 ]; 2912 2913 *t_ptr = arg_number; 2914 while (*arg_end_p1 == ',' && arg_was_number) 2915 { 2916 arg_start = arg_end_p1+1; 2917 ch = *arg_start; 2918 while (ch == ' ' || ch == '\t') 2919 ch = *++arg_start; 2920 2921 arg_was_number = 0; 2922 if (ISDIGIT (ch) || ch == '-' || ch == '+') 2923 { 2924 int ch2; 2925 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0); 2926 if (arg_end_p1 != arg_start && (((ch2 = *arg_end_p1) == ';') || ch2 == ',')) 2927 arg_was_number++; 2928 2929 if (t_ptr == &temp_array[0]) 2930 { 2931 error_line = __LINE__; 2932 goto bomb_out; 2933 } 2934 2935 *--t_ptr = arg_number; 2936 } 2937 } 2938 2939 /* Reverse order of sizes. */ 2940 while (t_ptr <= &temp_array[ N_TQ-1 ]) 2941 { 2942 if (t.num_sizes >= N_TQ-1) 2943 { 2944 error_line = __LINE__; 2945 goto bomb_out; 2946 } 2947 2948 t.sizes[ t.num_sizes++ ] = *t_ptr++; 2949 } 2950 break; 2951 } 2952 2953 else 2954 { 2955 error_line = __LINE__; 2956 goto bomb_out; 2957 } 2958 2959 2960 case 't': 2961 if (len == sizeof (".type")-1 2962 && memcmp (dir_start, ".type", sizeof (".type")-1) == 0 2963 && arg_was_number) 2964 { 2965 tq_t *tq_ptr = &t.type_qualifiers[0]; 2966 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--) 2970 { 2971 int dt = (arg_number >> ((i * N_TQ_SHIFT) + N_BT_SHIFT) 2972 & N_TMASK); 2973 2974 if (dt != (int) DT_NON) 2975 *tq_ptr++ = map_coff_derived_type [dt]; 2976 } 2977 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) 2985 { 2986 is_function = 1; 2987 tq_ptr[-1] = tq_Nil; 2988 } 2989 2990 break; 2991 } 2992 2993 else if (len == sizeof (".tag")-1 2994 && memcmp (dir_start, ".tag", sizeof (".tag")-1) == 0) 2995 { 2996 tag_start = arg_start; 2997 tag_end_p1 = arg_end_p1; 2998 break; 2999 } 3000 3001 else 3002 { 3003 error_line = __LINE__; 3004 goto bomb_out; 3005 } 3006 3007 3008 case 'v': 3009 if (len == sizeof (".val")-1 3010 && memcmp (dir_start, ".val", sizeof (".val")-1) == 0) 3011 { 3012 if (arg_was_number) 3013 value = arg_number; 3014 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. */ 3019 else 3020 { 3021 shash_t *orig_hash_ptr; /* hash within orig sym table*/ 3022 shash_t *ext_hash_ptr; /* hash within ext. sym table*/ 3023 3024 ext_hash_ptr = hash_string (arg_start, 3025 arg_end_p1 - arg_start, 3026 &ext_str_hash[0], 3027 (symint_t *) 0); 3028 3029 if (ext_hash_ptr != (shash_t *) 0 3030 && ext_hash_ptr->esym_ptr != (EXTR *) 0) 3031 eptr = ext_hash_ptr->esym_ptr; 3032 3033 orig_hash_ptr = hash_string (arg_start, 3034 arg_end_p1 - arg_start, 3035 &orig_str_hash[0], 3036 (symint_t *) 0); 3037 3038 if ((orig_hash_ptr == (shash_t *) 0 3039 || orig_hash_ptr->sym_ptr == (SYMR *) 0) 3040 && eptr == (EXTR *) 0) 3041 { 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), 3044 arg_start); 3045 value = 0; 3046 } 3047 else 3048 { 3049 SYMR *ptr = (orig_hash_ptr != (shash_t *) 0 3050 && orig_hash_ptr->sym_ptr != (SYMR *) 0) 3051 ? orig_hash_ptr->sym_ptr 3052 : &eptr->asym; 3053 3054 symbol_type = (st_t) ptr->st; 3055 storage_class = (sc_t) ptr->sc; 3056 value = ptr->value; 3057 } 3058 } 3059 break; 3060 } 3061 else 3062 { 3063 error_line = __LINE__; 3064 goto bomb_out; 3065 } 3066 } 3067 3068 /* Set up to find next directive. */ 3069 dir_start = arg_end_p1 + 1; 3070 } 3071 3072 3073 if (storage_class == sc_Bits) 3074 { 3075 t.bitfield = 1; 3076 t.extra_sizes = 1; 3077 } 3078 else 3079 t.extra_sizes = 0; 3080 3081 if (t.num_dims > 0) 3082 { 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; 3086 int j; 3087 3088 if (num_real_sizes != 1 || diff < 0) 3089 { 3090 error_line = __LINE__; 3091 goto bomb_out; 3092 } 3093 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. */ 3097 3098 if (diff) 3099 { 3100 for (j = ARRAY_SIZE (t.sizes) - 1; j >= 0; j--) 3101 t.sizes[ j ] = ((j-diff) >= 0) ? t.sizes[ j-diff ] : 0; 3102 3103 t.num_sizes = i + 1; 3104 for ( i--; i >= 0; i-- ) 3105 { 3106 if (t.dimensions[ i+1 ]) 3107 t.sizes[ i ] = t.sizes[ i+1 ] / t.dimensions[ i+1 ]; 3108 else 3109 t.sizes[ i ] = t.sizes[ i+1 ]; 3110 } 3111 } 3112 } 3113 3114 /* Except for enumeration members & begin/ending of scopes, put the 3115 type word in the aux. symbol table. */ 3116 3117 if (symbol_type == st_Block || symbol_type == st_End) 3118 indx = 0; 3119 3120 else if (inside_enumeration) 3121 indx = cur_file_ptr->void_type; 3122 3123 else 3124 { 3125 if (t.basic_type == bt_Struct 3126 || t.basic_type == bt_Union 3127 || t.basic_type == bt_Enum) 3128 { 3129 if (tag_start == (char *) 0) 3130 { 3131 error ("no tag specified for %.*s", 3132 (int) (name_end_p1 - name_start), 3133 name_start); 3134 return; 3135 } 3136 3137 t.tag_ptr = get_tag (tag_start, tag_end_p1, (symint_t) indexNil, 3138 t.basic_type); 3139 } 3140 3141 if (is_function) 3142 { 3143 last_func_type_info = t; 3144 last_func_eptr = eptr; 3145 return; 3146 } 3147 3148 indx = add_aux_sym_tir (&t, 3149 hash_yes, 3150 &cur_file_ptr->thash_head[0]); 3151 } 3152 3153 3154 /* If this is an external or static symbol, update the appropriate 3155 external symbol. */ 3156 3157 if (eptr != (EXTR *) 0 3158 && (eptr->asym.index == indexNil || cur_proc_ptr == (PDR *) 0)) 3159 { 3160 eptr->ifd = cur_file_ptr->file_index; 3161 eptr->asym.index = indx; 3162 } 3163 3164 3165 /* Do any last minute adjustments that are necessary. */ 3166 switch (symbol_type) 3167 { 3168 default: 3169 break; 3170 3171 3172 /* For the beginning of structs, unions, and enumerations, the 3173 size info needs to be passed in the value field. */ 3174 3175 case st_Block: 3176 if (t.num_sizes - t.num_dims - t.extra_sizes != 1) 3177 { 3178 error_line = __LINE__; 3179 goto bomb_out; 3180 } 3181 3182 else 3183 value = t.sizes[0]; 3184 3185 inside_enumeration = (t.orig_type == T_ENUM); 3186 break; 3187 3188 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. */ 3192 3193 case st_End: 3194 name_start = name_end_p1 = 0; 3195 value = inside_enumeration = 0; 3196 break; 3197 3198 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. */ 3204 3205 case st_Member: 3206 if (!t.bitfield && !inside_enumeration) 3207 value *= 8; 3208 3209 break; 3210 } 3211 3212 3213 /* Add the symbol, except for global symbols outside of functions, 3214 for which the external symbol table is fine enough. */ 3215 3216 if (eptr == (EXTR *) 0 3217 || eptr->asym.st == (int) st_Nil 3218 || cur_proc_ptr != (PDR *) 0) 3219 { 3220 symint_t isym = add_local_symbol (name_start, name_end_p1, 3221 symbol_type, storage_class, 3222 value, 3223 indx); 3224 3225 /* Deal with struct, union, and enum tags. */ 3226 if (symbol_type == st_Block) 3227 { 3228 /* Create or update the tag information. */ 3229 tag_t *tag_ptr = get_tag (name_start, 3230 name_end_p1, 3231 isym, 3232 t.basic_type); 3233 3234 /* If there are any forward references, fill in the appropriate 3235 file and symbol indexes. */ 3236 3237 symint_t file_index = cur_file_ptr->file_index; 3238 forward_t *f_next = tag_ptr->forward_ref; 3239 forward_t *f_cur; 3240 3241 while (f_next != (forward_t *) 0) 3242 { 3243 f_cur = f_next; 3244 f_next = f_next->next; 3245 3246 f_cur->ifd_ptr->isym = file_index; 3247 f_cur->index_ptr->rndx.index = isym; 3248 3249 free_forward (f_cur); 3250 } 3251 3252 tag_ptr->forward_ref = (forward_t *) 0; 3253 } 3254 } 3255 3256 /* Normal return */ 3257 return; 3258 3259 /* Error return, issue message. */ 3260 bomb_out: 3261 if (error_line) 3262 error ("compiler error, badly formed #.def (internal line # = %d)", error_line); 3263 else 3264 error ("compiler error, badly formed #.def"); 3265 3266 return; 3267 } 3268 3269 3270 /* Parse .end directives. */ 3271 3272 static void 3273 parse_end (const char *start) 3274 { 3275 const char *start_func, *end_func_p1; 3276 int ch; 3277 symint_t value; 3278 FDR *orig_fdr; 3279 3280 if (cur_file_ptr == (efdr_t *) 0) 3281 { 3282 error (".end directive without a preceding .file directive"); 3283 return; 3284 } 3285 3286 if (cur_proc_ptr == (PDR *) 0) 3287 { 3288 error (".end directive without a preceding .ent directive"); 3289 return; 3290 } 3291 3292 /* Get the function name, skipping whitespace. */ 3293 for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++) 3294 ; 3295 3296 ch = *start_func; 3297 if (!IS_ASM_IDENT (ch)) 3298 { 3299 error (".end directive has no name"); 3300 return; 3301 } 3302 3303 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1) 3304 ; 3305 3306 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 3312 value. */ 3313 3314 orig_fdr = cur_file_ptr->orig_fdr; 3315 value = 0; 3316 if (orig_fdr != (FDR *) 0 && cur_oproc_end != (SYMR *) 0) 3317 value = cur_oproc_end->value; 3318 3319 else 3320 error ("cannot find .end block for %.*s", 3321 (int) (end_func_p1 - start_func), start_func); 3322 3323 (void) add_local_symbol (start_func, end_func_p1, 3324 st_End, sc_Text, 3325 value, 3326 (symint_t) 0); 3327 3328 cur_proc_ptr = cur_oproc_ptr = (PDR *) 0; 3329 } 3330 3331 3332 /* Parse .ent directives. */ 3333 3334 static void 3335 parse_ent (const char *start) 3336 { 3337 const char *start_func, *end_func_p1; 3338 int ch; 3339 3340 if (cur_file_ptr == (efdr_t *) 0) 3341 { 3342 error (".ent directive without a preceding .file directive"); 3343 return; 3344 } 3345 3346 if (cur_proc_ptr != (PDR *) 0) 3347 { 3348 error ("second .ent directive found before .end directive"); 3349 return; 3350 } 3351 3352 for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++) 3353 ; 3354 3355 ch = *start_func; 3356 if (!IS_ASM_IDENT (ch)) 3357 { 3358 error (".ent directive has no name"); 3359 return; 3360 } 3361 3362 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1) 3363 ; 3364 3365 (void) add_procedure (start_func, end_func_p1); 3366 } 3367 3368 3369 /* Parse .file directives. */ 3370 3371 static void 3372 parse_file (const char *start) 3373 { 3374 char *p; 3375 char *start_name, *end_name_p1; 3376 3377 (void) strtol (start, &p, 0); 3378 if (start == p 3379 || (start_name = strchr (p, '"')) == (char *) 0 3380 || (end_name_p1 = strrchr (++start_name, '"')) == (char *) 0) 3381 { 3382 error ("invalid .file directive"); 3383 return; 3384 } 3385 3386 if (cur_proc_ptr != (PDR *) 0) 3387 { 3388 error ("no way to handle .file within .ent/.end section"); 3389 return; 3390 } 3391 3392 add_file (start_name, end_name_p1); 3393 } 3394 3395 3396 /* Make sure the @stabs symbol is emitted. */ 3397 3398 static void 3399 mark_stabs (const char *start ATTRIBUTE_UNUSED) 3400 { 3401 if (!stabs_seen) 3402 { 3403 /* Add a dummy @stabs symbol. */ 3404 stabs_seen = 1; 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)); 3409 3410 } 3411 } 3412 3413 3414 /* Parse .stabs directives. 3415 3416 .stabs directives have five fields: 3417 "string" a string, encoding the type information. 3418 code a numeric code, defined in <stab.h> 3419 0 a zero 3420 0 a zero or line number 3421 value a numeric value or an address. 3422 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 3429 3430 If the value is not relocatable, we transform this into: 3431 iss points as an index into string space 3432 value value 3433 st st_Nil 3434 sc sc_Nil 3435 index code|CODE_MASK 3436 3437 .stabn directives have four fields (string is null): 3438 code a numeric code, defined in <stab.h> 3439 0 a zero 3440 0 a zero or a line number 3441 value a numeric value or an address. */ 3442 3443 static void 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. */ 3447 { 3448 efdr_t *save_file_ptr = cur_file_ptr; 3449 symint_t code; 3450 symint_t value; 3451 char *p; 3452 st_t st; 3453 sc_t sc; 3454 int ch; 3455 3456 if (stabs_seen == 0) 3457 mark_stabs (""); 3458 3459 /* Read code from stabs. */ 3460 if (!ISDIGIT (*rest)) 3461 { 3462 error ("invalid .stabs/.stabn directive, code is non-numeric"); 3463 return; 3464 } 3465 3466 code = strtol (rest, &p, 0); 3467 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. */ 3473 3474 if (code == (int) N_SLINE) 3475 { 3476 SYMR *sym_ptr, dummy_symr; 3477 shash_t *shash_ptr; 3478 3479 /* Skip ,0, */ 3480 if (p[0] != ',' || p[1] != '0' || p[2] != ',' || !ISDIGIT (p[3])) 3481 { 3482 error ("invalid line number .stabs/.stabn directive"); 3483 return; 3484 } 3485 3486 code = strtol (p+3, &p, 0); 3487 ch = *++p; 3488 if (p[-1] != ',' || ISDIGIT (ch) || !IS_ASM_IDENT (ch)) 3489 { 3490 error ("invalid line number .stabs/.stabn directive"); 3491 return; 3492 } 3493 3494 dummy_symr.index = code; 3495 if (dummy_symr.index != code) 3496 { 3497 error ("line number (%lu) for .stabs/.stabn directive cannot fit in index field (20 bits)", 3498 code); 3499 3500 return; 3501 } 3502 3503 shash_ptr = hash_string (p, 3504 strlen (p) - 1, 3505 &orig_str_hash[0], 3506 (symint_t *) 0); 3507 3508 if (shash_ptr == (shash_t *) 0 3509 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0) 3510 { 3511 error ("invalid .stabs/.stabn directive, value not found"); 3512 return; 3513 } 3514 3515 if ((st_t) sym_ptr->st != st_Label) 3516 { 3517 error ("invalid line number .stabs/.stabn directive"); 3518 return; 3519 } 3520 3521 st = st_Label; 3522 sc = (sc_t) sym_ptr->sc; 3523 value = sym_ptr->value; 3524 } 3525 else 3526 { 3527 /* Skip ,<num>,<num>, */ 3528 if (*p++ != ',') 3529 goto failure; 3530 for (; ISDIGIT (*p); p++) 3531 ; 3532 if (*p++ != ',') 3533 goto failure; 3534 for (; ISDIGIT (*p); p++) 3535 ; 3536 if (*p++ != ',') 3537 goto failure; 3538 ch = *p; 3539 if (!IS_ASM_IDENT (ch) && ch != '-') 3540 { 3541 failure: 3542 error ("invalid .stabs/.stabn directive, bad character"); 3543 return; 3544 } 3545 3546 if (ISDIGIT (ch) || ch == '-') 3547 { 3548 st = st_Nil; 3549 sc = sc_Nil; 3550 value = strtol (p, &p, 0); 3551 if (*p != '\n') 3552 { 3553 error ("invalid .stabs/.stabn directive, stuff after numeric value"); 3554 return; 3555 } 3556 } 3557 else if (!IS_ASM_IDENT (ch)) 3558 { 3559 error ("invalid .stabs/.stabn directive, bad character"); 3560 return; 3561 } 3562 else 3563 { 3564 SYMR *sym_ptr; 3565 shash_t *shash_ptr; 3566 const char *start, *end_p1; 3567 3568 start = p; 3569 if ((end_p1 = strchr (start, '+')) == (char *) 0) 3570 { 3571 if ((end_p1 = strchr (start, '-')) == (char *) 0) 3572 end_p1 = start + strlen (start) - 1; 3573 } 3574 3575 shash_ptr = hash_string (start, 3576 end_p1 - start, 3577 &orig_str_hash[0], 3578 (symint_t *) 0); 3579 3580 if (shash_ptr == (shash_t *) 0 3581 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0) 3582 { 3583 shash_ptr = hash_string (start, 3584 end_p1 - start, 3585 &ext_str_hash[0], 3586 (symint_t *) 0); 3587 3588 if (shash_ptr == (shash_t *) 0 3589 || shash_ptr->esym_ptr == (EXTR *) 0) 3590 { 3591 error ("invalid .stabs/.stabn directive, value not found"); 3592 return; 3593 } 3594 else 3595 sym_ptr = &(shash_ptr->esym_ptr->asym); 3596 } 3597 3598 /* Traditionally, N_LBRAC and N_RBRAC are *not* relocated. */ 3599 if (code == (int) N_LBRAC || code == (int) N_RBRAC) 3600 { 3601 sc = (sc_t) scNil; 3602 st = (st_t) stNil; 3603 } 3604 else 3605 { 3606 sc = (sc_t) sym_ptr->sc; 3607 st = (st_t) sym_ptr->st; 3608 } 3609 value = sym_ptr->value; 3610 3611 ch = *end_p1++; 3612 if (ch != '\n') 3613 { 3614 if (((!ISDIGIT (*end_p1)) && (*end_p1 != '-')) 3615 || ((ch != '+') && (ch != '-'))) 3616 { 3617 error ("invalid .stabs/.stabn directive, badly formed value"); 3618 return; 3619 } 3620 if (ch == '+') 3621 value += strtol (end_p1, &p, 0); 3622 else if (ch == '-') 3623 value -= strtol (end_p1, &p, 0); 3624 3625 if (*p != '\n') 3626 { 3627 error ("invalid .stabs/.stabn directive, stuff after numeric value"); 3628 return; 3629 } 3630 } 3631 } 3632 code = MIPS_MARK_STAB (code); 3633 } 3634 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; 3638 } 3639 3640 3641 static void 3642 parse_stabs (const char *start) 3643 { 3644 const char *end = strchr (start+1, '"'); 3645 3646 if (*start != '"' || end == (const char *) 0 || end[1] != ',') 3647 { 3648 error ("invalid .stabs directive, no string"); 3649 return; 3650 } 3651 3652 parse_stabs_common (start+1, end, end+2); 3653 } 3654 3655 3656 static void 3657 parse_stabn (const char *start) 3658 { 3659 parse_stabs_common ((const char *) 0, (const char *) 0, start); 3660 } 3661 3662 3663 /* Parse the input file, and write the lines to the output file 3664 if needed. */ 3665 3666 static void 3667 parse_input (void) 3668 { 3669 char *p; 3670 size_t i; 3671 thead_t *ptag_head; 3672 tag_t *ptag; 3673 tag_t *ptag_next; 3674 3675 if (debug) 3676 fprintf (stderr, "\tinput\n"); 3677 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; 3684 3685 while ((p = read_line ()) != (char *) 0) 3686 { 3687 /* Skip leading blanks. */ 3688 while (ISSPACE ((unsigned char)*p)) 3689 p++; 3690 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]))) 3695 { 3696 p += pseudo_ops[i].len; /* skip to first argument */ 3697 while (ISSPACE ((unsigned char)*p)) 3698 p++; 3699 3700 (*pseudo_ops[i].func)( p ); 3701 break; 3702 } 3703 } 3704 3705 /* Process any tags at global level. */ 3706 ptag_head = cur_tag_head; 3707 cur_tag_head = ptag_head->prev; 3708 3709 for (ptag = ptag_head->first_tag; 3710 ptag != (tag_t *) 0; 3711 ptag = ptag_next) 3712 { 3713 if (ptag->forward_ref != (forward_t *) 0) 3714 add_unknown_tag (ptag); 3715 3716 ptag_next = ptag->same_block; 3717 ptag->hash_ptr->tag_ptr = ptag->same_name; 3718 free_tag (ptag); 3719 } 3720 3721 free_thead (ptag_head); 3722 3723 } 3724 3725 3726 /* Update the global headers with the final offsets in preparation 3727 to write out the .T file. */ 3728 3729 static void 3730 update_headers (void) 3731 { 3732 symint_t i; 3733 efdr_t *file_ptr; 3734 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; 3739 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; 3749 3750 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. */ 3754 3755 for (file_ptr = first_file; 3756 file_ptr != (efdr_t *) 0; 3757 file_ptr = file_ptr->next_file) 3758 { 3759 SYMR *sym_start; 3760 SYMR *sym; 3761 SYMR *sym_end_p1; 3762 FDR *fd_ptr = file_ptr->orig_fdr; 3763 3764 cur_file_ptr = file_ptr; 3765 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++) 3773 { 3774 if ((st_t) sym->st == st_Static) 3775 { 3776 char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss); 3777 size_t len = strlen (str); 3778 shash_t *hash_ptr; 3779 3780 /* Ignore internal labels. */ 3781 if (str[0] == '$' && str[1] == 'L') 3782 continue; 3783 hash_ptr = hash_string (str, 3784 (ptrdiff_t) len, 3785 &file_ptr->shash_head[0], 3786 (symint_t *) 0); 3787 if (hash_ptr == (shash_t *) 0) 3788 { 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); 3793 } 3794 } 3795 } 3796 (void) add_local_symbol ((const char *) 0, (const char *) 0, 3797 st_End, sc_Text, 3798 (symint_t) 0, 3799 (symint_t) 0); 3800 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; 3804 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; 3808 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; 3812 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; 3816 } 3817 3818 /* Align ecoff symbol tables to avoid OSF1/1.3 nm complaints. */ 3819 #define ALIGN_SYMTABLE_OFFSET(OFFSET) (((OFFSET) + 7) & ~7) 3820 3821 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3822 i = WORD_ALIGN (symbolic_header.cbLine); /* line numbers */ 3823 if (i > 0) 3824 { 3825 symbolic_header.cbLineOffset = file_offset; 3826 file_offset += i; 3827 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3828 } 3829 3830 i = symbolic_header.ioptMax; /* optimization symbols */ 3831 if (((long) i) > 0) 3832 { 3833 symbolic_header.cbOptOffset = file_offset; 3834 file_offset += i * sizeof (OPTR); 3835 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3836 } 3837 3838 i = symbolic_header.idnMax; /* dense numbers */ 3839 if (i > 0) 3840 { 3841 symbolic_header.cbDnOffset = file_offset; 3842 file_offset += i * sizeof (DNR); 3843 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3844 } 3845 3846 i = symbolic_header.ipdMax; /* procedure tables */ 3847 if (i > 0) 3848 { 3849 symbolic_header.cbPdOffset = file_offset; 3850 file_offset += i * sizeof (PDR); 3851 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3852 } 3853 3854 i = symbolic_header.isymMax; /* local symbols */ 3855 if (i > 0) 3856 { 3857 symbolic_header.cbSymOffset = file_offset; 3858 file_offset += i * sizeof (SYMR); 3859 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3860 } 3861 3862 i = symbolic_header.iauxMax; /* aux syms. */ 3863 if (i > 0) 3864 { 3865 symbolic_header.cbAuxOffset = file_offset; 3866 file_offset += i * sizeof (TIR); 3867 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3868 } 3869 3870 i = WORD_ALIGN (symbolic_header.issMax); /* local strings */ 3871 if (i > 0) 3872 { 3873 symbolic_header.cbSsOffset = file_offset; 3874 file_offset += i; 3875 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3876 } 3877 3878 i = WORD_ALIGN (symbolic_header.issExtMax); /* external strings */ 3879 if (i > 0) 3880 { 3881 symbolic_header.cbSsExtOffset = file_offset; 3882 file_offset += i; 3883 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3884 } 3885 3886 i = symbolic_header.ifdMax; /* file tables */ 3887 if (i > 0) 3888 { 3889 symbolic_header.cbFdOffset = file_offset; 3890 file_offset += i * sizeof (FDR); 3891 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3892 } 3893 3894 i = symbolic_header.crfd; /* relative file descriptors */ 3895 if (i > 0) 3896 { 3897 symbolic_header.cbRfdOffset = file_offset; 3898 file_offset += i * sizeof (symint_t); 3899 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3900 } 3901 3902 i = symbolic_header.iextMax; /* external symbols */ 3903 if (i > 0) 3904 { 3905 symbolic_header.cbExtOffset = file_offset; 3906 file_offset += i * sizeof (EXTR); 3907 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset); 3908 } 3909 } 3910 3911 3912 /* Write out a varray at a given location. */ 3913 3914 static void 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 */ 3918 { 3919 int num_write, sys_write; 3920 vlinks_t *ptr; 3921 3922 if (vp->num_allocated == 0) 3923 return; 3924 3925 if (debug) 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); 3930 3931 if (file_offset != (unsigned long) offset 3932 && fseek (object_stream, (long) offset, SEEK_SET) < 0) 3933 pfatal_with_name (object_name); 3934 3935 for (ptr = vp->first; ptr != (vlinks_t *) 0; ptr = ptr->next) 3936 { 3937 num_write = (ptr->next == (vlinks_t *) 0) 3938 ? vp->objects_last_page * vp->object_size 3939 : vp->objects_per_page * vp->object_size; 3940 3941 sys_write = fwrite (ptr->datum, 1, num_write, object_stream); 3942 if (sys_write <= 0) 3943 pfatal_with_name (object_name); 3944 3945 else if (sys_write != num_write) 3946 fatal ("wrote %d bytes to %s, system returned %d", 3947 num_write, 3948 object_name, 3949 sys_write); 3950 3951 file_offset += num_write; 3952 } 3953 } 3954 3955 3956 /* Write out the symbol table in the object file. */ 3957 3958 static void 3959 write_object (void) 3960 { 3961 int sys_write; 3962 efdr_t *file_ptr; 3963 off_t offset; 3964 3965 if (debug) 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"); 3970 3971 sys_write = fwrite (&symbolic_header, 3972 1, 3973 sizeof (symbolic_header), 3974 object_stream); 3975 3976 if (sys_write < 0) 3977 pfatal_with_name (object_name); 3978 3979 else if (sys_write != sizeof (symbolic_header)) 3980 fatal ("wrote %d bytes to %s, system returned %d", 3981 (int) sizeof (symbolic_header), 3982 object_name, 3983 sys_write); 3984 3985 3986 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr; 3987 3988 if (symbolic_header.cbLine > 0) /* line numbers */ 3989 { 3990 long sys_write; 3991 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); 3995 3996 if (debug) 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"); 4001 4002 sys_write = fwrite (orig_linenum, 4003 1, 4004 symbolic_header.cbLine, 4005 object_stream); 4006 4007 if (sys_write <= 0) 4008 pfatal_with_name (object_name); 4009 4010 else if (sys_write != symbolic_header.cbLine) 4011 fatal ("wrote %ld bytes to %s, system returned %ld", 4012 (long) symbolic_header.cbLine, 4013 object_name, 4014 sys_write); 4015 4016 file_offset = symbolic_header.cbLineOffset + symbolic_header.cbLine; 4017 } 4018 4019 if (symbolic_header.ioptMax > 0) /* optimization symbols */ 4020 { 4021 long sys_write; 4022 long num_write = symbolic_header.ioptMax * sizeof (OPTR); 4023 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); 4027 4028 if (debug) 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"); 4033 4034 sys_write = fwrite (orig_opt_syms, 4035 1, 4036 num_write, 4037 object_stream); 4038 4039 if (sys_write <= 0) 4040 pfatal_with_name (object_name); 4041 4042 else if (sys_write != num_write) 4043 fatal ("wrote %ld bytes to %s, system returned %ld", 4044 num_write, 4045 object_name, 4046 sys_write); 4047 4048 file_offset = symbolic_header.cbOptOffset + num_write; 4049 } 4050 4051 if (symbolic_header.idnMax > 0) /* dense numbers */ 4052 write_varray (&dense_num, (off_t) symbolic_header.cbDnOffset, "Dense numbers"); 4053 4054 if (symbolic_header.ipdMax > 0) /* procedure tables */ 4055 { 4056 offset = symbolic_header.cbPdOffset; 4057 for (file_ptr = first_file; 4058 file_ptr != (efdr_t *) 0; 4059 file_ptr = file_ptr->next_file) 4060 { 4061 write_varray (&file_ptr->procs, offset, "Procedure tables"); 4062 offset = file_offset; 4063 } 4064 } 4065 4066 if (symbolic_header.isymMax > 0) /* local symbols */ 4067 { 4068 offset = symbolic_header.cbSymOffset; 4069 for (file_ptr = first_file; 4070 file_ptr != (efdr_t *) 0; 4071 file_ptr = file_ptr->next_file) 4072 { 4073 write_varray (&file_ptr->symbols, offset, "Local symbols"); 4074 offset = file_offset; 4075 } 4076 } 4077 4078 if (symbolic_header.iauxMax > 0) /* aux symbols */ 4079 { 4080 offset = symbolic_header.cbAuxOffset; 4081 for (file_ptr = first_file; 4082 file_ptr != (efdr_t *) 0; 4083 file_ptr = file_ptr->next_file) 4084 { 4085 write_varray (&file_ptr->aux_syms, offset, "Aux. symbols"); 4086 offset = file_offset; 4087 } 4088 } 4089 4090 if (symbolic_header.issMax > 0) /* local strings */ 4091 { 4092 offset = symbolic_header.cbSsOffset; 4093 for (file_ptr = first_file; 4094 file_ptr != (efdr_t *) 0; 4095 file_ptr = file_ptr->next_file) 4096 { 4097 write_varray (&file_ptr->strings, offset, "Local strings"); 4098 offset = file_offset; 4099 } 4100 } 4101 4102 if (symbolic_header.issExtMax > 0) /* external strings */ 4103 write_varray (&ext_strings, symbolic_header.cbSsExtOffset, "External strings"); 4104 4105 if (symbolic_header.ifdMax > 0) /* file tables */ 4106 { 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); 4111 4112 file_offset = offset; 4113 for (file_ptr = first_file; 4114 file_ptr != (efdr_t *) 0; 4115 file_ptr = file_ptr->next_file) 4116 { 4117 if (debug) 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"); 4122 4123 sys_write = fwrite (&file_ptr->fdr, 4124 1, 4125 sizeof (FDR), 4126 object_stream); 4127 4128 if (sys_write < 0) 4129 pfatal_with_name (object_name); 4130 4131 else if (sys_write != sizeof (FDR)) 4132 fatal ("wrote %d bytes to %s, system returned %d", 4133 (int) sizeof (FDR), 4134 object_name, 4135 sys_write); 4136 4137 file_offset = offset += sizeof (FDR); 4138 } 4139 } 4140 4141 if (symbolic_header.crfd > 0) /* relative file descriptors */ 4142 { 4143 long sys_write; 4144 symint_t num_write = symbolic_header.crfd * sizeof (symint_t); 4145 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); 4149 4150 if (debug) 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"); 4155 4156 sys_write = fwrite (orig_rfds, 4157 1, 4158 num_write, 4159 object_stream); 4160 4161 if (sys_write <= 0) 4162 pfatal_with_name (object_name); 4163 4164 else if (sys_write != (long) num_write) 4165 fatal ("wrote %lu bytes to %s, system returned %ld", 4166 num_write, 4167 object_name, 4168 sys_write); 4169 4170 file_offset = symbolic_header.cbRfdOffset + num_write; 4171 } 4172 4173 if (symbolic_header.issExtMax > 0) /* external symbols */ 4174 write_varray (&ext_symbols, (off_t) symbolic_header.cbExtOffset, "External symbols"); 4175 4176 if (fclose (object_stream) != 0) 4177 pfatal_with_name (object_name); 4178 } 4179 4180 4181 /* Read some bytes at a specified location, and return a pointer. */ 4182 4183 static page_t * 4184 read_seek (size_t size, /* # bytes to read */ 4185 off_t offset, /* offset to read at */ 4186 const char *str) /* name for tracing */ 4187 { 4188 page_t *ptr; 4189 long sys_read = 0; 4190 4191 if (size == 0) /* nothing to read */ 4192 return (page_t *) 0; 4193 4194 if (debug) 4195 fprintf (stderr, 4196 "\trseek\tsize = %7lu, offset = %7lu, currently at %7lu, %s\n", 4197 (unsigned long) size, (unsigned long) offset, file_offset, str); 4198 4199 #ifndef MALLOC_CHECK 4200 ptr = allocate_multiple_pages ((size + PAGE_USIZE - 1) / PAGE_USIZE); 4201 #else 4202 ptr = xcalloc (1, size); 4203 #endif 4204 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) 4208 { 4209 symint_t difference = offset - file_offset; 4210 4211 if (difference < 8) 4212 { 4213 char small_buffer[8]; 4214 4215 sys_read = fread (small_buffer, 1, difference, obj_in_stream); 4216 if (sys_read <= 0) 4217 pfatal_with_name (obj_in_name); 4218 4219 if ((symint_t) sys_read != difference) 4220 fatal ("wanted to read %lu bytes from %s, system returned %ld", 4221 (unsigned long) size, 4222 obj_in_name, 4223 sys_read); 4224 } 4225 else if (fseek (obj_in_stream, offset, SEEK_SET) < 0) 4226 pfatal_with_name (obj_in_name); 4227 } 4228 4229 sys_read = fread (ptr, 1, size, obj_in_stream); 4230 if (sys_read <= 0) 4231 pfatal_with_name (obj_in_name); 4232 4233 if (sys_read != (long) size) 4234 fatal ("wanted to read %lu bytes from %s, system returned %ld", 4235 (unsigned long) size, 4236 obj_in_name, 4237 sys_read); 4238 4239 file_offset = offset + size; 4240 4241 if (file_offset > max_file_offset) 4242 max_file_offset = file_offset; 4243 4244 return ptr; 4245 } 4246 4247 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 4250 symbol table. */ 4251 4252 static void 4253 copy_object (void) 4254 { 4255 char buffer[ PAGE_SIZE ]; 4256 int sys_read; 4257 int remaining; 4258 int num_write; 4259 int sys_write; 4260 int fd, es; 4261 int delete_ifd = 0; 4262 int *remap_file_number; 4263 struct stat stat_buf; 4264 4265 if (debug) 4266 fprintf (stderr, "\tcopy\n"); 4267 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); 4271 4272 sys_read = fread (&orig_file_header, 4273 1, 4274 sizeof (struct filehdr), 4275 obj_in_stream); 4276 4277 if (sys_read < 0) 4278 pfatal_with_name (obj_in_name); 4279 4280 else if (sys_read == 0 && feof (obj_in_stream)) 4281 return; /* create a .T file sans file header */ 4282 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), 4286 obj_in_name, 4287 sys_read); 4288 4289 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)); 4293 4294 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); 4298 4299 sys_read = fread (&orig_sym_hdr, 4300 1, 4301 sizeof (orig_sym_hdr), 4302 obj_in_stream); 4303 4304 if (sys_read < 0) 4305 pfatal_with_name (object_name); 4306 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), 4310 obj_in_name, 4311 sys_read); 4312 4313 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. 4317 4318 For simplicity sake, round each read up to a page boundary, 4319 we may want to revisit this later.... */ 4320 4321 file_offset = orig_file_header.f_symptr + sizeof (struct filehdr); 4322 4323 if (orig_sym_hdr.cbLine > 0) /* line numbers */ 4324 orig_linenum = (char *) read_seek (orig_sym_hdr.cbLine, 4325 orig_sym_hdr.cbLineOffset, 4326 "Line numbers"); 4327 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"); 4332 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, 4336 "Local symbols"); 4337 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, 4341 "Aux. symbols"); 4342 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, 4346 "Local strings"); 4347 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"); 4352 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, 4356 "File tables"); 4357 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"); 4362 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"); 4367 4368 if (orig_sym_hdr.idnMax > 0) /* dense numbers */ 4369 { 4370 orig_dense = (DNR *) read_seek (orig_sym_hdr.idnMax * sizeof (DNR), 4371 orig_sym_hdr.cbDnOffset, 4372 "Dense numbers"); 4373 4374 add_bytes (&dense_num, (char *) orig_dense, orig_sym_hdr.idnMax); 4375 } 4376 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"); 4381 4382 4383 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", 4387 max_file_offset, 4388 (long) stat_buf.st_size); 4389 4390 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) 4396 { 4397 char *filename = orig_local_strs + (orig_files->issBase + orig_files->rss); 4398 char *suffix = strrchr (filename, '.'); 4399 4400 if (suffix != (char *) 0 && strcmp (suffix, ".s") == 0) 4401 delete_ifd = 1; 4402 } 4403 4404 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). */ 4408 4409 remap_file_number = (int *) alloca (sizeof (int) * orig_sym_hdr.ifdMax); 4410 4411 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++) 4412 { 4413 FDR *fd_ptr = ORIG_FILES (fd); 4414 char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss); 4415 4416 /* file support itself. */ 4417 add_file (filename, filename + strlen (filename)); 4418 remap_file_number[fd] = cur_file_ptr->file_index; 4419 } 4420 4421 if (delete_ifd > 0) /* just in case */ 4422 remap_file_number[0] = remap_file_number[1]; 4423 4424 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. */ 4432 4433 if (debug) 4434 fprintf (stderr, "\tehash\n"); 4435 4436 for (es = 0; es < orig_sym_hdr.iextMax; es++) 4437 { 4438 EXTR *eptr = orig_ext_syms + es; 4439 int ifd = eptr->ifd; 4440 4441 (void) add_ext_symbol (eptr, ((long) ifd < orig_sym_hdr.ifdMax) 4442 ? remap_file_number[ ifd ] : ifd ); 4443 } 4444 4445 4446 /* For each of the files in the object file, copy the symbols, and such 4447 into the varrays for the new object file. */ 4448 4449 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++) 4450 { 4451 FDR *fd_ptr = ORIG_FILES (fd); 4452 char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss); 4453 SYMR *sym_start; 4454 SYMR *sym; 4455 SYMR *sym_end_p1; 4456 PDR *proc_start; 4457 PDR *proc; 4458 PDR *proc_end_p1; 4459 4460 /* file support itself. */ 4461 add_file (filename, filename + strlen (filename)); 4462 cur_file_ptr->orig_fdr = fd_ptr; 4463 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; 4475 4476 if (debug) 4477 fprintf (stderr, "\thash\tstart, filename %s\n", filename); 4478 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 4481 their values. */ 4482 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++) 4486 { 4487 switch ((st_t) sym->st) 4488 { 4489 default: 4490 break; 4491 4492 case st_Global: 4493 case st_Static: 4494 case st_Label: 4495 case st_Proc: 4496 case st_StaticProc: 4497 { 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, 4502 (ptrdiff_t) len, 4503 &orig_str_hash[0], 4504 &hash_index); 4505 4506 if (shash_ptr != (shash_t *) 0) 4507 error ("internal error, %s is already in original symbol table", str); 4508 4509 else 4510 { 4511 shash_ptr = allocate_shash (); 4512 shash_ptr->next = orig_str_hash[hash_index]; 4513 orig_str_hash[hash_index] = shash_ptr; 4514 4515 shash_ptr->len = len; 4516 shash_ptr->indx = indexNil; 4517 shash_ptr->string = str; 4518 shash_ptr->sym_ptr = sym; 4519 } 4520 } 4521 break; 4522 4523 case st_End: 4524 if ((sc_t) sym->sc == sc_Text) 4525 { 4526 char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss); 4527 4528 if (*str != '\0') 4529 { 4530 size_t len = strlen (str); 4531 shash_t *shash_ptr = hash_string (str, 4532 (ptrdiff_t) len, 4533 &orig_str_hash[0], 4534 (symint_t *) 0); 4535 4536 if (shash_ptr != (shash_t *) 0) 4537 shash_ptr->end_ptr = sym; 4538 } 4539 } 4540 break; 4541 4542 } 4543 } 4544 4545 if (debug) 4546 { 4547 fprintf (stderr, "\thash\tdone, filename %s\n", filename); 4548 fprintf (stderr, "\tproc\tstart, filename %s\n", filename); 4549 } 4550 4551 /* Go through each of the procedures in this file, and add the 4552 procedure pointer to the hash entry for the given name. */ 4553 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++) 4557 { 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, 4562 (ptrdiff_t) len, 4563 &orig_str_hash[0], 4564 (symint_t *) 0); 4565 4566 if (shash_ptr == (shash_t *) 0) 4567 error ("internal error, function %s is not in original symbol table", str); 4568 4569 else 4570 shash_ptr->proc_ptr = proc; 4571 } 4572 4573 if (debug) 4574 fprintf (stderr, "\tproc\tdone, filename %s\n", filename); 4575 4576 } 4577 cur_file_ptr = first_file; 4578 4579 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.... */ 4583 4584 if (fseek (obj_in_stream, (long) 0, SEEK_SET) != 0) 4585 pfatal_with_name (obj_in_name); 4586 4587 if (fseek (object_stream, (long) 0, SEEK_SET) != 0) 4588 pfatal_with_name (object_name); 4589 4590 for (remaining = orig_file_header.f_symptr; 4591 remaining > 0; 4592 remaining -= num_write) 4593 { 4594 num_write 4595 = (remaining <= (int) sizeof (buffer)) 4596 ? remaining : (int) sizeof (buffer); 4597 sys_read = fread (buffer, 1, num_write, obj_in_stream); 4598 if (sys_read <= 0) 4599 pfatal_with_name (obj_in_name); 4600 4601 else if (sys_read != num_write) 4602 fatal ("wanted to read %d bytes from %s, system returned %d", 4603 num_write, 4604 obj_in_name, 4605 sys_read); 4606 4607 sys_write = fwrite (buffer, 1, num_write, object_stream); 4608 if (sys_write <= 0) 4609 pfatal_with_name (object_name); 4610 4611 else if (sys_write != num_write) 4612 fatal ("wrote %d bytes to %s, system returned %d", 4613 num_write, 4614 object_name, 4615 sys_write); 4616 } 4617 } 4618 4619 4620 /* Ye olde main program. */ 4621 4622 extern int main (int, char **); 4623 4624 int 4625 main (int argc, char **argv) 4626 { 4627 int iflag = 0; 4628 char *num_end; 4629 int option; 4630 int i; 4631 4632 progname = lbasename (argv[0]); 4633 4634 (void) signal (SIGSEGV, catch_signal); 4635 (void) signal (SIGBUS, catch_signal); 4636 (void) signal (SIGABRT, catch_signal); 4637 4638 #ifndef lint 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), 4642 (int) PAGE_USIZE); 4643 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), 4647 (int) PAGE_USIZE); 4648 4649 #endif 4650 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"; 4660 4661 int_type_info = type_info_init; 4662 int_type_info.basic_type = bt_Int; 4663 4664 void_type_info = type_info_init; 4665 void_type_info.basic_type = bt_Void; 4666 4667 while ((option = getopt_long (argc, argv, "d:i:I:o:v", options, NULL)) != -1) 4668 switch (option) 4669 { 4670 default: 4671 had_errors++; 4672 break; 4673 4674 case 'd': 4675 debug = strtol (optarg, &num_end, 0); 4676 if ((unsigned) debug > 4 || num_end == optarg) 4677 had_errors++; 4678 4679 break; 4680 4681 case 'I': 4682 if (rename_output || obj_in_name != (char *) 0) 4683 had_errors++; 4684 else 4685 rename_output = 1; 4686 4687 /* Fall through to 'i' case. */ 4688 4689 case 'i': 4690 if (obj_in_name == (char *) 0) 4691 { 4692 obj_in_name = optarg; 4693 iflag++; 4694 } 4695 else 4696 had_errors++; 4697 break; 4698 4699 case 'o': 4700 if (object_name == (char *) 0) 4701 object_name = optarg; 4702 else 4703 had_errors++; 4704 break; 4705 4706 case 'v': 4707 verbose++; 4708 break; 4709 4710 case 'V': 4711 version++; 4712 break; 4713 } 4714 4715 if (version) 4716 { 4717 printf (_("mips-tfile %s%s\n"), pkgversion_string, version_string); 4718 fputs ("Copyright (C) 2012 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"), 4721 stdout); 4722 exit (0); 4723 } 4724 4725 if (obj_in_name == (char *) 0 && optind <= argc - 2) 4726 obj_in_name = argv[--argc]; 4727 4728 if (object_name == (char *) 0 && optind <= argc - 2) 4729 object_name = argv[--argc]; 4730 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) 4735 { 4736 obj_in_name = object_name; 4737 delete_input = 1; 4738 } 4739 4740 if (optind != argc - 1) 4741 had_errors++; 4742 4743 if (verbose || had_errors) 4744 fprintf (stderr, _("mips-tfile (GCC) %s\n"), version_string); 4745 4746 if (object_name == (char *) 0 || had_errors) 4747 { 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")); 4758 return 1; 4759 } 4760 4761 if (obj_in_name == (char *) 0) 4762 obj_in_name = object_name; 4763 4764 if (rename_output && rename (object_name, obj_in_name) != 0) 4765 { 4766 char *buffer = (char *) allocate_multiple_pages (4); 4767 int len; 4768 int len2; 4769 int in_fd; 4770 int out_fd; 4771 4772 /* Rename failed, copy input file */ 4773 in_fd = open (object_name, O_RDONLY, 0666); 4774 if (in_fd < 0) 4775 pfatal_with_name (object_name); 4776 4777 out_fd = open (obj_in_name, O_WRONLY | O_CREAT | O_TRUNC, 0666); 4778 if (out_fd < 0) 4779 pfatal_with_name (obj_in_name); 4780 4781 while ((len = read (in_fd, buffer, 4*PAGE_SIZE)) > 0) 4782 { 4783 len2 = write (out_fd, buffer, len); 4784 if (len2 < 0) 4785 pfatal_with_name (object_name); 4786 4787 if (len != len2) 4788 fatal ("wrote %d bytes to %s, expected to write %d", len2, obj_in_name, len); 4789 } 4790 4791 free_multiple_pages ((page_t *) buffer, 4); 4792 4793 if (len < 0) 4794 pfatal_with_name (object_name); 4795 4796 if (close (in_fd) < 0) 4797 pfatal_with_name (object_name); 4798 4799 if (close (out_fd) < 0) 4800 pfatal_with_name (obj_in_name); 4801 } 4802 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); 4808 4809 if (delete_input && unlink (obj_in_name) != 0) 4810 pfatal_with_name (obj_in_name); 4811 4812 object_stream = fopen (object_name, "w"); 4813 if (object_stream == (FILE *) 0) 4814 pfatal_with_name (object_name); 4815 4816 if (strcmp (argv[optind], "-") != 0) 4817 { 4818 input_name = argv[optind]; 4819 if (freopen (argv[optind], "r", stdin) != stdin) 4820 pfatal_with_name (argv[optind]); 4821 } 4822 4823 copy_object (); /* scan & copy object file */ 4824 parse_input (); /* scan all of input */ 4825 4826 update_headers (); /* write out tfile */ 4827 write_object (); 4828 4829 if (debug) 4830 { 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) 4834 { 4835 fprintf (stderr, 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); 4841 } 4842 } 4843 4844 return (had_errors) ? 1 : 0; 4845 } 4846 4847 4848 /* Catch a signal and exit without dumping core. */ 4849 4850 static void 4851 catch_signal (int signum) 4852 { 4853 (void) signal (signum, SIG_DFL); /* just in case... */ 4854 fatal ("%s", strsignal (signum)); 4855 } 4856 4857 /* Print a fatal error message. NAME is the text. 4858 Also include a system error message based on `errno'. */ 4859 4860 void 4861 pfatal_with_name (const char *msg) 4862 { 4863 int save_errno = errno; /* just in case.... */ 4864 if (line_number > 0) 4865 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number); 4866 else 4867 fprintf (stderr, "%s:", progname); 4868 4869 errno = save_errno; 4870 if (errno == 0) 4871 fprintf (stderr, "[errno = 0] %s\n", msg); 4872 else 4873 perror (msg); 4874 4875 exit (1); 4876 } 4877 4878 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. */ 4882 4883 static int 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 */ 4888 { 4889 if (indx < max) /* just in case */ 4890 return 0; 4891 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); 4894 4895 exit (1); 4896 return 0; /* turn off warning messages */ 4897 } 4898 4899 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. */ 4903 4904 #ifndef MALLOC_CHECK 4905 #ifdef USE_MALLOC 4906 4907 static page_t * 4908 allocate_cluster (size_t npages) 4909 { 4910 page_t *value = xcalloc (npages, PAGE_USIZE); 4911 4912 if (debug > 3) 4913 fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value); 4914 4915 return value; 4916 } 4917 4918 #else /* USE_MALLOC */ 4919 4920 static page_t * 4921 allocate_cluster (size_t npages) 4922 { 4923 page_t *ptr = (page_t *) sbrk (0); /* current sbreak */ 4924 unsigned long offset = ((unsigned long) ptr) & (PAGE_SIZE - 1); 4925 4926 if (offset != 0) /* align to a page boundary */ 4927 { 4928 if (sbrk (PAGE_USIZE - offset) == (char *)-1) 4929 pfatal_with_name ("allocate_cluster"); 4930 4931 ptr = (page_t *) (((char *) ptr) + PAGE_SIZE - offset); 4932 } 4933 4934 if (sbrk (npages * PAGE_USIZE) == (char *) -1) 4935 pfatal_with_name ("allocate_cluster"); 4936 4937 if (debug > 3) 4938 fprintf (stderr, "\talloc\tnpages = %lu, value = " HOST_PTR_PRINTF "\n", 4939 (unsigned long) npages, (void *) ptr); 4940 4941 return ptr; 4942 } 4943 4944 #endif /* USE_MALLOC */ 4945 4946 4947 static page_t *cluster_ptr = NULL; 4948 static unsigned pages_left = 0; 4949 4950 #endif /* MALLOC_CHECK */ 4951 4952 4953 /* Allocate some pages (which is initialized to 0). */ 4954 4955 static page_t * 4956 allocate_multiple_pages (size_t npages) 4957 { 4958 #ifndef MALLOC_CHECK 4959 if (pages_left == 0 && npages < MAX_CLUSTER_PAGES) 4960 { 4961 pages_left = MAX_CLUSTER_PAGES; 4962 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES); 4963 } 4964 4965 if (npages <= pages_left) 4966 { 4967 page_t *ptr = cluster_ptr; 4968 cluster_ptr += npages; 4969 pages_left -= npages; 4970 return ptr; 4971 } 4972 4973 return allocate_cluster (npages); 4974 4975 #else /* MALLOC_CHECK */ 4976 return xcalloc (npages, PAGE_SIZE); 4977 4978 #endif /* MALLOC_CHECK */ 4979 } 4980 4981 4982 /* Release some pages. */ 4983 4984 static void 4985 free_multiple_pages (page_t *page_ptr, size_t npages) 4986 { 4987 #ifndef MALLOC_CHECK 4988 if (pages_left == 0) 4989 { 4990 cluster_ptr = page_ptr; 4991 pages_left = npages; 4992 } 4993 4994 else if ((page_ptr + npages) == cluster_ptr) 4995 { 4996 cluster_ptr -= npages; 4997 pages_left += npages; 4998 } 4999 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. */ 5003 5004 #else /* MALLOC_CHECK */ 5005 free (page_ptr); 5006 5007 #endif /* MALLOC_CHECK */ 5008 } 5009 5010 5011 /* Allocate one page (which is initialized to 0). */ 5012 5013 static page_t * 5014 allocate_page (void) 5015 { 5016 #ifndef MALLOC_CHECK 5017 if (pages_left == 0) 5018 { 5019 pages_left = MAX_CLUSTER_PAGES; 5020 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES); 5021 } 5022 5023 pages_left--; 5024 return cluster_ptr++; 5025 5026 #else /* MALLOC_CHECK */ 5027 return xcalloc (1, PAGE_SIZE); 5028 5029 #endif /* MALLOC_CHECK */ 5030 } 5031 5032 5033 /* Allocate scoping information. */ 5034 5035 static scope_t * 5036 allocate_scope (void) 5037 { 5038 scope_t *ptr; 5039 static scope_t initial_scope; 5040 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; 5045 5046 else 5047 { 5048 int unallocated = alloc_counts[ (int) alloc_type_scope ].unallocated; 5049 page_t *cur_page = alloc_counts[ (int) alloc_type_scope ].cur_page; 5050 5051 if (unallocated == 0) 5052 { 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++; 5056 } 5057 5058 ptr = &cur_page->scope[ --unallocated ]; 5059 alloc_counts[ (int) alloc_type_scope ].unallocated = unallocated; 5060 } 5061 5062 #else 5063 ptr = xmalloc (sizeof (scope_t)); 5064 5065 #endif 5066 5067 alloc_counts[ (int) alloc_type_scope ].total_alloc++; 5068 *ptr = initial_scope; 5069 return ptr; 5070 } 5071 5072 /* Free scoping information. */ 5073 5074 static void 5075 free_scope (scope_t *ptr) 5076 { 5077 alloc_counts[ (int) alloc_type_scope ].total_free++; 5078 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; 5082 5083 #else 5084 free (ptr); 5085 #endif 5086 5087 } 5088 5089 5090 /* Allocate links for pages in a virtual array. */ 5091 5092 static vlinks_t * 5093 allocate_vlinks (void) 5094 { 5095 vlinks_t *ptr; 5096 static vlinks_t initial_vlinks; 5097 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; 5101 5102 if (unallocated == 0) 5103 { 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++; 5107 } 5108 5109 ptr = &cur_page->vlinks[ --unallocated ]; 5110 alloc_counts[ (int) alloc_type_vlinks ].unallocated = unallocated; 5111 5112 #else 5113 ptr = xmalloc (sizeof (vlinks_t)); 5114 5115 #endif 5116 5117 alloc_counts[ (int) alloc_type_vlinks ].total_alloc++; 5118 *ptr = initial_vlinks; 5119 return ptr; 5120 } 5121 5122 5123 /* Allocate string hash buckets. */ 5124 5125 static shash_t * 5126 allocate_shash (void) 5127 { 5128 shash_t *ptr; 5129 static shash_t initial_shash; 5130 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; 5134 5135 if (unallocated == 0) 5136 { 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++; 5140 } 5141 5142 ptr = &cur_page->shash[ --unallocated ]; 5143 alloc_counts[ (int) alloc_type_shash ].unallocated = unallocated; 5144 5145 #else 5146 ptr = xmalloc (sizeof (shash_t)); 5147 5148 #endif 5149 5150 alloc_counts[ (int) alloc_type_shash ].total_alloc++; 5151 *ptr = initial_shash; 5152 return ptr; 5153 } 5154 5155 5156 /* Allocate type hash buckets. */ 5157 5158 static thash_t * 5159 allocate_thash (void) 5160 { 5161 thash_t *ptr; 5162 static thash_t initial_thash; 5163 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; 5167 5168 if (unallocated == 0) 5169 { 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++; 5173 } 5174 5175 ptr = &cur_page->thash[ --unallocated ]; 5176 alloc_counts[ (int) alloc_type_thash ].unallocated = unallocated; 5177 5178 #else 5179 ptr = xmalloc (sizeof (thash_t)); 5180 5181 #endif 5182 5183 alloc_counts[ (int) alloc_type_thash ].total_alloc++; 5184 *ptr = initial_thash; 5185 return ptr; 5186 } 5187 5188 5189 /* Allocate structure, union, or enum tag information. */ 5190 5191 static tag_t * 5192 allocate_tag (void) 5193 { 5194 tag_t *ptr; 5195 static tag_t initial_tag; 5196 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; 5201 5202 else 5203 { 5204 int unallocated = alloc_counts[ (int) alloc_type_tag ].unallocated; 5205 page_t *cur_page = alloc_counts[ (int) alloc_type_tag ].cur_page; 5206 5207 if (unallocated == 0) 5208 { 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++; 5212 } 5213 5214 ptr = &cur_page->tag[ --unallocated ]; 5215 alloc_counts[ (int) alloc_type_tag ].unallocated = unallocated; 5216 } 5217 5218 #else 5219 ptr = xmalloc (sizeof (tag_t)); 5220 5221 #endif 5222 5223 alloc_counts[ (int) alloc_type_tag ].total_alloc++; 5224 *ptr = initial_tag; 5225 return ptr; 5226 } 5227 5228 /* Free scoping information. */ 5229 5230 static void 5231 free_tag (tag_t *ptr) 5232 { 5233 alloc_counts[ (int) alloc_type_tag ].total_free++; 5234 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; 5238 5239 #else 5240 free (ptr); 5241 #endif 5242 5243 } 5244 5245 5246 /* Allocate forward reference to a yet unknown tag. */ 5247 5248 static forward_t * 5249 allocate_forward (void) 5250 { 5251 forward_t *ptr; 5252 static forward_t initial_forward; 5253 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; 5258 5259 else 5260 { 5261 int unallocated = alloc_counts[ (int) alloc_type_forward ].unallocated; 5262 page_t *cur_page = alloc_counts[ (int) alloc_type_forward ].cur_page; 5263 5264 if (unallocated == 0) 5265 { 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++; 5269 } 5270 5271 ptr = &cur_page->forward[ --unallocated ]; 5272 alloc_counts[ (int) alloc_type_forward ].unallocated = unallocated; 5273 } 5274 5275 #else 5276 ptr = xmalloc (sizeof (forward_t)); 5277 5278 #endif 5279 5280 alloc_counts[ (int) alloc_type_forward ].total_alloc++; 5281 *ptr = initial_forward; 5282 return ptr; 5283 } 5284 5285 /* Free scoping information. */ 5286 5287 static void 5288 free_forward (forward_t *ptr) 5289 { 5290 alloc_counts[ (int) alloc_type_forward ].total_free++; 5291 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; 5295 5296 #else 5297 free (ptr); 5298 #endif 5299 5300 } 5301 5302 5303 /* Allocate head of type hash list. */ 5304 5305 static thead_t * 5306 allocate_thead (void) 5307 { 5308 thead_t *ptr; 5309 static thead_t initial_thead; 5310 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; 5315 5316 else 5317 { 5318 int unallocated = alloc_counts[ (int) alloc_type_thead ].unallocated; 5319 page_t *cur_page = alloc_counts[ (int) alloc_type_thead ].cur_page; 5320 5321 if (unallocated == 0) 5322 { 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++; 5326 } 5327 5328 ptr = &cur_page->thead[ --unallocated ]; 5329 alloc_counts[ (int) alloc_type_thead ].unallocated = unallocated; 5330 } 5331 5332 #else 5333 ptr = xmalloc (sizeof (thead_t)); 5334 5335 #endif 5336 5337 alloc_counts[ (int) alloc_type_thead ].total_alloc++; 5338 *ptr = initial_thead; 5339 return ptr; 5340 } 5341 5342 /* Free scoping information. */ 5343 5344 static void 5345 free_thead (thead_t *ptr) 5346 { 5347 alloc_counts[ (int) alloc_type_thead ].total_free++; 5348 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; 5352 5353 #else 5354 free (ptr); 5355 #endif 5356 5357 } 5358 5359 /* Output an error message and exit. */ 5360 5361 void 5362 fatal (const char *format, ...) 5363 { 5364 va_list ap; 5365 5366 va_start (ap, format); 5367 5368 if (line_number > 0) 5369 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number); 5370 else 5371 fprintf (stderr, "%s:", progname); 5372 5373 vfprintf (stderr, format, ap); 5374 va_end (ap); 5375 fprintf (stderr, "\n"); 5376 if (line_number > 0) 5377 fprintf (stderr, "line:\t%s\n", cur_line_start); 5378 5379 exit (1); 5380 } 5381 5382 void 5383 error (const char *format, ...) 5384 { 5385 va_list ap; 5386 5387 va_start (ap, format); 5388 5389 if (line_number > 0) 5390 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number); 5391 else 5392 fprintf (stderr, "%s:", progname); 5393 5394 vfprintf (stderr, format, ap); 5395 fprintf (stderr, "\n"); 5396 if (line_number > 0) 5397 fprintf (stderr, "line:\t%s\n", cur_line_start); 5398 5399 had_errors++; 5400 va_end (ap); 5401 } 5402 5403 /* More 'friendly' abort that prints the line and file. */ 5404 5405 void 5406 fancy_abort (const char *file, int line, const char *func) 5407 { 5408 fatal ("abort in %s, at %s:%d", func, file, line); 5409 } 5410 5411 5412 /* When `malloc.c' is compiled with `rcheck' defined, 5413 it calls this function to report clobberage. */ 5414 5415 void 5416 botch (const char *s) 5417 { 5418 fatal ("%s", s); 5419 } 5420