00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 #include "config.h"
00604 #include "system.h"
00605 #include "version.h"
00606 #include "intl.h"
00607
00608 #ifndef __SABER__
00609 #define saber_stop()
00610 #endif
00611
00612 #ifndef __LINE__
00613 #define __LINE__ 0
00614 #endif
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 #if defined(__OSF1__) || defined(__OSF__) || defined(__osf__)
00625 #define Size_t long unsigned int
00626 #else
00627 #define Size_t unsigned int
00628 #endif
00629 #define Ptrdiff_t long
00630
00631
00632
00633
00634 extern void pfatal_with_name
00635 PARAMS ((const char *)) ATTRIBUTE_NORETURN;
00636 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
00637 void botch PARAMS ((const char *)) ATTRIBUTE_NORETURN;
00638
00639 extern void fatal PARAMS ((const char *format, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
00640 extern void error PARAMS ((const char *format, ...)) ATTRIBUTE_PRINTF_1;
00641
00642 #ifndef MIPS_DEBUGGING_INFO
00643
00644 static int line_number;
00645 static int cur_line_start;
00646 static int debug;
00647 static int had_errors;
00648 static const char *progname;
00649 static const char *input_name;
00650
00651 int
00652 main ()
00653 {
00654 fprintf (stderr, "Mips-tfile should only be run on a MIPS computer!\n");
00655 exit (1);
00656 }
00657
00658 #else
00659
00660
00661
00662
00663 #undef index
00664
00665 #include <signal.h>
00666
00667 #ifndef CROSS_COMPILE
00668 #include <a.out.h>
00669 #else
00670 #include "mips/a.out.h"
00671 #endif
00672
00673 #include "gstab.h"
00674
00675 #define STAB_CODE_TYPE enum __stab_debug_code
00676
00677 #ifndef MALLOC_CHECK
00678 #ifdef __SABER__
00679 #define MALLOC_CHECK
00680 #endif
00681 #endif
00682
00683 #define IS_ASM_IDENT(ch) \
00684 (ISIDNUM (ch) || (ch) == '.' || (ch) == '$')
00685
00686
00687
00688
00689
00690 typedef enum sc {
00691 sc_Nil = scNil,
00692 sc_Text = scText,
00693 sc_Data = scData,
00694 sc_Bss = scBss,
00695 sc_Register = scRegister,
00696 sc_Abs = scAbs,
00697 sc_Undefined = scUndefined,
00698 sc_CdbLocal = scCdbLocal,
00699 sc_Bits = scBits,
00700 sc_CdbSystem = scCdbSystem,
00701 sc_RegImage = scRegImage,
00702 sc_Info = scInfo,
00703 sc_UserStruct = scUserStruct,
00704 sc_SData = scSData,
00705 sc_SBss = scSBss,
00706 sc_RData = scRData,
00707 sc_Var = scVar,
00708 sc_Common = scCommon,
00709 sc_SCommon = scSCommon,
00710 sc_VarRegister = scVarRegister,
00711 sc_Variant = scVariant,
00712 sc_SUndefined = scSUndefined,
00713 sc_Init = scInit,
00714 sc_Max = scMax
00715 } sc_t;
00716
00717
00718
00719 typedef enum st {
00720 st_Nil = stNil,
00721 st_Global = stGlobal,
00722 st_Static = stStatic,
00723 st_Param = stParam,
00724 st_Local = stLocal,
00725 st_Label = stLabel,
00726 st_Proc = stProc,
00727 st_Block = stBlock,
00728 st_End = stEnd,
00729 st_Member = stMember,
00730 st_Typedef = stTypedef,
00731 st_File = stFile,
00732 st_RegReloc = stRegReloc,
00733 st_Forward = stForward,
00734 st_StaticProc = stStaticProc,
00735 st_Constant = stConstant,
00736 st_Str = stStr,
00737 st_Number = stNumber,
00738 st_Expr = stExpr,
00739 st_Type = stType,
00740 st_Max = stMax
00741 } st_t;
00742
00743
00744
00745 typedef enum tq {
00746 tq_Nil = tqNil,
00747 tq_Ptr = tqPtr,
00748 tq_Proc = tqProc,
00749 tq_Array = tqArray,
00750 tq_Far = tqFar,
00751 tq_Vol = tqVol,
00752 tq_Max = tqMax
00753 } tq_t;
00754
00755
00756
00757 typedef enum bt {
00758 bt_Nil = btNil,
00759 bt_Adr = btAdr,
00760 bt_Char = btChar,
00761 bt_UChar = btUChar,
00762 bt_Short = btShort,
00763 bt_UShort = btUShort,
00764 bt_Int = btInt,
00765 bt_UInt = btUInt,
00766 bt_Long = btLong,
00767 bt_ULong = btULong,
00768 bt_Float = btFloat,
00769 bt_Double = btDouble,
00770 bt_Struct = btStruct,
00771 bt_Union = btUnion,
00772 bt_Enum = btEnum,
00773 bt_Typedef = btTypedef,
00774 bt_Range = btRange,
00775 bt_Set = btSet,
00776 bt_Complex = btComplex,
00777 bt_DComplex = btDComplex,
00778 bt_Indirect = btIndirect,
00779 bt_FixedDec = btFixedDec,
00780 bt_FloatDec = btFloatDec,
00781 bt_String = btString,
00782 bt_Bit = btBit,
00783 bt_Picture = btPicture,
00784
00785 #ifdef btVoid
00786 bt_Void = btVoid,
00787 #else
00788 #define bt_Void bt_Nil
00789 #endif
00790
00791 bt_Max = btMax
00792 } bt_t;
00793
00794
00795
00796
00797 enum coff_storage {
00798 C_EFCN = -1,
00799 C_NULL = 0,
00800 C_AUTO = 1,
00801 C_EXT = 2,
00802 C_STAT = 3,
00803 C_REG = 4,
00804 C_EXTDEF = 5,
00805 C_LABEL = 6,
00806 C_ULABEL = 7,
00807 C_MOS = 8,
00808 C_ARG = 9,
00809 C_STRTAG = 10,
00810 C_MOU = 11,
00811 C_UNTAG = 12,
00812 C_TPDEF = 13,
00813 C_USTATIC = 14,
00814 C_ENTAG = 15,
00815 C_MOE = 16,
00816 C_REGPARM = 17,
00817 C_FIELD = 18,
00818 C_BLOCK = 100,
00819 C_FCN = 101,
00820 C_EOS = 102,
00821 C_FILE = 103,
00822 C_LINE = 104,
00823 C_ALIAS = 105,
00824 C_HIDDEN = 106,
00825 C_MAX = 107
00826 } coff_storage_t;
00827
00828
00829 typedef enum coff_type {
00830 T_NULL = 0,
00831 T_ARG = 1,
00832 T_CHAR = 2,
00833 T_SHORT = 3,
00834 T_INT = 4,
00835 T_LONG = 5,
00836 T_FLOAT = 6,
00837 T_DOUBLE = 7,
00838 T_STRUCT = 8,
00839 T_UNION = 9,
00840 T_ENUM = 10,
00841 T_MOE = 11,
00842 T_UCHAR = 12,
00843 T_USHORT = 13,
00844 T_UINT = 14,
00845 T_ULONG = 15,
00846 T_MAX = 16
00847 } coff_type_t;
00848
00849
00850 typedef enum coff_dt {
00851 DT_NON = 0,
00852 DT_PTR = 1,
00853 DT_FCN = 2,
00854 DT_ARY = 3,
00855 DT_MAX = 4
00856 } coff_dt_t;
00857
00858 #define N_BTMASK 017
00859 #define N_TMASK 003
00860 #define N_BT_SHIFT 4
00861 #define N_TQ_SHIFT 2
00862 #define N_TQ 6
00863
00864
00865 typedef enum hash_state {
00866 hash_no = 0,
00867 hash_yes = 1,
00868 hash_record = 2
00869 } hash_state_t;
00870
00871
00872
00873 enum alloc_type {
00874 alloc_type_none,
00875 alloc_type_scope,
00876 alloc_type_vlinks,
00877 alloc_type_shash,
00878 alloc_type_thash,
00879 alloc_type_tag,
00880 alloc_type_forward,
00881 alloc_type_thead,
00882 alloc_type_varray,
00883 alloc_type_last
00884 };
00885
00886
00887 #define WORD_ALIGN(x) (((x) + (sizeof (long) - 1)) & ~ (sizeof (long) - 1))
00888 #define DWORD_ALIGN(x) (((x) + 7) & ~7)
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901 #ifndef PAGE_SIZE
00902 #define PAGE_SIZE 4096
00903 #endif
00904
00905 #define PAGE_USIZE ((Size_t) PAGE_SIZE)
00906
00907
00908 #ifndef MAX_CLUSTER_PAGES
00909 #ifndef USE_MALLOC
00910 #define MAX_CLUSTER_PAGES 64
00911 #else
00912 #define MAX_CLUSTER_PAGES 63
00913 #endif
00914 #endif
00915
00916
00917
00918 typedef struct vlinks {
00919 struct vlinks *prev;
00920 struct vlinks *next;
00921 union page *datum;
00922 unsigned long start_index;
00923 } vlinks_t;
00924
00925
00926
00927 typedef struct varray {
00928 vlinks_t *first;
00929 vlinks_t *last;
00930 unsigned long num_allocated;
00931 unsigned short object_size;
00932 unsigned short objects_per_page;
00933 unsigned short objects_last_page;
00934 } varray_t;
00935
00936 #ifndef MALLOC_CHECK
00937 #define OBJECTS_PER_PAGE(type) (PAGE_SIZE / sizeof (type))
00938 #else
00939 #define OBJECTS_PER_PAGE(type) ((sizeof (type) > 1) ? 1 : PAGE_SIZE)
00940 #endif
00941
00942 #define INIT_VARRAY(type) { \
00943 (vlinks_t *) 0, \
00944 (vlinks_t *) 0, \
00945 0, \
00946 sizeof (type), \
00947 OBJECTS_PER_PAGE (type), \
00948 OBJECTS_PER_PAGE (type), \
00949 }
00950
00951
00952 typedef unsigned long symint_t;
00953
00954
00955
00956 typedef struct scope {
00957 struct scope *prev;
00958 struct scope *free;
00959 SYMR *lsym;
00960 symint_t lnumber;
00961 st_t type;
00962 } scope_t;
00963
00964
00965
00966 typedef struct forward {
00967 struct forward *next;
00968 struct forward *free;
00969 AUXU *ifd_ptr;
00970 AUXU *index_ptr;
00971 AUXU *type_ptr;
00972 } forward_t;
00973
00974
00975
00976
00977 typedef struct tag {
00978 struct tag *free;
00979 struct shash *hash_ptr;
00980 struct tag *same_name;
00981 struct tag *same_block;
00982 struct forward *forward_ref;
00983 bt_t basic_type;
00984 symint_t ifd;
00985 symint_t indx;
00986 } tag_t;
00987
00988
00989
00990 typedef struct thead {
00991 struct thead *prev;
00992 struct thead *free;
00993 struct tag *first_tag;
00994 } thead_t;
00995
00996
00997
00998 typedef union small_free {
00999 scope_t *f_scope;
01000 thead_t *f_thead;
01001 tag_t *f_tag;
01002 forward_t *f_forward;
01003 } small_free_t;
01004
01005
01006
01007
01008
01009 #ifndef SHASH_SIZE
01010 #define SHASH_SIZE 1009
01011 #endif
01012
01013 #define HASH_LEN_MAX ((1 << 12) - 1)
01014
01015 typedef struct shash {
01016 struct shash *next;
01017 char *string;
01018 symint_t len;
01019 symint_t indx;
01020 EXTR *esym_ptr;
01021 SYMR *sym_ptr;
01022 SYMR *end_ptr;
01023 tag_t *tag_ptr;
01024 PDR *proc_ptr;
01025 } shash_t;
01026
01027
01028
01029
01030
01031
01032
01033 #ifndef THASH_SIZE
01034 #define THASH_SIZE 113
01035 #endif
01036
01037 typedef struct thash {
01038 struct thash *next;
01039 AUXU type;
01040 symint_t indx;
01041 } thash_t;
01042
01043
01044
01045
01046 typedef struct efdr {
01047 FDR fdr;
01048 FDR *orig_fdr;
01049 char *name;
01050 int name_len;
01051 symint_t void_type;
01052 symint_t int_type;
01053 scope_t *cur_scope;
01054 symint_t file_index;
01055 int nested_scopes;
01056 varray_t strings;
01057 varray_t symbols;
01058 varray_t procs;
01059 varray_t aux_syms;
01060 struct efdr *next_file;
01061
01062 shash_t **shash_head;
01063 thash_t *thash_head[THASH_SIZE];
01064 } efdr_t;
01065
01066
01067 static efdr_t init_file =
01068 {
01069 {
01070 #ifdef __alpha
01071 0,
01072 0,
01073 0,
01074 0,
01075 0,
01076 0,
01077 0,
01078 0,
01079 0,
01080 0,
01081 0,
01082 0,
01083 0,
01084 0,
01085 0,
01086 0,
01087 0,
01088 0,
01089 langC,
01090 1,
01091 0,
01092 #ifdef HOST_WORDS_BIG_ENDIAN
01093 1,
01094 #else
01095 0,
01096 #endif
01097 0,
01098 GLEVEL_2,
01099 0,
01100 #else
01101 0,
01102 0,
01103 0,
01104 0,
01105 0,
01106 0,
01107 0,
01108 0,
01109 0,
01110 0,
01111 0,
01112 0,
01113 0,
01114 0,
01115 0,
01116 0,
01117 langC,
01118 1,
01119 0,
01120 #ifdef HOST_WORDS_BIG_ENDIAN
01121 1,
01122 #else
01123 0,
01124 #endif
01125 GLEVEL_2,
01126 0,
01127 0,
01128 0,
01129 #endif
01130 },
01131
01132 (FDR *) 0,
01133 (char *) 0,
01134 0,
01135 0,
01136 0,
01137 (scope_t *) 0,
01138 0,
01139 0,
01140 INIT_VARRAY (char),
01141 INIT_VARRAY (SYMR),
01142 INIT_VARRAY (PDR),
01143 INIT_VARRAY (AUXU),
01144
01145 (struct efdr *) 0,
01146
01147 (shash_t **) 0,
01148 { 0 },
01149 };
01150
01151
01152 static efdr_t *first_file;
01153 static efdr_t **last_file_ptr = &first_file;
01154
01155
01156
01157 typedef union page {
01158 char byte [ PAGE_SIZE ];
01159 unsigned char ubyte [ PAGE_SIZE ];
01160 efdr_t file [ PAGE_SIZE / sizeof (efdr_t) ];
01161 FDR ofile [ PAGE_SIZE / sizeof (FDR) ];
01162 PDR proc [ PAGE_SIZE / sizeof (PDR) ];
01163 SYMR sym [ PAGE_SIZE / sizeof (SYMR) ];
01164 EXTR esym [ PAGE_SIZE / sizeof (EXTR) ];
01165 AUXU aux [ PAGE_SIZE / sizeof (AUXU) ];
01166 DNR dense [ PAGE_SIZE / sizeof (DNR) ];
01167 scope_t scope [ PAGE_SIZE / sizeof (scope_t) ];
01168 vlinks_t vlinks [ PAGE_SIZE / sizeof (vlinks_t) ];
01169 shash_t shash [ PAGE_SIZE / sizeof (shash_t) ];
01170 thash_t thash [ PAGE_SIZE / sizeof (thash_t) ];
01171 tag_t tag [ PAGE_SIZE / sizeof (tag_t) ];
01172 forward_t forward [ PAGE_SIZE / sizeof (forward_t) ];
01173 thead_t thead [ PAGE_SIZE / sizeof (thead_t) ];
01174 } page_t;
01175
01176
01177
01178 typedef struct alloc_info {
01179 const char *alloc_name;
01180 page_t *cur_page;
01181 small_free_t free_list;
01182 int unallocated;
01183 int total_alloc;
01184 int total_free;
01185 int total_pages;
01186 } alloc_info_t;
01187
01188
01189 typedef struct type_info {
01190 bt_t basic_type;
01191 coff_type_t orig_type;
01192 int num_tq;
01193 int num_dims;
01194 int num_sizes;
01195 int extra_sizes;
01196 tag_t * tag_ptr;
01197 int bitfield;
01198 int unknown_tag;
01199 tq_t type_qualifiers[N_TQ];
01200 symint_t dimensions [N_TQ];
01201 symint_t sizes [N_TQ+2];
01202
01203 } type_info_t;
01204
01205
01206 static type_info_t type_info_init = {
01207 bt_Nil,
01208 T_NULL,
01209 0,
01210 0,
01211 0,
01212 0,
01213 NULL,
01214 0,
01215 0,
01216 {
01217 tq_Nil,
01218 tq_Nil,
01219 tq_Nil,
01220 tq_Nil,
01221 tq_Nil,
01222 tq_Nil,
01223 },
01224 {
01225 0,
01226 0,
01227 0,
01228 0,
01229 0,
01230 0
01231 },
01232 {
01233 0,
01234 0,
01235 0,
01236 0,
01237 0,
01238 0,
01239 0,
01240 0,
01241 },
01242 };
01243
01244
01245
01246
01247
01248
01249 static varray_t file_desc = INIT_VARRAY (efdr_t);
01250 static varray_t dense_num = INIT_VARRAY (DNR);
01251 static varray_t tag_strings = INIT_VARRAY (char);
01252 static varray_t ext_strings = INIT_VARRAY (char);
01253 static varray_t ext_symbols = INIT_VARRAY (EXTR);
01254
01255 static shash_t *orig_str_hash[SHASH_SIZE];
01256 static shash_t *ext_str_hash [SHASH_SIZE];
01257 static shash_t *tag_hash [SHASH_SIZE];
01258
01259
01260
01261
01262
01263 static type_info_t int_type_info;
01264 static type_info_t void_type_info;
01265 static type_info_t last_func_type_info;
01266 static EXTR *last_func_eptr;
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276 static const bt_t map_coff_types[ (int) T_MAX ] = {
01277 bt_Nil,
01278 bt_Nil,
01279 bt_Char,
01280 bt_Short,
01281 bt_Int,
01282 bt_Long,
01283 bt_Float,
01284 bt_Double,
01285 bt_Struct,
01286 bt_Union,
01287 bt_Enum,
01288 bt_Enum,
01289 bt_UChar,
01290 bt_UShort,
01291 bt_UInt,
01292 bt_ULong
01293 };
01294
01295
01296 static const sc_t map_coff_storage[ (int) C_MAX ] = {
01297 sc_Nil,
01298 sc_Abs,
01299 sc_Undefined,
01300 sc_Data,
01301 sc_Register,
01302 sc_Undefined,
01303 sc_Text,
01304 sc_Text,
01305 sc_Info,
01306 sc_Abs,
01307 sc_Info,
01308 sc_Info,
01309 sc_Info,
01310 sc_Info,
01311 sc_Data,
01312 sc_Info,
01313 sc_Info,
01314 sc_Register,
01315 sc_Bits,
01316 sc_Nil,
01317 sc_Nil,
01318 sc_Nil,
01319 sc_Nil,
01320 sc_Nil,
01321 sc_Nil,
01322 sc_Nil,
01323 sc_Nil,
01324 sc_Nil,
01325 sc_Nil,
01326 sc_Nil,
01327 sc_Nil,
01328 sc_Nil,
01329 sc_Nil,
01330 sc_Nil,
01331 sc_Nil,
01332 sc_Nil,
01333 sc_Nil,
01334 sc_Nil,
01335 sc_Nil,
01336 sc_Nil,
01337 sc_Nil,
01338 sc_Nil,
01339 sc_Nil,
01340 sc_Nil,
01341 sc_Nil,
01342 sc_Nil,
01343 sc_Nil,
01344 sc_Nil,
01345 sc_Nil,
01346 sc_Nil,
01347 sc_Nil,
01348 sc_Nil,
01349 sc_Nil,
01350 sc_Nil,
01351 sc_Nil,
01352 sc_Nil,
01353 sc_Nil,
01354 sc_Nil,
01355 sc_Nil,
01356 sc_Nil,
01357 sc_Nil,
01358 sc_Nil,
01359 sc_Nil,
01360 sc_Nil,
01361 sc_Nil,
01362 sc_Nil,
01363 sc_Nil,
01364 sc_Nil,
01365 sc_Nil,
01366 sc_Nil,
01367 sc_Nil,
01368 sc_Nil,
01369 sc_Nil,
01370 sc_Nil,
01371 sc_Nil,
01372 sc_Nil,
01373 sc_Nil,
01374 sc_Nil,
01375 sc_Nil,
01376 sc_Nil,
01377 sc_Nil,
01378 sc_Nil,
01379 sc_Nil,
01380 sc_Nil,
01381 sc_Nil,
01382 sc_Nil,
01383 sc_Nil,
01384 sc_Nil,
01385 sc_Nil,
01386 sc_Nil,
01387 sc_Nil,
01388 sc_Nil,
01389 sc_Nil,
01390 sc_Nil,
01391 sc_Nil,
01392 sc_Nil,
01393 sc_Nil,
01394 sc_Nil,
01395 sc_Nil,
01396 sc_Nil,
01397 sc_Text,
01398 sc_Text,
01399 sc_Info,
01400 sc_Nil,
01401 sc_Nil,
01402 sc_Nil,
01403 sc_Nil,
01404 };
01405
01406
01407 static const st_t map_coff_sym_type[ (int) C_MAX ] = {
01408 st_Nil,
01409 st_Local,
01410 st_Global,
01411 st_Static,
01412 st_Local,
01413 st_Global,
01414 st_Label,
01415 st_Label,
01416 st_Member,
01417 st_Param,
01418 st_Block,
01419 st_Member,
01420 st_Block,
01421 st_Typedef,
01422 st_Static,
01423 st_Block,
01424 st_Member,
01425 st_Param,
01426 st_Member,
01427 st_Nil,
01428 st_Nil,
01429 st_Nil,
01430 st_Nil,
01431 st_Nil,
01432 st_Nil,
01433 st_Nil,
01434 st_Nil,
01435 st_Nil,
01436 st_Nil,
01437 st_Nil,
01438 st_Nil,
01439 st_Nil,
01440 st_Nil,
01441 st_Nil,
01442 st_Nil,
01443 st_Nil,
01444 st_Nil,
01445 st_Nil,
01446 st_Nil,
01447 st_Nil,
01448 st_Nil,
01449 st_Nil,
01450 st_Nil,
01451 st_Nil,
01452 st_Nil,
01453 st_Nil,
01454 st_Nil,
01455 st_Nil,
01456 st_Nil,
01457 st_Nil,
01458 st_Nil,
01459 st_Nil,
01460 st_Nil,
01461 st_Nil,
01462 st_Nil,
01463 st_Nil,
01464 st_Nil,
01465 st_Nil,
01466 st_Nil,
01467 st_Nil,
01468 st_Nil,
01469 st_Nil,
01470 st_Nil,
01471 st_Nil,
01472 st_Nil,
01473 st_Nil,
01474 st_Nil,
01475 st_Nil,
01476 st_Nil,
01477 st_Nil,
01478 st_Nil,
01479 st_Nil,
01480 st_Nil,
01481 st_Nil,
01482 st_Nil,
01483 st_Nil,
01484 st_Nil,
01485 st_Nil,
01486 st_Nil,
01487 st_Nil,
01488 st_Nil,
01489 st_Nil,
01490 st_Nil,
01491 st_Nil,
01492 st_Nil,
01493 st_Nil,
01494 st_Nil,
01495 st_Nil,
01496 st_Nil,
01497 st_Nil,
01498 st_Nil,
01499 st_Nil,
01500 st_Nil,
01501 st_Nil,
01502 st_Nil,
01503 st_Nil,
01504 st_Nil,
01505 st_Nil,
01506 st_Nil,
01507 st_Nil,
01508 st_Block,
01509 st_Proc,
01510 st_End,
01511 st_File,
01512 st_Nil,
01513 st_Nil,
01514 st_Nil,
01515 };
01516
01517
01518 static const tq_t map_coff_derived_type[ (int) DT_MAX ] = {
01519 tq_Nil,
01520 tq_Ptr,
01521 tq_Proc,
01522 tq_Array,
01523 };
01524
01525
01526
01527 static alloc_info_t alloc_counts[ (int) alloc_type_last ];
01528
01529
01530
01531 static struct filehdr orig_file_header;
01532
01533 static HDRR orig_sym_hdr;
01534 static char *orig_linenum;
01535 static DNR *orig_dense;
01536 static PDR *orig_procs;
01537 static SYMR *orig_local_syms;
01538 static OPTR *orig_opt_syms;
01539 static AUXU *orig_aux_syms;
01540 static char *orig_local_strs;
01541 static char *orig_ext_strs;
01542 static FDR *orig_files;
01543 static symint_t *orig_rfds;
01544 static EXTR *orig_ext_syms;
01545
01546
01547
01548 #define CHECK(num,max,str) \
01549 (((unsigned long) num > (unsigned long) max) ? out_of_bounds (num, max, str, __LINE__) : 0)
01550
01551 #define ORIG_LINENUM(indx) (CHECK ((indx), orig_sym_hdr.cbLine, "line#"), (indx) + orig_linenum)
01552 #define ORIG_DENSE(indx) (CHECK ((indx), orig_sym_hdr.idnMax, "dense"), (indx) + orig_dense)
01553 #define ORIG_PROCS(indx) (CHECK ((indx), orig_sym_hdr.ipdMax, "procs"), (indx) + orig_procs)
01554 #define ORIG_FILES(indx) (CHECK ((indx), orig_sym_hdr.ifdMax, "funcs"), (indx) + orig_files)
01555 #define ORIG_LSYMS(indx) (CHECK ((indx), orig_sym_hdr.isymMax, "lsyms"), (indx) + orig_local_syms)
01556 #define ORIG_LSTRS(indx) (CHECK ((indx), orig_sym_hdr.issMax, "lstrs"), (indx) + orig_local_strs)
01557 #define ORIG_ESYMS(indx) (CHECK ((indx), orig_sym_hdr.iextMax, "esyms"), (indx) + orig_ext_syms)
01558 #define ORIG_ESTRS(indx) (CHECK ((indx), orig_sym_hdr.issExtMax, "estrs"), (indx) + orig_ext_strs)
01559 #define ORIG_OPT(indx) (CHECK ((indx), orig_sym_hdr.ioptMax, "opt"), (indx) + orig_opt_syms)
01560 #define ORIG_AUX(indx) (CHECK ((indx), orig_sym_hdr.iauxMax, "aux"), (indx) + orig_aux_syms)
01561 #define ORIG_RFDS(indx) (CHECK ((indx), orig_sym_hdr.crfd, "rfds"), (indx) + orig_rfds)
01562
01563
01564 static HDRR symbolic_header;
01565 static efdr_t *cur_file_ptr = (efdr_t *) 0;
01566 static PDR *cur_proc_ptr = (PDR *) 0;
01567 static SYMR *cur_oproc_begin = (SYMR *) 0;
01568 static SYMR *cur_oproc_end = (SYMR *) 0;
01569 static PDR *cur_oproc_ptr = (PDR *) 0;
01570 static thead_t *cur_tag_head = (thead_t *) 0;
01571 static long file_offset = 0;
01572 static long max_file_offset = 0;
01573 static FILE *object_stream = (FILE *) 0;
01574 static FILE *obj_in_stream = (FILE *) 0;
01575 static char *progname = (char *) 0;
01576 static const char *input_name = "stdin";
01577 static char *object_name = (char *) 0;
01578 static char *obj_in_name = (char *) 0;
01579 static char *cur_line_start = (char *) 0;
01580 static char *cur_line_ptr = (char *) 0;
01581 static unsigned cur_line_nbytes = 0;
01582 static unsigned cur_line_alloc = 0;
01583 static long line_number = 0;
01584 static int debug = 0;
01585 static int version = 0;
01586 static int had_errors = 0;
01587 static int rename_output = 0;
01588 static int delete_input = 0;
01589 static int stabs_seen = 0;
01590
01591
01592
01593 #ifndef STABS_SYMBOL
01594 #define STABS_SYMBOL "@stabs"
01595 #endif
01596
01597 static const char stabs_symbol[] = STABS_SYMBOL;
01598
01599
01600
01601
01602 #ifndef STATIC
01603 #define STATIC static
01604 #endif
01605
01606 STATIC int out_of_bounds PARAMS ((symint_t, symint_t, const char *, int));
01607
01608 STATIC shash_t *hash_string PARAMS ((const char *,
01609 Ptrdiff_t,
01610 shash_t **,
01611 symint_t *));
01612
01613 STATIC symint_t add_string PARAMS ((varray_t *,
01614 shash_t **,
01615 const char *,
01616 const char *,
01617 shash_t **));
01618
01619 STATIC symint_t add_local_symbol
01620 PARAMS ((const char *,
01621 const char *,
01622 st_t,
01623 sc_t,
01624 symint_t,
01625 symint_t));
01626
01627 STATIC symint_t add_ext_symbol PARAMS ((EXTR *,
01628 int));
01629
01630 STATIC symint_t add_aux_sym_symint
01631 PARAMS ((symint_t));
01632
01633 STATIC symint_t add_aux_sym_rndx
01634 PARAMS ((int, symint_t));
01635
01636 STATIC symint_t add_aux_sym_tir PARAMS ((type_info_t *,
01637 hash_state_t,
01638 thash_t **));
01639
01640 STATIC tag_t * get_tag PARAMS ((const char *,
01641 const char *,
01642 symint_t,
01643 bt_t));
01644
01645 STATIC void add_unknown_tag PARAMS ((tag_t *));
01646
01647 STATIC void add_procedure PARAMS ((const char *,
01648 const char *));
01649
01650 STATIC void add_file PARAMS ((const char *,
01651 const char *));
01652
01653 STATIC void add_bytes PARAMS ((varray_t *,
01654 char *,
01655 Size_t));
01656
01657 STATIC void add_varray_page PARAMS ((varray_t *));
01658
01659 STATIC void update_headers PARAMS ((void));
01660
01661 STATIC void write_varray PARAMS ((varray_t *, off_t, const char *));
01662 STATIC void write_object PARAMS ((void));
01663 STATIC const char *st_to_string PARAMS ((st_t));
01664 STATIC const char *sc_to_string PARAMS ((sc_t));
01665 STATIC char *read_line PARAMS ((void));
01666 STATIC void parse_input PARAMS ((void));
01667 STATIC void mark_stabs PARAMS ((const char *));
01668 STATIC void parse_begin PARAMS ((const char *));
01669 STATIC void parse_bend PARAMS ((const char *));
01670 STATIC void parse_def PARAMS ((const char *));
01671 STATIC void parse_end PARAMS ((const char *));
01672 STATIC void parse_ent PARAMS ((const char *));
01673 STATIC void parse_file PARAMS ((const char *));
01674 STATIC void parse_stabs_common
01675 PARAMS ((const char *, const char *, const char *));
01676 STATIC void parse_stabs PARAMS ((const char *));
01677 STATIC void parse_stabn PARAMS ((const char *));
01678 STATIC page_t *read_seek PARAMS ((Size_t, off_t, const char *));
01679 STATIC void copy_object PARAMS ((void));
01680
01681 STATIC void catch_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
01682 STATIC page_t *allocate_page PARAMS ((void));
01683
01684 STATIC page_t *allocate_multiple_pages
01685 PARAMS ((Size_t));
01686
01687 STATIC void free_multiple_pages
01688 PARAMS ((page_t *, Size_t));
01689
01690 #ifndef MALLOC_CHECK
01691 STATIC page_t *allocate_cluster
01692 PARAMS ((Size_t));
01693 #endif
01694
01695 STATIC forward_t *allocate_forward PARAMS ((void));
01696 STATIC scope_t *allocate_scope PARAMS ((void));
01697 STATIC shash_t *allocate_shash PARAMS ((void));
01698 STATIC tag_t *allocate_tag PARAMS ((void));
01699 STATIC thash_t *allocate_thash PARAMS ((void));
01700 STATIC thead_t *allocate_thead PARAMS ((void));
01701 STATIC vlinks_t *allocate_vlinks PARAMS ((void));
01702
01703 STATIC void free_forward PARAMS ((forward_t *));
01704 STATIC void free_scope PARAMS ((scope_t *));
01705 STATIC void free_tag PARAMS ((tag_t *));
01706 STATIC void free_thead PARAMS ((thead_t *));
01707
01708 extern char *optarg;
01709 extern int optind;
01710 extern int opterr;
01711
01712
01713
01714
01715
01716
01717 typedef struct _pseudo_ops {
01718 const char *const name;
01719 const int len;
01720 void (*const func) PARAMS ((const char *));
01721 } pseudo_ops_t;
01722
01723 static const pseudo_ops_t pseudo_ops[] = {
01724 { "#.def", sizeof("#.def")-1, parse_def },
01725 { "#.begin", sizeof("#.begin")-1, parse_begin },
01726 { "#.bend", sizeof("#.bend")-1, parse_bend },
01727 { ".end", sizeof(".end")-1, parse_end },
01728 { ".ent", sizeof(".ent")-1, parse_ent },
01729 { ".file", sizeof(".file")-1, parse_file },
01730 { "#.stabs", sizeof("#.stabs")-1, parse_stabs },
01731 { "#.stabn", sizeof("#.stabn")-1, parse_stabn },
01732 { ".stabs", sizeof(".stabs")-1, parse_stabs },
01733 { ".stabn", sizeof(".stabn")-1, parse_stabn },
01734 { "#@stabs", sizeof("#@stabs")-1, mark_stabs },
01735 };
01736
01737
01738
01739
01740 STATIC void
01741 add_varray_page (vp)
01742 varray_t *vp;
01743 {
01744 vlinks_t *new_links = allocate_vlinks ();
01745
01746 #ifdef MALLOC_CHECK
01747 if (vp->object_size > 1)
01748 new_links->datum = (page_t *) xcalloc (1, vp->object_size);
01749 else
01750 #endif
01751 new_links->datum = allocate_page ();
01752
01753 alloc_counts[ (int) alloc_type_varray ].total_alloc++;
01754 alloc_counts[ (int) alloc_type_varray ].total_pages++;
01755
01756 new_links->start_index = vp->num_allocated;
01757 vp->objects_last_page = 0;
01758
01759 if (vp->first == (vlinks_t *) 0)
01760 vp->first = vp->last = new_links;
01761 else
01762 {
01763 new_links->prev = vp->last;
01764 vp->last->next = new_links;
01765 vp->last = new_links;
01766 }
01767 }
01768
01769
01770
01771
01772 #define HASHBITS 30
01773
01774 STATIC shash_t *
01775 hash_string (text, hash_len, hash_tbl, ret_hash_index)
01776 const char *text;
01777 Ptrdiff_t hash_len;
01778 shash_t **hash_tbl;
01779 symint_t *ret_hash_index;
01780 {
01781 unsigned long hi;
01782 Ptrdiff_t i;
01783 shash_t *ptr;
01784 int first_ch = *text;
01785
01786 hi = hash_len;
01787 for (i = 0; i < hash_len; i++)
01788 hi = ((hi & 0x003fffff) * 613) + (text[i] & 0xff);
01789
01790 hi &= (1 << HASHBITS) - 1;
01791 hi %= SHASH_SIZE;
01792
01793 if (ret_hash_index != (symint_t *) 0)
01794 *ret_hash_index = hi;
01795
01796 for (ptr = hash_tbl[hi]; ptr != (shash_t *) 0; ptr = ptr->next)
01797 if ((symint_t) hash_len == ptr->len
01798 && first_ch == ptr->string[0]
01799 && memcmp (text, ptr->string, hash_len) == 0)
01800 break;
01801
01802 return ptr;
01803 }
01804
01805
01806
01807
01808
01809
01810 STATIC symint_t
01811 add_string (vp, hash_tbl, start, end_p1, ret_hash)
01812 varray_t *vp;
01813 shash_t **hash_tbl;
01814 const char *start;
01815 const char *end_p1;
01816 shash_t **ret_hash;
01817 {
01818 Ptrdiff_t len = end_p1 - start;
01819 shash_t *hash_ptr;
01820 symint_t hi;
01821
01822 if (len >= (Ptrdiff_t) PAGE_USIZE)
01823 fatal ("string too big (%ld bytes)", (long) len);
01824
01825 hash_ptr = hash_string (start, len, hash_tbl, &hi);
01826 if (hash_ptr == (shash_t *) 0)
01827 {
01828 char *p;
01829
01830 if (vp->objects_last_page + len >= (long) PAGE_USIZE)
01831 {
01832 vp->num_allocated
01833 = ((vp->num_allocated + PAGE_USIZE - 1) / PAGE_USIZE) * PAGE_USIZE;
01834 add_varray_page (vp);
01835 }
01836
01837 hash_ptr = allocate_shash ();
01838 hash_ptr->next = hash_tbl[hi];
01839 hash_tbl[hi] = hash_ptr;
01840
01841 hash_ptr->len = len;
01842 hash_ptr->indx = vp->num_allocated;
01843 hash_ptr->string = p = & vp->last->datum->byte[ vp->objects_last_page ];
01844
01845 vp->objects_last_page += len+1;
01846 vp->num_allocated += len+1;
01847
01848 while (len-- > 0)
01849 *p++ = *start++;
01850
01851 *p = '\0';
01852 }
01853
01854 if (ret_hash != (shash_t **) 0)
01855 *ret_hash = hash_ptr;
01856
01857 return hash_ptr->indx;
01858 }
01859
01860
01861
01862
01863 STATIC symint_t
01864 add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
01865 const char *str_start;
01866 const char *str_end_p1;
01867 st_t type;
01868 sc_t storage;
01869 symint_t value;
01870 symint_t indx;
01871 {
01872 symint_t ret;
01873 SYMR *psym;
01874 scope_t *pscope;
01875 thead_t *ptag_head;
01876 tag_t *ptag;
01877 tag_t *ptag_next;
01878 varray_t *vp = &cur_file_ptr->symbols;
01879 int scope_delta = 0;
01880 shash_t *hash_ptr = (shash_t *) 0;
01881
01882 if (vp->objects_last_page == vp->objects_per_page)
01883 add_varray_page (vp);
01884
01885 psym = &vp->last->datum->sym[ vp->objects_last_page++ ];
01886
01887 psym->value = value;
01888 psym->st = (unsigned) type;
01889 psym->sc = (unsigned) storage;
01890 psym->index = indx;
01891 psym->iss = (str_start == (const char *) 0)
01892 ? 0
01893 : add_string (&cur_file_ptr->strings,
01894 &cur_file_ptr->shash_head[0],
01895 str_start,
01896 str_end_p1,
01897 &hash_ptr);
01898
01899 ret = vp->num_allocated++;
01900
01901 if (MIPS_IS_STAB (psym))
01902 return ret;
01903
01904
01905
01906 if (hash_ptr != (shash_t *) 0
01907 && (type == st_Global || type == st_Static || type == st_Label
01908 || type == st_Proc || type == st_StaticProc))
01909 hash_ptr->sym_ptr = psym;
01910
01911
01912 switch (type)
01913 {
01914 default:
01915 break;
01916
01917 case st_File:
01918 case st_Proc:
01919 case st_StaticProc:
01920 case st_Block:
01921 pscope = allocate_scope ();
01922 pscope->prev = cur_file_ptr->cur_scope;
01923 pscope->lsym = psym;
01924 pscope->lnumber = ret;
01925 pscope->type = type;
01926 cur_file_ptr->cur_scope = pscope;
01927
01928 if (type != st_File)
01929 scope_delta = 1;
01930
01931
01932
01933
01934 if (type != st_File && storage != sc_Info)
01935 {
01936 ptag_head = allocate_thead ();
01937 ptag_head->first_tag = 0;
01938 ptag_head->prev = cur_tag_head;
01939 cur_tag_head = ptag_head;
01940 }
01941 break;
01942
01943 case st_End:
01944 pscope = cur_file_ptr->cur_scope;
01945 if (pscope == (scope_t *) 0)
01946 error ("internal error, too many st_End's");
01947
01948 else
01949 {
01950 st_t begin_type = (st_t) pscope->lsym->st;
01951
01952 if (begin_type != st_File)
01953 scope_delta = -1;
01954
01955
01956
01957 if (begin_type != st_File && storage != sc_Info)
01958 {
01959 ptag_head = cur_tag_head;
01960 cur_tag_head = ptag_head->prev;
01961
01962 for (ptag = ptag_head->first_tag;
01963 ptag != (tag_t *) 0;
01964 ptag = ptag_next)
01965 {
01966 if (ptag->forward_ref != (forward_t *) 0)
01967 add_unknown_tag (ptag);
01968
01969 ptag_next = ptag->same_block;
01970 ptag->hash_ptr->tag_ptr = ptag->same_name;
01971 free_tag (ptag);
01972 }
01973
01974 free_thead (ptag_head);
01975 }
01976
01977 cur_file_ptr->cur_scope = pscope->prev;
01978 psym->index = pscope->lnumber;
01979
01980 if (storage != sc_Info)
01981 psym->iss = pscope->lsym->iss;
01982
01983 if (begin_type == st_File || begin_type == st_Block)
01984 pscope->lsym->index = ret+1;
01985
01986
01987
01988
01989
01990 else
01991 {
01992 symint_t type;
01993 pscope->lsym->index = add_aux_sym_symint (ret+1);
01994 type = add_aux_sym_tir (&last_func_type_info,
01995 hash_no,
01996 &cur_file_ptr->thash_head[0]);
01997 if (last_func_eptr)
01998 {
01999 last_func_eptr->ifd = cur_file_ptr->file_index;
02000
02001
02002
02003 last_func_eptr->asym.index = psym->index;
02004 }
02005 }
02006
02007 free_scope (pscope);
02008 }
02009 }
02010
02011 cur_file_ptr->nested_scopes += scope_delta;
02012
02013 if (debug && type != st_File
02014 && (debug > 2 || type == st_Block || type == st_End
02015 || type == st_Proc || type == st_StaticProc))
02016 {
02017 const char *sc_str = sc_to_string (storage);
02018 const char *st_str = st_to_string (type);
02019 int depth = cur_file_ptr->nested_scopes + (scope_delta < 0);
02020
02021 fprintf (stderr,
02022 "\tlsym\tv= %10ld, depth= %2d, sc= %-12s",
02023 value, depth, sc_str);
02024
02025 if (str_start && str_end_p1 - str_start > 0)
02026 fprintf (stderr, " st= %-11s name= %.*s\n",
02027 st_str, (int) (str_end_p1 - str_start), str_start);
02028 else
02029 {
02030 Size_t len = strlen (st_str);
02031 fprintf (stderr, " st= %.*s\n", (int) (len-1), st_str);
02032 }
02033 }
02034
02035 return ret;
02036 }
02037
02038
02039
02040
02041 STATIC symint_t
02042 add_ext_symbol (esym, ifd)
02043 EXTR *esym;
02044 int ifd;
02045 {
02046 const char *str_start;
02047 const char *str_end_p1;
02048 EXTR *psym;
02049 varray_t *vp = &ext_symbols;
02050 shash_t *hash_ptr = (shash_t *) 0;
02051
02052 str_start = ORIG_ESTRS (esym->asym.iss);
02053 str_end_p1 = str_start + strlen (str_start);
02054
02055 if (debug > 1)
02056 {
02057 long value = esym->asym.value;
02058 const char *sc_str = sc_to_string (esym->asym.sc);
02059 const char *st_str = st_to_string (esym->asym.st);
02060
02061 fprintf (stderr,
02062 "\tesym\tv= %10ld, ifd= %2d, sc= %-12s",
02063 value, ifd, sc_str);
02064
02065 if (str_start && str_end_p1 - str_start > 0)
02066 fprintf (stderr, " st= %-11s name= %.*s\n",
02067 st_str, (int) (str_end_p1 - str_start), str_start);
02068 else
02069 fprintf (stderr, " st= %s\n", st_str);
02070 }
02071
02072 if (vp->objects_last_page == vp->objects_per_page)
02073 add_varray_page (vp);
02074
02075 psym = &vp->last->datum->esym[ vp->objects_last_page++ ];
02076
02077 *psym = *esym;
02078 psym->ifd = ifd;
02079 psym->asym.index = indexNil;
02080 psym->asym.iss = (str_start == (const char *) 0)
02081 ? 0
02082 : add_string (&ext_strings,
02083 &ext_str_hash[0],
02084 str_start,
02085 str_end_p1,
02086 &hash_ptr);
02087
02088 hash_ptr->esym_ptr = psym;
02089 return vp->num_allocated++;
02090 }
02091
02092
02093
02094
02095 STATIC symint_t
02096 add_aux_sym_symint (aux_word)
02097 symint_t aux_word;
02098 {
02099 AUXU *aux_ptr;
02100 efdr_t *file_ptr = cur_file_ptr;
02101 varray_t *vp = &file_ptr->aux_syms;
02102
02103 if (vp->objects_last_page == vp->objects_per_page)
02104 add_varray_page (vp);
02105
02106 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
02107 aux_ptr->isym = aux_word;
02108
02109 return vp->num_allocated++;
02110 }
02111
02112
02113
02114
02115 STATIC symint_t
02116 add_aux_sym_rndx (file_index, sym_index)
02117 int file_index;
02118 symint_t sym_index;
02119 {
02120 AUXU *aux_ptr;
02121 efdr_t *file_ptr = cur_file_ptr;
02122 varray_t *vp = &file_ptr->aux_syms;
02123
02124 if (vp->objects_last_page == vp->objects_per_page)
02125 add_varray_page (vp);
02126
02127 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
02128 aux_ptr->rndx.rfd = file_index;
02129 aux_ptr->rndx.index = sym_index;
02130
02131 return vp->num_allocated++;
02132 }
02133
02134
02135
02136
02137
02138 STATIC symint_t
02139 add_aux_sym_tir (t, state, hash_tbl)
02140 type_info_t *t;
02141 hash_state_t state;
02142 thash_t **hash_tbl;
02143 {
02144 AUXU *aux_ptr;
02145 efdr_t *file_ptr = cur_file_ptr;
02146 varray_t *vp = &file_ptr->aux_syms;
02147 static AUXU init_aux;
02148 symint_t ret;
02149 int i;
02150 AUXU aux;
02151
02152 aux = init_aux;
02153 aux.ti.bt = (int) t->basic_type;
02154 aux.ti.continued = 0;
02155 aux.ti.fBitfield = t->bitfield;
02156
02157 aux.ti.tq0 = (int) t->type_qualifiers[0];
02158 aux.ti.tq1 = (int) t->type_qualifiers[1];
02159 aux.ti.tq2 = (int) t->type_qualifiers[2];
02160 aux.ti.tq3 = (int) t->type_qualifiers[3];
02161 aux.ti.tq4 = (int) t->type_qualifiers[4];
02162 aux.ti.tq5 = (int) t->type_qualifiers[5];
02163
02164
02165
02166
02167
02168 if (state != hash_no
02169 && (t->type_qualifiers[0] == tq_Array
02170 || t->type_qualifiers[1] == tq_Array
02171 || t->type_qualifiers[2] == tq_Array
02172 || t->type_qualifiers[3] == tq_Array
02173 || t->type_qualifiers[4] == tq_Array
02174 || t->type_qualifiers[5] == tq_Array
02175 || t->basic_type == bt_Struct
02176 || t->basic_type == bt_Union
02177 || t->basic_type == bt_Enum
02178 || t->bitfield
02179 || t->num_dims > 0))
02180 state = hash_no;
02181
02182
02183
02184
02185
02186
02187 if (state != hash_no)
02188 {
02189 thash_t *hash_ptr;
02190 symint_t hi;
02191
02192 hi = aux.isym & ((1 << HASHBITS) - 1);
02193 hi %= THASH_SIZE;
02194
02195 for (hash_ptr = hash_tbl[hi];
02196 hash_ptr != (thash_t *) 0;
02197 hash_ptr = hash_ptr->next)
02198 {
02199 if (aux.isym == hash_ptr->type.isym)
02200 break;
02201 }
02202
02203 if (hash_ptr != (thash_t *) 0 && state == hash_yes)
02204 return hash_ptr->indx;
02205
02206 if (hash_ptr == (thash_t *) 0)
02207 {
02208 hash_ptr = allocate_thash ();
02209 hash_ptr->next = hash_tbl[hi];
02210 hash_ptr->type = aux;
02211 hash_ptr->indx = vp->num_allocated;
02212 hash_tbl[hi] = hash_ptr;
02213 }
02214 }
02215
02216
02217 if (vp->objects_last_page == vp->objects_per_page)
02218 add_varray_page (vp);
02219
02220 aux_ptr = &vp->last->datum->aux[ vp->objects_last_page++ ];
02221 *aux_ptr = aux;
02222
02223 ret = vp->num_allocated++;
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234 if (t->bitfield)
02235 (void) add_aux_sym_symint ((symint_t) t->sizes[t->num_sizes-1]);
02236
02237
02238
02239
02240
02241
02242 if (t->basic_type == bt_Struct
02243 || t->basic_type == bt_Union
02244 || t->basic_type == bt_Enum)
02245 {
02246 symint_t file_index = t->tag_ptr->ifd;
02247 symint_t sym_index = t->tag_ptr->indx;
02248
02249 if (t->unknown_tag)
02250 {
02251 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
02252 (void) add_aux_sym_symint ((symint_t)-1);
02253 }
02254 else if (sym_index != indexNil)
02255 {
02256 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
02257 (void) add_aux_sym_symint (file_index);
02258 }
02259 else
02260 {
02261 forward_t *forward_ref = allocate_forward ();
02262
02263 forward_ref->type_ptr = aux_ptr;
02264 forward_ref->next = t->tag_ptr->forward_ref;
02265 t->tag_ptr->forward_ref = forward_ref;
02266
02267 (void) add_aux_sym_rndx (ST_RFDESCAPE, sym_index);
02268 forward_ref->index_ptr
02269 = &vp->last->datum->aux[ vp->objects_last_page - 1];
02270
02271 (void) add_aux_sym_symint (file_index);
02272 forward_ref->ifd_ptr
02273 = &vp->last->datum->aux[ vp->objects_last_page - 1];
02274 }
02275 }
02276
02277
02278 for (i = 0; i < t->num_dims; i++)
02279 {
02280 (void) add_aux_sym_rndx (ST_RFDESCAPE,
02281 cur_file_ptr->int_type);
02282
02283 (void) add_aux_sym_symint (cur_file_ptr->file_index);
02284 (void) add_aux_sym_symint ((symint_t) 0);
02285 (void) add_aux_sym_symint (t->dimensions[i] - 1);
02286 (void) add_aux_sym_symint ((t->dimensions[i] == 0)
02287 ? 0
02288 : (t->sizes[i] * 8) / t->dimensions[i]);
02289 };
02290
02291
02292
02293
02294 return ret;
02295 }
02296
02297
02298
02299
02300 STATIC tag_t *
02301 get_tag (tag_start, tag_end_p1, indx, basic_type)
02302 const char *tag_start;
02303 const char *tag_end_p1;
02304 symint_t indx;
02305 bt_t basic_type;
02306 {
02307 shash_t *hash_ptr;
02308 tag_t *tag_ptr;
02309 hash_ptr = hash_string (tag_start,
02310 tag_end_p1 - tag_start,
02311 &tag_hash[0],
02312 (symint_t *) 0);
02313
02314 if (hash_ptr != (shash_t *) 0
02315 && hash_ptr->tag_ptr != (tag_t *) 0)
02316 {
02317 tag_ptr = hash_ptr->tag_ptr;
02318 if (indx != indexNil)
02319 {
02320 tag_ptr->basic_type = basic_type;
02321 tag_ptr->ifd = cur_file_ptr->file_index;
02322 tag_ptr->indx = indx;
02323 }
02324 return tag_ptr;
02325 }
02326
02327 (void) add_string (&tag_strings,
02328 &tag_hash[0],
02329 tag_start,
02330 tag_end_p1,
02331 &hash_ptr);
02332
02333 tag_ptr = allocate_tag ();
02334 tag_ptr->forward_ref = (forward_t *) 0;
02335 tag_ptr->hash_ptr = hash_ptr;
02336 tag_ptr->same_name = hash_ptr->tag_ptr;
02337 tag_ptr->basic_type = basic_type;
02338 tag_ptr->indx = indx;
02339 tag_ptr->ifd = (indx == indexNil
02340 ? (symint_t) -1 : cur_file_ptr->file_index);
02341 tag_ptr->same_block = cur_tag_head->first_tag;
02342
02343 cur_tag_head->first_tag = tag_ptr;
02344 hash_ptr->tag_ptr = tag_ptr;
02345
02346 return tag_ptr;
02347 }
02348
02349
02350
02351
02352 STATIC void
02353 add_unknown_tag (ptag)
02354 tag_t *ptag;
02355 {
02356 shash_t *hash_ptr = ptag->hash_ptr;
02357 char *name_start = hash_ptr->string;
02358 char *name_end_p1 = name_start + hash_ptr->len;
02359 forward_t *f_next = ptag->forward_ref;
02360 forward_t *f_cur;
02361 int sym_index;
02362 int file_index = cur_file_ptr->file_index;
02363
02364 if (debug > 1)
02365 {
02366 const char *agg_type = "{unknown aggregate type}";
02367 switch (ptag->basic_type)
02368 {
02369 case bt_Struct: agg_type = "struct"; break;
02370 case bt_Union: agg_type = "union"; break;
02371 case bt_Enum: agg_type = "enum"; break;
02372 default: break;
02373 }
02374
02375 fprintf (stderr, "unknown %s %.*s found\n",
02376 agg_type, (int) hash_ptr->len, name_start);
02377 }
02378
02379 sym_index = add_local_symbol (name_start,
02380 name_end_p1,
02381 st_Block,
02382 sc_Info,
02383 (symint_t) 0,
02384 (symint_t) 0);
02385
02386 (void) add_local_symbol (name_start,
02387 name_end_p1,
02388 st_End,
02389 sc_Info,
02390 (symint_t) 0,
02391 (symint_t) 0);
02392
02393 while (f_next != (forward_t *) 0)
02394 {
02395 f_cur = f_next;
02396 f_next = f_next->next;
02397
02398 f_cur->ifd_ptr->isym = file_index;
02399 f_cur->index_ptr->rndx.index = sym_index;
02400
02401 free_forward (f_cur);
02402 }
02403
02404 return;
02405 }
02406
02407
02408
02409
02410
02411
02412 STATIC void
02413 add_procedure (func_start, func_end_p1)
02414 const char *func_start;
02415 const char *func_end_p1;
02416 {
02417 PDR *new_proc_ptr;
02418 efdr_t *file_ptr = cur_file_ptr;
02419 varray_t *vp = &file_ptr->procs;
02420 symint_t value = 0;
02421 st_t proc_type = st_Proc;
02422 shash_t *shash_ptr = hash_string (func_start,
02423 func_end_p1 - func_start,
02424 &orig_str_hash[0],
02425 (symint_t *) 0);
02426
02427 if (debug)
02428 fputc ('\n', stderr);
02429
02430 if (vp->objects_last_page == vp->objects_per_page)
02431 add_varray_page (vp);
02432
02433 cur_proc_ptr = new_proc_ptr = &vp->last->datum->proc[ vp->objects_last_page++ ];
02434
02435 vp->num_allocated++;
02436
02437
02438
02439 cur_oproc_ptr = (PDR *) 0;
02440 if (shash_ptr != (shash_t *) 0)
02441 {
02442 PDR *old_proc_ptr = shash_ptr->proc_ptr;
02443 SYMR *sym_ptr = shash_ptr->sym_ptr;
02444
02445 if (old_proc_ptr != (PDR *) 0
02446 && sym_ptr != (SYMR *) 0
02447 && ((st_t) sym_ptr->st == st_Proc || (st_t) sym_ptr->st == st_StaticProc))
02448 {
02449 cur_oproc_begin = sym_ptr;
02450 cur_oproc_end = shash_ptr->end_ptr;
02451 value = sym_ptr->value;
02452
02453 cur_oproc_ptr = old_proc_ptr;
02454 proc_type = (st_t) sym_ptr->st;
02455 *new_proc_ptr = *old_proc_ptr;
02456 }
02457 }
02458
02459 if (cur_oproc_ptr == (PDR *) 0)
02460 error ("did not find a PDR block for %.*s",
02461 (int) (func_end_p1 - func_start), func_start);
02462
02463
02464 new_proc_ptr->isym = file_ptr->symbols.num_allocated;
02465
02466
02467 (void) add_local_symbol (func_start, func_end_p1,
02468 proc_type, sc_Text,
02469 value,
02470 (symint_t) 0);
02471 }
02472
02473
02474
02475
02476
02477
02478 STATIC void
02479 add_file (file_start, file_end_p1)
02480 const char *file_start;
02481 const char *file_end_p1;
02482 {
02483 static char zero_bytes[2] = { '\0', '\0' };
02484
02485 Ptrdiff_t len = file_end_p1 - file_start;
02486 int first_ch = *file_start;
02487 efdr_t *file_ptr;
02488
02489 if (debug)
02490 fprintf (stderr, "\tfile\t%.*s\n", (int) len, file_start);
02491
02492
02493 for (file_ptr = first_file;
02494 file_ptr != (efdr_t *) 0;
02495 file_ptr = file_ptr->next_file)
02496 {
02497 if (first_ch == file_ptr->name[0]
02498 && file_ptr->name[len] == '\0'
02499 && memcmp (file_start, file_ptr->name, len) == 0)
02500 {
02501 cur_file_ptr = file_ptr;
02502 break;
02503 }
02504 }
02505
02506
02507 if (file_ptr == (efdr_t *) 0)
02508 {
02509 if (file_desc.objects_last_page == file_desc.objects_per_page)
02510 add_varray_page (&file_desc);
02511
02512 file_ptr = cur_file_ptr
02513 = &file_desc.last->datum->file[ file_desc.objects_last_page++ ];
02514 *file_ptr = init_file;
02515
02516 file_ptr->file_index = file_desc.num_allocated++;
02517
02518
02519 file_ptr->shash_head = (shash_t **) allocate_page ();
02520
02521
02522 add_string (&file_ptr->strings,
02523 &file_ptr->shash_head[0],
02524 &zero_bytes[0],
02525 &zero_bytes[0],
02526 (shash_t **) 0);
02527
02528 if (file_end_p1 - file_start > (long) PAGE_USIZE-2)
02529 fatal ("filename goes over one page boundary");
02530
02531
02532
02533 (void) add_local_symbol (file_start, file_end_p1, st_File, sc_Text,
02534 (symint_t) 0, (symint_t) 0);
02535 file_ptr->fdr.rss = 1;
02536 file_ptr->name = &file_ptr->strings.last->datum->byte[1];
02537 file_ptr->name_len = file_end_p1 - file_start;
02538
02539
02540 *last_file_ptr = file_ptr;
02541 last_file_ptr = &file_ptr->next_file;
02542
02543
02544
02545 file_ptr->void_type = add_aux_sym_tir (&void_type_info,
02546 hash_yes,
02547 &cur_file_ptr->thash_head[0]);
02548
02549 file_ptr->int_type = add_aux_sym_tir (&int_type_info,
02550 hash_yes,
02551 &cur_file_ptr->thash_head[0]);
02552 }
02553 }
02554
02555
02556
02557
02558 STATIC void
02559 add_bytes (vp, input_ptr, nitems)
02560 varray_t *vp;
02561 char *input_ptr;
02562 Size_t nitems;
02563 {
02564 Size_t move_items;
02565 Size_t move_bytes;
02566 char *ptr;
02567
02568 while (nitems > 0)
02569 {
02570 if (vp->objects_last_page >= vp->objects_per_page)
02571 add_varray_page (vp);
02572
02573 ptr = &vp->last->datum->byte[ vp->objects_last_page * vp->object_size ];
02574 move_items = vp->objects_per_page - vp->objects_last_page;
02575 if (move_items > nitems)
02576 move_items = nitems;
02577
02578 move_bytes = move_items * vp->object_size;
02579 nitems -= move_items;
02580
02581 if (move_bytes >= 32)
02582 {
02583 (void) memcpy (ptr, input_ptr, move_bytes);
02584 input_ptr += move_bytes;
02585 }
02586 else
02587 {
02588 while (move_bytes-- > 0)
02589 *ptr++ = *input_ptr++;
02590 }
02591 }
02592 }
02593
02594
02595
02596
02597 STATIC const char *
02598 sc_to_string (storage_class)
02599 sc_t storage_class;
02600 {
02601 switch (storage_class)
02602 {
02603 case sc_Nil: return "Nil,";
02604 case sc_Text: return "Text,";
02605 case sc_Data: return "Data,";
02606 case sc_Bss: return "Bss,";
02607 case sc_Register: return "Register,";
02608 case sc_Abs: return "Abs,";
02609 case sc_Undefined: return "Undefined,";
02610 case sc_CdbLocal: return "CdbLocal,";
02611 case sc_Bits: return "Bits,";
02612 case sc_CdbSystem: return "CdbSystem,";
02613 case sc_RegImage: return "RegImage,";
02614 case sc_Info: return "Info,";
02615 case sc_UserStruct: return "UserStruct,";
02616 case sc_SData: return "SData,";
02617 case sc_SBss: return "SBss,";
02618 case sc_RData: return "RData,";
02619 case sc_Var: return "Var,";
02620 case sc_Common: return "Common,";
02621 case sc_SCommon: return "SCommon,";
02622 case sc_VarRegister: return "VarRegister,";
02623 case sc_Variant: return "Variant,";
02624 case sc_SUndefined: return "SUndefined,";
02625 case sc_Init: return "Init,";
02626 case sc_Max: return "Max,";
02627 }
02628
02629 return "???,";
02630 }
02631
02632
02633
02634
02635 STATIC const char *
02636 st_to_string (symbol_type)
02637 st_t symbol_type;
02638 {
02639 switch (symbol_type)
02640 {
02641 case st_Nil: return "Nil,";
02642 case st_Global: return "Global,";
02643 case st_Static: return "Static,";
02644 case st_Param: return "Param,";
02645 case st_Local: return "Local,";
02646 case st_Label: return "Label,";
02647 case st_Proc: return "Proc,";
02648 case st_Block: return "Block,";
02649 case st_End: return "End,";
02650 case st_Member: return "Member,";
02651 case st_Typedef: return "Typedef,";
02652 case st_File: return "File,";
02653 case st_RegReloc: return "RegReloc,";
02654 case st_Forward: return "Forward,";
02655 case st_StaticProc: return "StaticProc,";
02656 case st_Constant: return "Constant,";
02657 case st_Str: return "String,";
02658 case st_Number: return "Number,";
02659 case st_Expr: return "Expr,";
02660 case st_Type: return "Type,";
02661 case st_Max: return "Max,";
02662 }
02663
02664 return "???,";
02665 }
02666
02667
02668
02669
02670
02671
02672 STATIC char *
02673 read_line ()
02674 {
02675 static int line_split_p = 0;
02676 int string_p = 0;
02677 int comment_p = 0;
02678 int ch;
02679 char *ptr;
02680
02681 if (cur_line_start == (char *) 0)
02682 {
02683 cur_line_start = (char *) allocate_page ();
02684 cur_line_alloc = PAGE_SIZE;
02685 }
02686
02687 if (!line_split_p)
02688 line_number++;
02689
02690 line_split_p = 0;
02691 cur_line_nbytes = 0;
02692
02693 for (ptr = cur_line_start; (ch = getchar ()) != EOF; *ptr++ = ch)
02694 {
02695 if (++cur_line_nbytes >= cur_line_alloc-1)
02696 {
02697 int num_pages = cur_line_alloc / PAGE_SIZE;
02698 char *old_buffer = cur_line_start;
02699
02700 cur_line_alloc += PAGE_SIZE;
02701 cur_line_start = (char *) allocate_multiple_pages (num_pages+1);
02702 memcpy (cur_line_start, old_buffer, num_pages * PAGE_SIZE);
02703
02704 ptr = cur_line_start + cur_line_nbytes - 1;
02705 }
02706
02707 if (ch == '\n')
02708 {
02709 *ptr++ = '\n';
02710 *ptr = '\0';
02711 cur_line_ptr = cur_line_start;
02712 return cur_line_ptr;
02713 }
02714
02715 else if (ch == '\0')
02716 error ("null character found in input");
02717
02718 else if (!comment_p)
02719 {
02720 if (ch == '"')
02721 string_p = !string_p;
02722
02723 else if (ch == '#')
02724 comment_p++;
02725
02726 else if (ch == ';' && !string_p)
02727 {
02728 line_split_p = 1;
02729 *ptr++ = '\n';
02730 *ptr = '\0';
02731 cur_line_ptr = cur_line_start;
02732 return cur_line_ptr;
02733 }
02734 }
02735 }
02736
02737 if (ferror (stdin))
02738 pfatal_with_name (input_name);
02739
02740 cur_line_ptr = (char *) 0;
02741 return (char *) 0;
02742 }
02743
02744
02745
02746
02747
02748 STATIC void
02749 parse_begin (start)
02750 const char *start;
02751 {
02752 const char *end_p1;
02753 int ch;
02754 shash_t *hash_ptr;
02755
02756 if (cur_file_ptr == (efdr_t *) 0)
02757 {
02758 error ("#.begin directive without a preceding .file directive");
02759 return;
02760 }
02761
02762 if (cur_proc_ptr == (PDR *) 0)
02763 {
02764 error ("#.begin directive without a preceding .ent directive");
02765 return;
02766 }
02767
02768 for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++)
02769 ;
02770
02771 hash_ptr = hash_string (start,
02772 end_p1 - start,
02773 &orig_str_hash[0],
02774 (symint_t *) 0);
02775
02776 if (hash_ptr == (shash_t *) 0)
02777 {
02778 error ("label %.*s not found for #.begin",
02779 (int) (end_p1 - start), start);
02780 return;
02781 }
02782
02783 if (cur_oproc_begin == (SYMR *) 0)
02784 {
02785 error ("procedure table %.*s not found for #.begin",
02786 (int) (end_p1 - start), start);
02787 return;
02788 }
02789
02790 (void) add_local_symbol ((const char *) 0, (const char *) 0,
02791 st_Block, sc_Text,
02792 (symint_t) hash_ptr->sym_ptr->value - cur_oproc_begin->value,
02793 (symint_t) 0);
02794 }
02795
02796
02797
02798
02799
02800 STATIC void
02801 parse_bend (start)
02802 const char *start;
02803 {
02804 const char *end_p1;
02805 int ch;
02806 shash_t *hash_ptr;
02807
02808 if (cur_file_ptr == (efdr_t *) 0)
02809 {
02810 error ("#.begin directive without a preceding .file directive");
02811 return;
02812 }
02813
02814 if (cur_proc_ptr == (PDR *) 0)
02815 {
02816 error ("#.bend directive without a preceding .ent directive");
02817 return;
02818 }
02819
02820 for (end_p1 = start; (ch = *end_p1) != '\0' && !ISSPACE (ch); end_p1++)
02821 ;
02822
02823 hash_ptr = hash_string (start,
02824 end_p1 - start,
02825 &orig_str_hash[0],
02826 (symint_t *) 0);
02827
02828 if (hash_ptr == (shash_t *) 0)
02829 {
02830 error ("label %.*s not found for #.bend", (int) (end_p1 - start), start);
02831 return;
02832 }
02833
02834 if (cur_oproc_begin == (SYMR *) 0)
02835 {
02836 error ("procedure table %.*s not found for #.bend",
02837 (int) (end_p1 - start), start);
02838 return;
02839 }
02840
02841 (void) add_local_symbol ((const char *) 0, (const char *) 0,
02842 st_End, sc_Text,
02843 (symint_t) hash_ptr->sym_ptr->value - cur_oproc_begin->value,
02844 (symint_t) 0);
02845 }
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859 STATIC void
02860 parse_def (name_start)
02861 const char *name_start;
02862 {
02863 const char *dir_start;
02864 const char *dir_end_p1;
02865 const char *arg_start;
02866 const char *arg_end_p1;
02867 const char *name_end_p1;
02868 const char *tag_start = 0;
02869 const char *tag_end_p1 = 0;
02870 sc_t storage_class = sc_Nil;
02871 st_t symbol_type = st_Nil;
02872 type_info_t t;
02873 EXTR *eptr = (EXTR *) 0;
02874 int is_function = 0;
02875 symint_t value = 0;
02876 symint_t indx = cur_file_ptr->void_type;
02877 int error_line = 0;
02878 symint_t arg_number;
02879 symint_t temp_array[ N_TQ ];
02880 int arg_was_number;
02881 int ch, i;
02882 Ptrdiff_t len;
02883
02884 static int inside_enumeration = 0;
02885
02886
02887
02888 t = type_info_init;
02889
02890
02891
02892
02893
02894
02895
02896
02897 for (name_end_p1 = name_start; (ch = *name_end_p1) != ';' && ch != '\0'; name_end_p1++)
02898 ;
02899
02900 if (ch == '\0')
02901 {
02902 error_line = __LINE__;
02903 saber_stop ();
02904 goto bomb_out;
02905 }
02906
02907
02908 dir_start = name_end_p1+1;
02909 for (;;)
02910 {
02911 while ((ch = *dir_start) == ' ' || ch == '\t')
02912 ++dir_start;
02913
02914 if (ch != '.')
02915 {
02916 error_line = __LINE__;
02917 saber_stop ();
02918 goto bomb_out;
02919 }
02920
02921
02922 if (dir_start[1] == 'e'
02923 && memcmp (dir_start, ".endef", sizeof (".endef")-1) == 0)
02924 break;
02925
02926
02927 for (dir_end_p1 = dir_start+1;
02928 (ch = *dir_end_p1) != ' ' && ch != '\t';
02929 dir_end_p1++)
02930 {
02931 if (ch == '\0' || ISSPACE (ch))
02932 {
02933 error_line = __LINE__;
02934 saber_stop ();
02935 goto bomb_out;
02936 }
02937 }
02938
02939
02940 arg_was_number = arg_number = 0;
02941 arg_end_p1 = 0;
02942 arg_start = dir_end_p1+1;
02943 ch = *arg_start;
02944 while (ch == ' ' || ch == '\t')
02945 ch = *++arg_start;
02946
02947 if (ISDIGIT (ch) || ch == '-' || ch == '+')
02948 {
02949 int ch2;
02950 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
02951 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
02952 arg_was_number++;
02953 }
02954
02955 else if (ch == '\0' || ISSPACE (ch))
02956 {
02957 error_line = __LINE__;
02958 saber_stop ();
02959 goto bomb_out;
02960 }
02961
02962 if (!arg_was_number)
02963 {
02964
02965 for (arg_end_p1 = arg_start+1;
02966 (ch = *arg_end_p1) != ';' && ch != '\0';
02967 arg_end_p1++)
02968 ;
02969
02970 if (ch == '\0')
02971 {
02972 error_line = __LINE__;
02973 saber_stop ();
02974 goto bomb_out;
02975 }
02976 }
02977
02978
02979 len = dir_end_p1 - dir_start;
02980 switch (dir_start[1])
02981 {
02982 default:
02983 error_line = __LINE__;
02984 saber_stop ();
02985 goto bomb_out;
02986
02987 case 'd':
02988 if (len == sizeof (".dim")-1
02989 && memcmp (dir_start, ".dim", sizeof (".dim")-1) == 0
02990 && arg_was_number)
02991 {
02992 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
02993
02994 *t_ptr = arg_number;
02995 while (*arg_end_p1 == ',' && arg_was_number)
02996 {
02997 arg_start = arg_end_p1+1;
02998 ch = *arg_start;
02999 while (ch == ' ' || ch == '\t')
03000 ch = *++arg_start;
03001
03002 arg_was_number = 0;
03003 if (ISDIGIT (ch) || ch == '-' || ch == '+')
03004 {
03005 int ch2;
03006 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
03007 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
03008 arg_was_number++;
03009
03010 if (t_ptr == &temp_array[0])
03011 {
03012 error_line = __LINE__;
03013 saber_stop ();
03014 goto bomb_out;
03015 }
03016
03017 *--t_ptr = arg_number;
03018 }
03019 }
03020
03021
03022 while (t_ptr <= &temp_array[ N_TQ-1 ])
03023 {
03024 if (t.num_dims >= N_TQ-1)
03025 {
03026 error_line = __LINE__;
03027 saber_stop ();
03028 goto bomb_out;
03029 }
03030
03031 t.dimensions[ t.num_dims++ ] = *t_ptr++;
03032 }
03033 break;
03034 }
03035 else
03036 {
03037 error_line = __LINE__;
03038 saber_stop ();
03039 goto bomb_out;
03040 }
03041
03042
03043 case 's':
03044 if (len == sizeof (".scl")-1
03045 && memcmp (dir_start, ".scl", sizeof (".scl")-1) == 0
03046 && arg_was_number
03047 && arg_number < ((symint_t) C_MAX))
03048 {
03049
03050
03051
03052
03053
03054 if (symbol_type == st_Nil)
03055 {
03056 symbol_type = map_coff_sym_type[arg_number];
03057 storage_class = map_coff_storage [arg_number];
03058 }
03059 break;
03060 }
03061
03062 else if (len == sizeof (".size")-1
03063 && memcmp (dir_start, ".size", sizeof (".size")-1) == 0
03064 && arg_was_number)
03065 {
03066 symint_t *t_ptr = &temp_array[ N_TQ-1 ];
03067
03068 *t_ptr = arg_number;
03069 while (*arg_end_p1 == ',' && arg_was_number)
03070 {
03071 arg_start = arg_end_p1+1;
03072 ch = *arg_start;
03073 while (ch == ' ' || ch == '\t')
03074 ch = *++arg_start;
03075
03076 arg_was_number = 0;
03077 if (ISDIGIT (ch) || ch == '-' || ch == '+')
03078 {
03079 int ch2;
03080 arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
03081 if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
03082 arg_was_number++;
03083
03084 if (t_ptr == &temp_array[0])
03085 {
03086 error_line = __LINE__;
03087 saber_stop ();
03088 goto bomb_out;
03089 }
03090
03091 *--t_ptr = arg_number;
03092 }
03093 }
03094
03095
03096 while (t_ptr <= &temp_array[ N_TQ-1 ])
03097 {
03098 if (t.num_sizes >= N_TQ-1)
03099 {
03100 error_line = __LINE__;
03101 saber_stop ();
03102 goto bomb_out;
03103 }
03104
03105 t.sizes[ t.num_sizes++ ] = *t_ptr++;
03106 }
03107 break;
03108 }
03109
03110 else
03111 {
03112 error_line = __LINE__;
03113 saber_stop ();
03114 goto bomb_out;
03115 }
03116
03117
03118 case 't':
03119 if (len == sizeof (".type")-1
03120 && memcmp (dir_start, ".type", sizeof (".type")-1) == 0
03121 && arg_was_number)
03122 {
03123 tq_t *tq_ptr = &t.type_qualifiers[0];
03124
03125 t.orig_type = (coff_type_t) (arg_number & N_BTMASK);
03126 t.basic_type = map_coff_types [(int) t.orig_type];
03127 for (i = N_TQ-1; i >= 0; i--)
03128 {
03129 int dt = (arg_number >> ((i * N_TQ_SHIFT) + N_BT_SHIFT)
03130 & N_TMASK);
03131
03132 if (dt != (int) DT_NON)
03133 *tq_ptr++ = map_coff_derived_type [dt];
03134 }
03135
03136
03137
03138
03139
03140
03141
03142 if (tq_ptr != &t.type_qualifiers[0] && tq_ptr[-1] == tq_Proc)
03143 {
03144 is_function = 1;
03145 tq_ptr[-1] = tq_Nil;
03146 }
03147
03148 break;
03149 }
03150
03151 else if (len == sizeof (".tag")-1
03152 && memcmp (dir_start, ".tag", sizeof (".tag")-1) == 0)
03153 {
03154 tag_start = arg_start;
03155 tag_end_p1 = arg_end_p1;
03156 break;
03157 }
03158
03159 else
03160 {
03161 error_line = __LINE__;
03162 saber_stop ();
03163 goto bomb_out;
03164 }
03165
03166
03167 case 'v':
03168 if (len == sizeof (".val")-1
03169 && memcmp (dir_start, ".val", sizeof (".val")-1) == 0)
03170 {
03171 if (arg_was_number)
03172 value = arg_number;
03173
03174
03175
03176
03177
03178 else
03179 {
03180 shash_t *orig_hash_ptr;
03181 shash_t *ext_hash_ptr;
03182
03183 ext_hash_ptr = hash_string (arg_start,
03184 arg_end_p1 - arg_start,
03185 &ext_str_hash[0],
03186 (symint_t *) 0);
03187
03188 if (ext_hash_ptr != (shash_t *) 0
03189 && ext_hash_ptr->esym_ptr != (EXTR *) 0)
03190 eptr = ext_hash_ptr->esym_ptr;
03191
03192 orig_hash_ptr = hash_string (arg_start,
03193 arg_end_p1 - arg_start,
03194 &orig_str_hash[0],
03195 (symint_t *) 0);
03196
03197 if ((orig_hash_ptr == (shash_t *) 0
03198 || orig_hash_ptr->sym_ptr == (SYMR *) 0)
03199 && eptr == (EXTR *) 0)
03200 {
03201 fprintf (stderr, "warning, %.*s not found in original or external symbol tables, value defaults to 0\n",
03202 (int) (arg_end_p1 - arg_start),
03203 arg_start);
03204 value = 0;
03205 }
03206 else
03207 {
03208 SYMR *ptr = (orig_hash_ptr != (shash_t *) 0
03209 && orig_hash_ptr->sym_ptr != (SYMR *) 0)
03210 ? orig_hash_ptr->sym_ptr
03211 : &eptr->asym;
03212
03213 symbol_type = (st_t) ptr->st;
03214 storage_class = (sc_t) ptr->sc;
03215 value = ptr->value;
03216 }
03217 }
03218 break;
03219 }
03220 else
03221 {
03222 error_line = __LINE__;
03223 saber_stop ();
03224 goto bomb_out;
03225 }
03226 }
03227
03228
03229 dir_start = arg_end_p1 + 1;
03230 }
03231
03232
03233 if (storage_class == sc_Bits)
03234 {
03235 t.bitfield = 1;
03236 t.extra_sizes = 1;
03237 }
03238 else
03239 t.extra_sizes = 0;
03240
03241 if (t.num_dims > 0)
03242 {
03243 int num_real_sizes = t.num_sizes - t.extra_sizes;
03244 int diff = t.num_dims - num_real_sizes;
03245 int i = t.num_dims - 1;
03246 int j;
03247
03248 if (num_real_sizes != 1 || diff < 0)
03249 {
03250 error_line = __LINE__;
03251 saber_stop ();
03252 goto bomb_out;
03253 }
03254
03255
03256
03257
03258
03259 if (diff)
03260 {
03261 for (j = ARRAY_SIZE (t.sizes) - 1; j >= 0; j--)
03262 t.sizes[ j ] = ((j-diff) >= 0) ? t.sizes[ j-diff ] : 0;
03263
03264 t.num_sizes = i + 1;
03265 for ( i--; i >= 0; i-- )
03266 {
03267 if (t.dimensions[ i+1 ])
03268 t.sizes[ i ] = t.sizes[ i+1 ] / t.dimensions[ i+1 ];
03269 else
03270 t.sizes[ i ] = t.sizes[ i+1 ];
03271 }
03272 }
03273 }
03274
03275
03276
03277
03278 if (symbol_type == st_Block || symbol_type == st_End)
03279 indx = 0;
03280
03281 else if (inside_enumeration)
03282 indx = cur_file_ptr->void_type;
03283
03284 else
03285 {
03286 if (t.basic_type == bt_Struct
03287 || t.basic_type == bt_Union
03288 || t.basic_type == bt_Enum)
03289 {
03290 if (tag_start == (char *) 0)
03291 {
03292 error ("no tag specified for %.*s",
03293 (int) (name_end_p1 - name_start),
03294 name_start);
03295 return;
03296 }
03297
03298 t.tag_ptr = get_tag (tag_start, tag_end_p1, (symint_t) indexNil,
03299 t.basic_type);
03300 }
03301
03302 if (is_function)
03303 {
03304 last_func_type_info = t;
03305 last_func_eptr = eptr;
03306 return;
03307 }
03308
03309 indx = add_aux_sym_tir (&t,
03310 hash_yes,
03311 &cur_file_ptr->thash_head[0]);
03312 }
03313
03314
03315
03316
03317
03318 if (eptr != (EXTR *) 0
03319 && (eptr->asym.index == indexNil || cur_proc_ptr == (PDR *) 0))
03320 {
03321 eptr->ifd = cur_file_ptr->file_index;
03322 eptr->asym.index = indx;
03323 }
03324
03325
03326
03327 switch (symbol_type)
03328 {
03329 default:
03330 break;
03331
03332
03333
03334
03335
03336 case st_Block:
03337 if (t.num_sizes - t.num_dims - t.extra_sizes != 1)
03338 {
03339 error_line = __LINE__;
03340 saber_stop ();
03341 goto bomb_out;
03342 }
03343
03344 else
03345 value = t.sizes[0];
03346
03347 inside_enumeration = (t.orig_type == T_ENUM);
03348 break;
03349
03350
03351
03352
03353
03354
03355 case st_End:
03356 name_start = name_end_p1 = 0;
03357 value = inside_enumeration = 0;
03358 break;
03359
03360
03361
03362
03363
03364
03365
03366
03367 case st_Member:
03368 if (!t.bitfield && !inside_enumeration)
03369 value *= 8;
03370
03371 break;
03372 }
03373
03374
03375
03376
03377
03378 if (eptr == (EXTR *) 0
03379 || eptr->asym.st == (int) st_Nil
03380 || cur_proc_ptr != (PDR *) 0)
03381 {
03382 symint_t isym = add_local_symbol (name_start, name_end_p1,
03383 symbol_type, storage_class,
03384 value,
03385 indx);
03386
03387
03388 if (symbol_type == st_Block)
03389 {
03390
03391 tag_t *tag_ptr = get_tag (name_start,
03392 name_end_p1,
03393 isym,
03394 t.basic_type);
03395
03396
03397
03398
03399 symint_t file_index = cur_file_ptr->file_index;
03400 forward_t *f_next = tag_ptr->forward_ref;
03401 forward_t *f_cur;
03402
03403 while (f_next != (forward_t *) 0)
03404 {
03405 f_cur = f_next;
03406 f_next = f_next->next;
03407
03408 f_cur->ifd_ptr->isym = file_index;
03409 f_cur->index_ptr->rndx.index = isym;
03410
03411 free_forward (f_cur);
03412 }
03413
03414 tag_ptr->forward_ref = (forward_t *) 0;
03415 }
03416 }
03417
03418
03419 return;
03420
03421
03422 bomb_out:
03423 if (error_line)
03424 error ("compiler error, badly formed #.def (internal line # = %d)", error_line);
03425 else
03426 error ("compiler error, badly formed #.def");
03427
03428 return;
03429 }
03430
03431
03432
03433
03434 STATIC void
03435 parse_end (start)
03436 const char *start;
03437 {
03438 const char *start_func, *end_func_p1;
03439 int ch;
03440 symint_t value;
03441 FDR *orig_fdr;
03442
03443 if (cur_file_ptr == (efdr_t *) 0)
03444 {
03445 error (".end directive without a preceding .file directive");
03446 return;
03447 }
03448
03449 if (cur_proc_ptr == (PDR *) 0)
03450 {
03451 error (".end directive without a preceding .ent directive");
03452 return;
03453 }
03454
03455
03456 for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++)
03457 ;
03458
03459 ch = *start_func;
03460 if (!IS_ASM_IDENT (ch))
03461 {
03462 error (".end directive has no name");
03463 return;
03464 }
03465
03466 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
03467 ;
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477 orig_fdr = cur_file_ptr->orig_fdr;
03478 value = 0;
03479 if (orig_fdr != (FDR *) 0 && cur_oproc_end != (SYMR *) 0)
03480 value = cur_oproc_end->value;
03481
03482 else
03483 error ("cannot find .end block for %.*s",
03484 (int) (end_func_p1 - start_func), start_func);
03485
03486 (void) add_local_symbol (start_func, end_func_p1,
03487 st_End, sc_Text,
03488 value,
03489 (symint_t) 0);
03490
03491 cur_proc_ptr = cur_oproc_ptr = (PDR *) 0;
03492 }
03493
03494
03495
03496
03497 STATIC void
03498 parse_ent (start)
03499 const char *start;
03500 {
03501 const char *start_func, *end_func_p1;
03502 int ch;
03503
03504 if (cur_file_ptr == (efdr_t *) 0)
03505 {
03506 error (".ent directive without a preceding .file directive");
03507 return;
03508 }
03509
03510 if (cur_proc_ptr != (PDR *) 0)
03511 {
03512 error ("second .ent directive found before .end directive");
03513 return;
03514 }
03515
03516 for (start_func = start; ISSPACE ((unsigned char)*start_func); start_func++)
03517 ;
03518
03519 ch = *start_func;
03520 if (!IS_ASM_IDENT (ch))
03521 {
03522 error (".ent directive has no name");
03523 return;
03524 }
03525
03526 for (end_func_p1 = start_func; IS_ASM_IDENT (ch); ch = *++end_func_p1)
03527 ;
03528
03529 (void) add_procedure (start_func, end_func_p1);
03530 }
03531
03532
03533
03534
03535 STATIC void
03536 parse_file (start)
03537 const char *start;
03538 {
03539 char *p;
03540 char *start_name, *end_name_p1;
03541
03542 (void) strtol (start, &p, 0);
03543 if (start == p
03544 || (start_name = strchr (p, '"')) == (char *) 0
03545 || (end_name_p1 = strrchr (++start_name, '"')) == (char *) 0)
03546 {
03547 error ("invalid .file directive");
03548 return;
03549 }
03550
03551 if (cur_proc_ptr != (PDR *) 0)
03552 {
03553 error ("no way to handle .file within .ent/.end section");
03554 return;
03555 }
03556
03557 add_file (start_name, end_name_p1);
03558 }
03559
03560
03561
03562
03563 static void
03564 mark_stabs (start)
03565 const char *start ATTRIBUTE_UNUSED;
03566 {
03567 if (!stabs_seen)
03568 {
03569
03570 stabs_seen = 1;
03571 (void) add_local_symbol (stabs_symbol,
03572 stabs_symbol + sizeof (stabs_symbol),
03573 stNil, scInfo, -1, MIPS_MARK_STAB (0));
03574
03575 }
03576 }
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608 STATIC void
03609 parse_stabs_common (string_start, string_end, rest)
03610 const char *string_start;
03611 const char *string_end;
03612 const char *rest;
03613 {
03614 efdr_t *save_file_ptr = cur_file_ptr;
03615 symint_t code;
03616 symint_t value;
03617 char *p;
03618 st_t st;
03619 sc_t sc;
03620 int ch;
03621
03622 if (stabs_seen == 0)
03623 mark_stabs ("");
03624
03625
03626 if (!ISDIGIT (*rest))
03627 {
03628 error ("invalid .stabs/.stabn directive, code is non-numeric");
03629 return;
03630 }
03631
03632 code = strtol (rest, &p, 0);
03633
03634
03635
03636
03637
03638
03639
03640 if (code == (int) N_SLINE)
03641 {
03642 SYMR *sym_ptr, dummy_symr;
03643 shash_t *shash_ptr;
03644
03645
03646 if (p[0] != ',' || p[1] != '0' || p[2] != ',' || !ISDIGIT (p[3]))
03647 {
03648 error ("invalid line number .stabs/.stabn directive");
03649 return;
03650 }
03651
03652 code = strtol (p+3, &p, 0);
03653 ch = *++p;
03654 if (p[-1] != ',' || ISDIGIT (ch) || !IS_ASM_IDENT (ch))
03655 {
03656 error ("invalid line number .stabs/.stabn directive");
03657 return;
03658 }
03659
03660 dummy_symr.index = code;
03661 if (dummy_symr.index != code)
03662 {
03663 error ("line number (%lu) for .stabs/.stabn directive cannot fit in index field (20 bits)",
03664 code);
03665
03666 return;
03667 }
03668
03669 shash_ptr = hash_string (p,
03670 strlen (p) - 1,
03671 &orig_str_hash[0],
03672 (symint_t *) 0);
03673
03674 if (shash_ptr == (shash_t *) 0
03675 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0)
03676 {
03677 error ("invalid .stabs/.stabn directive, value not found");
03678 return;
03679 }
03680
03681 if ((st_t) sym_ptr->st != st_Label)
03682 {
03683 error ("invalid line number .stabs/.stabn directive");
03684 return;
03685 }
03686
03687 st = st_Label;
03688 sc = (sc_t) sym_ptr->sc;
03689 value = sym_ptr->value;
03690 }
03691 else
03692 {
03693
03694 if (*p++ != ',')
03695 goto failure;
03696 for (; ISDIGIT (*p); p++)
03697 ;
03698 if (*p++ != ',')
03699 goto failure;
03700 for (; ISDIGIT (*p); p++)
03701 ;
03702 if (*p++ != ',')
03703 goto failure;
03704 ch = *p;
03705 if (!IS_ASM_IDENT (ch) && ch != '-')
03706 {
03707 failure:
03708 error ("invalid .stabs/.stabn directive, bad character");
03709 return;
03710 }
03711
03712 if (ISDIGIT (ch) || ch == '-')
03713 {
03714 st = st_Nil;
03715 sc = sc_Nil;
03716 value = strtol (p, &p, 0);
03717 if (*p != '\n')
03718 {
03719 error ("invalid .stabs/.stabn directive, stuff after numeric value");
03720 return;
03721 }
03722 }
03723 else if (!IS_ASM_IDENT (ch))
03724 {
03725 error ("invalid .stabs/.stabn directive, bad character");
03726 return;
03727 }
03728 else
03729 {
03730 SYMR *sym_ptr;
03731 shash_t *shash_ptr;
03732 const char *start, *end_p1;
03733
03734 start = p;
03735 if ((end_p1 = strchr (start, '+')) == (char *) 0)
03736 {
03737 if ((end_p1 = strchr (start, '-')) == (char *) 0)
03738 end_p1 = start + strlen (start) - 1;
03739 }
03740
03741 shash_ptr = hash_string (start,
03742 end_p1 - start,
03743 &orig_str_hash[0],
03744 (symint_t *) 0);
03745
03746 if (shash_ptr == (shash_t *) 0
03747 || (sym_ptr = shash_ptr->sym_ptr) == (SYMR *) 0)
03748 {
03749 shash_ptr = hash_string (start,
03750 end_p1 - start,
03751 &ext_str_hash[0],
03752 (symint_t *) 0);
03753
03754 if (shash_ptr == (shash_t *) 0
03755 || shash_ptr->esym_ptr == (EXTR *) 0)
03756 {
03757 error ("invalid .stabs/.stabn directive, value not found");
03758 return;
03759 }
03760 else
03761 sym_ptr = &(shash_ptr->esym_ptr->asym);
03762 }
03763
03764
03765 if (code == (int) N_LBRAC || code == (int) N_RBRAC)
03766 {
03767 sc = scNil;
03768 st = stNil;
03769 }
03770 else
03771 {
03772 sc = (sc_t) sym_ptr->sc;
03773 st = (st_t) sym_ptr->st;
03774 }
03775 value = sym_ptr->value;
03776
03777 ch = *end_p1++;
03778 if (ch != '\n')
03779 {
03780 if (((!ISDIGIT (*end_p1)) && (*end_p1 != '-'))
03781 || ((ch != '+') && (ch != '-')))
03782 {
03783 error ("invalid .stabs/.stabn directive, badly formed value");
03784 return;
03785 }
03786 if (ch == '+')
03787 value += strtol (end_p1, &p, 0);
03788 else if (ch == '-')
03789 value -= strtol (end_p1, &p, 0);
03790
03791 if (*p != '\n')
03792 {
03793 error ("invalid .stabs/.stabn directive, stuff after numeric value");
03794 return;
03795 }
03796 }
03797 }
03798 code = MIPS_MARK_STAB (code);
03799 }
03800
03801 (void) add_local_symbol (string_start, string_end, st, sc, value, code);
03802
03803 cur_file_ptr = save_file_ptr;
03804 }
03805
03806
03807 STATIC void
03808 parse_stabs (start)
03809 const char *start;
03810 {
03811 const char *end = strchr (start+1, '"');
03812
03813 if (*start != '"' || end == (const char *) 0 || end[1] != ',')
03814 {
03815 error ("invalid .stabs directive, no string");
03816 return;
03817 }
03818
03819 parse_stabs_common (start+1, end, end+2);
03820 }
03821
03822
03823 STATIC void
03824 parse_stabn (start)
03825 const char *start;
03826 {
03827 parse_stabs_common ((const char *) 0, (const char *) 0, start);
03828 }
03829
03830
03831
03832
03833
03834 STATIC void
03835 parse_input ()
03836 {
03837 char *p;
03838 Size_t i;
03839 thead_t *ptag_head;
03840 tag_t *ptag;
03841 tag_t *ptag_next;
03842
03843 if (debug)
03844 fprintf (stderr, "\tinput\n");
03845
03846
03847
03848 ptag_head = allocate_thead ();
03849 ptag_head->first_tag = 0;
03850 ptag_head->prev = cur_tag_head;
03851 cur_tag_head = ptag_head;
03852
03853 while ((p = read_line ()) != (char *) 0)
03854 {
03855
03856 while (ISSPACE ((unsigned char)*p))
03857 p++;
03858
03859
03860 for (i = 0; i < ARRAY_SIZE (pseudo_ops); i++)
03861 if (memcmp (p, pseudo_ops[i].name, pseudo_ops[i].len) == 0
03862 && ISSPACE ((unsigned char)(p[pseudo_ops[i].len])))
03863 {
03864 p += pseudo_ops[i].len;
03865 while (ISSPACE ((unsigned char)*p))
03866 p++;
03867
03868 (*pseudo_ops[i].func)( p );
03869 break;
03870 }
03871 }
03872
03873
03874 ptag_head = cur_tag_head;
03875 cur_tag_head = ptag_head->prev;
03876
03877 for (ptag = ptag_head->first_tag;
03878 ptag != (tag_t *) 0;
03879 ptag = ptag_next)
03880 {
03881 if (ptag->forward_ref != (forward_t *) 0)
03882 add_unknown_tag (ptag);
03883
03884 ptag_next = ptag->same_block;
03885 ptag->hash_ptr->tag_ptr = ptag->same_name;
03886 free_tag (ptag);
03887 }
03888
03889 free_thead (ptag_head);
03890
03891 }
03892
03893
03894
03895
03896
03897 STATIC void
03898 update_headers ()
03899 {
03900 symint_t i;
03901 efdr_t *file_ptr;
03902
03903
03904 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
03905 symbolic_header.magic = orig_sym_hdr.magic;
03906 symbolic_header.vstamp = orig_sym_hdr.vstamp;
03907
03908
03909 symbolic_header.issExtMax = ext_strings.num_allocated;
03910 symbolic_header.idnMax = dense_num.num_allocated;
03911 symbolic_header.ifdMax = file_desc.num_allocated;
03912 symbolic_header.iextMax = ext_symbols.num_allocated;
03913 symbolic_header.ilineMax = orig_sym_hdr.ilineMax;
03914 symbolic_header.ioptMax = orig_sym_hdr.ioptMax;
03915 symbolic_header.cbLine = orig_sym_hdr.cbLine;
03916 symbolic_header.crfd = orig_sym_hdr.crfd;
03917
03918
03919
03920
03921
03922
03923 for (file_ptr = first_file;
03924 file_ptr != (efdr_t *) 0;
03925 file_ptr = file_ptr->next_file)
03926 {
03927 SYMR *sym_start;
03928 SYMR *sym;
03929 SYMR *sym_end_p1;
03930 FDR *fd_ptr = file_ptr->orig_fdr;
03931
03932 cur_file_ptr = file_ptr;
03933
03934
03935
03936
03937
03938 sym_start = ORIG_LSYMS (fd_ptr->isymBase);
03939 sym_end_p1 = sym_start + fd_ptr->csym;
03940 for (sym = sym_start; sym < sym_end_p1; sym++)
03941 {
03942 if ((st_t) sym->st == st_Static)
03943 {
03944 char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
03945 Size_t len = strlen (str);
03946 shash_t *hash_ptr;
03947
03948
03949 if (str[0] == '$' && str[1] == 'L')
03950 continue;
03951 hash_ptr = hash_string (str,
03952 (Ptrdiff_t) len,
03953 &file_ptr->shash_head[0],
03954 (symint_t *) 0);
03955 if (hash_ptr == (shash_t *) 0)
03956 {
03957 (void) add_local_symbol (str, str + len,
03958 (st_t) sym->st, (sc_t) sym->sc,
03959 (symint_t) sym->value,
03960 (symint_t) indexNil);
03961 }
03962 }
03963 }
03964 (void) add_local_symbol ((const char *) 0, (const char *) 0,
03965 st_End, sc_Text,
03966 (symint_t) 0,
03967 (symint_t) 0);
03968
03969 file_ptr->fdr.cpd = file_ptr->procs.num_allocated;
03970 file_ptr->fdr.ipdFirst = symbolic_header.ipdMax;
03971 symbolic_header.ipdMax += file_ptr->fdr.cpd;
03972
03973 file_ptr->fdr.csym = file_ptr->symbols.num_allocated;
03974 file_ptr->fdr.isymBase = symbolic_header.isymMax;
03975 symbolic_header.isymMax += file_ptr->fdr.csym;
03976
03977 file_ptr->fdr.caux = file_ptr->aux_syms.num_allocated;
03978 file_ptr->fdr.iauxBase = symbolic_header.iauxMax;
03979 symbolic_header.iauxMax += file_ptr->fdr.caux;
03980
03981 file_ptr->fdr.cbSs = file_ptr->strings.num_allocated;
03982 file_ptr->fdr.issBase = symbolic_header.issMax;
03983 symbolic_header.issMax += file_ptr->fdr.cbSs;
03984 }
03985
03986 #ifndef ALIGN_SYMTABLE_OFFSET
03987 #define ALIGN_SYMTABLE_OFFSET(OFFSET) (OFFSET)
03988 #endif
03989
03990 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
03991 i = WORD_ALIGN (symbolic_header.cbLine);
03992 if (i > 0)
03993 {
03994 symbolic_header.cbLineOffset = file_offset;
03995 file_offset += i;
03996 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
03997 }
03998
03999 i = symbolic_header.ioptMax;
04000 if (((long) i) > 0)
04001 {
04002 symbolic_header.cbOptOffset = file_offset;
04003 file_offset += i * sizeof (OPTR);
04004 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04005 }
04006
04007 i = symbolic_header.idnMax;
04008 if (i > 0)
04009 {
04010 symbolic_header.cbDnOffset = file_offset;
04011 file_offset += i * sizeof (DNR);
04012 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04013 }
04014
04015 i = symbolic_header.ipdMax;
04016 if (i > 0)
04017 {
04018 symbolic_header.cbPdOffset = file_offset;
04019 file_offset += i * sizeof (PDR);
04020 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04021 }
04022
04023 i = symbolic_header.isymMax;
04024 if (i > 0)
04025 {
04026 symbolic_header.cbSymOffset = file_offset;
04027 file_offset += i * sizeof (SYMR);
04028 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04029 }
04030
04031 i = symbolic_header.iauxMax;
04032 if (i > 0)
04033 {
04034 symbolic_header.cbAuxOffset = file_offset;
04035 file_offset += i * sizeof (TIR);
04036 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04037 }
04038
04039 i = WORD_ALIGN (symbolic_header.issMax);
04040 if (i > 0)
04041 {
04042 symbolic_header.cbSsOffset = file_offset;
04043 file_offset += i;
04044 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04045 }
04046
04047 i = WORD_ALIGN (symbolic_header.issExtMax);
04048 if (i > 0)
04049 {
04050 symbolic_header.cbSsExtOffset = file_offset;
04051 file_offset += i;
04052 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04053 }
04054
04055 i = symbolic_header.ifdMax;
04056 if (i > 0)
04057 {
04058 symbolic_header.cbFdOffset = file_offset;
04059 file_offset += i * sizeof (FDR);
04060 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04061 }
04062
04063 i = symbolic_header.crfd;
04064 if (i > 0)
04065 {
04066 symbolic_header.cbRfdOffset = file_offset;
04067 file_offset += i * sizeof (symint_t);
04068 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04069 }
04070
04071 i = symbolic_header.iextMax;
04072 if (i > 0)
04073 {
04074 symbolic_header.cbExtOffset = file_offset;
04075 file_offset += i * sizeof (EXTR);
04076 file_offset = ALIGN_SYMTABLE_OFFSET (file_offset);
04077 }
04078 }
04079
04080
04081
04082
04083 STATIC void
04084 write_varray (vp, offset, str)
04085 varray_t *vp;
04086 off_t offset;
04087 const char *str;
04088 {
04089 int num_write, sys_write;
04090 vlinks_t *ptr;
04091
04092 if (vp->num_allocated == 0)
04093 return;
04094
04095 if (debug)
04096 {
04097 fputs ("\twarray\tvp = ", stderr);
04098 fprintf (stderr, HOST_PTR_PRINTF, (PTR) vp);
04099 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
04100 (unsigned long) offset, vp->num_allocated * vp->object_size, str);
04101 }
04102
04103 if (file_offset != offset
04104 && fseek (object_stream, (long) offset, SEEK_SET) < 0)
04105 pfatal_with_name (object_name);
04106
04107 for (ptr = vp->first; ptr != (vlinks_t *) 0; ptr = ptr->next)
04108 {
04109 num_write = (ptr->next == (vlinks_t *) 0)
04110 ? vp->objects_last_page * vp->object_size
04111 : vp->objects_per_page * vp->object_size;
04112
04113 sys_write = fwrite ((PTR) ptr->datum, 1, num_write, object_stream);
04114 if (sys_write <= 0)
04115 pfatal_with_name (object_name);
04116
04117 else if (sys_write != num_write)
04118 fatal ("wrote %d bytes to %s, system returned %d",
04119 num_write,
04120 object_name,
04121 sys_write);
04122
04123 file_offset += num_write;
04124 }
04125 }
04126
04127
04128
04129
04130 STATIC void
04131 write_object ()
04132 {
04133 int sys_write;
04134 efdr_t *file_ptr;
04135 off_t offset;
04136
04137 if (debug)
04138 {
04139 fputs ("\n\twrite\tvp = ", stderr);
04140 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &symbolic_header);
04141 fprintf (stderr, ", offset = %7u, size = %7lu, %s\n",
04142 0, (unsigned long) sizeof (symbolic_header), "symbolic header");
04143 }
04144
04145 sys_write = fwrite ((PTR) &symbolic_header,
04146 1,
04147 sizeof (symbolic_header),
04148 object_stream);
04149
04150 if (sys_write < 0)
04151 pfatal_with_name (object_name);
04152
04153 else if (sys_write != sizeof (symbolic_header))
04154 fatal ("wrote %d bytes to %s, system returned %d",
04155 (int) sizeof (symbolic_header),
04156 object_name,
04157 sys_write);
04158
04159
04160 file_offset = sizeof (symbolic_header) + orig_file_header.f_symptr;
04161
04162 if (symbolic_header.cbLine > 0)
04163 {
04164 long sys_write;
04165
04166 if (file_offset != symbolic_header.cbLineOffset
04167 && fseek (object_stream, symbolic_header.cbLineOffset, SEEK_SET) != 0)
04168 pfatal_with_name (object_name);
04169
04170 if (debug)
04171 {
04172 fputs ("\twrite\tvp = ", stderr);
04173 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &orig_linenum);
04174 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
04175 (long) symbolic_header.cbLineOffset,
04176 (long) symbolic_header.cbLine, "Line numbers");
04177 }
04178
04179 sys_write = fwrite ((PTR) orig_linenum,
04180 1,
04181 symbolic_header.cbLine,
04182 object_stream);
04183
04184 if (sys_write <= 0)
04185 pfatal_with_name (object_name);
04186
04187 else if (sys_write != symbolic_header.cbLine)
04188 fatal ("wrote %ld bytes to %s, system returned %ld",
04189 (long) symbolic_header.cbLine,
04190 object_name,
04191 sys_write);
04192
04193 file_offset = symbolic_header.cbLineOffset + symbolic_header.cbLine;
04194 }
04195
04196 if (symbolic_header.ioptMax > 0)
04197 {
04198 long sys_write;
04199 long num_write = symbolic_header.ioptMax * sizeof (OPTR);
04200
04201 if (file_offset != symbolic_header.cbOptOffset
04202 && fseek (object_stream, symbolic_header.cbOptOffset, SEEK_SET) != 0)
04203 pfatal_with_name (object_name);
04204
04205 if (debug)
04206 {
04207 fputs ("\twrite\tvp = ", stderr);
04208 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &orig_opt_syms);
04209 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
04210 (long) symbolic_header.cbOptOffset,
04211 num_write, "Optimizer symbols");
04212 }
04213
04214 sys_write = fwrite ((PTR) orig_opt_syms,
04215 1,
04216 num_write,
04217 object_stream);
04218
04219 if (sys_write <= 0)
04220 pfatal_with_name (object_name);
04221
04222 else if (sys_write != num_write)
04223 fatal ("wrote %ld bytes to %s, system returned %ld",
04224 num_write,
04225 object_name,
04226 sys_write);
04227
04228 file_offset = symbolic_header.cbOptOffset + num_write;
04229 }
04230
04231 if (symbolic_header.idnMax > 0)
04232 write_varray (&dense_num, (off_t) symbolic_header.cbDnOffset, "Dense numbers");
04233
04234 if (symbolic_header.ipdMax > 0)
04235 {
04236 offset = symbolic_header.cbPdOffset;
04237 for (file_ptr = first_file;
04238 file_ptr != (efdr_t *) 0;
04239 file_ptr = file_ptr->next_file)
04240 {
04241 write_varray (&file_ptr->procs, offset, "Procedure tables");
04242 offset = file_offset;
04243 }
04244 }
04245
04246 if (symbolic_header.isymMax > 0)
04247 {
04248 offset = symbolic_header.cbSymOffset;
04249 for (file_ptr = first_file;
04250 file_ptr != (efdr_t *) 0;
04251 file_ptr = file_ptr->next_file)
04252 {
04253 write_varray (&file_ptr->symbols, offset, "Local symbols");
04254 offset = file_offset;
04255 }
04256 }
04257
04258 if (symbolic_header.iauxMax > 0)
04259 {
04260 offset = symbolic_header.cbAuxOffset;
04261 for (file_ptr = first_file;
04262 file_ptr != (efdr_t *) 0;
04263 file_ptr = file_ptr->next_file)
04264 {
04265 write_varray (&file_ptr->aux_syms, offset, "Aux. symbols");
04266 offset = file_offset;
04267 }
04268 }
04269
04270 if (symbolic_header.issMax > 0)
04271 {
04272 offset = symbolic_header.cbSsOffset;
04273 for (file_ptr = first_file;
04274 file_ptr != (efdr_t *) 0;
04275 file_ptr = file_ptr->next_file)
04276 {
04277 write_varray (&file_ptr->strings, offset, "Local strings");
04278 offset = file_offset;
04279 }
04280 }
04281
04282 if (symbolic_header.issExtMax > 0)
04283 write_varray (&ext_strings, symbolic_header.cbSsExtOffset, "External strings");
04284
04285 if (symbolic_header.ifdMax > 0)
04286 {
04287 offset = symbolic_header.cbFdOffset;
04288 if (file_offset != offset
04289 && fseek (object_stream, (long) offset, SEEK_SET) < 0)
04290 pfatal_with_name (object_name);
04291
04292 file_offset = offset;
04293 for (file_ptr = first_file;
04294 file_ptr != (efdr_t *) 0;
04295 file_ptr = file_ptr->next_file)
04296 {
04297 if (debug)
04298 {
04299 fputs ("\twrite\tvp = ", stderr);
04300 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &file_ptr->fdr);
04301 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
04302 file_offset, (unsigned long) sizeof (FDR),
04303 "File header");
04304 }
04305
04306 sys_write = fwrite (&file_ptr->fdr,
04307 1,
04308 sizeof (FDR),
04309 object_stream);
04310
04311 if (sys_write < 0)
04312 pfatal_with_name (object_name);
04313
04314 else if (sys_write != sizeof (FDR))
04315 fatal ("wrote %d bytes to %s, system returned %d",
04316 (int) sizeof (FDR),
04317 object_name,
04318 sys_write);
04319
04320 file_offset = offset += sizeof (FDR);
04321 }
04322 }
04323
04324 if (symbolic_header.crfd > 0)
04325 {
04326 long sys_write;
04327 symint_t num_write = symbolic_header.crfd * sizeof (symint_t);
04328
04329 if (file_offset != symbolic_header.cbRfdOffset
04330 && fseek (object_stream, symbolic_header.cbRfdOffset, SEEK_SET) != 0)
04331 pfatal_with_name (object_name);
04332
04333 if (debug)
04334 {
04335 fputs ("\twrite\tvp = ", stderr);
04336 fprintf (stderr, HOST_PTR_PRINTF, (PTR) &orig_rfds);
04337 fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
04338 (long) symbolic_header.cbRfdOffset,
04339 num_write, "Relative file descriptors");
04340 }
04341
04342 sys_write = fwrite (orig_rfds,
04343 1,
04344 num_write,
04345 object_stream);
04346
04347 if (sys_write <= 0)
04348 pfatal_with_name (object_name);
04349
04350 else if (sys_write != (long) num_write)
04351 fatal ("wrote %lu bytes to %s, system returned %ld",
04352 num_write,
04353 object_name,
04354 sys_write);
04355
04356 file_offset = symbolic_header.cbRfdOffset + num_write;
04357 }
04358
04359 if (symbolic_header.issExtMax > 0)
04360 write_varray (&ext_symbols, (off_t) symbolic_header.cbExtOffset, "External symbols");
04361
04362 if (fclose (object_stream) != 0)
04363 pfatal_with_name (object_name);
04364 }
04365
04366
04367
04368
04369 STATIC page_t *
04370 read_seek (size, offset, str)
04371 Size_t size;
04372 off_t offset;
04373 const char *str;
04374 {
04375 page_t *ptr;
04376 long sys_read = 0;
04377
04378 if (size == 0)
04379 return (page_t *) 0;
04380
04381 if (debug)
04382 fprintf (stderr,
04383 "\trseek\tsize = %7lu, offset = %7lu, currently at %7lu, %s\n",
04384 (unsigned long) size, (unsigned long) offset, file_offset, str);
04385
04386 #ifndef MALLOC_CHECK
04387 ptr = allocate_multiple_pages ((size + PAGE_USIZE - 1) / PAGE_USIZE);
04388 #else
04389 ptr = (page_t *) xcalloc (1, size);
04390 #endif
04391
04392
04393
04394 if (file_offset != offset)
04395 {
04396 symint_t difference = offset - file_offset;
04397
04398 if (difference < 8)
04399 {
04400 char small_buffer[8];
04401
04402 sys_read = fread (small_buffer, 1, difference, obj_in_stream);
04403 if (sys_read <= 0)
04404 pfatal_with_name (obj_in_name);
04405
04406 if ((symint_t) sys_read != difference)
04407 fatal ("wanted to read %lu bytes from %s, system returned %ld",
04408 (unsigned long) size,
04409 obj_in_name,
04410 sys_read);
04411 }
04412 else if (fseek (obj_in_stream, offset, SEEK_SET) < 0)
04413 pfatal_with_name (obj_in_name);
04414 }
04415
04416 sys_read = fread ((PTR) ptr, 1, size, obj_in_stream);
04417 if (sys_read <= 0)
04418 pfatal_with_name (obj_in_name);
04419
04420 if (sys_read != (long) size)
04421 fatal ("wanted to read %lu bytes from %s, system returned %ld",
04422 (unsigned long) size,
04423 obj_in_name,
04424 sys_read);
04425
04426 file_offset = offset + size;
04427
04428 if (file_offset > max_file_offset)
04429 max_file_offset = file_offset;
04430
04431 return ptr;
04432 }
04433
04434
04435
04436
04437
04438
04439 STATIC void
04440 copy_object ()
04441 {
04442 char buffer[ PAGE_SIZE ];
04443 int sys_read;
04444 int remaining;
04445 int num_write;
04446 int sys_write;
04447 int fd, es;
04448 int delete_ifd = 0;
04449 int *remap_file_number;
04450 struct stat stat_buf;
04451
04452 if (debug)
04453 fprintf (stderr, "\tcopy\n");
04454
04455 if (fstat (fileno (obj_in_stream), &stat_buf) != 0
04456 || fseek (obj_in_stream, 0L, SEEK_SET) != 0)
04457 pfatal_with_name (obj_in_name);
04458
04459 sys_read = fread ((PTR) &orig_file_header,
04460 1,
04461 sizeof (struct filehdr),
04462 obj_in_stream);
04463
04464 if (sys_read < 0)
04465 pfatal_with_name (obj_in_name);
04466
04467 else if (sys_read == 0 && feof (obj_in_stream))
04468 return;
04469
04470 else if (sys_read < (int) sizeof (struct filehdr))
04471 fatal ("wanted to read %d bytes from %s, system returned %d",
04472 (int) sizeof (struct filehdr),
04473 obj_in_name,
04474 sys_read);
04475
04476
04477 if (orig_file_header.f_nsyms != sizeof (HDRR))
04478 fatal ("%s symbolic header wrong size (%ld bytes, should be %ld)",
04479 input_name, (long) orig_file_header.f_nsyms, (long) sizeof (HDRR));
04480
04481
04482
04483 if (fseek (obj_in_stream, (long) orig_file_header.f_symptr, SEEK_SET) != 0)
04484 pfatal_with_name (input_name);
04485
04486 sys_read = fread ((PTR) &orig_sym_hdr,
04487 1,
04488 sizeof (orig_sym_hdr),
04489 obj_in_stream);
04490
04491 if (sys_read < 0)
04492 pfatal_with_name (object_name);
04493
04494 else if (sys_read < (int) sizeof (struct filehdr))
04495 fatal ("wanted to read %d bytes from %s, system returned %d",
04496 (int) sizeof (struct filehdr),
04497 obj_in_name,
04498 sys_read);
04499
04500
04501
04502
04503
04504
04505
04506
04507
04508 file_offset = orig_file_header.f_symptr + sizeof (struct filehdr);
04509
04510 if (orig_sym_hdr.cbLine > 0)
04511 orig_linenum = (char *) read_seek ((Size_t) orig_sym_hdr.cbLine,
04512 orig_sym_hdr.cbLineOffset,
04513 "Line numbers");
04514
04515 if (orig_sym_hdr.ipdMax > 0)
04516 orig_procs = (PDR *) read_seek ((Size_t) orig_sym_hdr.ipdMax * sizeof (PDR),
04517 orig_sym_hdr.cbPdOffset,
04518 "Procedure tables");
04519
04520 if (orig_sym_hdr.isymMax > 0)
04521 orig_local_syms = (SYMR *) read_seek ((Size_t) orig_sym_hdr.isymMax * sizeof (SYMR),
04522 orig_sym_hdr.cbSymOffset,
04523 "Local symbols");
04524
04525 if (orig_sym_hdr.iauxMax > 0)
04526 orig_aux_syms = (AUXU *) read_seek ((Size_t) orig_sym_hdr.iauxMax * sizeof (AUXU),
04527 orig_sym_hdr.cbAuxOffset,
04528 "Aux. symbols");
04529
04530 if (orig_sym_hdr.issMax > 0)
04531 orig_local_strs = (char *) read_seek ((Size_t) orig_sym_hdr.issMax,
04532 orig_sym_hdr.cbSsOffset,
04533 "Local strings");
04534
04535 if (orig_sym_hdr.issExtMax > 0)
04536 orig_ext_strs = (char *) read_seek ((Size_t) orig_sym_hdr.issExtMax,
04537 orig_sym_hdr.cbSsExtOffset,
04538 "External strings");
04539
04540 if (orig_sym_hdr.ifdMax > 0)
04541 orig_files = (FDR *) read_seek ((Size_t) orig_sym_hdr.ifdMax * sizeof (FDR),
04542 orig_sym_hdr.cbFdOffset,
04543 "File tables");
04544
04545 if (orig_sym_hdr.crfd > 0)
04546 orig_rfds = (symint_t *) read_seek ((Size_t) orig_sym_hdr.crfd * sizeof (symint_t),
04547 orig_sym_hdr.cbRfdOffset,
04548 "Relative file descriptors");
04549
04550 if (orig_sym_hdr.issExtMax > 0)
04551 orig_ext_syms = (EXTR *) read_seek ((Size_t) orig_sym_hdr.iextMax * sizeof (EXTR),
04552 orig_sym_hdr.cbExtOffset,
04553 "External symbols");
04554
04555 if (orig_sym_hdr.idnMax > 0)
04556 {
04557 orig_dense = (DNR *) read_seek ((Size_t) orig_sym_hdr.idnMax * sizeof (DNR),
04558 orig_sym_hdr.cbDnOffset,
04559 "Dense numbers");
04560
04561 add_bytes (&dense_num, (char *) orig_dense, (Size_t) orig_sym_hdr.idnMax);
04562 }
04563
04564 if (orig_sym_hdr.ioptMax > 0)
04565 orig_opt_syms = (OPTR *) read_seek ((Size_t) orig_sym_hdr.ioptMax * sizeof (OPTR),
04566 orig_sym_hdr.cbOptOffset,
04567 "Optimizer symbols");
04568
04569
04570
04571
04572 if (max_file_offset != stat_buf.st_size)
04573 fatal ("symbol table is not last (symbol table ends at %ld, .o ends at %ld",
04574 max_file_offset,
04575 (long) stat_buf.st_size);
04576
04577
04578
04579
04580 if (orig_sym_hdr.ifdMax > 1
04581 && orig_files->csym == 2
04582 && orig_files->caux == 0)
04583 {
04584 char *filename = orig_local_strs + (orig_files->issBase + orig_files->rss);
04585 char *suffix = strrchr (filename, '.');
04586
04587 if (suffix != (char *) 0 && strcmp (suffix, ".s") == 0)
04588 delete_ifd = 1;
04589 }
04590
04591
04592
04593
04594
04595
04596 remap_file_number = (int *) alloca (sizeof (int) * orig_sym_hdr.ifdMax);
04597
04598 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
04599 {
04600 FDR *fd_ptr = ORIG_FILES (fd);
04601 char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
04602
04603
04604 add_file (filename, filename + strlen (filename));
04605 remap_file_number[fd] = cur_file_ptr->file_index;
04606 }
04607
04608 if (delete_ifd > 0)
04609 remap_file_number[0] = remap_file_number[1];
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620 if (debug)
04621 fprintf (stderr, "\tehash\n");
04622
04623 for (es = 0; es < orig_sym_hdr.iextMax; es++)
04624 {
04625 EXTR *eptr = orig_ext_syms + es;
04626 unsigned ifd = eptr->ifd;
04627
04628 (void) add_ext_symbol (eptr, ((long) ifd < orig_sym_hdr.ifdMax)
04629 ? remap_file_number[ ifd ] : ifd );
04630 }
04631
04632
04633
04634
04635
04636 for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
04637 {
04638 FDR *fd_ptr = ORIG_FILES (fd);
04639 char *filename = ORIG_LSTRS (fd_ptr->issBase + fd_ptr->rss);
04640 SYMR *sym_start;
04641 SYMR *sym;
04642 SYMR *sym_end_p1;
04643 PDR *proc_start;
04644 PDR *proc;
04645 PDR *proc_end_p1;
04646
04647
04648 add_file (filename, filename + strlen (filename));
04649 cur_file_ptr->orig_fdr = fd_ptr;
04650
04651
04652 cur_file_ptr->fdr.adr = fd_ptr->adr;
04653 cur_file_ptr->fdr.ilineBase = fd_ptr->ilineBase;
04654 cur_file_ptr->fdr.cline = fd_ptr->cline;
04655 cur_file_ptr->fdr.rfdBase = fd_ptr->rfdBase;
04656 cur_file_ptr->fdr.crfd = fd_ptr->crfd;
04657 cur_file_ptr->fdr.cbLineOffset = fd_ptr->cbLineOffset;
04658 cur_file_ptr->fdr.cbLine = fd_ptr->cbLine;
04659 cur_file_ptr->fdr.fMerge = fd_ptr->fMerge;
04660 cur_file_ptr->fdr.fReadin = fd_ptr->fReadin;
04661 cur_file_ptr->fdr.glevel = fd_ptr->glevel;
04662
04663 if (debug)
04664 fprintf (stderr, "\thash\tstart, filename %s\n", filename);
04665
04666
04667
04668
04669
04670 sym_start = ORIG_LSYMS (fd_ptr->isymBase);
04671 sym_end_p1 = sym_start + fd_ptr->csym;
04672 for (sym = sym_start; sym < sym_end_p1; sym++)
04673 {
04674 switch ((st_t) sym->st)
04675 {
04676 default:
04677 break;
04678
04679 case st_Global:
04680 case st_Static:
04681 case st_Label:
04682 case st_Proc:
04683 case st_StaticProc:
04684 {
04685 auto symint_t hash_index;
04686 char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
04687 Size_t len = strlen (str);
04688 shash_t *shash_ptr = hash_string (str,
04689 (Ptrdiff_t) len,
04690 &orig_str_hash[0],
04691 &hash_index);
04692
04693 if (shash_ptr != (shash_t *) 0)
04694 error ("internal error, %s is already in original symbol table", str);
04695
04696 else
04697 {
04698 shash_ptr = allocate_shash ();
04699 shash_ptr->next = orig_str_hash[hash_index];
04700 orig_str_hash[hash_index] = shash_ptr;
04701
04702 shash_ptr->len = len;
04703 shash_ptr->indx = indexNil;
04704 shash_ptr->string = str;
04705 shash_ptr->sym_ptr = sym;
04706 }
04707 }
04708 break;
04709
04710 case st_End:
04711 if ((sc_t) sym->sc == sc_Text)
04712 {
04713 char *str = ORIG_LSTRS (fd_ptr->issBase + sym->iss);
04714
04715 if (*str != '\0')
04716 {
04717 Size_t len = strlen (str);
04718 shash_t *shash_ptr = hash_string (str,
04719 (Ptrdiff_t) len,
04720 &orig_str_hash[0],
04721 (symint_t *) 0);
04722
04723 if (shash_ptr != (shash_t *) 0)
04724 shash_ptr->end_ptr = sym;
04725 }
04726 }
04727 break;
04728
04729 }
04730 }
04731
04732 if (debug)
04733 {
04734 fprintf (stderr, "\thash\tdone, filename %s\n", filename);
04735 fprintf (stderr, "\tproc\tstart, filename %s\n", filename);
04736 }
04737
04738
04739
04740
04741 proc_start = ORIG_PROCS (fd_ptr->ipdFirst);
04742 proc_end_p1 = proc_start + fd_ptr->cpd;
04743 for (proc = proc_start; proc < proc_end_p1; proc++)
04744 {
04745 SYMR *proc_sym = ORIG_LSYMS (fd_ptr->isymBase + proc->isym);
04746 char *str = ORIG_LSTRS (fd_ptr->issBase + proc_sym->iss);
04747 Size_t len = strlen (str);
04748 shash_t *shash_ptr = hash_string (str,
04749 (Ptrdiff_t) len,
04750 &orig_str_hash[0],
04751 (symint_t *) 0);
04752
04753 if (shash_ptr == (shash_t *) 0)
04754 error ("internal error, function %s is not in original symbol table", str);
04755
04756 else
04757 shash_ptr->proc_ptr = proc;
04758 }
04759
04760 if (debug)
04761 fprintf (stderr, "\tproc\tdone, filename %s\n", filename);
04762
04763 }
04764 cur_file_ptr = first_file;
04765
04766
04767
04768
04769
04770
04771 if (fseek (obj_in_stream, (long) 0, SEEK_SET) != 0)
04772 pfatal_with_name (obj_in_name);
04773
04774 if (fseek (object_stream, (long) 0, SEEK_SET) != 0)
04775 pfatal_with_name (object_name);
04776
04777 for (remaining = orig_file_header.f_symptr;
04778 remaining > 0;
04779 remaining -= num_write)
04780 {
04781 num_write
04782 = (remaining <= (int) sizeof (buffer))
04783 ? remaining : (int) sizeof (buffer);
04784 sys_read = fread ((PTR) buffer, 1, num_write, obj_in_stream);
04785 if (sys_read <= 0)
04786 pfatal_with_name (obj_in_name);
04787
04788 else if (sys_read != num_write)
04789 fatal ("wanted to read %d bytes from %s, system returned %d",
04790 num_write,
04791 obj_in_name,
04792 sys_read);
04793
04794 sys_write = fwrite (buffer, 1, num_write, object_stream);
04795 if (sys_write <= 0)
04796 pfatal_with_name (object_name);
04797
04798 else if (sys_write != num_write)
04799 fatal ("wrote %d bytes to %s, system returned %d",
04800 num_write,
04801 object_name,
04802 sys_write);
04803 }
04804 }
04805
04806
04807
04808
04809 extern int main PARAMS ((int, char **));
04810
04811 int
04812 main (argc, argv)
04813 int argc;
04814 char **argv;
04815 {
04816 int iflag = 0;
04817 char *p = strrchr (argv[0], '/');
04818 char *num_end;
04819 int option;
04820 int i;
04821
04822 progname = (p != 0) ? p+1 : argv[0];
04823
04824 (void) signal (SIGSEGV, catch_signal);
04825 (void) signal (SIGBUS, catch_signal);
04826 (void) signal (SIGABRT, catch_signal);
04827
04828 #if !defined(__SABER__) && !defined(lint)
04829 if (sizeof (efdr_t) > PAGE_USIZE)
04830 fatal ("efdr_t has a sizeof %d bytes, when it should be less than %d",
04831 (int) sizeof (efdr_t),
04832 (int) PAGE_USIZE);
04833
04834 if (sizeof (page_t) != PAGE_USIZE)
04835 fatal ("page_t has a sizeof %d bytes, when it should be %d",
04836 (int) sizeof (page_t),
04837 (int) PAGE_USIZE);
04838
04839 #endif
04840
04841 alloc_counts[ alloc_type_none ].alloc_name = "none";
04842 alloc_counts[ alloc_type_scope ].alloc_name = "scope";
04843 alloc_counts[ alloc_type_vlinks ].alloc_name = "vlinks";
04844 alloc_counts[ alloc_type_shash ].alloc_name = "shash";
04845 alloc_counts[ alloc_type_thash ].alloc_name = "thash";
04846 alloc_counts[ alloc_type_tag ].alloc_name = "tag";
04847 alloc_counts[ alloc_type_forward ].alloc_name = "forward";
04848 alloc_counts[ alloc_type_thead ].alloc_name = "thead";
04849 alloc_counts[ alloc_type_varray ].alloc_name = "varray";
04850
04851 int_type_info = type_info_init;
04852 int_type_info.basic_type = bt_Int;
04853
04854 void_type_info = type_info_init;
04855 void_type_info.basic_type = bt_Void;
04856
04857 while ((option = getopt (argc, argv, "d:i:I:o:v")) != EOF)
04858 switch (option)
04859 {
04860 default:
04861 had_errors++;
04862 break;
04863
04864 case 'd':
04865 debug = strtol (optarg, &num_end, 0);
04866 if ((unsigned) debug > 4 || num_end == optarg)
04867 had_errors++;
04868
04869 break;
04870
04871 case 'I':
04872 if (rename_output || obj_in_name != (char *) 0)
04873 had_errors++;
04874 else
04875 rename_output = 1;
04876
04877
04878
04879 case 'i':
04880 if (obj_in_name == (char *) 0)
04881 {
04882 obj_in_name = optarg;
04883 iflag++;
04884 }
04885 else
04886 had_errors++;
04887 break;
04888
04889 case 'o':
04890 if (object_name == (char *) 0)
04891 object_name = optarg;
04892 else
04893 had_errors++;
04894 break;
04895
04896 case 'v':
04897 version++;
04898 break;
04899 }
04900
04901 if (obj_in_name == (char *) 0 && optind <= argc - 2)
04902 obj_in_name = argv[--argc];
04903
04904 if (object_name == (char *) 0 && optind <= argc - 2)
04905 object_name = argv[--argc];
04906
04907
04908
04909
04910 if (obj_in_name == (char *) 0 && object_name != (char *) 0)
04911 {
04912 obj_in_name = object_name;
04913 delete_input = 1;
04914 }
04915
04916 if (object_name == (char *) 0 || had_errors || optind != argc - 1)
04917 {
04918 fprintf (stderr, _("Calling Sequence:\n"));
04919 fprintf (stderr, _("\tmips-tfile [-d <num>] [-v] [-i <o-in-file>] -o <o-out-file> <s-file> (or)\n"));
04920 fprintf (stderr, _("\tmips-tfile [-d <num>] [-v] [-I <o-in-file>] -o <o-out-file> <s-file> (or)\n"));
04921 fprintf (stderr, _("\tmips-tfile [-d <num>] [-v] <s-file> <o-in-file> <o-out-file>\n"));
04922 fprintf (stderr, "\n");
04923 fprintf (stderr, _("Debug levels are:\n"));
04924 fprintf (stderr, _(" 1\tGeneral debug + trace functions/blocks.\n"));
04925 fprintf (stderr, _(" 2\tDebug level 1 + trace externals.\n"));
04926 fprintf (stderr, _(" 3\tDebug level 2 + trace all symbols.\n"));
04927 fprintf (stderr, _(" 4\tDebug level 3 + trace memory allocations.\n"));
04928 return 1;
04929 }
04930
04931
04932 if (version)
04933 {
04934 fprintf (stderr, _("mips-tfile version %s"), version_string);
04935 #ifdef TARGET_VERSION
04936 TARGET_VERSION;
04937 #endif
04938 fputc ('\n', stderr);
04939 }
04940
04941 if (obj_in_name == (char *) 0)
04942 obj_in_name = object_name;
04943
04944 if (rename_output && rename (object_name, obj_in_name) != 0)
04945 {
04946 char *buffer = (char *) allocate_multiple_pages (4);
04947 int len;
04948 int len2;
04949 int in_fd;
04950 int out_fd;
04951
04952
04953 in_fd = open (object_name, O_RDONLY, 0666);
04954 if (in_fd < 0)
04955 pfatal_with_name (object_name);
04956
04957 out_fd = open (obj_in_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
04958 if (out_fd < 0)
04959 pfatal_with_name (obj_in_name);
04960
04961 while ((len = read (in_fd, buffer, 4*PAGE_SIZE)) > 0)
04962 {
04963 len2 = write (out_fd, buffer, len);
04964 if (len2 < 0)
04965 pfatal_with_name (object_name);
04966
04967 if (len != len2)
04968 fatal ("wrote %d bytes to %s, expected to write %d", len2, obj_in_name, len);
04969 }
04970
04971 free_multiple_pages ((page_t *) buffer, 4);
04972
04973 if (len < 0)
04974 pfatal_with_name (object_name);
04975
04976 if (close (in_fd) < 0)
04977 pfatal_with_name (object_name);
04978
04979 if (close (out_fd) < 0)
04980 pfatal_with_name (obj_in_name);
04981 }
04982
04983
04984
04985 obj_in_stream = fopen (obj_in_name, "r");
04986 if (obj_in_stream == (FILE *) 0)
04987 pfatal_with_name (obj_in_name);
04988
04989 if (delete_input && unlink (obj_in_name) != 0)
04990 pfatal_with_name (obj_in_name);
04991
04992 object_stream = fopen (object_name, "w");
04993 if (object_stream == (FILE *) 0)
04994 pfatal_with_name (object_name);
04995
04996 if (strcmp (argv[optind], "-") != 0)
04997 {
04998 input_name = argv[optind];
04999 if (freopen (argv[optind], "r", stdin) != stdin)
05000 pfatal_with_name (argv[optind]);
05001 }
05002
05003 copy_object ();
05004 parse_input ();
05005
05006 update_headers ();
05007 write_object ();
05008
05009 if (debug)
05010 {
05011 fprintf (stderr, "\n\tAllocation summary:\n\n");
05012 for (i = (int) alloc_type_none; i < (int) alloc_type_last; i++)
05013 if (alloc_counts[i].total_alloc)
05014 {
05015 fprintf (stderr,
05016 "\t%s\t%5d allocation(s), %5d free(s), %2d page(s)\n",
05017 alloc_counts[i].alloc_name,
05018 alloc_counts[i].total_alloc,
05019 alloc_counts[i].total_free,
05020 alloc_counts[i].total_pages);
05021 }
05022 }
05023
05024 return (had_errors) ? 1 : 0;
05025 }
05026
05027
05028
05029
05030 STATIC void
05031 catch_signal (signum)
05032 int signum;
05033 {
05034 (void) signal (signum, SIG_DFL);
05035 fatal ("%s", strsignal (signum));
05036 }
05037
05038
05039
05040
05041 void
05042 pfatal_with_name (msg)
05043 const char *msg;
05044 {
05045 int save_errno = errno;
05046 if (line_number > 0)
05047 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
05048 else
05049 fprintf (stderr, "%s:", progname);
05050
05051 errno = save_errno;
05052 if (errno == 0)
05053 fprintf (stderr, "[errno = 0] %s\n", msg);
05054 else
05055 perror (msg);
05056
05057 exit (1);
05058 }
05059
05060
05061
05062
05063
05064
05065 static int
05066 out_of_bounds (indx, max, str, prog_line)
05067 symint_t indx;
05068 symint_t max;
05069 const char *str;
05070 int prog_line;
05071 {
05072 if (indx < max)
05073 return 0;
05074
05075 fprintf (stderr, "%s, %s:%ld index %lu is out of bounds for %s, max is %lu, mips-tfile.c line# %d\n",
05076 progname, input_name, line_number, indx, str, max, prog_line);
05077
05078 exit (1);
05079 return 0;
05080 }
05081
05082
05083
05084
05085
05086
05087 #ifndef MALLOC_CHECK
05088 #ifdef USE_MALLOC
05089
05090 STATIC page_t *
05091 allocate_cluster (npages)
05092 Size_t npages;
05093 {
05094 page_t *value = (page_t *) xcalloc (npages, PAGE_USIZE);
05095
05096 if (debug > 3)
05097 fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
05098
05099 return value;
05100 }
05101
05102 #else
05103
05104 STATIC page_t *
05105 allocate_cluster (npages)
05106 Size_t npages;
05107 {
05108 page_t *ptr = (page_t *) sbrk (0);
05109 unsigned long offset = ((unsigned long) ptr) & (PAGE_SIZE - 1);
05110
05111 if (offset != 0)
05112 {
05113 if (sbrk (PAGE_USIZE - offset) == (char *)-1)
05114 pfatal_with_name ("allocate_cluster");
05115
05116 ptr = (page_t *) (((char *) ptr) + PAGE_SIZE - offset);
05117 }
05118
05119 if (sbrk (npages * PAGE_USIZE) == (char *) -1)
05120 pfatal_with_name ("allocate_cluster");
05121
05122 if (debug > 3)
05123 {
05124 fprintf (stderr, "\talloc\tnpages = %lu, value = ",
05125 (unsigned long) npages);
05126 fprintf (stderr, HOST_PTR_PRINTF, (PTR) ptr);
05127 fputs ("\n", stderr);
05128 }
05129
05130 return ptr;
05131 }
05132
05133 #endif
05134
05135
05136 static page_t *cluster_ptr = NULL;
05137 static unsigned pages_left = 0;
05138
05139 #endif
05140
05141
05142
05143
05144 STATIC page_t *
05145 allocate_multiple_pages (npages)
05146 Size_t npages;
05147 {
05148 #ifndef MALLOC_CHECK
05149 if (pages_left == 0 && npages < MAX_CLUSTER_PAGES)
05150 {
05151 pages_left = MAX_CLUSTER_PAGES;
05152 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
05153 }
05154
05155 if (npages <= pages_left)
05156 {
05157 page_t *ptr = cluster_ptr;
05158 cluster_ptr += npages;
05159 pages_left -= npages;
05160 return ptr;
05161 }
05162
05163 return allocate_cluster (npages);
05164
05165 #else
05166 return (page_t *) xcalloc (npages, PAGE_SIZE);
05167
05168 #endif
05169 }
05170
05171
05172
05173
05174 STATIC void
05175 free_multiple_pages (page_ptr, npages)
05176 page_t *page_ptr;
05177 Size_t npages;
05178 {
05179 #ifndef MALLOC_CHECK
05180 if (pages_left == 0)
05181 {
05182 cluster_ptr = page_ptr;
05183 pages_left = npages;
05184 }
05185
05186 else if ((page_ptr + npages) == cluster_ptr)
05187 {
05188 cluster_ptr -= npages;
05189 pages_left += npages;
05190 }
05191
05192
05193
05194
05195
05196 #else
05197 free ((char *) page_ptr);
05198
05199 #endif
05200 }
05201
05202
05203
05204
05205 STATIC page_t *
05206 allocate_page ()
05207 {
05208 #ifndef MALLOC_CHECK
05209 if (pages_left == 0)
05210 {
05211 pages_left = MAX_CLUSTER_PAGES;
05212 cluster_ptr = allocate_cluster (MAX_CLUSTER_PAGES);
05213 }
05214
05215 pages_left--;
05216 return cluster_ptr++;
05217
05218 #else
05219 return (page_t *) xcalloc (1, PAGE_SIZE);
05220
05221 #endif
05222 }
05223
05224
05225
05226
05227 STATIC scope_t *
05228 allocate_scope ()
05229 {
05230 scope_t *ptr;
05231 static scope_t initial_scope;
05232
05233 #ifndef MALLOC_CHECK
05234 ptr = alloc_counts[ (int) alloc_type_scope ].free_list.f_scope;
05235 if (ptr != (scope_t *) 0)
05236 alloc_counts[ (int) alloc_type_scope ].free_list.f_scope = ptr->free;
05237
05238 else
05239 {
05240 int unallocated = alloc_counts[ (int) alloc_type_scope ].unallocated;
05241 page_t *cur_page = alloc_counts[ (int) alloc_type_scope ].cur_page;
05242
05243 if (unallocated == 0)
05244 {
05245 unallocated = PAGE_SIZE / sizeof (scope_t);
05246 alloc_counts[ (int) alloc_type_scope ].cur_page = cur_page = allocate_page ();
05247 alloc_counts[ (int) alloc_type_scope ].total_pages++;
05248 }
05249
05250 ptr = &cur_page->scope[ --unallocated ];
05251 alloc_counts[ (int) alloc_type_scope ].unallocated = unallocated;
05252 }
05253
05254 #else
05255 ptr = (scope_t *) xmalloc (sizeof (scope_t));
05256
05257 #endif
05258
05259 alloc_counts[ (int) alloc_type_scope ].total_alloc++;
05260 *ptr = initial_scope;
05261 return ptr;
05262 }
05263
05264
05265
05266 STATIC void
05267 free_scope (ptr)
05268 scope_t *ptr;
05269 {
05270 alloc_counts[ (int) alloc_type_scope ].total_free++;
05271
05272 #ifndef MALLOC_CHECK
05273 ptr->free = alloc_counts[ (int) alloc_type_scope ].free_list.f_scope;
05274 alloc_counts[ (int) alloc_type_scope ].free_list.f_scope = ptr;
05275
05276 #else
05277 free ((PTR) ptr);
05278 #endif
05279
05280 }
05281
05282
05283
05284
05285 STATIC vlinks_t *
05286 allocate_vlinks ()
05287 {
05288 vlinks_t *ptr;
05289 static vlinks_t initial_vlinks;
05290
05291 #ifndef MALLOC_CHECK
05292 int unallocated = alloc_counts[ (int) alloc_type_vlinks ].unallocated;
05293 page_t *cur_page = alloc_counts[ (int) alloc_type_vlinks ].cur_page;
05294
05295 if (unallocated == 0)
05296 {
05297 unallocated = PAGE_SIZE / sizeof (vlinks_t);
05298 alloc_counts[ (int) alloc_type_vlinks ].cur_page = cur_page = allocate_page ();
05299 alloc_counts[ (int) alloc_type_vlinks ].total_pages++;
05300 }
05301
05302 ptr = &cur_page->vlinks[ --unallocated ];
05303 alloc_counts[ (int) alloc_type_vlinks ].unallocated = unallocated;
05304
05305 #else
05306 ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
05307
05308 #endif
05309
05310 alloc_counts[ (int) alloc_type_vlinks ].total_alloc++;
05311 *ptr = initial_vlinks;
05312 return ptr;
05313 }
05314
05315
05316
05317
05318 STATIC shash_t *
05319 allocate_shash ()
05320 {
05321 shash_t *ptr;
05322 static shash_t initial_shash;
05323
05324 #ifndef MALLOC_CHECK
05325 int unallocated = alloc_counts[ (int) alloc_type_shash ].unallocated;
05326 page_t *cur_page = alloc_counts[ (int) alloc_type_shash ].cur_page;
05327
05328 if (unallocated == 0)
05329 {
05330 unallocated = PAGE_SIZE / sizeof (shash_t);
05331 alloc_counts[ (int) alloc_type_shash ].cur_page = cur_page = allocate_page ();
05332 alloc_counts[ (int) alloc_type_shash ].total_pages++;
05333 }
05334
05335 ptr = &cur_page->shash[ --unallocated ];
05336 alloc_counts[ (int) alloc_type_shash ].unallocated = unallocated;
05337
05338 #else
05339 ptr = (shash_t *) xmalloc (sizeof (shash_t));
05340
05341 #endif
05342
05343 alloc_counts[ (int) alloc_type_shash ].total_alloc++;
05344 *ptr = initial_shash;
05345 return ptr;
05346 }
05347
05348
05349
05350
05351 STATIC thash_t *
05352 allocate_thash ()
05353 {
05354 thash_t *ptr;
05355 static thash_t initial_thash;
05356
05357 #ifndef MALLOC_CHECK
05358 int unallocated = alloc_counts[ (int) alloc_type_thash ].unallocated;
05359 page_t *cur_page = alloc_counts[ (int) alloc_type_thash ].cur_page;
05360
05361 if (unallocated == 0)
05362 {
05363 unallocated = PAGE_SIZE / sizeof (thash_t);
05364 alloc_counts[ (int) alloc_type_thash ].cur_page = cur_page = allocate_page ();
05365 alloc_counts[ (int) alloc_type_thash ].total_pages++;
05366 }
05367
05368 ptr = &cur_page->thash[ --unallocated ];
05369 alloc_counts[ (int) alloc_type_thash ].unallocated = unallocated;
05370
05371 #else
05372 ptr = (thash_t *) xmalloc (sizeof (thash_t));
05373
05374 #endif
05375
05376 alloc_counts[ (int) alloc_type_thash ].total_alloc++;
05377 *ptr = initial_thash;
05378 return ptr;
05379 }
05380
05381
05382
05383
05384 STATIC tag_t *
05385 allocate_tag ()
05386 {
05387 tag_t *ptr;
05388 static tag_t initial_tag;
05389
05390 #ifndef MALLOC_CHECK
05391 ptr = alloc_counts[ (int) alloc_type_tag ].free_list.f_tag;
05392 if (ptr != (tag_t *) 0)
05393 alloc_counts[ (int) alloc_type_tag ].free_list.f_tag = ptr->free;
05394
05395 else
05396 {
05397 int unallocated = alloc_counts[ (int) alloc_type_tag ].unallocated;
05398 page_t *cur_page = alloc_counts[ (int) alloc_type_tag ].cur_page;
05399
05400 if (unallocated == 0)
05401 {
05402 unallocated = PAGE_SIZE / sizeof (tag_t);
05403 alloc_counts[ (int) alloc_type_tag ].cur_page = cur_page = allocate_page ();
05404 alloc_counts[ (int) alloc_type_tag ].total_pages++;
05405 }
05406
05407 ptr = &cur_page->tag[ --unallocated ];
05408 alloc_counts[ (int) alloc_type_tag ].unallocated = unallocated;
05409 }
05410
05411 #else
05412 ptr = (tag_t *) xmalloc (sizeof (tag_t));
05413
05414 #endif
05415
05416 alloc_counts[ (int) alloc_type_tag ].total_alloc++;
05417 *ptr = initial_tag;
05418 return ptr;
05419 }
05420
05421
05422
05423 STATIC void
05424 free_tag (ptr)
05425 tag_t *ptr;
05426 {
05427 alloc_counts[ (int) alloc_type_tag ].total_free++;
05428
05429 #ifndef MALLOC_CHECK
05430 ptr->free = alloc_counts[ (int) alloc_type_tag ].free_list.f_tag;
05431 alloc_counts[ (int) alloc_type_tag ].free_list.f_tag = ptr;
05432
05433 #else
05434 free ((PTR) ptr);
05435 #endif
05436
05437 }
05438
05439
05440
05441
05442 STATIC forward_t *
05443 allocate_forward ()
05444 {
05445 forward_t *ptr;
05446 static forward_t initial_forward;
05447
05448 #ifndef MALLOC_CHECK
05449 ptr = alloc_counts[ (int) alloc_type_forward ].free_list.f_forward;
05450 if (ptr != (forward_t *) 0)
05451 alloc_counts[ (int) alloc_type_forward ].free_list.f_forward = ptr->free;
05452
05453 else
05454 {
05455 int unallocated = alloc_counts[ (int) alloc_type_forward ].unallocated;
05456 page_t *cur_page = alloc_counts[ (int) alloc_type_forward ].cur_page;
05457
05458 if (unallocated == 0)
05459 {
05460 unallocated = PAGE_SIZE / sizeof (forward_t);
05461 alloc_counts[ (int) alloc_type_forward ].cur_page = cur_page = allocate_page ();
05462 alloc_counts[ (int) alloc_type_forward ].total_pages++;
05463 }
05464
05465 ptr = &cur_page->forward[ --unallocated ];
05466 alloc_counts[ (int) alloc_type_forward ].unallocated = unallocated;
05467 }
05468
05469 #else
05470 ptr = (forward_t *) xmalloc (sizeof (forward_t));
05471
05472 #endif
05473
05474 alloc_counts[ (int) alloc_type_forward ].total_alloc++;
05475 *ptr = initial_forward;
05476 return ptr;
05477 }
05478
05479
05480
05481 STATIC void
05482 free_forward (ptr)
05483 forward_t *ptr;
05484 {
05485 alloc_counts[ (int) alloc_type_forward ].total_free++;
05486
05487 #ifndef MALLOC_CHECK
05488 ptr->free = alloc_counts[ (int) alloc_type_forward ].free_list.f_forward;
05489 alloc_counts[ (int) alloc_type_forward ].free_list.f_forward = ptr;
05490
05491 #else
05492 free ((PTR) ptr);
05493 #endif
05494
05495 }
05496
05497
05498
05499
05500 STATIC thead_t *
05501 allocate_thead ()
05502 {
05503 thead_t *ptr;
05504 static thead_t initial_thead;
05505
05506 #ifndef MALLOC_CHECK
05507 ptr = alloc_counts[ (int) alloc_type_thead ].free_list.f_thead;
05508 if (ptr != (thead_t *) 0)
05509 alloc_counts[ (int) alloc_type_thead ].free_list.f_thead = ptr->free;
05510
05511 else
05512 {
05513 int unallocated = alloc_counts[ (int) alloc_type_thead ].unallocated;
05514 page_t *cur_page = alloc_counts[ (int) alloc_type_thead ].cur_page;
05515
05516 if (unallocated == 0)
05517 {
05518 unallocated = PAGE_SIZE / sizeof (thead_t);
05519 alloc_counts[ (int) alloc_type_thead ].cur_page = cur_page = allocate_page ();
05520 alloc_counts[ (int) alloc_type_thead ].total_pages++;
05521 }
05522
05523 ptr = &cur_page->thead[ --unallocated ];
05524 alloc_counts[ (int) alloc_type_thead ].unallocated = unallocated;
05525 }
05526
05527 #else
05528 ptr = (thead_t *) xmalloc (sizeof (thead_t));
05529
05530 #endif
05531
05532 alloc_counts[ (int) alloc_type_thead ].total_alloc++;
05533 *ptr = initial_thead;
05534 return ptr;
05535 }
05536
05537
05538
05539 STATIC void
05540 free_thead (ptr)
05541 thead_t *ptr;
05542 {
05543 alloc_counts[ (int) alloc_type_thead ].total_free++;
05544
05545 #ifndef MALLOC_CHECK
05546 ptr->free = (thead_t *) alloc_counts[ (int) alloc_type_thead ].free_list.f_thead;
05547 alloc_counts[ (int) alloc_type_thead ].free_list.f_thead = ptr;
05548
05549 #else
05550 free ((PTR) ptr);
05551 #endif
05552
05553 }
05554
05555 #endif
05556
05557
05558
05559
05560
05561 void
05562 fatal VPARAMS ((const char *format, ...))
05563 {
05564 VA_OPEN (ap, format);
05565 VA_FIXEDARG (ap, const char *, format);
05566
05567 if (line_number > 0)
05568 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
05569 else
05570 fprintf (stderr, "%s:", progname);
05571
05572 vfprintf (stderr, format, ap);
05573 VA_CLOSE (ap);
05574 fprintf (stderr, "\n");
05575 if (line_number > 0)
05576 fprintf (stderr, "line:\t%s\n", cur_line_start);
05577
05578 saber_stop ();
05579 exit (1);
05580 }
05581
05582
05583 void
05584 error VPARAMS ((const char *format, ...))
05585 {
05586 VA_OPEN (ap, format);
05587 VA_FIXEDARG (ap, char *, format);
05588
05589 if (line_number > 0)
05590 fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
05591 else
05592 fprintf (stderr, "%s:", progname);
05593
05594 vfprintf (stderr, format, ap);
05595 fprintf (stderr, "\n");
05596 if (line_number > 0)
05597 fprintf (stderr, "line:\t%s\n", cur_line_start);
05598
05599 had_errors++;
05600 VA_CLOSE (ap);
05601
05602 saber_stop ();
05603 }
05604
05605
05606
05607
05608 void
05609 fancy_abort ()
05610 {
05611 fatal ("internal abort");
05612 }
05613
05614
05615
05616
05617
05618 void
05619 botch (s)
05620 const char *s;
05621 {
05622 fatal ("%s", s);
05623 }