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 #ifdef USE_PCH
00052 #include "be_com_pch.h"
00053 #endif
00054 #pragma hdrstop
00055 #include <elf.h>
00056 #include <cmplrs/rcodes.h>
00057 #include <sys/resource.h>
00058 #include "defs.h"
00059 #include "erglob.h"
00060 #include "erbe.h"
00061 #include "config.h"
00062 #include "tracing.h"
00063 #include "strtab.h"
00064 #include "stab.h"
00065 #include "const.h"
00066 #include "glob.h"
00067 #include "mtypes.h"
00068 #include "targ_const.h"
00069 #include "targ_sim.h"
00070 #include "ttype.h"
00071 #include "irbdata.h"
00072 #include "util.h"
00073 #include "stblock.h"
00074 #include "data_layout.h"
00075
00076 #define SYMTAB_level(s) s
00077
00078 #define Has_No_Base_Block(st) (ST_base(st) == st)
00079
00080 #define ROUNDUP(val,align) ( (-(INT64)align) & (INT64)(val+align-1) )
00081 #define ROUNDDOWN(val,align) ( (-(INT64)align) & (INT64)(val) )
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 extern INT16
00094 Adjusted_Alignment(ST *sym)
00095 {
00096 if (ST_class(sym) == CLASS_BLOCK)
00097 return STB_align(sym);
00098
00099 INT32 align;
00100 TY_IDX ty_idx = ST_type(sym);
00101 TY& ty = Ty_Table[ST_type (sym)];
00102
00103 switch(ST_class(sym))
00104 {
00105 case CLASS_VAR:
00106 align= TY_align(ty_idx);
00107
00108 if (Is_Structure_Type(ty) && TY_is_packed(ty))
00109 {
00110 return align;
00111 }
00112
00113 switch(ST_sclass(sym))
00114 {
00115 case SCLASS_AUTO:
00116 case SCLASS_PSTATIC:
00117 case SCLASS_FSTATIC:
00118 case SCLASS_DGLOBAL:
00119 case SCLASS_UGLOBAL:
00120 case SCLASS_COMMON:
00121
00122
00123
00124
00125 if (Is_Composite_Type(ty))
00126 {
00127
00128 if (ST_is_datapool(sym)) {
00129 break;
00130 }
00131 else {
00132 align = MAX(align, Aggregate_Alignment);
00133 }
00134 }
00135 break;
00136
00137 case SCLASS_FORMAL:
00138
00139
00140
00141
00142 break;
00143 }
00144 #ifdef TARG_IA32
00145
00146
00147
00148 if (ST_sclass(sym) == SCLASS_AUTO || ST_sclass(sym) == SCLASS_FORMAL) {
00149 INT16 stack_align = Stack_Alignment();
00150 if (align > stack_align) {
00151 align = stack_align;
00152 }
00153 }
00154 #endif
00155 return align ;
00156
00157 case CLASS_CONST:
00158 if (TCON_ty(STC_val(sym)) == MTYPE_STR && TY_kind(ty) == KIND_POINTER)
00159 {
00160
00161
00162
00163
00164 align = TY_align(TY_pointed(ty));
00165 }
00166 else
00167 {
00168 align = TY_align(ty_idx);
00169 }
00170
00171 if (TY_kind(ty) != KIND_SCALAR) {
00172
00173
00174
00175
00176
00177 align = MAX(align, Aggregate_Alignment);
00178 }
00179
00180
00181
00182
00183
00184 if ( TRUE )
00185 {
00186 INT64 size = ST_size(sym);
00187
00188 if (size)
00189 {
00190 if(size < MTYPE_align_best(Spill_Int_Mtype))
00191 {
00192 INT32 pow2= nearest_power_of_two(size);
00193
00194 align = MAX(align, pow2);
00195 }
00196 else
00197 {
00198 align = MAX(align, MTYPE_align_best(Spill_Int_Mtype));
00199 }
00200 }
00201 }
00202 return align;
00203 }
00204
00205 return TY_align(ty_idx);
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 extern ST*
00221 New_ST_Block (STR_IDX name, BOOL is_global, ST_SCLASS sclass, UINT16 align, INT64 size)
00222 {
00223 ST *new_blk = New_ST(is_global ? GLOBAL_SYMTAB : CURRENT_SYMTAB);
00224 ST_Init (new_blk, name, CLASS_BLOCK, sclass, EXPORT_LOCAL, 0);
00225 BLK_IDX blk_idx;
00226 (void) New_BLK(blk_idx);
00227 Set_ST_blk(new_blk, blk_idx);
00228 Set_STB_align(new_blk, align);
00229 Set_STB_size(new_blk, size);
00230 return new_blk;
00231 }
00232
00233 extern ST*
00234 Copy_ST_Block (ST *orig_blk)
00235 {
00236 ST *new_blk = New_ST_Block (ST_name_idx(orig_blk),
00237 ST_level(orig_blk) == GLOBAL_SYMTAB,
00238 ST_sclass(orig_blk), STB_align(orig_blk), STB_size(orig_blk) );
00239 Set_STB_flags(new_blk, STB_flags(orig_blk));
00240 Set_STB_section_idx(new_blk, STB_section_idx(orig_blk));
00241 Set_STB_scninfo_idx(new_blk, STB_scninfo_idx(orig_blk));
00242 return new_blk;
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 static ST *
00261 Create_And_Set_ST_Base(ST *blk1, ST *blk2, STACK_DIR dir)
00262 {
00263 ST *base;
00264 ST *blk1_base = Base_Symbol(blk1);
00265 #if 0
00266 Is_True(ST_sclass(blk1) != SCLASS_UNKNOWN &&
00267 ST_sclass(blk2) != SCLASS_UNKNOWN,
00268 ("Block_Merge: Invalid SCLASS %d, %d",
00269 ST_sclass(blk1), ST_sclass(blk2)));
00270
00271 Is_True(ST_sclass(blk1) == ST_sclass(blk2),
00272 ("Block_Merge: Different SCLASS %d, %d",
00273 ST_sclass(blk1), ST_sclass(blk2)));
00274
00275 FmtAssert(Has_No_Base_Block(blk2),
00276 ("Block_Merge: ST_base of blk2 is already initialized"));
00277 #endif
00278 if (ST_class(blk1_base) != CLASS_BLOCK) {
00279 base = New_ST_Block (Save_Str2(ST_name(blk1_base),".BLOCK"),
00280 Is_Global_Symbol(blk1_base),
00281 ST_sclass(blk1_base), Adjusted_Alignment(blk1_base),
00282 ST_size(blk1_base));
00283 if (dir == DECREMENT) Set_STB_decrement(base);
00284 Set_ST_base(blk1_base, base);
00285 Enter_ST(base);
00286 }
00287 else if (ST_class(blk1) == CLASS_BLOCK) {
00288 base = blk1;
00289 } else {
00290 base = blk1_base;
00291 }
00292
00293 Set_ST_base(blk2, base);
00294 return base;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 void St_Block_Union(ST *blk1, ST *blk2)
00314 {
00315 ST *base;
00316 INT64 size1,size2;
00317
00318 Is_True(!ST_is_initialized(blk2),
00319 ("St_Block_Union: union an initialized ST is not allowed"));
00320 Is_True(ST_sclass(blk1) == ST_sclass(blk2),
00321 ("Block_Union: Different SCLASS for %s and %s",
00322 ST_name(blk1), ST_name(blk2) ) );
00323
00324 base = Create_And_Set_ST_Base(blk1,blk2, INCREMENT);
00325
00326 size1 = ST_size(base);
00327 size2 = ST_size(blk2);
00328
00329 Set_STB_align(base, MAX(STB_align(base), Adjusted_Alignment(blk2)));
00330 Set_STB_size(base, ROUNDUP(MAX(size1,size2),STB_align(base)));
00331 Set_ST_ofst(blk2,0);
00332
00333 if (Is_Global_Symbol(base)) {
00334
00335
00336
00337 Allocate_Object(base);
00338 }
00339
00340 if ( Get_Trace(TP_DATALAYOUT, 1)) {
00341 fprintf(TFile, "union %s with %s, base = %s\n",
00342 ST_name(blk1), ST_name(blk2), ST_name(base) );
00343 }
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 INT64
00357 Offset_From_Base_Symbol ( ST *st )
00358 {
00359 INT64 ofst;
00360 ST *base;
00361
00362 Base_Symbol_And_Offset ( st, &base, &ofst );
00363 return ofst;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375 ST *
00376 Base_Symbol (ST *st)
00377 {
00378 INT64 ofst;
00379 ST *base;
00380
00381 Base_Symbol_And_Offset ( st, &base, &ofst );
00382 return base;
00383 }
00384
00385
00386
00387 void
00388 Create_Slink_Symbol (void)
00389 {
00390
00391 if ( ! PU_is_nested_func(Get_Current_PU())) return;
00392
00393 ST *st = Gen_Temp_Symbol (MTYPE_To_TY(Pointer_type), "__slink_sym");
00394 }
00395
00396
00397
00398 struct is_slink_sym
00399 {
00400 BOOL operator () (UINT32, const ST *st) const {
00401 return (strncmp (ST_name (st), "__slink_sym", 11) == 0);
00402 }
00403 };
00404
00405 ST *
00406 Find_Slink_Symbol (SYMTAB_IDX stab)
00407 {
00408 if (!PU_is_nested_func (Get_Scope_PU (stab)))
00409 return NULL;
00410
00411 ST_IDX st_idx = For_all_until (St_Table, stab, is_slink_sym ());
00412
00413 if (st_idx == 0)
00414 return NULL;
00415 else
00416 return &St_Table[st_idx];
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 ST *Find_Slink_For_ST(ST *st)
00432 {
00433 UINT level = ST_level(st);
00434 SYMTAB_IDX stab= CURRENT_SYMTAB;
00435
00436 while(stab)
00437 {
00438 SYMTAB_IDX parent = SYMTAB_parent(stab);
00439
00440 if (parent && (SYMTAB_level(parent) == level))
00441 {
00442 ST *slink = Find_Slink_Symbol(stab);
00443 Is_True ((slink), ("no SYMTAB_slink_sym() "));
00444 return slink;
00445 }
00446 stab = parent;
00447 }
00448
00449 FmtAssert(FALSE,
00450 ("Find_Slink_For_ST() cannot find symtab for %s (level=%d)",
00451 ST_name(st), ST_level(st)));
00452
00453 return NULL;
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 ST *Find_Slink_For_Scope(ST *function, ST *sym)
00467 {
00468 SYMTAB_IDX symtab= CURRENT_SYMTAB;
00469 INT32 level = PU_lexical_level (function) - PU_lexical_level (sym);
00470
00471 while(level-- > 0)
00472 {
00473 symtab= SYMTAB_parent(symtab);
00474
00475 Is_True ((symtab), ("no symtab at correct level"));
00476 }
00477
00478 {
00479 ST *slink = Find_Slink_Symbol (symtab);
00480 Is_True ((slink), ("no SYMTAB_slink_sym() "));
00481 return slink;
00482 }
00483
00484 return NULL;
00485 }
00486
00487 BOOL ST_is_uplevelTemp(const ST *st)
00488 {
00489 if (ST_class(st) != CLASS_VAR &&
00490 ST_class(st) != CLASS_BLOCK)
00491 return FALSE;
00492
00493 if (Is_Global_Symbol(st) || Is_Local_Symbol(st))
00494 return FALSE;
00495
00496 if (PU_has_altentry(Get_Current_PU()) && ST_declared_static(st))
00497 return FALSE;
00498
00499 switch(ST_sclass(st))
00500 {
00501 case SCLASS_AUTO:
00502 case SCLASS_FORMAL:
00503 return TRUE;
00504 }
00505
00506 return FALSE;
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 void
00526 Base_Symbol_And_Offset_For_Addressing (
00527 ST *sym,
00528 INT64 ofst,
00529 ST **base_symbol,
00530 INT64 *offset_from_base)
00531 {
00532
00533
00534
00535
00536
00537
00538 INT64 tofst = 0;
00539 ST *base = sym;
00540
00541 while ( (ST_base(base) != base )
00542 && (ST_sclass(base) != SCLASS_TEXT)
00543 && !((Gen_PIC_Shared || Gen_PIC_Call_Shared) && ST_is_preemptible(base)) )
00544 {
00545 tofst += ST_ofst(base);
00546 base = ST_base(base);
00547 }
00548
00549 *base_symbol = base;
00550 *offset_from_base = tofst + ofst;
00551 }
00552