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