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 #ifdef USE_PCH
00042 #include "common_com_pch.h"
00043 #endif
00044 #pragma hdrstop
00045 #include <unistd.h>
00046 #include <sys/stat.h>
00047 #ifdef __MINGW32__
00048 #include <WINDOWS.h>
00049 #else
00050 #include <sys/mman.h>
00051 #endif
00052 #include <fcntl.h>
00053 #include "elf_stuff.h"
00054 #include <sys/elf_whirl.h>
00055 #include <errno.h>
00056
00057 #define USE_STANDARD_TYPES
00058
00059 #include "defs.h"
00060 #ifdef OWN_ERROR_PACKAGE
00061
00062
00063
00064
00065 #define Is_True(x,y) (0)
00066 #define ERRORS_INCLUDED
00067 #else
00068 #include "erglob.h"
00069 #endif
00070 #include "errors.h"
00071 #include "opcode.h"
00072 #include "mempool.h"
00073 #include "strtab.h"
00074 #include "symtab.h"
00075 #include "const.h"
00076 #include "targ_const.h"
00077 #include "config_targ.h"
00078 #include "config_debug.h"
00079 #include "config_elf_targ.h"
00080 #include "irbdata.h"
00081 #include "wn_core.h"
00082 #include "wn.h"
00083 #include "wn_map.h"
00084 #define USE_DST_INTERNALS
00085 #include "dwarf_DST_mem.h"
00086 #include "pu_info.h"
00087 #include "ir_elf.h"
00088 #include "ir_bwrite.h"
00089 #include "ir_bcom.h"
00090 #include "ir_bread.h"
00091
00092 #if defined(BACK_END)
00093 #include "xstats.h"
00094 #endif
00095 #if defined(BACK_END) || defined(BUILD_WHIRL2C) || defined(BUILD_WHIRL2F)
00096 #include "pf_cg.h"
00097 #endif
00098
00099 #ifdef BACK_END
00100 extern "C" {
00101 extern void Init_Dep_Graph(void *g);
00102 extern void Dealloc_Dep_Graph(void);
00103 extern void *Depgraph_Read(char *cur_addr, char *end_addr, char *tree_base);
00104 }
00105 #endif
00106
00107 static BOOL verbose_info = FALSE;
00108 static WN *last_node = NULL;
00109
00110 static off_t global_mapped_size;
00111 static off_t local_mapped_size;
00112
00113 static char file_revision[80];
00114
00115
00116 #define DOUBLE_ALIGNED(sz) (((sz) % 8) == 0 ? (sz) : (sz)+(8-((sz)%8)))
00117 #define ERROR_VALUE -1
00118
00119
00120 #if defined(Is_True_On) || defined(DEBUG_IR)
00121
00122 static INT
00123 Error_Return_Func (void)
00124 {
00125 if (verbose_info && last_node != NULL) {
00126 printf("last_node at %p, opcode = %s\n",
00127 last_node, OPCODE_name(WN_opcode(last_node)));
00128 }
00129 return ERROR_VALUE;
00130 }
00131
00132 #define ERROR_RETURN Error_Return_Func()
00133 #else
00134 #define ERROR_RETURN ERROR_VALUE
00135 #endif
00136
00137
00138 template <class Shdr>
00139 static const Shdr*
00140 get_section_header (const Shdr* shdr, UINT n, Elf64_Word type, Elf64_Word info)
00141 {
00142 for (INT i = 1; i < n; ++i) {
00143 if (shdr[i].sh_type == type && shdr[i].sh_info == info)
00144 return shdr + i;
00145 }
00146
00147 return NULL;
00148 }
00149
00150 OFFSET_AND_SIZE
00151 get_section (void *handle, Elf64_Word type, Elf64_Word info)
00152 {
00153 if (handle == 0 || handle == (void *)(ERROR_VALUE)) {
00154 errno = EINVAL;
00155 return OFFSET_AND_SIZE (0, 0);
00156 }
00157
00158 errno = 0;
00159
00160 Elf64_Ehdr *eh = (Elf64_Ehdr *) handle;
00161
00162 #ifndef __ALWAYS_USE_64BIT_ELF__
00163 if (eh->e_ident[EI_CLASS] == ELFCLASS32) {
00164 Elf32_Ehdr* ehdr = (Elf32_Ehdr*) handle;
00165 const Elf32_Shdr* shdr = (const Elf32_Shdr *)
00166 ((char *) handle + ehdr->e_shoff);
00167 shdr = get_section_header (shdr, ehdr->e_shnum, type, info);
00168 if (!shdr)
00169 return OFFSET_AND_SIZE (0, 0);
00170 return OFFSET_AND_SIZE (shdr->sh_offset, shdr->sh_size);
00171 } else
00172 #endif
00173 {
00174 const Elf64_Shdr* shdr = (const Elf64_Shdr *)
00175 ((char *) handle + eh->e_shoff);
00176 shdr = get_section_header (shdr, eh->e_shnum, type, info);
00177 if (!shdr)
00178 return OFFSET_AND_SIZE (0, 0);
00179 return OFFSET_AND_SIZE (shdr->sh_offset, shdr->sh_size);
00180 }
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190 #if defined(Is_True_On) || defined(DEBUG_IR)
00191 #define CHECK_INPUT_FILES
00192 #endif
00193
00194 #ifdef CHECK_INPUT_FILES
00195
00196 #define CONVERT_OFFSET(typ, fld) \
00197 if ((INTPTR)(fld) >= size) return ERROR_RETURN; \
00198 else (fld) = (typ)(base + (INTPTR)(fld))
00199
00200 #else
00201
00202 #define CONVERT_OFFSET(typ, fld) \
00203 (fld) = (typ)(base + (INTPTR)(fld))
00204
00205 #endif // CHECK_INPUT_FILES
00206
00207
00208
00209
00210
00211
00212 INT
00213 WN_get_global_symtab (void *handle)
00214 {
00215
00216 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_GLOBALS);
00217 if (shdr.offset == 0)
00218 return ERROR_RETURN;
00219
00220 const char *base = (char *) handle + shdr.offset;
00221
00222 const GLOBAL_SYMTAB_HEADER_TABLE *gsymtab =
00223 (GLOBAL_SYMTAB_HEADER_TABLE *) base;
00224
00225 UINT64 size = shdr.size;
00226
00227 if (gsymtab->size < sizeof(gsymtab) ||
00228 gsymtab->entries < GLOBAL_SYMTAB_TABLES || gsymtab->size > size)
00229 return ERROR_RETURN;
00230
00231 UINT i;
00232 for (i = 0; i < GLOBAL_SYMTAB_TABLES; ++i)
00233 if (gsymtab->header[i].offset + gsymtab->header[i].size > size)
00234 return ERROR_RETURN;
00235
00236 for (i = 0; i < GLOBAL_SYMTAB_TABLES; ++i) {
00237 const SYMTAB_HEADER& hdr = gsymtab->header[i];
00238 const char *addr = base + hdr.offset;
00239
00240 switch (hdr.type) {
00241
00242 case SHDR_FILE:
00243 File_info = *((FILE_INFO *) addr);
00244 break;
00245
00246 case SHDR_ST:
00247 Scope_tab[GLOBAL_SYMTAB].st_tab->
00248 Transfer ((ST *) addr, hdr.size / hdr.entsize);
00249 break;
00250
00251 case SHDR_TY:
00252 Ty_tab.Transfer ((TY *) addr, hdr.size / hdr.entsize);
00253 break;
00254
00255 case SHDR_PU:
00256 Pu_Table.Transfer ((PU *) addr, hdr.size / hdr.entsize);
00257 break;
00258
00259 case SHDR_FLD:
00260 Fld_Table.Transfer ((FLD *) addr, hdr.size / hdr.entsize);
00261 break;
00262
00263 case SHDR_ARB:
00264 Arb_Table.Transfer ((ARB *) addr, hdr.size / hdr.entsize);
00265 break;
00266
00267 case SHDR_TYLIST:
00268 Tylist_Table.Transfer ((TYLIST *) addr, hdr.size / hdr.entsize);
00269 break;
00270
00271 case SHDR_TCON:
00272 Tcon_Table.Transfer ((TCON *) addr, hdr.size / hdr.entsize);
00273 break;
00274
00275 case SHDR_STR:
00276 Initialize_TCON_strtab (addr, hdr.size);
00277 break;
00278
00279 case SHDR_INITO:
00280 Scope_tab[GLOBAL_SYMTAB].inito_tab->
00281 Transfer ((INITO *) addr, hdr.size / hdr.entsize);
00282 break;
00283
00284 case SHDR_INITV:
00285 Initv_Table.Transfer ((INITV *) addr, hdr.size / hdr.entsize);
00286 break;
00287
00288 case SHDR_BLK:
00289 Blk_Table.Transfer ((BLK *) addr, hdr.size / hdr.entsize);
00290 break;
00291
00292 case SHDR_ST_ATTR:
00293 Scope_tab[GLOBAL_SYMTAB].st_attr_tab->
00294 Transfer ((ST_ATTR *) addr, hdr.size / hdr.entsize);
00295 break;
00296 }
00297 }
00298
00299 return 0;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309 INT
00310 WN_get_symtab (void *handle, PU_Info *pu)
00311 {
00312 Subsect_State st = PU_Info_state(pu, WT_SYMTAB);
00313 if (st == Subsect_InMem)
00314 return 0;
00315 else if (st != Subsect_Exists)
00316 return ERROR_RETURN;
00317
00318 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_PU_SECTION);
00319 if (shdr.offset == 0)
00320 return ERROR_RETURN;
00321
00322 const char *base = (char *) handle + shdr.offset +
00323 PU_Info_subsect_offset (pu, WT_SYMTAB);
00324 Elf64_Word size = PU_Info_subsect_size(pu, WT_SYMTAB);
00325 const LOCAL_SYMTAB_HEADER_TABLE *lsymtab =
00326 (LOCAL_SYMTAB_HEADER_TABLE *) base;
00327
00328 if (lsymtab->size < sizeof(lsymtab) ||
00329 lsymtab->entries < LOCAL_SYMTAB_TABLES || lsymtab->size > size) {
00330 errno = EINVAL;
00331 return ERROR_RETURN;
00332 }
00333
00334 UINT i;
00335 for (i = 0; i < LOCAL_SYMTAB_TABLES; ++i)
00336 if (lsymtab->header[i].offset + lsymtab->header[i].size > size) {
00337 errno = EINVAL;
00338 return ERROR_RETURN;
00339 }
00340
00341 for (i = 0; i < LOCAL_SYMTAB_TABLES; ++i) {
00342 const SYMTAB_HEADER& hdr = lsymtab->header[i];
00343 const char *addr = base + hdr.offset;
00344
00345 switch (hdr.type) {
00346
00347 case SHDR_ST:
00348 Is_True(Scope_tab[CURRENT_SYMTAB].st_tab != 0,
00349 ("Null st_tab, level = %d", CURRENT_SYMTAB));
00350 Scope_tab[CURRENT_SYMTAB].st_tab->
00351 Transfer ((ST *) addr, hdr.size / hdr.entsize);
00352 break;
00353
00354 case SHDR_LABEL:
00355 Is_True(Scope_tab[CURRENT_SYMTAB].label_tab != 0,
00356 ("Null label_tab, level = %d", CURRENT_SYMTAB));
00357 Scope_tab[CURRENT_SYMTAB].label_tab->
00358 Transfer ((LABEL *) addr, hdr.size / hdr.entsize);
00359 break;
00360
00361 case SHDR_PREG:
00362 Is_True(Scope_tab[CURRENT_SYMTAB].preg_tab != 0,
00363 ("Null preg_tab, level = %d", CURRENT_SYMTAB));
00364 Scope_tab[CURRENT_SYMTAB].preg_tab->
00365 Transfer ((PREG *) addr, hdr.size / hdr.entsize);
00366 break;
00367
00368 case SHDR_INITO:
00369 Is_True(Scope_tab[CURRENT_SYMTAB].inito_tab != 0,
00370 ("Null inito_tab, level = %d", CURRENT_SYMTAB));
00371 Scope_tab[CURRENT_SYMTAB].inito_tab->
00372 Transfer ((INITO *) addr, hdr.size / hdr.entsize);
00373 break;
00374
00375 case SHDR_ST_ATTR:
00376 Is_True(Scope_tab[CURRENT_SYMTAB].st_attr_tab != 0,
00377 ("Null st_attr_tab, level = %d", CURRENT_SYMTAB));
00378 Scope_tab[CURRENT_SYMTAB].st_attr_tab->
00379 Transfer ((ST_ATTR *) addr, hdr.size / hdr.entsize);
00380 break;
00381 }
00382 }
00383
00384 Set_PU_Info_state(pu, WT_SYMTAB, Subsect_InMem);
00385
00386 return 0;
00387 }
00388
00389
00390 INT
00391 WN_get_strtab (void *handle)
00392 {
00393 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_STRTAB);
00394 if (shdr.offset == 0)
00395 return ERROR_RETURN;
00396
00397 Initialize_Strtab ((char *) handle + shdr.offset, shdr.size);
00398
00399 return 0;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408 static INT
00409 fix_tree (WN *node, char *base, Elf64_Word size)
00410 {
00411 OPCODE opcode = (OPCODE) WN_opcode (node);
00412 WN *wn;
00413
00414 #if defined(Is_True_On) || defined(DEBUG_IR)
00415 if (verbose_info) {
00416 printf("opcode %s\n", OPCODE_name(opcode));
00417 last_node = node;
00418 }
00419 #endif
00420
00421 #ifndef CFE
00422 if (opcode == OPC_REGION)
00423 Set_Max_Region_Id (WN_region_id(node));
00424 #endif
00425
00426 #if defined(BACK_END)
00427 if (opcode == OPC_ALTENTRY)
00428 Set_PU_has_altentry (Get_Current_PU ());
00429
00430
00431 Count_WN_Opcode (opcode, &PU_WN_BB_Cnt, &PU_WN_Stmt_Cnt);
00432 #endif
00433
00434 if (opcode == OPC_BLOCK) {
00435 wn = WN_first(node);
00436 if (wn == (WN *) -1) {
00437 WN_first(node) = NULL;
00438 WN_last(node) = NULL;
00439 } else {
00440 CONVERT_OFFSET(WN*, wn);
00441 WN_first(node) = wn;
00442 CONVERT_OFFSET(WN*, WN_last(node));
00443
00444 do {
00445 if (fix_tree (wn, base, size) == ERROR_VALUE)
00446 return ERROR_VALUE;
00447 wn = WN_next(wn);
00448 } while (wn);
00449 }
00450 } else if (!OPCODE_is_leaf(opcode)) {
00451 register INT i, cnt;
00452 register WN **wn_ptr;
00453
00454 cnt = WN_kid_count(node);
00455 wn_ptr = &WN_kid(node, 0);
00456 for (i = 0; i < cnt; i++, wn_ptr++) {
00457 wn = *wn_ptr;
00458 if (wn == (WN *) -1) {
00459 *wn_ptr = NULL;
00460 } else {
00461 CONVERT_OFFSET(WN*, wn);
00462 *wn_ptr = wn;
00463 if (fix_tree (wn, base, size) == ERROR_VALUE)
00464 return ERROR_VALUE;
00465 }
00466 }
00467 }
00468
00469 if (OPCODE_has_next_prev(opcode)) {
00470 wn = WN_prev(node);
00471 if (wn == (WN *) -1) {
00472 WN_prev(node) = NULL;
00473 } else {
00474 CONVERT_OFFSET(WN*, wn);
00475 WN_prev(node) = wn;
00476 }
00477 wn = WN_next(node);
00478 if (wn == (WN *) -1) {
00479 WN_next(node) = NULL;
00480 } else {
00481 CONVERT_OFFSET(WN*, wn);
00482 WN_next(node) = wn;
00483 }
00484 }
00485
00486
00487 if (WN_map_id(node) != -1) {
00488 register OPERATOR_MAPCAT category = OPCODE_mapcat(opcode);
00489 register INT32 map_id = WN_map_id(node);
00490 register INT32 *last_id_ptr;
00491
00492 last_id_ptr = &WN_MAP_TAB_Last_ID(Current_Map_Tab, category);
00493 if (map_id > *last_id_ptr) {
00494 *last_id_ptr = map_id;
00495 }
00496 }
00497
00498 return 0;
00499 }
00500
00501
00502
00503 void
00504 Set_Verbose_Info (BOOL val)
00505 {
00506 verbose_info = val;
00507 }
00508
00509
00510 template <class ELF>
00511 static INT
00512 check_elf_header (char* baseaddr, Elf64_Word size, const ELF& tag)
00513 {
00514 typename ELF::Elf_Ehdr* ehdr = (typename ELF::Elf_Ehdr*) baseaddr;
00515 if (ehdr->e_ident[EI_VERSION] != EV_CURRENT ||
00516 ehdr->e_version != EV_CURRENT)
00517 return ERROR_RETURN;
00518 if (ehdr->e_type != ET_IR ||
00519 ehdr->e_shentsize != sizeof(typename ELF::Elf_Shdr))
00520 return ERROR_RETURN;
00521 if (Target_ABI != ABI_UNDEF &&
00522
00523 ehdr->e_machine != Get_Elf_Target_Machine())
00524 return ABI_MISMATCH;
00525 BOOL is_64bit;
00526 INT isa;
00527 Config_Target_From_ELF (ehdr->e_flags, &is_64bit, &isa);
00528 if ( ! Set_Target_ABI (is_64bit, isa))
00529 return ABI_MISMATCH;
00530 if (ehdr->e_shstrndx >= ehdr->e_shnum)
00531 return ERROR_RETURN;
00532 if (ehdr->e_shoff >= size ||
00533 ehdr->e_shoff + ehdr->e_shnum * sizeof(typename ELF::Elf_Shdr) > size)
00534 return ERROR_RETURN;
00535 typename ELF::Elf_Shdr* shdr =
00536 (typename ELF::Elf_Shdr *) (baseaddr + ehdr->e_shoff);
00537 if ((long) shdr & (
00538 #ifndef __GNUC__
00539 __builtin_alignof(typename ELF::Elf_Shdr)
00540 #else
00541 __alignof__(typename ELF::Elf_Shdr)
00542 #endif
00543 - 1))
00544 return ERROR_RETURN;
00545 return tag.Elf_class();
00546 }
00547
00548
00549 static INT
00550 check_elf_header (char *baseaddr, Elf64_Word size)
00551 {
00552 if (size < sizeof(Elf64_Ehdr))
00553 return ERROR_RETURN;
00554 Elf64_Ehdr* ehdr = (Elf64_Ehdr *) baseaddr;
00555
00556 if (!IS_ELF (*ehdr))
00557 return ERROR_RETURN;
00558
00559 if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
00560 return check_elf_header (baseaddr, size, ELF64());
00561 #ifndef __ALWAYS_USE_64BIT_ELF__
00562 else if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
00563 return check_elf_header (baseaddr, size, ELF32());
00564 #endif
00565 else
00566 return ERROR_RETURN;
00567 }
00568
00569
00570 template <class ELF>
00571 static INT
00572 check_section_headers (char *baseaddr, Elf64_Word size, char* file_revision,
00573 const ELF& tag)
00574 {
00575 typename ELF::Elf_Ehdr* ehdr = (typename ELF::Elf_Ehdr*) baseaddr;
00576 typename ELF::Elf_Shdr* shdr =
00577 (typename ELF::Elf_Shdr*) (baseaddr + ehdr->e_shoff);
00578
00579 errno = ENOEXEC;
00580
00581 if (shdr[ehdr->e_shstrndx].sh_offset >= size ||
00582 shdr[ehdr->e_shstrndx].sh_offset +
00583 shdr[ehdr->e_shstrndx].sh_size > size)
00584 return ERROR_RETURN;
00585
00586 char* shstrtab = baseaddr + shdr[ehdr->e_shstrndx].sh_offset;
00587
00588 for (INT i = 1; i < ehdr->e_shnum; i++) {
00589 if (shdr[i].sh_offset >= size ||
00590 shdr[i].sh_offset + shdr[i].sh_size > size)
00591 return ERROR_RETURN;
00592 if (shdr[i].sh_name >= shdr[ehdr->e_shstrndx].sh_size)
00593 return ERROR_RETURN;
00594 if (shdr[i].sh_link >= ehdr->e_shnum)
00595 return ERROR_RETURN;
00596 if (shdr[i].sh_addralign & (shdr[i].sh_addralign - 1))
00597 return ERROR_RETURN;
00598 if (shdr[i].sh_addralign > 1 &&
00599 (long)(baseaddr + shdr[i].sh_offset) & ((shdr[i].sh_addralign - 1)))
00600 return ERROR_RETURN;
00601
00602
00603 if (shdr[i].sh_type == SHT_PROGBITS &&
00604 strcmp (shstrtab + shdr[i].sh_name, ELF_COMMENT) == 0) {
00605 register char *p = baseaddr + shdr[i].sh_offset;
00606 register char *eob = p + shdr[i].sh_size - 1;
00607 register int match = 0;
00608
00609 if (*eob != 0)
00610
00611 return ERROR_RETURN;
00612
00613 while (p <= eob) {
00614 if (strncmp ("WHIRL:", p, 6) == 0) {
00615 strcpy (file_revision, p);
00616 if (strcmp (WHIRL_REVISION, p) == 0) {
00617 match = 1;
00618 break;
00619 }
00620 }
00621 p += strlen (p) + 1;
00622 }
00623
00624 if (!match && DEBUG_Ir_Version_Check)
00625 return REVISION_MISMATCH;
00626 }
00627 }
00628
00629 errno = 0;
00630 return 1;
00631 }
00632
00633 static INT
00634 fix_comp_flags (char *base, Elf64_Word size)
00635 {
00636 register char **argv;
00637 register Elf64_Word argc;
00638
00639 if (sizeof(Elf64_Word) > size)
00640 return ERROR_RETURN;
00641
00642 argc = *((Elf64_Word *) base);
00643
00644 if (sizeof(Elf64_Word) + argc * sizeof(Elf64_Word) > size)
00645 return ERROR_RETURN;
00646 argv = (char **) (base + sizeof(Elf64_Word));
00647
00648 while (argc--) {
00649 register Elf64_Word offset = *((Elf64_Word *)argv);
00650
00651 if (offset > size)
00652 return ERROR_RETURN;
00653 *argv = base + offset;
00654 argv++;
00655 }
00656
00657 return 0;
00658 }
00659
00660
00661 INT
00662 WN_massage_input (char *baseaddr, Elf64_Word size, char* file_revision)
00663 {
00664 INT st;
00665
00666 if ((st = check_elf_header (baseaddr, size)) < 0)
00667 return st;
00668
00669 #ifndef __ALWAYS_USE_64BIT_ELF__
00670 if (st == ELFCLASS32) {
00671 if ((st = check_section_headers (baseaddr, size, file_revision,
00672 ELF32())) <= 0)
00673 return st;
00674 } else
00675 #endif
00676 {
00677 if ((st = check_section_headers (baseaddr, size, file_revision,
00678 ELF64())) <= 0)
00679 return st;
00680 }
00681
00682 return 1;
00683 }
00684
00685
00686 #ifdef __MINGW32__
00687 static void *
00688 read_file (char *filename, off_t* mapped_size, char* file_revision, int *ret_fd, HANDLE *retMapHd)
00689 #else
00690 static void *
00691 read_file (char *filename, off_t* mapped_size, char* file_revision)
00692 #endif
00693 {
00694 int fd;
00695 INT st;
00696 struct stat stat_buf;
00697 register char *map_addr;
00698
00699 fd = open (filename, O_RDONLY);
00700 if (fd < 0)
00701 return (void *) (INTPTR) ERROR_RETURN;
00702
00703 if (fstat (fd, &stat_buf) != 0)
00704 return (void *) (INTPTR) ERROR_RETURN;
00705
00706 #ifdef __MINGW32__
00707 *retMapHd = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL,
00708 PAGE_READONLY, 0, stat_buf.st_size, filename);
00709 if (*retMapHd == NULL)
00710 return (void *) (INTPTR)ERROR_RETURN;
00711 map_addr = (char *)MapViewOfFileEx(*retMapHd, FILE_MAP_COPY,
00712 0,0,stat_buf.st_size, 0);
00713 #else
00714 map_addr = (char *) mmap (0, stat_buf.st_size, PROT_READ|PROT_WRITE,
00715 MAP_PRIVATE, fd, 0);
00716 #endif
00717 if (map_addr == (char *)(INTPTR)(ERROR_VALUE)) {
00718 close (fd);
00719 return (void *) (INTPTR) ERROR_RETURN;
00720 }
00721
00722 #ifdef __MINGW32__
00723 CloseHandle((HANDLE)_get_osfhandle(fd));
00724 if (ret_fd) *ret_fd = fd;
00725 #else
00726 close (fd);
00727 #endif
00728
00729 if ((st = WN_massage_input (map_addr, stat_buf.st_size,file_revision)) <= 0) {
00730 #ifdef __MINGW32__
00731 UnmapViewOfFile(map_addr);
00732 CloseHandle(*retMapHd);
00733 #else
00734 munmap (map_addr, stat_buf.st_size);
00735 #endif
00736 return (void *) (INTPTR) (st);
00737 }
00738
00739
00740 *mapped_size = stat_buf.st_size;
00741
00742 return map_addr;
00743
00744 }
00745
00746
00747 Elf64_Word
00748 Get_Elf_Section_Size (void *handle, Elf64_Word type, Elf64_Word info)
00749 {
00750 OFFSET_AND_SIZE shdr = get_section (handle, type, info);
00751 if (shdr.offset == 0) return 0;
00752 return shdr.size;
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762 #ifdef __MINGW32__
00763 void *
00764 WN_open_input (char *filename, off_t *mapped_size, int *fd, HANDLE *mapHd)
00765 #else
00766 void *
00767 WN_open_input (char *filename, off_t *mapped_size)
00768 #endif
00769 {
00770 if (filename == 0) {
00771 errno = ENOENT;
00772 return (void *) (INTPTR) ERROR_RETURN;
00773 }
00774
00775 errno = 0;
00776
00777 #ifdef __MINGW32__
00778 return read_file (filename, mapped_size, file_revision, fd, mapHd);
00779 #else
00780 return read_file (filename, mapped_size, file_revision);
00781 #endif
00782
00783 }
00784
00785
00786
00787
00788
00789
00790 #ifdef __MINGW32__
00791 extern void *
00792 WN_inline_open_file(char* file_name, off_t *mapped_size, char* file_revision, HANDLE *mapHd)
00793 #else
00794 extern void *
00795 WN_inline_open_file(char* file_name, off_t *mapped_size, char* file_revision)
00796 #endif
00797 {
00798 if (file_name == 0) {
00799 errno = ENOENT;
00800 return (void *) (INTPTR) ERROR_RETURN;
00801 }
00802
00803 errno = 0;
00804
00805 #ifdef __MINGW32__
00806 return read_file (file_name, mapped_size, file_revision, 0, mapHd);
00807 #else
00808 return read_file (file_name, mapped_size, file_revision);
00809 #endif
00810
00811 }
00812
00813
00814
00815
00816
00817
00818
00819
00820 PU_Info *
00821 WN_get_PU_Infos (void *handle, INT32 *p_num_PUs)
00822 {
00823 char *base;
00824 INT32 size;
00825 PU_Info *pu_tree;
00826
00827 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_PU_SECTION);
00828 if (shdr.offset == 0) return (PU_Info *)(INTPTR)ERROR_RETURN;
00829
00830 base = (char *) handle + shdr.offset;
00831 size = shdr.size;
00832
00833 pu_tree = Read_PU_Infos (base, size, p_num_PUs);
00834 if (pu_tree == (PU_Info *)ERROR_VALUE)
00835 return (PU_Info *)(INTPTR)ERROR_RETURN;
00836
00837 return pu_tree;
00838 }
00839
00840
00841 #ifdef BACK_END
00842 void *
00843 WN_get_section_base (void *handle, INT sect)
00844 {
00845 char *base;
00846
00847 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, sect);
00848 if (shdr.offset == 0) return (void *) (INTPTR)ERROR_RETURN;
00849
00850 base = (char *) handle + shdr.offset;
00851 return (void *) base;
00852 }
00853 #endif
00854
00855
00856
00857
00858
00859
00860
00861 ST *
00862 WN_get_proc_sym (PU_Info *pu)
00863 {
00864 Subsect_State st = PU_Info_state(pu, WT_PROC_SYM);
00865
00866 if (st == Subsect_InMem)
00867 return &St_Table[PU_Info_proc_sym(pu)];
00868 if (st != Subsect_Exists)
00869 return (ST *) (INTPTR) ERROR_RETURN;
00870 ST *ps = &St_Table[PU_Info_proc_sym(pu)];
00871 if (ps == NULL)
00872 return (ST *) (INTPTR) ERROR_RETURN;
00873
00874 Set_PU_Info_state(pu, WT_PROC_SYM, Subsect_InMem);
00875
00876 return ps;
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886 WN *
00887 WN_get_tree (void *handle, PU_Info *pu)
00888 {
00889 register char *section_base, *tree_base;
00890 register Elf64_Word offset, size;
00891 WN *wn;
00892 Elf64_Word first_node;
00893 Subsect_State st = PU_Info_state(pu, WT_TREE);
00894
00895 if (st == Subsect_InMem)
00896 return PU_Info_tree_ptr(pu);
00897 if (st != Subsect_Exists)
00898 return (WN *) (INTPTR) ERROR_RETURN;
00899
00900 offset = PU_Info_subsect_offset(pu, WT_TREE);
00901 size = PU_Info_subsect_size(pu, WT_TREE);
00902
00903 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_PU_SECTION);
00904 if (shdr.offset == 0) return (WN *) (INTPTR) ERROR_RETURN;
00905
00906 if (offset + size > shdr.size) {
00907 errno = EINVAL;
00908 return (WN *) (INTPTR) ERROR_RETURN;
00909 }
00910
00911 section_base = (char *) handle + shdr.offset;
00912 tree_base = section_base + offset;
00913
00914
00915 first_node = *(Elf64_Word *)tree_base;
00916 wn = (WN *) (tree_base + first_node);
00917
00918 #ifndef CFE
00919 Set_Max_Region_Id(0);
00920 #endif
00921
00922
00923
00924
00925
00926 Current_Map_Tab = PU_Info_maptab(pu);
00927 if (fix_tree (wn, tree_base, size) == ERROR_VALUE)
00928 return (WN *)ERROR_VALUE;
00929
00930 WN_next(wn) = NULL;
00931 WN_prev(wn) = NULL;
00932
00933 Set_PU_Info_tree_ptr(pu, wn);
00934 Set_PU_Info_state(pu, WT_TREE, Subsect_InMem);
00935
00936 return wn;
00937 }
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 INT
00949 WN_get_flags (void *handle, char ***argv)
00950 {
00951 Elf64_Word argc;
00952 char *baseaddr;
00953
00954 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_COMP_FLAGS);
00955 if (shdr.offset == 0) return 0;
00956
00957 baseaddr = (char *) handle + shdr.offset;
00958 if (fix_comp_flags (baseaddr, shdr.size) == ERROR_VALUE)
00959 return 0;
00960 argc = *((Elf64_Word *) baseaddr);
00961 *argv = (char **) (baseaddr + sizeof(Elf64_Word));
00962
00963 return argc;
00964 }
00965
00966
00967
00968
00969
00970
00971
00972
00973 INT
00974 WN_get_dst (void *handle)
00975 {
00976 register INT size, num_blocks;
00977 char *base, *ptr, *blk;
00978 DST_BLOCK_IDX j;
00979
00980 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_DST);
00981 if (shdr.offset == 0) return ERROR_RETURN;
00982
00983 base = (char *) handle + shdr.offset;
00984 size = shdr.size;
00985
00986
00987 ptr = base + size - sizeof(mINT32);
00988 num_blocks = *(INT32*) ptr;
00989 num_blocks++;
00990 ptr -= (num_blocks * sizeof(block_header));
00991
00992 DST_Init (ptr, num_blocks);
00993 FOREACH_DST_BLOCK(j) {
00994 blk = ((DST_Type *)Current_DST)->dst_blocks[j].offset;
00995 if (blk == (char *)-1) {
00996 ((DST_Type *)Current_DST)->dst_blocks[j].offset = NULL;
00997 } else {
00998 CONVERT_OFFSET(char*, blk);
00999 ((DST_Type *)Current_DST)->dst_blocks[j].offset = blk;
01000 }
01001 }
01002
01003 return size;
01004 }
01005
01006
01007 #if defined(BACK_END) || defined(IR_TOOLS)
01008
01009 INT
01010 WN_get_feedback (void* handle, PU_Info* pu, MEM_POOL* pool)
01011 {
01012 Subsect_State st = PU_Info_state(pu, WT_FEEDBACK);
01013
01014 switch (st) {
01015 case Subsect_Missing:
01016 case Subsect_InMem:
01017 default:
01018 return 0;
01019 case Subsect_Exists:
01020 break;
01021 case Subsect_Written:
01022 return ERROR_RETURN;
01023 }
01024
01025 Elf64_Word offset = PU_Info_subsect_offset (pu, WT_FEEDBACK);
01026 Elf64_Word size = PU_Info_subsect_size (pu, WT_FEEDBACK);
01027 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_PU_SECTION);
01028 if (shdr.offset == 0)
01029 return ERROR_RETURN;
01030
01031 if (offset + size >= shdr.size) {
01032 errno = EINVAL;
01033 return ERROR_RETURN;
01034 }
01035
01036 INTPTR baseaddr = (INTPTR)handle + shdr.offset + offset;
01037
01038 Set_PU_Info_feedback_ptr (pu, baseaddr);
01039 Set_PU_Info_state (pu, WT_FEEDBACK, Subsect_InMem);
01040
01041 return 0;
01042 }
01043 #endif
01044
01045 #ifdef BACK_END
01046
01047 void *
01048 WN_get_depgraph (void *handle, PU_Info *pu)
01049 {
01050 Elf64_Word offset, size;
01051 char *cur_addr, *end_addr, *tree_base;
01052 void *g;
01053 Subsect_State st = PU_Info_state(pu, WT_DEPGRAPH);
01054 Current_Map_Tab = PU_Info_maptab(pu);
01055
01056 if (st == Subsect_Written)
01057 return (void *) (INTPTR) ERROR_RETURN;
01058 if (st == Subsect_InMem)
01059 return PU_Info_depgraph_ptr(pu);
01060 if (st != Subsect_Exists) {
01061 Init_Dep_Graph(NULL);
01062 return NULL;
01063 }
01064
01065 offset = PU_Info_subsect_offset(pu, WT_DEPGRAPH);
01066 size = PU_Info_subsect_size(pu, WT_DEPGRAPH);
01067
01068 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_PU_SECTION);
01069 if (shdr.offset == 0) return (void *) (INTPTR) ERROR_RETURN;
01070
01071 if (offset + size >= shdr.size) {
01072 errno = EINVAL;
01073 return (void *) (INTPTR) ERROR_RETURN;
01074 }
01075
01076
01077 tree_base = (char *) handle + shdr.offset +
01078 PU_Info_subsect_offset(pu, WT_TREE);
01079
01080 cur_addr = (char *)handle + shdr.offset + offset;
01081 end_addr = cur_addr + size;
01082
01083
01084 g = Depgraph_Read(cur_addr, end_addr, tree_base);
01085
01086
01087
01088 Is_True(g, ("Error: Unable to read the dependence graph"));
01089
01090 Init_Dep_Graph(g);
01091 Set_PU_Info_depgraph_ptr(pu, g);
01092 Set_PU_Info_state(pu, WT_DEPGRAPH, Subsect_InMem);
01093
01094 return g;
01095 }
01096 #endif
01097
01098
01099 #if defined(BACK_END) || defined(BUILD_WHIRL2C) || defined(BUILD_WHIRL2F)
01100
01101 INT
01102 WN_get_prefetch (void *handle, PU_Info *pu)
01103 {
01104 Elf64_Word offset, size;
01105 char *cur_addr, *end_addr, *tree_base;
01106 Elf64_Word node_offset;
01107 WN *node;
01108 PF_POINTER *pf_ptr;
01109 Subsect_State st = PU_Info_state(pu, WT_PREFETCH);
01110 Current_Map_Tab = PU_Info_maptab(pu);
01111
01112 if (st == Subsect_Written)
01113 return ERROR_RETURN;
01114 if (st != Subsect_Exists)
01115 return 0;
01116
01117 offset = PU_Info_subsect_offset(pu, WT_PREFETCH);
01118 size = PU_Info_subsect_size(pu, WT_PREFETCH);
01119
01120 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_PU_SECTION);
01121 if (shdr.offset == 0) return ERROR_RETURN;
01122
01123 if (offset + size >= shdr.size) {
01124 errno = EINVAL;
01125 return ERROR_RETURN;
01126 }
01127
01128
01129 tree_base = (char *) handle + shdr.offset +
01130 PU_Info_subsect_offset(pu, WT_TREE);
01131
01132 cur_addr = (char *)handle + shdr.offset + offset;
01133 end_addr = cur_addr + size;
01134
01135 for (;;) {
01136 node_offset = *(Elf64_Word *)cur_addr;
01137 cur_addr += (sizeof(Elf64_Word));
01138
01139 if (node_offset == -1) break;
01140
01141 cur_addr = (char *)(INTPS)ir_b_align((off_t)(INTPS) cur_addr,
01142 #ifndef __GNUC__
01143 __builtin_alignof(PF_POINTER),
01144 #else
01145 __alignof__(PF_POINTER),
01146 #endif
01147 0);
01148 pf_ptr = (PF_POINTER *)cur_addr;
01149 cur_addr += (sizeof(PF_POINTER));
01150
01151
01152 node = (WN *)(tree_base + node_offset);
01153 if (pf_ptr->wn_pref_1L == (WN*) -1) {
01154 pf_ptr->wn_pref_1L = NULL;
01155 } else {
01156 pf_ptr->wn_pref_1L =
01157 (WN*)(tree_base + (INTPTR)pf_ptr->wn_pref_1L);
01158 }
01159
01160 if (pf_ptr->wn_pref_2L == (WN*) -1) {
01161 pf_ptr->wn_pref_2L = NULL;
01162 } else {
01163 pf_ptr->wn_pref_2L =
01164 (WN*)(tree_base + (INTPTR)pf_ptr->wn_pref_2L);
01165 }
01166
01167
01168 WN_MAP_Set(WN_MAP_PREFETCH, node, (void *)pf_ptr);
01169
01170 if (cur_addr > end_addr) return ERROR_RETURN;
01171 }
01172
01173 PU_Info_subsect_ptr(pu, WT_PREFETCH) = NULL;
01174 Set_PU_Info_state(pu, WT_PREFETCH, Subsect_InMem);
01175
01176 return 0;
01177 }
01178
01179 #endif
01180
01181 #if defined(KEY) && defined(BACK_END)
01182 #include "cxx_memory.h"
01183 #include "be_ipa_util.h"
01184 static void
01185 WN_get_mod_ref_table (void * handle)
01186 {
01187 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_IPA_SUMMARY);
01188
01189 if (shdr.offset == 0)
01190 return;
01191
01192 const char *base = (char *) handle + shdr.offset;
01193
01194
01195 const BE_SUMMARY_HEADER *header =
01196 (BE_SUMMARY_HEADER *) (base + *((Elf64_Word *)base));
01197
01198 const char *addr = base + header->offset;
01199
01200 const char * p = addr;
01201
01202 for (INT i=0; i<header->size; i++)
01203 {
01204 UINT32 index;
01205 New_Mod_Ref_Info (index);
01206
01207 Mod_Ref_Info_Table[index].pu_idx = *((PU_IDX *) p);
01208 p += sizeof (PU_IDX);
01209
01210 mUINT32 bv_size = Mod_Ref_Info_Table[index].size = *((mUINT32 *) p);
01211 p += sizeof (mUINT32);
01212
01213 Mod_Ref_Info_Table[index].mod = CXX_NEW_ARRAY (mUINT8, bv_size, Malloc_Mem_Pool);
01214 memcpy (Mod_Ref_Info_Table[index].mod, p, bv_size);
01215 p += bv_size;
01216
01217 Mod_Ref_Info_Table[index].ref = CXX_NEW_ARRAY (mUINT8, bv_size, Malloc_Mem_Pool);
01218 memcpy (Mod_Ref_Info_Table[index].ref, p, bv_size);
01219 p += bv_size;
01220 }
01221 }
01222 #endif
01223
01224 static inline void
01225 WN_MAP_put(WN_MAP wn_map, WN *wn, INT32 value)
01226 {
01227 WN_MAP32_Set(wn_map, wn, value);
01228 }
01229
01230 static inline void
01231 WN_MAP_put(WN_MAP wn_map, WN *wn, INT64 value)
01232 {
01233 WN_MAP64_Set(wn_map, wn, value);
01234 }
01235
01236 static inline void
01237 WN_MAP_put(WN_MAP wn_map, WN *wn, void *value)
01238 {
01239 WN_MAP_Set(wn_map, wn, value);
01240 }
01241
01242 template<class MAP_ENTRY_TYPE>
01243 static inline INT
01244 WN_read_generic_map(void *handle,
01245 PU_Info *pu,
01246 INT32 subsection_type,
01247 WN_MAP value_map,
01248 MAP_ENTRY_TYPE)
01249 {
01250 Subsect_State state = PU_Info_state (pu, subsection_type);
01251 Elf64_Word offset, size;
01252 char *cur_addr, *end_addr, *tree_base;
01253
01254 if (state == Subsect_Written) {
01255 return ERROR_RETURN;
01256 }
01257 if (state != Subsect_Exists) {
01258 return 0;
01259 }
01260
01261 OFFSET_AND_SIZE shdr = get_section (handle, SHT_MIPS_WHIRL, WT_PU_SECTION);
01262 if (shdr.offset == 0) {
01263 return ERROR_RETURN;
01264 }
01265
01266 offset = PU_Info_subsect_offset(pu, subsection_type);
01267 size = PU_Info_subsect_size(pu, subsection_type);
01268
01269 if (offset + size >= shdr.size) {
01270 errno = EINVAL;
01271 return ERROR_RETURN;
01272 }
01273
01274
01275 tree_base = (char *) handle + shdr.offset +
01276 PU_Info_subsect_offset(pu, WT_TREE);
01277
01278 cur_addr = (char *)handle + shdr.offset + offset;
01279 end_addr = cur_addr + size;
01280
01281 for (;;) {
01282 MAP_ENTRY_TYPE map_value;
01283 Elf64_Word node_offset = *(Elf64_Word *) cur_addr;
01284 WN *node;
01285
01286 cur_addr += (sizeof(Elf64_Word));
01287
01288 if (node_offset == -1)
01289 break;
01290
01291
01292 cur_addr = (char *)(INTPS)ir_b_align ((off_t) (INTPS)cur_addr,
01293 sizeof(MAP_ENTRY_TYPE),
01294 0);
01295 map_value = * (MAP_ENTRY_TYPE *) cur_addr;
01296 cur_addr += sizeof(MAP_ENTRY_TYPE);
01297
01298 node = (WN *) (tree_base + node_offset);
01299
01300
01301
01302 WN_MAP_put(value_map, node, map_value);
01303
01304 if (cur_addr > end_addr)
01305 return ERROR_RETURN;
01306 }
01307
01308 PU_Info_subsect_ptr(pu, subsection_type) = NULL;
01309 Set_PU_Info_state(pu, subsection_type, Subsect_InMem);
01310
01311 return 0;
01312 }
01313
01314 INT
01315 WN_get_INT32_map(void *handle,
01316 PU_Info *pu,
01317 INT32 subsection_type,
01318 WN_MAP value_map)
01319 {
01320 return WN_read_generic_map(handle, pu, subsection_type,
01321 value_map, (INT32) 0);
01322 }
01323
01324 INT
01325 WN_get_voidptr_map(void *handle,
01326 PU_Info *pu,
01327 INT32 subsection_type,
01328 WN_MAP value_map)
01329 {
01330 return WN_read_generic_map(handle, pu, subsection_type,
01331 value_map, (void *) 0);
01332 }
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342 #ifdef __MINGW32__
01343 void
01344 WN_free_input (void *handle, HANDLE *mapHd, off_t mapped_size)
01345 #else
01346 void
01347 WN_free_input (void *handle, off_t mapped_size)
01348 #endif
01349 {
01350 if (handle == 0 || handle == (void *)(-1))
01351 return;
01352
01353 #ifdef __MINGW32__
01354 UnmapViewOfFile((char *)handle);
01355 CloseHandle(*mapHd);
01356 #else
01357 munmap (handle, mapped_size);
01358 #endif
01359 }
01360
01361
01362 #ifndef OWN_ERROR_PACKAGE
01363
01364
01365
01366
01367
01368 #ifdef __MINGW32__
01369 static void *global_fhandle = NULL;
01370 void *local_fhandle = NULL;
01371 static HANDLE global_mapHandle = NULL;
01372 static HANDLE local_mapHandle = NULL;
01373 #else
01374 static void *global_fhandle;
01375 void *local_fhandle;
01376 #endif
01377 static char *global_ir_file;
01378 static char *local_ir_file;
01379
01380 #ifdef __MINGW32__
01381 static void
01382 open_specified_input (char *input_file,
01383 char **ir_input, void **fhandle, HANDLE * mapHd, off_t *mapped_size, int *fd = 0)
01384 #else
01385 static void
01386 open_specified_input (char *input_file,
01387 char **ir_input, void **fhandle, off_t *mapped_size)
01388 #endif
01389 {
01390 Set_Error_Phase ( "Reading WHIRL file" );
01391 *ir_input = input_file;
01392 #ifdef __MINGW32__
01393 *fhandle = WN_open_input (input_file, mapped_size, fd, mapHd);
01394 #else
01395 *fhandle = WN_open_input (input_file, mapped_size);
01396 #endif
01397 if (*fhandle == (void*) REVISION_MISMATCH) {
01398 ErrMsg ( EC_IR_Revision, file_revision, *ir_input);
01399 } else if (*fhandle == (void*) ABI_MISMATCH) {
01400 ErrMsg ( EC_IR_Revision,
01401 "abi of whirl file doesn't match abi from command-line",
01402 *ir_input);
01403 } else if (*fhandle == (void*) READER_ERROR) {
01404 ErrMsg ( EC_IR_Open, *ir_input, errno );
01405 }
01406 }
01407
01408
01409 void *
01410 Open_Input_Info (char *input_file)
01411 {
01412 #ifdef __MINGW32__
01413 open_specified_input (input_file,
01414 &global_ir_file, &global_fhandle, &global_mapHandle, &global_mapped_size);
01415 local_mapHandle = global_mapHandle;
01416 #else
01417 open_specified_input (input_file,
01418 &global_ir_file, &global_fhandle, &global_mapped_size);
01419 #endif
01420 local_ir_file = global_ir_file;
01421 local_fhandle = global_fhandle;
01422 local_mapped_size = global_mapped_size;
01423 return global_fhandle;
01424 }
01425
01426 void *
01427 Open_Global_Input (char *input_file)
01428 {
01429 #ifdef __MINGW32__
01430 open_specified_input (input_file,
01431 &global_ir_file, &global_fhandle, &global_mapHandle, &global_mapped_size);
01432 #else
01433 open_specified_input (input_file,
01434 &global_ir_file, &global_fhandle, &global_mapped_size);
01435 #endif
01436 return global_fhandle;
01437 }
01438
01439 void *
01440 Open_Local_Input (char *input_file)
01441 {
01442 #ifdef __MINGW32__
01443 open_specified_input (input_file,
01444 &local_ir_file, &local_fhandle, &local_mapHandle, &local_mapped_size);
01445 #else
01446 open_specified_input (input_file,
01447 &local_ir_file, &local_fhandle, &local_mapped_size);
01448 #endif
01449 return local_fhandle;
01450 }
01451
01452
01453
01454
01455
01456
01457
01458 PU_Info *
01459 Read_Global_Info (INT32 *p_num_PUs)
01460 {
01461 PU_Info *pu_tree;
01462
01463 Set_Error_Phase ( "Reading WHIRL file" );
01464
01465 if (WN_get_strtab(global_fhandle) == -1) {
01466 ErrMsg ( EC_IR_Scn_Read, "strtab", global_ir_file);
01467 }
01468
01469 if ((INT) WN_get_global_symtab (global_fhandle) == -1) {
01470 ErrMsg ( EC_IR_Scn_Read, "global symtab", global_ir_file);
01471 }
01472
01473 #if defined(KEY) && defined(BACK_END)
01474 WN_get_mod_ref_table (global_fhandle);
01475 #endif
01476
01477
01478
01479 if (WN_get_dst(local_fhandle) == -1) {
01480 ErrMsg ( EC_IR_Scn_Read, "dst", local_ir_file);
01481 }
01482
01483
01484 pu_tree = WN_get_PU_Infos (local_fhandle, p_num_PUs);
01485 if (pu_tree == (PU_Info *)-1) {
01486 ErrMsg ( EC_IR_Scn_Read, "PU headers", local_ir_file);
01487 }
01488 if (verbose_info) {
01489 printf("done reading global info\n");
01490 }
01491
01492 return pu_tree;
01493 }
01494
01495
01496 void
01497 Read_Local_Info (MEM_POOL *pool, PU_Info *pu)
01498 {
01499 const char *save_phase = Get_Error_Phase();
01500 Set_Error_Phase ( "Reading WHIRL file" );
01501
01502
01503 Current_Map_Tab = PU_Info_maptab(pu);
01504 if (!Current_Map_Tab) {
01505 Current_Map_Tab = WN_MAP_TAB_Create(pool);
01506 PU_Info_maptab(pu) = Current_Map_Tab;
01507 }
01508
01509 CURRENT_SYMTAB = PU_lexical_level (&St_Table[PU_Info_proc_sym (pu)]);
01510 New_Scope (CURRENT_SYMTAB, MEM_pu_nz_pool_ptr, FALSE);
01511
01512 if (WN_get_symtab (local_fhandle, pu) == -1)
01513 ErrMsg ( EC_IR_Scn_Read, "local symtab", local_ir_file);
01514
01515 Scope_tab[CURRENT_SYMTAB].st = WN_get_proc_sym (pu);
01516 if (Scope_tab[CURRENT_SYMTAB].st == (ST *) -1)
01517 ErrMsg ( EC_IR_Scn_Read, "proc ST", local_ir_file);
01518 else
01519 Current_pu = &Pu_Table[ST_pu (Scope_tab[CURRENT_SYMTAB].st)];
01520
01521
01522 if (WN_get_tree (local_fhandle, pu) == (WN*) -1) {
01523 ErrMsg ( EC_IR_Scn_Read, "tree", local_ir_file);
01524 }
01525
01526 #if defined(BACK_END) || defined(IR_TOOLS)
01527 if (WN_get_feedback (local_fhandle, pu, pool) == ERROR_RETURN) {
01528 ErrMsg ( EC_IR_Scn_Read, "feedback info", local_ir_file);
01529 }
01530 #endif
01531
01532 #ifdef BACK_END
01533 if (WN_get_depgraph (local_fhandle, pu) == (void *) -1) {
01534 ErrMsg ( EC_IR_Scn_Read, "dependence graph", local_ir_file);
01535 }
01536 #endif
01537
01538 #if defined(BACK_END) || defined(BUILD_WHIRL2C) || defined(BUILD_WHIRL2F)
01539 if (WN_get_prefetch (local_fhandle, pu) == -1) {
01540 ErrMsg ( EC_IR_Scn_Read, "prefetch map", local_ir_file);
01541 }
01542 #endif
01543
01544
01545 if (WN_get_INT32_map(local_fhandle, pu,
01546 WT_ALIAS_CLASS, WN_MAP_ALIAS_CLASS) == -1) {
01547 ErrMsg ( EC_IR_Scn_Read, "alias class map", local_ir_file);
01548 }
01549
01550 if (WN_get_voidptr_map(local_fhandle, pu,
01551 WT_AC_INTERNAL, WN_MAP_AC_INTERNAL) == -1) {
01552 ErrMsg ( EC_IR_Scn_Read, "alias class internal map", local_ir_file);
01553 }
01554
01555 Set_Error_Phase(save_phase);
01556 }
01557
01558
01559 void
01560 Free_Local_Info (PU_Info *pu)
01561 {
01562 #ifdef BACK_END
01563 Dealloc_Dep_Graph();
01564 #endif
01565
01566 Delete_Scope (PU_lexical_level (&St_Table[PU_Info_proc_sym (pu)]));
01567
01568
01569 if (PU_Info_maptab(pu)) {
01570 WN_MAP_TAB_Delete(PU_Info_maptab(pu));
01571 PU_Info_maptab(pu) = NULL;
01572 }
01573 }
01574
01575 void
01576 Free_Dep_Graph (void)
01577 {
01578 #ifdef BACK_END
01579 Dealloc_Dep_Graph();
01580 #endif
01581 }
01582
01583 #ifdef __MINGW32__
01584 void
01585 Free_Local_Input(void)
01586 {
01587 WN_free_input(local_fhandle, &local_mapHandle, local_mapped_size);
01588
01589
01590 }
01591
01592 void
01593 Free_Input_Info (void)
01594 {
01595 WN_free_input(global_fhandle, &global_mapHandle, global_mapped_size);
01596 if (global_fhandle != local_fhandle) {
01597 Free_Local_Input();
01598 }
01599 else
01600 {
01601 local_fhandle = 0;
01602 local_mapHandle = NULL;
01603 }
01604 global_fhandle = 0;
01605 global_mapHandle = NULL;
01606 }
01607
01608 #else
01609 void
01610 Free_Local_Input(void)
01611 {
01612 WN_free_input(local_fhandle, local_mapped_size);
01613 local_fhandle = 0;
01614 }
01615
01616 void
01617 Free_Input_Info (void)
01618 {
01619 WN_free_input(global_fhandle, global_mapped_size);
01620 if (global_fhandle != local_fhandle) {
01621 Free_Local_Input();
01622 }
01623 global_fhandle = 0;
01624 }
01625 #endif
01626
01627 #endif
01628