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 #ifdef USE_PCH
00059 #include "common_com_pch.h"
00060 #endif
00061 #pragma hdrstop
00062
00063 #if defined(BUILD_OS_DARWIN)
00064 #include <darwin_elf.h>
00065 #else
00066 #include <elf.h>
00067 #endif
00068 #include "cxx_memory.h"
00069 #include "defs.h"
00070 #include "symtab.h"
00071 #include "pu_info.h"
00072
00073 PU_Info *Current_PU_Info = NULL;
00074
00075 void
00076 PU_Info_init (PU_Info *pu)
00077 {
00078 pu->state = 0;
00079 PU_Info_next(pu) = NULL;
00080 PU_Info_child(pu) = NULL;
00081 PU_Info_proc_id(pu) = 0;
00082 PU_Info_flags(pu) = 0;
00083 PU_Info_pu_dst(pu) = DST_INVALID_IDX;
00084 PU_Info_cu_dst(pu) = DST_INVALID_IDX;
00085 PU_Info_maptab(pu) = NULL;
00086 }
00087
00088
00089 static INT number_PU_Infos(PU_Info *pu_tree, INT num_PUs);
00090
00091 INT
00092 Sizeof_PU_Infos (PU_Info *pu_tree)
00093 {
00094 INT32 hdr_sz, num_PUs;
00095
00096
00097 num_PUs = number_PU_Infos(pu_tree, 0);
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 hdr_sz = (sizeof(mINT32) * (3 + WT_SUBSECTIONS)) +
00109 num_PUs * ((3 * sizeof(mINT32)) + sizeof(DST_IDX) +
00110 (2 * sizeof(Elf64_Word) * WT_SUBSECTIONS));
00111
00112 return hdr_sz;
00113 }
00114
00115
00116 INT
00117 number_PU_Infos (PU_Info *pu_tree, INT num_PUs)
00118 {
00119 PU_Info *pu;
00120 for (pu = pu_tree; pu; pu = PU_Info_next(pu)) {
00121
00122
00123 PU_Info_maptab(pu) = (struct wn_map_tab *)(INTPTR)num_PUs;
00124
00125 num_PUs += 1;
00126
00127 if (PU_Info_child(pu)) {
00128 num_PUs = number_PU_Infos(PU_Info_child(pu), num_PUs);
00129 }
00130 }
00131 return num_PUs;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 static char *write_PU_fields(PU_Info *pu_tree, char *addr, INT32 *p_num_PUs);
00144 static char *write_PU_subsect_info(PU_Info *pu_tree, INT32 k, char *addr);
00145
00146 INT
00147 Write_PU_Infos (PU_Info *pu_tree, char *base)
00148 {
00149 INT32 k, num_PUs = 0;
00150 char *addr;
00151
00152
00153 *(INT32 *)base = PU_HEADER_VERSION;
00154 base += sizeof(mINT32);
00155
00156
00157 addr = base + sizeof(mINT32);
00158
00159 addr = write_PU_fields(pu_tree, addr, &num_PUs);
00160
00161
00162 *(INT32 *)addr = WT_SUBSECTIONS;
00163 addr += sizeof(mINT32);
00164
00165 for (k = 0; k < WT_SUBSECTIONS; k++) {
00166
00167
00168 *(INT32 *)addr = k;
00169 addr += sizeof(mINT32);
00170
00171 addr = write_PU_subsect_info(pu_tree, k, addr);
00172 if (!addr) return -1;
00173 }
00174
00175
00176 *(INT32 *)base = num_PUs;
00177
00178 return 0;
00179 }
00180
00181
00182 char *
00183 write_PU_fields (PU_Info *pu_tree, char *addr, INT32 *p_num_PUs)
00184 {
00185 PU_Info *pu, *prev_pu = NULL;
00186 for (pu = pu_tree; pu; pu = PU_Info_next(pu)) {
00187
00188
00189 *(INT32 *)addr = (INT32) PU_Info_proc_sym(pu);
00190 addr += sizeof(mINT32);
00191
00192
00193 *(INT32 *)addr = PU_Info_flags(pu);
00194 addr += sizeof(mINT32);
00195
00196
00197 *(DST_IDX *)addr = PU_Info_pu_dst(pu);
00198 addr += sizeof(DST_IDX);
00199
00200
00201
00202 if (prev_pu) {
00203 *(INT32 *)addr = (INT32) (INTPS) PU_Info_maptab(prev_pu);
00204 } else {
00205 *(INT32 *)addr = -1;
00206 }
00207 addr += sizeof(mINT32);
00208
00209 *p_num_PUs += 1;
00210
00211 if (PU_Info_child(pu)) {
00212 addr = write_PU_fields(PU_Info_child(pu), addr, p_num_PUs);
00213 }
00214
00215 prev_pu = pu;
00216 }
00217 return addr;
00218 }
00219
00220
00221 char *
00222 write_PU_subsect_info (PU_Info *pu_tree, INT32 k, char *addr)
00223 {
00224 PU_Info *pu;
00225 for (pu = pu_tree; pu; pu = PU_Info_next(pu)) {
00226
00227 if (PU_Info_state(pu, k) == Subsect_Missing) {
00228 PU_Info_subsect_offset(pu, k) = 0;
00229 PU_Info_subsect_size(pu, k) = 0;
00230 } else if (PU_Info_state(pu, k) != Subsect_Written) {
00231 return NULL;
00232 }
00233
00234
00235 *(Elf64_Word *)addr = PU_Info_subsect_offset(pu, k);
00236 addr += sizeof(Elf64_Word);
00237 *(Elf64_Word *)addr = PU_Info_subsect_size(pu, k);
00238 addr += sizeof(Elf64_Word);
00239
00240 if (PU_Info_child(pu)) {
00241 addr = write_PU_subsect_info(PU_Info_child(pu), k, addr);
00242 if (!addr) return NULL;
00243 }
00244 }
00245 return addr;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 PU_Info *
00258 Read_PU_Infos (char *base, INT32 size, INT32 *p_num_PUs)
00259 {
00260 INT n, k;
00261 char *addr;
00262 INT32 version_num, num_PUs, prev_index, subsect_kinds, kind;
00263 PU_Info *pu_array, *pu;
00264 Elf64_Word hdr_offset;
00265
00266 hdr_offset = *(Elf64_Word *)base;
00267 addr = base + hdr_offset;
00268
00269
00270 version_num = *(INT32 *)addr;
00271 addr += sizeof(mINT32);
00272 if (version_num != PU_HEADER_VERSION) {
00273 return (PU_Info *)-1;
00274 }
00275
00276 num_PUs = *(INT32 *)addr;
00277 addr += sizeof(mINT32);
00278
00279 if (p_num_PUs) *p_num_PUs = num_PUs;
00280 if (num_PUs < 0) {
00281 return (PU_Info *)-1;
00282 }
00283 if (num_PUs == 0) {
00284 return NULL;
00285 }
00286
00287 pu_array = (PU_Info *)malloc(sizeof(PU_Info) * num_PUs);
00288
00289 BZERO(pu_array, sizeof(PU_Info) * num_PUs);
00290
00291 for (n = 0, pu = pu_array; n < num_PUs; n++, pu++) {
00292
00293 PU_Info_init(pu);
00294
00295
00296 Set_PU_Info_state(pu, WT_PROC_SYM, Subsect_Exists);
00297 PU_Info_proc_id(pu) = *(INT32 *)addr;
00298 addr += sizeof(mINT32);
00299
00300
00301 PU_Info_flags(pu) = *(INT32 *)addr;
00302 addr += sizeof(mINT32);
00303
00304
00305 PU_Info_pu_dst(pu) = *(DST_IDX *)addr;
00306 addr += sizeof(DST_IDX);
00307
00308
00309 prev_index = *(INT32 *)addr;
00310 addr += sizeof(mINT32);
00311 if (prev_index == -1) {
00312 if (n != 0) PU_Info_child(&pu_array[n-1]) = pu;
00313 } else {
00314 PU_Info_next(&pu_array[prev_index]) = pu;
00315 }
00316 }
00317
00318 subsect_kinds = *(INT32 *)addr;
00319 addr += sizeof(mINT32);
00320
00321 for (k = 0; k < subsect_kinds; k++) {
00322
00323
00324 kind = *(INT32 *)addr;
00325 addr += sizeof(mINT32);
00326
00327
00328 if (kind >= WT_SUBSECTIONS) {
00329 addr += (num_PUs * 2 * sizeof(Elf64_Word));
00330 continue;
00331 }
00332
00333 for (n = 0, pu = pu_array; n < num_PUs; n++, pu++) {
00334
00335 PU_Info_subsect_offset(pu, kind) = *(Elf64_Word *)addr;
00336 addr += sizeof(Elf64_Word);
00337 PU_Info_subsect_size(pu, kind) = *(Elf64_Word *)addr;
00338 addr += sizeof(Elf64_Word);
00339
00340 if (PU_Info_subsect_size(pu, kind) != 0) {
00341 Set_PU_Info_state(pu, kind, Subsect_Exists);
00342 }
00343 }
00344 }
00345
00346
00347 if (addr > base + size) return (PU_Info *)-1;
00348
00349 return pu_array;
00350 }
00351
00352
00353
00354 struct SAVED_SCOPE {
00355 enum {
00356 MAGIC = 0x23456789
00357 };
00358 INT32 magic;
00359 ST *parent_pu_st;
00360 SCOPE *saved_scope;
00361
00362 SAVED_SCOPE(SCOPE *sc, SYMTAB_IDX level) :
00363 magic(MAGIC), parent_pu_st(Scope_tab[level - 1].st), saved_scope(sc)
00364 { }
00365
00366
00367 SCOPE *Get_Scope(SYMTAB_IDX level) {
00368 if (magic != MAGIC)
00369 Fail_FmtAssertion("bad SAVED_SCOPE magic number");
00370 if (Scope_tab[level - 1].st != parent_pu_st)
00371 Fail_FmtAssertion("parent PU ST mismatch between save and restore");
00372
00373 return saved_scope;
00374 }
00375 };
00376
00377
00378
00379
00380
00381
00382
00383
00384 void
00385 Save_Local_Symtab (SYMTAB_IDX level, PU_Info *pu)
00386 {
00387
00388
00389
00390
00391 FmtAssert (PU_Info_state (pu, WT_SYMTAB) == Subsect_InMem,
00392 ("Local symbol table not in memory"));
00393 FmtAssert (level >= 2,
00394 ("saving symtab at too high a level (%d)", level));
00395 FmtAssert (Current_scope >= level, ("bad level and/or Current_scope"));
00396
00397
00398
00399 FmtAssert (PU_Info_symtab_ptr(pu) == NULL,
00400 ("Incorrect call to Save_Local_Symtab"));
00401 FmtAssert (level == PU_lexical_level (&St_Table[PU_Info_proc_sym (pu)]),
00402 ("Invalid pu_info in Save_Local_Symtab"));
00403
00404 SCOPE *scope = (SCOPE*) MEM_POOL_Alloc (Scope_tab[CURRENT_SYMTAB].pool,
00405 sizeof(SCOPE));
00406 *scope = Scope_tab[level];
00407 SAVED_SCOPE *saved_scope = CXX_NEW(SAVED_SCOPE(scope, level),
00408 Scope_tab[CURRENT_SYMTAB].pool);
00409
00410 Set_PU_Info_symtab_ptr (pu, saved_scope);
00411 }
00412
00413
00414 void
00415 Restore_Local_Symtab (PU_Info *pu)
00416 {
00417 FmtAssert (PU_Info_state (pu, WT_SYMTAB) == Subsect_InMem,
00418 ("Local symbol table not in memory"));
00419
00420 FmtAssert (PU_Info_symtab_ptr(pu),
00421 ("Incorrect call to Save/Restore_Local_Symtab pair"));
00422
00423 SYMTAB_IDX level = PU_lexical_level (&St_Table[PU_Info_proc_sym (pu)]);
00424
00425 FmtAssert(Current_scope >= level, ("bad level and/or Current_scope"));
00426
00427 SAVED_SCOPE *saved_scope = (SAVED_SCOPE *) PU_Info_symtab_ptr(pu);
00428
00429 Scope_tab[level] = *saved_scope->Get_Scope(level);
00430
00431 }
00432
00433
00434 #ifdef Is_True_On
00435
00436
00437 const static char *PU_Info_subsect_name[WT_SUBSECTIONS] = {
00438 "WT_SYMTAB",
00439 "WT_TREE",
00440 "WT_DEPGRAPH",
00441 "WT_PREFETCH",
00442 "WT_REGIONS",
00443 "WT_FEEDBACK",
00444 "WT_FREQ",
00445 "WT_AC_INTERNAL",
00446 "WT_ALIAS_CLASS"
00447 };
00448
00449 void fdump_PU_Info_state(FILE *f, PU_Info *pu_info)
00450 {
00451 INT i;
00452
00453
00454 for (i = WT_PROC_SYM; i < WT_SUBSECTIONS; i++) {
00455
00456 if (i == WT_PROC_SYM) {
00457 (void) fprintf(f, "WT_PROC_SYM: ");
00458 }
00459 else {
00460 (void) fprintf(f, "%s: ", PU_Info_subsect_name[i]);
00461 }
00462 switch (PU_Info_state(pu_info, i)) {
00463 case Subsect_Missing:
00464 (void) fprintf(f, "Subsect_Missing\n");
00465 break;
00466 case Subsect_Exists:
00467 (void) fprintf(f, "Subsect_Exists\n");
00468 break;
00469 case Subsect_InMem:
00470 (void) fprintf(f, "Subsect_InMem\n");
00471 break;
00472 case Subsect_Written:
00473 (void) fprintf(f, "Subsect_Written\n");
00474 break;
00475 default:
00476 (void) fprintf(f, "Unknown state\n");
00477 break;
00478 }
00479 }
00480 }
00481
00482 void dump_PU_Info_state(PU_Info *pu_info)
00483 {
00484 fdump_PU_Info_state(stdout, pu_info);
00485 }
00486 #endif