00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025 #include "system.h"
00026 #ifdef index
00027 #undef index
00028 #endif
00029 #ifndef CROSS_COMPILE
00030 #include <a.out.h>
00031 #else
00032 #include "mips/a.out.h"
00033 #endif
00034
00035 #ifndef MIPS_IS_STAB
00036
00037
00038
00039
00040
00041
00042
00043 #define CODE_MASK 0x8F300
00044 #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK)
00045 #define MIPS_MARK_STAB(code) ((code)+CODE_MASK)
00046 #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK)
00047 #endif
00048
00049 #define uchar unsigned char
00050 #define ushort unsigned short
00051 #define uint unsigned int
00052 #define ulong unsigned long
00053
00054
00055
00056
00057
00058 #ifndef stStaParam
00059 #define stStaParam 16
00060 #endif
00061
00062 #ifndef btVoid
00063 #define btVoid 26
00064 #endif
00065
00066 typedef enum sc {
00067 sc_Nil = scNil,
00068 sc_Text = scText,
00069 sc_Data = scData,
00070 sc_Bss = scBss,
00071 sc_Register = scRegister,
00072 sc_Abs = scAbs,
00073 sc_Undefined = scUndefined,
00074 sc_CdbLocal = scCdbLocal,
00075 sc_Bits = scBits,
00076 sc_CdbSystem = scCdbSystem,
00077 sc_RegImage = scRegImage,
00078 sc_Info = scInfo,
00079 sc_UserStruct = scUserStruct,
00080 sc_SData = scSData,
00081 sc_SBss = scSBss,
00082 sc_RData = scRData,
00083 sc_Var = scVar,
00084 sc_Common = scCommon,
00085 sc_SCommon = scSCommon,
00086 sc_VarRegister = scVarRegister,
00087 sc_Variant = scVariant,
00088 sc_SUndefined = scSUndefined,
00089 sc_Init = scInit,
00090 sc_Max = scMax
00091 } sc_t;
00092
00093
00094
00095 typedef enum st {
00096 st_Nil = stNil,
00097 st_Global = stGlobal,
00098 st_Static = stStatic,
00099 st_Param = stParam,
00100 st_Local = stLocal,
00101 st_Label = stLabel,
00102 st_Proc = stProc,
00103 st_Block = stBlock,
00104 st_End = stEnd,
00105 st_Member = stMember,
00106 st_Typedef = stTypedef,
00107 st_File = stFile,
00108 st_RegReloc = stRegReloc,
00109 st_Forward = stForward,
00110 st_StaticProc = stStaticProc,
00111 st_StaParam = stStaParam,
00112 st_Constant = stConstant,
00113 #ifdef stStruct
00114 st_Struct = stStruct,
00115 st_Union = stUnion,
00116 st_Enum = stEnum,
00117 #endif
00118 st_Str = stStr,
00119 st_Number = stNumber,
00120 st_Expr = stExpr,
00121 st_Type = stType,
00122 st_Max = stMax
00123 } st_t;
00124
00125
00126
00127 typedef enum tq {
00128 tq_Nil = tqNil,
00129 tq_Ptr = tqPtr,
00130 tq_Proc = tqProc,
00131 tq_Array = tqArray,
00132 tq_Far = tqFar,
00133 tq_Vol = tqVol,
00134 tq_Max = tqMax
00135 } tq_t;
00136
00137
00138
00139 typedef enum bt {
00140 bt_Nil = btNil,
00141 bt_Adr = btAdr,
00142 bt_Char = btChar,
00143 bt_UChar = btUChar,
00144 bt_Short = btShort,
00145 bt_UShort = btUShort,
00146 bt_Int = btInt,
00147 bt_UInt = btUInt,
00148 bt_Long = btLong,
00149 bt_ULong = btULong,
00150 bt_Float = btFloat,
00151 bt_Double = btDouble,
00152 bt_Struct = btStruct,
00153 bt_Union = btUnion,
00154 bt_Enum = btEnum,
00155 bt_Typedef = btTypedef,
00156 bt_Range = btRange,
00157 bt_Set = btSet,
00158 bt_Complex = btComplex,
00159 bt_DComplex = btDComplex,
00160 bt_Indirect = btIndirect,
00161 bt_FixedDec = btFixedDec,
00162 bt_FloatDec = btFloatDec,
00163 bt_String = btString,
00164 bt_Bit = btBit,
00165 bt_Picture = btPicture,
00166 bt_Void = btVoid,
00167 bt_Max = btMax
00168 } bt_t;
00169
00170
00171
00172 typedef enum lang {
00173 lang_C = langC,
00174 lang_Pascal = langPascal,
00175 lang_Fortran = langFortran,
00176 lang_Assembler = langAssembler,
00177 lang_Machine = langMachine,
00178 lang_Nil = langNil,
00179 lang_Ada = langAda,
00180 lang_Pl1 = langPl1,
00181 lang_Cobol = langCobol
00182 } lang_t;
00183
00184
00185
00186 typedef enum glevel {
00187 glevel_0 = GLEVEL_0,
00188 glevel_1 = GLEVEL_1,
00189 glevel_2 = GLEVEL_2,
00190 glevel_3 = GLEVEL_3
00191 } glevel_t;
00192
00193
00194
00195 typedef struct scope {
00196 struct scope *prev;
00197 ulong open_sym;
00198 sc_t sc;
00199 st_t st;
00200 } scope_t;
00201
00202 struct filehdr global_hdr;
00203
00204 int errors = 0;
00205 int want_aux = 0;
00206 int want_line = 0;
00207 int want_rfd = 0;
00208 int want_scope = 0;
00209 int tfile = 0;
00210 int tfile_fd;
00211 off_t tfile_offset;
00212 scope_t *cur_scope = 0;
00213 scope_t *free_scope = 0;
00214 HDRR sym_hdr;
00215 char *l_strings;
00216 char *e_strings;
00217 SYMR *l_symbols;
00218 EXTR *e_symbols;
00219 LINER *lines;
00220 DNR *dense_nums;
00221 OPTR *opt_symbols;
00222 AUXU *aux_symbols;
00223 char *aux_used;
00224 FDR *file_desc;
00225 ulong *rfile_desc;
00226 PDR *proc_desc;
00227
00228
00229 static PTR read_seek PARAMS ((PTR, size_t, off_t, const char *));
00230 static void read_tfile PARAMS ((void));
00231 static void print_global_hdr PARAMS ((struct filehdr *));
00232 static void print_sym_hdr PARAMS ((HDRR *));
00233 static void print_file_desc PARAMS ((FDR *, int));
00234 static void print_symbol PARAMS ((SYMR *, int, const char *, AUXU *, int, FDR *));
00235 static void print_aux PARAMS ((AUXU, int, int));
00236 static void emit_aggregate PARAMS ((char *, AUXU, AUXU, const char *, FDR *));
00237 static const char *st_to_string PARAMS ((st_t));
00238 static const char *sc_to_string PARAMS ((sc_t));
00239 static const char *glevel_to_string PARAMS ((glevel_t));
00240 static const char *lang_to_string PARAMS ((lang_t));
00241 static const char *type_to_string PARAMS ((AUXU *, int, FDR *));
00242
00243 extern char *optarg;
00244 extern int optind;
00245 extern int opterr;
00246
00247
00248
00249 #define __define_stab(NAME, CODE, STRING) {(int)CODE, STRING},
00250 const struct {const short code; const char string[10];} stab_names[] = {
00251 #include "stab.def"
00252 #undef __define_stab
00253 };
00254
00255
00256
00257
00258 static PTR
00259 read_seek (ptr, size, offset, context)
00260 PTR ptr;
00261 size_t size;
00262 off_t offset;
00263 const char *context;
00264 {
00265 long read_size = 0;
00266
00267 if (size == 0)
00268 return ptr;
00269
00270 if (!ptr)
00271 ptr = xmalloc (size);
00272
00273 if ((tfile_offset != offset && lseek (tfile_fd, offset, 0) == -1)
00274 || (read_size = read (tfile_fd, ptr, size)) < 0)
00275 {
00276 perror (context);
00277 exit (1);
00278 }
00279
00280 if (read_size != (long) size)
00281 {
00282 fprintf (stderr, "%s: read %ld bytes, expected %ld bytes\n",
00283 context, read_size, (long) size);
00284 exit (1);
00285 }
00286
00287 tfile_offset = offset + size;
00288 return ptr;
00289 }
00290
00291
00292
00293
00294 static const char *
00295 lang_to_string (lang)
00296 lang_t lang;
00297 {
00298 switch (lang)
00299 {
00300 case langC: return "C";
00301 case langPascal: return "Pascal";
00302 case langFortran: return "Fortran";
00303 case langAssembler: return "Assembler";
00304 case langMachine: return "Machine";
00305 case langNil: return "Nil";
00306 case langAda: return "Ada";
00307 case langPl1: return "Pl1";
00308 case langCobol: return "Cobol";
00309 }
00310
00311 return "Unknown language";
00312 }
00313
00314
00315
00316
00317 static const char *
00318 sc_to_string(storage_class)
00319 sc_t storage_class;
00320 {
00321 switch(storage_class)
00322 {
00323 case sc_Nil: return "Nil";
00324 case sc_Text: return "Text";
00325 case sc_Data: return "Data";
00326 case sc_Bss: return "Bss";
00327 case sc_Register: return "Register";
00328 case sc_Abs: return "Abs";
00329 case sc_Undefined: return "Undefined";
00330 case sc_CdbLocal: return "CdbLocal";
00331 case sc_Bits: return "Bits";
00332 case sc_CdbSystem: return "CdbSystem";
00333 case sc_RegImage: return "RegImage";
00334 case sc_Info: return "Info";
00335 case sc_UserStruct: return "UserStruct";
00336 case sc_SData: return "SData";
00337 case sc_SBss: return "SBss";
00338 case sc_RData: return "RData";
00339 case sc_Var: return "Var";
00340 case sc_Common: return "Common";
00341 case sc_SCommon: return "SCommon";
00342 case sc_VarRegister: return "VarRegister";
00343 case sc_Variant: return "Variant";
00344 case sc_SUndefined: return "SUndefined";
00345 case sc_Init: return "Init";
00346 case sc_Max: return "Max";
00347 }
00348
00349 return "???";
00350 }
00351
00352
00353
00354
00355 static const char *
00356 st_to_string(symbol_type)
00357 st_t symbol_type;
00358 {
00359 switch(symbol_type)
00360 {
00361 case st_Nil: return "Nil";
00362 case st_Global: return "Global";
00363 case st_Static: return "Static";
00364 case st_Param: return "Param";
00365 case st_Local: return "Local";
00366 case st_Label: return "Label";
00367 case st_Proc: return "Proc";
00368 case st_Block: return "Block";
00369 case st_End: return "End";
00370 case st_Member: return "Member";
00371 case st_Typedef: return "Typedef";
00372 case st_File: return "File";
00373 case st_RegReloc: return "RegReloc";
00374 case st_Forward: return "Forward";
00375 case st_StaticProc: return "StaticProc";
00376 case st_Constant: return "Constant";
00377 case st_StaParam: return "StaticParam";
00378 #ifdef stStruct
00379 case st_Struct: return "Struct";
00380 case st_Union: return "Union";
00381 case st_Enum: return "Enum";
00382 #endif
00383 case st_Str: return "String";
00384 case st_Number: return "Number";
00385 case st_Expr: return "Expr";
00386 case st_Type: return "Type";
00387 case st_Max: return "Max";
00388 }
00389
00390 return "???";
00391 }
00392
00393
00394
00395
00396 static const char *
00397 glevel_to_string (g_level)
00398 glevel_t g_level;
00399 {
00400 switch(g_level)
00401 {
00402 case GLEVEL_0: return "G0";
00403 case GLEVEL_1: return "G1";
00404 case GLEVEL_2: return "G2";
00405 case GLEVEL_3: return "G3";
00406 }
00407
00408 return "??";
00409 }
00410
00411
00412
00413
00414 static const char *
00415 type_to_string (aux_ptr, index, fdp)
00416 AUXU *aux_ptr;
00417 int index;
00418 FDR *fdp;
00419 {
00420 AUXU u;
00421 struct qual {
00422 tq_t type;
00423 int low_bound;
00424 int high_bound;
00425 int stride;
00426 } qualifiers[7];
00427
00428 bt_t basic_type;
00429 int i;
00430 static char buffer1[1024];
00431 static char buffer2[1024];
00432 char *p1 = buffer1;
00433 char *p2 = buffer2;
00434 char *used_ptr = aux_used + (aux_ptr - aux_symbols);
00435
00436 for (i = 0; i < 7; i++)
00437 {
00438 qualifiers[i].low_bound = 0;
00439 qualifiers[i].high_bound = 0;
00440 qualifiers[i].stride = 0;
00441 }
00442
00443 used_ptr[index] = 1;
00444 u = aux_ptr[index++];
00445 if (u.isym == -1)
00446 return "-1 (no type)";
00447
00448 basic_type = (bt_t) u.ti.bt;
00449 qualifiers[0].type = (tq_t) u.ti.tq0;
00450 qualifiers[1].type = (tq_t) u.ti.tq1;
00451 qualifiers[2].type = (tq_t) u.ti.tq2;
00452 qualifiers[3].type = (tq_t) u.ti.tq3;
00453 qualifiers[4].type = (tq_t) u.ti.tq4;
00454 qualifiers[5].type = (tq_t) u.ti.tq5;
00455 qualifiers[6].type = tq_Nil;
00456
00457
00458
00459
00460 switch (basic_type)
00461 {
00462 case bt_Nil:
00463 strcpy (p1, "nil");
00464 break;
00465
00466 case bt_Adr:
00467 strcpy (p1, "address");
00468 break;
00469
00470 case bt_Char:
00471 strcpy (p1, "char");
00472 break;
00473
00474 case bt_UChar:
00475 strcpy (p1, "unsigned char");
00476 break;
00477
00478 case bt_Short:
00479 strcpy (p1, "short");
00480 break;
00481
00482 case bt_UShort:
00483 strcpy (p1, "unsigned short");
00484 break;
00485
00486 case bt_Int:
00487 strcpy (p1, "int");
00488 break;
00489
00490 case bt_UInt:
00491 strcpy (p1, "unsigned int");
00492 break;
00493
00494 case bt_Long:
00495 strcpy (p1, "long");
00496 break;
00497
00498 case bt_ULong:
00499 strcpy (p1, "unsigned long");
00500 break;
00501
00502 case bt_Float:
00503 strcpy (p1, "float");
00504 break;
00505
00506 case bt_Double:
00507 strcpy (p1, "double");
00508 break;
00509
00510
00511
00512
00513
00514 case bt_Struct:
00515 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "struct", fdp);
00516 used_ptr[index] = 1;
00517 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
00518 used_ptr[++index] = 1;
00519
00520 index++;
00521 break;
00522
00523
00524
00525
00526
00527 case bt_Union:
00528 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "union", fdp);
00529 used_ptr[index] = 1;
00530 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
00531 used_ptr[++index] = 1;
00532
00533 index++;
00534 break;
00535
00536
00537
00538
00539
00540 case bt_Enum:
00541 emit_aggregate (p1, aux_ptr[index], aux_ptr[index+1], "enum", fdp);
00542 used_ptr[index] = 1;
00543 if (aux_ptr[index].rndx.rfd == ST_RFDESCAPE)
00544 used_ptr[++index] = 1;
00545
00546 index++;
00547 break;
00548
00549 case bt_Typedef:
00550 strcpy (p1, "typedef");
00551 break;
00552
00553 case bt_Range:
00554 strcpy (p1, "subrange");
00555 break;
00556
00557 case bt_Set:
00558 strcpy (p1, "set");
00559 break;
00560
00561 case bt_Complex:
00562 strcpy (p1, "complex");
00563 break;
00564
00565 case bt_DComplex:
00566 strcpy (p1, "double complex");
00567 break;
00568
00569 case bt_Indirect:
00570 strcpy (p1, "forward/unnamed typedef");
00571 break;
00572
00573 case bt_FixedDec:
00574 strcpy (p1, "fixed decimal");
00575 break;
00576
00577 case bt_FloatDec:
00578 strcpy (p1, "float decimal");
00579 break;
00580
00581 case bt_String:
00582 strcpy (p1, "string");
00583 break;
00584
00585 case bt_Bit:
00586 strcpy (p1, "bit");
00587 break;
00588
00589 case bt_Picture:
00590 strcpy (p1, "picture");
00591 break;
00592
00593 case bt_Void:
00594 strcpy (p1, "void");
00595 break;
00596
00597 default:
00598 sprintf (p1, "Unknown basic type %d", (int) basic_type);
00599 break;
00600 }
00601
00602 p1 += strlen (buffer1);
00603
00604
00605
00606
00607 if (u.ti.fBitfield)
00608 {
00609 int bitsize;
00610
00611 used_ptr[index] = 1;
00612 bitsize = aux_ptr[index++].width;
00613 sprintf (p1, " : %d", bitsize);
00614 p1 += strlen (buffer1);
00615 }
00616
00617
00618
00619
00620
00621 if (qualifiers[0].type != tq_Nil)
00622 {
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 for (i = 0; i < 7; i++)
00633 {
00634 if (qualifiers[i].type == tq_Array)
00635 {
00636 qualifiers[i].low_bound = aux_ptr[index+2].dnLow;
00637 qualifiers[i].high_bound = aux_ptr[index+3].dnHigh;
00638 qualifiers[i].stride = aux_ptr[index+4].width;
00639 used_ptr[index] = 1;
00640 used_ptr[index+1] = 1;
00641 used_ptr[index+2] = 1;
00642 used_ptr[index+3] = 1;
00643 used_ptr[index+4] = 1;
00644 index += 5;
00645 }
00646 }
00647
00648
00649
00650
00651 for (i = 0; i < 6; i++)
00652 {
00653 switch (qualifiers[i].type)
00654 {
00655 case tq_Nil:
00656 case tq_Max:
00657 break;
00658
00659 case tq_Ptr:
00660 strcpy (p2, "ptr to ");
00661 p2 += sizeof ("ptr to ")-1;
00662 break;
00663
00664 case tq_Vol:
00665 strcpy (p2, "volatile ");
00666 p2 += sizeof ("volatile ")-1;
00667 break;
00668
00669 case tq_Far:
00670 strcpy (p2, "far ");
00671 p2 += sizeof ("far ")-1;
00672 break;
00673
00674 case tq_Proc:
00675 strcpy (p2, "func. ret. ");
00676 p2 += sizeof ("func. ret. ");
00677 break;
00678
00679 case tq_Array:
00680 {
00681 int first_array = i;
00682 int j;
00683
00684
00685
00686
00687 while (i < 5 && qualifiers[i+1].type == tq_Array)
00688 i++;
00689
00690 for (j = i; j >= first_array; j--)
00691 {
00692 strcpy (p2, "array [");
00693 p2 += sizeof ("array [")-1;
00694 if (qualifiers[j].low_bound != 0)
00695 sprintf (p2,
00696 "%ld:%ld {%ld bits}",
00697 (long) qualifiers[j].low_bound,
00698 (long) qualifiers[j].high_bound,
00699 (long) qualifiers[j].stride);
00700
00701 else if (qualifiers[j].high_bound != -1)
00702 sprintf (p2,
00703 "%ld {%ld bits}",
00704 (long) (qualifiers[j].high_bound + 1),
00705 (long) (qualifiers[j].stride));
00706
00707 else
00708 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
00709
00710 p2 += strlen (p2);
00711 strcpy (p2, "] of ");
00712 p2 += sizeof ("] of ")-1;
00713 }
00714 }
00715 break;
00716 }
00717 }
00718 }
00719
00720 strcpy (p2, buffer1);
00721 return buffer2;
00722 }
00723
00724
00725
00726
00727 static void
00728 print_global_hdr (ptr)
00729 struct filehdr *ptr;
00730 {
00731 char *time = ctime ((time_t *)&ptr->f_timdat);
00732 ushort flags = ptr->f_flags;
00733
00734 printf("Global file header:\n");
00735 printf(" %-*s 0x%x\n", 24, "magic number", (ushort) ptr->f_magic);
00736 printf(" %-*s %d\n", 24, "# sections", (int) ptr->f_nscns);
00737 printf(" %-*s %ld, %s", 24, "timestamp", (long) ptr->f_timdat, time);
00738 printf(" %-*s %ld\n", 24, "symbolic header offset", (long) ptr->f_symptr);
00739 printf(" %-*s %ld\n", 24, "symbolic header size", (long) ptr->f_nsyms);
00740 printf(" %-*s %ld\n", 24, "optional header", (long) ptr->f_opthdr);
00741 printf(" %-*s 0x%x", 24, "flags", (ushort) flags);
00742
00743 if ((flags & F_RELFLG) != 0)
00744 printf (", F_RELFLG");
00745
00746 if ((flags & F_EXEC) != 0)
00747 printf (", F_EXEC");
00748
00749 if ((flags & F_LNNO) != 0)
00750 printf (", F_LNNO");
00751
00752 if ((flags & F_LSYMS) != 0)
00753 printf (", F_LSYMS");
00754
00755 if ((flags & F_MINMAL) != 0)
00756 printf (", F_MINMAL");
00757
00758 if ((flags & F_UPDATE) != 0)
00759 printf (", F_UPDATE");
00760
00761 if ((flags & F_SWABD) != 0)
00762 printf (", F_SWABD");
00763
00764 if ((flags & F_AR16WR) != 0)
00765 printf (", F_AR16WR");
00766
00767 if ((flags & F_AR32WR) != 0)
00768 printf (", F_AR32WR");
00769
00770 if ((flags & F_AR32W) != 0)
00771 printf (", F_AR32W");
00772
00773 if ((flags & F_PATCH) != 0)
00774 printf (", F_PATCH/F_NODF");
00775
00776 printf ("\n\n");
00777 }
00778
00779
00780
00781
00782 static void
00783 print_sym_hdr (sym_ptr)
00784 HDRR *sym_ptr;
00785 {
00786 int width = 20;
00787
00788 printf("Symbolic header, magic number = 0x%04x, vstamp = %d.%d:\n\n",
00789 sym_ptr->magic & 0xffff,
00790 (sym_ptr->vstamp & 0xffff) >> 8,
00791 sym_ptr->vstamp & 0xff);
00792
00793 printf(" %-*s %11s %11s %11s\n", width, "Info", "Offset", "Number", "Bytes");
00794 printf(" %-*s %11s %11s %11s\n", width, "====", "======", "======", "=====\n");
00795
00796 printf(" %-*s %11ld %11ld %11ld [%d]\n", width, "Line numbers",
00797 (long) sym_ptr->cbLineOffset,
00798 (long) sym_ptr->cbLine,
00799 (long) sym_ptr->cbLine,
00800 (int) sym_ptr->ilineMax);
00801
00802 printf(" %-*s %11ld %11ld %11ld\n", width, "Dense numbers",
00803 (long) sym_ptr->cbDnOffset,
00804 (long) sym_ptr->idnMax,
00805 (long) (sym_ptr->idnMax * sizeof (DNR)));
00806
00807 printf(" %-*s %11ld %11ld %11ld\n", width, "Procedures Tables",
00808 (long) sym_ptr->cbPdOffset,
00809 (long) sym_ptr->ipdMax,
00810 (long) (sym_ptr->ipdMax * sizeof (PDR)));
00811
00812 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Symbols",
00813 (long) sym_ptr->cbSymOffset,
00814 (long) sym_ptr->isymMax,
00815 (long) (sym_ptr->isymMax * sizeof (SYMR)));
00816
00817 printf(" %-*s %11ld %11ld %11ld\n", width, "Optimization Symbols",
00818 (long) sym_ptr->cbOptOffset,
00819 (long) sym_ptr->ioptMax,
00820 (long) (sym_ptr->ioptMax * sizeof (OPTR)));
00821
00822 printf(" %-*s %11ld %11ld %11ld\n", width, "Auxiliary Symbols",
00823 (long) sym_ptr->cbAuxOffset,
00824 (long) sym_ptr->iauxMax,
00825 (long) (sym_ptr->iauxMax * sizeof (AUXU)));
00826
00827 printf(" %-*s %11ld %11ld %11ld\n", width, "Local Strings",
00828 (long) sym_ptr->cbSsOffset,
00829 (long) sym_ptr->issMax,
00830 (long) sym_ptr->issMax);
00831
00832 printf(" %-*s %11ld %11ld %11ld\n", width, "External Strings",
00833 (long) sym_ptr->cbSsExtOffset,
00834 (long) sym_ptr->issExtMax,
00835 (long) sym_ptr->issExtMax);
00836
00837 printf(" %-*s %11ld %11ld %11ld\n", width, "File Tables",
00838 (long) sym_ptr->cbFdOffset,
00839 (long) sym_ptr->ifdMax,
00840 (long) (sym_ptr->ifdMax * sizeof (FDR)));
00841
00842 printf(" %-*s %11ld %11ld %11ld\n", width, "Relative Files",
00843 (long) sym_ptr->cbRfdOffset,
00844 (long) sym_ptr->crfd,
00845 (long) (sym_ptr->crfd * sizeof (ulong)));
00846
00847 printf(" %-*s %11ld %11ld %11ld\n", width, "External Symbols",
00848 (long) sym_ptr->cbExtOffset,
00849 (long) sym_ptr->iextMax,
00850 (long) (sym_ptr->iextMax * sizeof (EXTR)));
00851 }
00852
00853
00854
00855
00856 static void
00857 print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
00858 SYMR *sym_ptr;
00859 int number;
00860 const char *strbase;
00861 AUXU *aux_base;
00862 int ifd;
00863 FDR *fdp;
00864 {
00865 sc_t storage_class = (sc_t) sym_ptr->sc;
00866 st_t symbol_type = (st_t) sym_ptr->st;
00867 ulong index = sym_ptr->index;
00868 char *used_ptr = aux_used + (aux_base - aux_symbols);
00869 scope_t *scope_ptr;
00870
00871 printf ("\n Symbol# %d: \"%s\"\n", number, sym_ptr->iss + strbase);
00872
00873 if (aux_base != (AUXU *) 0 && index != indexNil)
00874 switch (symbol_type)
00875 {
00876 case st_Nil:
00877 case st_Label:
00878 break;
00879
00880 case st_File:
00881 case st_Block:
00882 printf (" End+1 symbol: %ld\n", index);
00883 if (want_scope)
00884 {
00885 if (free_scope == (scope_t *) 0)
00886 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
00887 else
00888 {
00889 scope_ptr = free_scope;
00890 free_scope = scope_ptr->prev;
00891 }
00892 scope_ptr->open_sym = number;
00893 scope_ptr->st = symbol_type;
00894 scope_ptr->sc = storage_class;
00895 scope_ptr->prev = cur_scope;
00896 cur_scope = scope_ptr;
00897 }
00898 break;
00899
00900 case st_End:
00901 if (storage_class == sc_Text || storage_class == sc_Info)
00902 printf (" First symbol: %ld\n", index);
00903 else
00904 {
00905 used_ptr[index] = 1;
00906 printf (" First symbol: %ld\n", (long) aux_base[index].isym);
00907 }
00908
00909 if (want_scope)
00910 {
00911 if (cur_scope == (scope_t *) 0)
00912 printf (" Can't pop end scope\n");
00913 else
00914 {
00915 scope_ptr = cur_scope;
00916 cur_scope = scope_ptr->prev;
00917 scope_ptr->prev = free_scope;
00918 free_scope = scope_ptr;
00919 }
00920 }
00921 break;
00922
00923 case st_Proc:
00924 case st_StaticProc:
00925 if (MIPS_IS_STAB(sym_ptr))
00926 ;
00927 else if (ifd == -1)
00928 {
00929 used_ptr[index] = used_ptr[index+1] = 1;
00930 printf (" End+1 symbol: %-7ld Type: %s\n",
00931 (long) aux_base[index].isym,
00932 type_to_string (aux_base, index+1, fdp));
00933 }
00934 else
00935 printf (" Local symbol: %ld\n", index);
00936
00937 if (want_scope)
00938 {
00939 if (free_scope == (scope_t *) 0)
00940 scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
00941 else
00942 {
00943 scope_ptr = free_scope;
00944 free_scope = scope_ptr->prev;
00945 }
00946 scope_ptr->open_sym = number;
00947 scope_ptr->st = symbol_type;
00948 scope_ptr->sc = storage_class;
00949 scope_ptr->prev = cur_scope;
00950 cur_scope = scope_ptr;
00951 }
00952 break;
00953
00954 #ifdef stStruct
00955 case st_Struct:
00956 case st_Union:
00957 case st_Enum:
00958 printf (" End+1 symbol: %lu\n", index);
00959 break;
00960 #endif
00961
00962 default:
00963 if (!MIPS_IS_STAB (sym_ptr))
00964 {
00965 used_ptr[index] = 1;
00966 printf (" Type: %s\n",
00967 type_to_string (aux_base, index, fdp));
00968 }
00969 break;
00970 }
00971
00972 if (want_scope)
00973 {
00974 printf (" Scopes: ");
00975 if (cur_scope == (scope_t *) 0)
00976 printf (" none\n");
00977 else
00978 {
00979 for (scope_ptr = cur_scope;
00980 scope_ptr != (scope_t *) 0;
00981 scope_ptr = scope_ptr->prev)
00982 {
00983 const char *class;
00984 if (scope_ptr->st == st_Proc || scope_ptr->st == st_StaticProc)
00985 class = "func.";
00986 else if (scope_ptr->st == st_File)
00987 class = "file";
00988 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Text)
00989 class = "block";
00990 else if (scope_ptr->st == st_Block && scope_ptr->sc == sc_Info)
00991 class = "type";
00992 else
00993 class = "???";
00994
00995 printf (" %ld [%s]", scope_ptr->open_sym, class);
00996 }
00997 printf ("\n");
00998 }
00999 }
01000
01001 printf (" Value: %-13ld ",
01002 (long)sym_ptr->value);
01003 if (ifd == -1)
01004 printf ("String index: %ld\n", (long)sym_ptr->iss);
01005 else
01006 printf ("String index: %-11ld Ifd: %d\n",
01007 (long)sym_ptr->iss, ifd);
01008
01009 printf (" Symbol type: %-11sStorage class: %-11s",
01010 st_to_string (symbol_type), sc_to_string (storage_class));
01011
01012 if (MIPS_IS_STAB(sym_ptr))
01013 {
01014 int i = ARRAY_SIZE (stab_names);
01015 const char *stab_name = "stab";
01016 short code = MIPS_UNMARK_STAB(sym_ptr->index);
01017
01018 while (--i >= 0)
01019 if (stab_names[i].code == code)
01020 {
01021 stab_name = stab_names[i].string;
01022 break;
01023 }
01024 printf ("Index: 0x%lx (%s)\n", (long)sym_ptr->index, stab_name);
01025 }
01026 else if (sym_ptr->st == stLabel && sym_ptr->index != indexNil)
01027 printf ("Index: %ld (line#)\n", (long)sym_ptr->index);
01028 else
01029 printf ("Index: %ld\n", (long)sym_ptr->index);
01030
01031 }
01032
01033
01034
01035
01036 static void
01037 print_aux (u, auxi, used)
01038 AUXU u;
01039 int auxi;
01040 int used;
01041 {
01042 printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
01043 (used) ? " " : "* ",
01044 auxi,
01045 (long) u.isym,
01046 (long) u.rndx.rfd,
01047 (long) u.rndx.index,
01048 u.ti.bt,
01049 u.ti.fBitfield,
01050 u.ti.continued,
01051 u.ti.tq0,
01052 u.ti.tq1,
01053 u.ti.tq2,
01054 u.ti.tq3,
01055 u.ti.tq4,
01056 u.ti.tq5);
01057 }
01058
01059
01060
01061
01062 static void
01063 emit_aggregate (string, u, u2, which, fdp)
01064 char *string;
01065 AUXU u;
01066 AUXU u2;
01067 const char *which;
01068 FDR *fdp;
01069 {
01070 unsigned int ifd = u.rndx.rfd;
01071 unsigned int index = u.rndx.index;
01072 const char *name;
01073
01074 if (ifd == ST_RFDESCAPE)
01075 ifd = u2.isym;
01076
01077
01078
01079 if (ifd == 0xffffffff
01080 || (u.rndx.rfd == ST_RFDESCAPE && index == 0))
01081 name = "<undefined>";
01082 else if (index == indexNil)
01083 name = "<no name>";
01084 else
01085 {
01086 if (fdp == 0 || sym_hdr.crfd == 0)
01087 fdp = &file_desc[ifd];
01088 else
01089 fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]];
01090 name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss];
01091 }
01092
01093 sprintf (string,
01094 "%s %s { ifd = %u, index = %u }",
01095 which, name, ifd, index);
01096 }
01097
01098
01099
01100
01101
01102 static void
01103 print_file_desc (fdp, number)
01104 FDR *fdp;
01105 int number;
01106 {
01107 char *str_base;
01108 AUXU *aux_base;
01109 int symi, pdi;
01110 int width = 20;
01111 char *used_base;
01112
01113 str_base = l_strings + fdp->issBase;
01114 aux_base = aux_symbols + fdp->iauxBase;
01115 used_base = aux_used + (aux_base - aux_symbols);
01116
01117 printf ("\nFile #%d, \"%s\"\n\n",
01118 number,
01119 fdp->rss != issNil ? str_base + fdp->rss : "<unknown>");
01120
01121 printf (" Name index = %-10ld Readin = %s\n",
01122 (long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
01123
01124 printf (" Merge = %-10s Endian = %s\n",
01125 (fdp->fMerge) ? "Yes" : "No",
01126 (fdp->fBigendian) ? "BIG" : "LITTLE");
01127
01128 printf (" Debug level = %-10s Language = %s\n",
01129 glevel_to_string (fdp->glevel),
01130 lang_to_string((lang_t) fdp->lang));
01131
01132 printf (" Adr = 0x%08lx\n\n", (long) fdp->adr);
01133
01134 printf(" %-*s %11s %11s %11s %11s\n", width, "Info", "Start", "Number", "Size", "Offset");
01135 printf(" %-*s %11s %11s %11s %11s\n", width, "====", "=====", "======", "====", "======");
01136
01137 printf(" %-*s %11lu %11lu %11lu %11lu\n",
01138 width, "Local strings",
01139 (ulong) fdp->issBase,
01140 (ulong) fdp->cbSs,
01141 (ulong) fdp->cbSs,
01142 (ulong) (fdp->issBase + sym_hdr.cbSsOffset));
01143
01144 printf(" %-*s %11lu %11lu %11lu %11lu\n",
01145 width, "Local symbols",
01146 (ulong) fdp->isymBase,
01147 (ulong) fdp->csym,
01148 (ulong) (fdp->csym * sizeof (SYMR)),
01149 (ulong) (fdp->isymBase * sizeof (SYMR) + sym_hdr.cbSymOffset));
01150
01151 printf(" %-*s %11lu %11lu %11lu %11lu\n",
01152 width, "Line numbers",
01153 (ulong) fdp->cbLineOffset,
01154 (ulong) fdp->cline,
01155 (ulong) fdp->cbLine,
01156 (ulong) (fdp->cbLineOffset + sym_hdr.cbLineOffset));
01157
01158 printf(" %-*s %11lu %11lu %11lu %11lu\n",
01159 width, "Optimization symbols",
01160 (ulong) fdp->ioptBase,
01161 (ulong) fdp->copt,
01162 (ulong) (fdp->copt * sizeof (OPTR)),
01163 (ulong) (fdp->ioptBase * sizeof (OPTR) + sym_hdr.cbOptOffset));
01164
01165 printf(" %-*s %11lu %11lu %11lu %11lu\n",
01166 width, "Procedures",
01167 (ulong) fdp->ipdFirst,
01168 (ulong) fdp->cpd,
01169 (ulong) (fdp->cpd * sizeof (PDR)),
01170 (ulong) (fdp->ipdFirst * sizeof (PDR) + sym_hdr.cbPdOffset));
01171
01172 printf(" %-*s %11lu %11lu %11lu %11lu\n",
01173 width, "Auxiliary symbols",
01174 (ulong) fdp->iauxBase,
01175 (ulong) fdp->caux,
01176 (ulong) (fdp->caux * sizeof (AUXU)),
01177 (ulong) (fdp->iauxBase * sizeof(AUXU) + sym_hdr.cbAuxOffset));
01178
01179 printf(" %-*s %11lu %11lu %11lu %11lu\n",
01180 width, "Relative Files",
01181 (ulong) fdp->rfdBase,
01182 (ulong) fdp->crfd,
01183 (ulong) (fdp->crfd * sizeof (ulong)),
01184 (ulong) (fdp->rfdBase * sizeof(ulong) + sym_hdr.cbRfdOffset));
01185
01186
01187 if (want_scope && cur_scope != (scope_t *) 0)
01188 printf ("\n Warning scope does not start at 0!\n");
01189
01190
01191
01192
01193 printf ("\n There are %lu local symbols, starting at %lu\n",
01194 (ulong) fdp->csym,
01195 (ulong) (fdp->isymBase + sym_hdr.cbSymOffset));
01196
01197 for(symi = fdp->isymBase; symi < (fdp->csym + fdp->isymBase); symi++)
01198 print_symbol (&l_symbols[symi],
01199 symi - fdp->isymBase,
01200 str_base,
01201 aux_base,
01202 -1,
01203 fdp);
01204
01205 if (want_scope && cur_scope != (scope_t *) 0)
01206 printf ("\n Warning scope does not end at 0!\n");
01207
01208
01209
01210
01211
01212 if (want_aux && fdp->caux != 0)
01213 {
01214 int auxi;
01215
01216 printf ("\n There are %lu auxiliary table entries, starting at %lu.\n\n",
01217 (ulong) fdp->caux,
01218 (ulong) (fdp->iauxBase + sym_hdr.cbAuxOffset));
01219
01220 for (auxi = fdp->iauxBase; auxi < (fdp->caux + fdp->iauxBase); auxi++)
01221 print_aux (aux_base[auxi], auxi, used_base[auxi]);
01222 }
01223
01224
01225
01226
01227 if (want_rfd && fdp->crfd != 0)
01228 {
01229 ulong *rfd_ptr, i;
01230
01231 printf ("\n There are %lu relative file descriptors, starting at %lu.\n",
01232 (ulong) fdp->crfd,
01233 (ulong) fdp->rfdBase);
01234
01235 rfd_ptr = rfile_desc + fdp->rfdBase;
01236 for (i = 0; i < (ulong) fdp->crfd; i++)
01237 {
01238 printf ("\t#%-5ld %11ld, 0x%08lx\n", i, *rfd_ptr, *rfd_ptr);
01239 rfd_ptr++;
01240 }
01241 }
01242
01243
01244
01245
01246 printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd);
01247 printf ("starting at %lu.\n", (ulong) fdp->ipdFirst);
01248
01249 for (pdi = fdp->ipdFirst; pdi < (fdp->cpd + fdp->ipdFirst); pdi++)
01250 {
01251 PDR *proc_ptr = &proc_desc[pdi];
01252 printf ("\n\tProcedure descriptor %d:\n", (pdi - fdp->ipdFirst));
01253
01254 if (l_symbols != 0)
01255 printf ("\t Name index = %-11ld Name = \"%s\"\n",
01256 (long) l_symbols[proc_ptr->isym + fdp->isymBase].iss,
01257 l_symbols[proc_ptr->isym + fdp->isymBase].iss + str_base);
01258
01259 printf ("\t .mask 0x%08lx,%-9ld .fmask 0x%08lx,%ld\n",
01260 (long) proc_ptr->regmask,
01261 (long) proc_ptr->regoffset,
01262 (long) proc_ptr->fregmask,
01263 (long) proc_ptr->fregoffset);
01264
01265 printf ("\t .frame $%d,%ld,$%d\n",
01266 (int) proc_ptr->framereg,
01267 (long) proc_ptr->frameoffset,
01268 (int) proc_ptr->pcreg);
01269
01270 printf ("\t Opt. start = %-11ld Symbols start = %ld\n",
01271 (long) proc_ptr->iopt,
01272 (long) proc_ptr->isym);
01273
01274 printf ("\t First line # = %-11ld Last line # = %ld\n",
01275 (long) proc_ptr->lnLow,
01276 (long) proc_ptr->lnHigh);
01277
01278 printf ("\t Line Offset = %-11ld Address = 0x%08lx\n",
01279 (long) proc_ptr->cbLineOffset,
01280 (long) proc_ptr->adr);
01281
01282
01283
01284
01285
01286 if (want_line && fdp->cline != 0)
01287 {
01288 int delta, count;
01289 long cur_line = proc_ptr->lnLow;
01290 uchar *line_ptr = (((uchar *)lines) + proc_ptr->cbLineOffset
01291 + fdp->cbLineOffset);
01292 uchar *line_end;
01293
01294 if (pdi == fdp->cpd + fdp->ipdFirst - 1)
01295 line_end = ((uchar *)lines) + fdp->cbLine + fdp->cbLineOffset;
01296 else
01297 line_end = (((uchar *)lines) + proc_desc[pdi+1].cbLineOffset
01298 + fdp->cbLineOffset);
01299
01300 printf ("\n\tThere are %lu bytes holding line numbers, starting at %lu.\n",
01301 (ulong) (line_end - line_ptr),
01302 (ulong) (fdp->ilineBase + sym_hdr.cbLineOffset));
01303
01304 while (line_ptr < line_end)
01305 {
01306 delta = ((*line_ptr >> 4) ^ 0x8) - 0x8;
01307 count = (*line_ptr & 0xf) + 1;
01308 if (delta != -8)
01309 line_ptr++;
01310 else
01311 {
01312 delta = (((line_ptr[1]) & 0xff) << 8) + ((line_ptr[2]) & 0xff);
01313 delta = (delta ^ 0x8000) - 0x8000;
01314 line_ptr += 3;
01315 }
01316
01317 cur_line += delta;
01318 printf ("\t Line %11ld, delta %5d, count %2d\n",
01319 cur_line,
01320 delta,
01321 count);
01322 }
01323 }
01324 }
01325 }
01326
01327
01328
01329
01330 static void
01331 read_tfile ()
01332 {
01333 short magic;
01334 off_t sym_hdr_offset = 0;
01335
01336 (void) read_seek ((PTR) &magic, sizeof (magic), (off_t) 0, "Magic number");
01337 if (!tfile)
01338 {
01339
01340
01341 (void) read_seek ((PTR) &global_hdr, sizeof (global_hdr), (off_t) 0,
01342 "Global file header");
01343
01344 print_global_hdr (&global_hdr);
01345
01346 if (global_hdr.f_symptr == 0)
01347 {
01348 printf ("No symbolic header, Goodbye!\n");
01349 exit (1);
01350 }
01351
01352 sym_hdr_offset = global_hdr.f_symptr;
01353 }
01354
01355 (void) read_seek ((PTR) &sym_hdr,
01356 sizeof (sym_hdr),
01357 sym_hdr_offset,
01358 "Symbolic header");
01359
01360 print_sym_hdr (&sym_hdr);
01361
01362 lines = (LINER *) read_seek (NULL,
01363 sym_hdr.cbLine,
01364 sym_hdr.cbLineOffset,
01365 "Line numbers");
01366
01367 dense_nums = (DNR *) read_seek (NULL,
01368 sym_hdr.idnMax * sizeof (DNR),
01369 sym_hdr.cbDnOffset,
01370 "Dense numbers");
01371
01372 proc_desc = (PDR *) read_seek (NULL,
01373 sym_hdr.ipdMax * sizeof (PDR),
01374 sym_hdr.cbPdOffset,
01375 "Procedure tables");
01376
01377 l_symbols = (SYMR *) read_seek (NULL,
01378 sym_hdr.isymMax * sizeof (SYMR),
01379 sym_hdr.cbSymOffset,
01380 "Local symbols");
01381
01382 opt_symbols = (OPTR *) read_seek (NULL,
01383 sym_hdr.ioptMax * sizeof (OPTR),
01384 sym_hdr.cbOptOffset,
01385 "Optimization symbols");
01386
01387 aux_symbols = (AUXU *) read_seek (NULL,
01388 sym_hdr.iauxMax * sizeof (AUXU),
01389 sym_hdr.cbAuxOffset,
01390 "Auxiliary symbols");
01391
01392 if (sym_hdr.iauxMax > 0)
01393 aux_used = xcalloc (sym_hdr.iauxMax, 1);
01394
01395 l_strings = (char *) read_seek (NULL,
01396 sym_hdr.issMax,
01397 sym_hdr.cbSsOffset,
01398 "Local string table");
01399
01400 e_strings = (char *) read_seek (NULL,
01401 sym_hdr.issExtMax,
01402 sym_hdr.cbSsExtOffset,
01403 "External string table");
01404
01405 file_desc = (FDR *) read_seek (NULL,
01406 sym_hdr.ifdMax * sizeof (FDR),
01407 sym_hdr.cbFdOffset,
01408 "File tables");
01409
01410 rfile_desc = (ulong *) read_seek (NULL,
01411 sym_hdr.crfd * sizeof (ulong),
01412 sym_hdr.cbRfdOffset,
01413 "Relative file tables");
01414
01415 e_symbols = (EXTR *) read_seek (NULL,
01416 sym_hdr.iextMax * sizeof (EXTR),
01417 sym_hdr.cbExtOffset,
01418 "External symbols");
01419 }
01420
01421
01422
01423 extern int main PARAMS ((int, char **));
01424
01425 int
01426 main (argc, argv)
01427 int argc;
01428 char **argv;
01429 {
01430 int i, opt;
01431
01432
01433
01434
01435 while ((opt = getopt (argc, argv, "alrst")) != EOF)
01436 switch (opt)
01437 {
01438 default: errors++; break;
01439 case 'a': want_aux++; break;
01440 case 'l': want_line++; break;
01441 case 'r': want_rfd++; break;
01442 case 's': want_scope++; break;
01443 case 't': tfile++; break;
01444 }
01445
01446 if (errors || optind != argc - 1)
01447 {
01448 fprintf (stderr, "Calling Sequence:\n");
01449 fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]);
01450 fprintf (stderr, "\n");
01451 fprintf (stderr, "switches:\n");
01452 fprintf (stderr, "\t-a Print out auxiliary table.\n");
01453 fprintf (stderr, "\t-l Print out line numbers.\n");
01454 fprintf (stderr, "\t-r Print out relative file descriptors.\n");
01455 fprintf (stderr, "\t-s Print out the current scopes for an item.\n");
01456 fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n");
01457 return 1;
01458 }
01459
01460
01461
01462
01463 tfile_fd = open (argv[optind], O_RDONLY);
01464 if (tfile_fd < 0)
01465 {
01466 perror (argv[optind]);
01467 return 1;
01468 }
01469
01470 read_tfile ();
01471
01472
01473
01474
01475 if (want_aux)
01476 {
01477 long last_aux_in_use;
01478
01479 if (sym_hdr.ifdMax != 0 && file_desc[0].iauxBase != 0)
01480 {
01481 printf ("\nGlobal auxiliary entries before first file:\n");
01482 for (i = 0; i < file_desc[0].iauxBase; i++)
01483 print_aux (aux_symbols[i], 0, aux_used[i]);
01484 }
01485
01486 if (sym_hdr.ifdMax == 0)
01487 last_aux_in_use = 0;
01488 else
01489 last_aux_in_use
01490 = (file_desc[sym_hdr.ifdMax-1].iauxBase
01491 + file_desc[sym_hdr.ifdMax-1].caux - 1);
01492
01493 if (last_aux_in_use < sym_hdr.iauxMax-1)
01494 {
01495 printf ("\nGlobal auxiliary entries after last file:\n");
01496 for (i = last_aux_in_use; i < sym_hdr.iauxMax; i++)
01497 print_aux (aux_symbols[i], i - last_aux_in_use, aux_used[i]);
01498 }
01499 }
01500
01501
01502
01503
01504 for (i = 0; i < sym_hdr.ifdMax; i++)
01505 print_file_desc (&file_desc[i], i);
01506
01507
01508
01509
01510 want_scope = 0;
01511 printf ("\nThere are %lu external symbols, starting at %lu\n",
01512 (ulong) sym_hdr.iextMax,
01513 (ulong) sym_hdr.cbExtOffset);
01514
01515 for(i = 0; i < sym_hdr.iextMax; i++)
01516 print_symbol (&e_symbols[i].asym, i, e_strings,
01517 aux_symbols + file_desc[e_symbols[i].ifd].iauxBase,
01518 e_symbols[i].ifd,
01519 &file_desc[e_symbols[i].ifd]);
01520
01521
01522
01523
01524
01525 if (want_aux)
01526 {
01527 int first_time = 1;
01528
01529 for (i = 0; i < sym_hdr.iauxMax; i++)
01530 {
01531 if (! aux_used[i])
01532 {
01533 if (first_time)
01534 {
01535 printf ("\nThe following auxiliary table entries were unused:\n\n");
01536 first_time = 0;
01537 }
01538
01539 printf (" #%-5d %11ld 0x%08lx %s\n",
01540 i,
01541 (long) aux_symbols[i].isym,
01542 (long) aux_symbols[i].isym,
01543 type_to_string (aux_symbols, i, (FDR *) 0));
01544 }
01545 }
01546 }
01547
01548 return 0;
01549 }