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 <fcntl.h>
00047 #ifdef __MINGW32__
00048 #include <WINDOWS.h>
00049 #else
00050 #include <sys/mman.h>
00051 #endif
00052 #include <alloca.h>
00053 #include <signal.h>
00054 #include <errno.h>
00055 #include "elf_stuff.h"
00056 #include <sys/elf_whirl.h>
00057 #include <cmplrs/rcodes.h>
00058
00059 #ifdef __MINGW32__
00060 #include <io.h>
00061 #include <sys/types.h>
00062 #include <sys/stat.h>
00063 #endif
00064
00065 #ifndef USE_STANDARD_TYPES
00066 #define USE_STANDARD_TYPES
00067 #endif
00068
00069 #include "defs.h"
00070 #ifdef OWN_ERROR_PACKAGE
00071
00072
00073
00074
00075 #define Is_True(x,y) (0)
00076 #define ERRORS_INCLUDED
00077 #else
00078 #include "erglob.h"
00079 #endif
00080 #include "errors.h"
00081 #include "opcode.h"
00082 #include "mempool.h"
00083 #include "strtab.h"
00084 #include "symtab.h"
00085 #include "const.h"
00086 #include "targ_const.h"
00087 #include "irbdata.h"
00088 #include "config_targ.h"
00089 #include "config_elf_targ.h"
00090 #include "wn_core.h"
00091 #include "wn.h"
00092 #include "wn_map.h"
00093 #include "dwarf_DST_mem.h"
00094 #include "pu_info.h"
00095 #include "ir_elf.h"
00096 #include "ir_bwrite.h"
00097 #include "ir_bcom.h"
00098 #include "ir_bread.h"
00099 #include "tracing.h"
00100
00101 #ifdef BACK_END
00102 #include "glob.h"
00103 #include "pf_cg.h"
00104 #include "instr_reader.h"
00105 #include "fb_whirl.h"
00106
00107 BOOL Write_BE_Maps = FALSE;
00108 BOOL Write_AC_INTERNAL_Map = FALSE;
00109 BOOL Write_ALIAS_CLASS_Map = FALSE;
00110
00111 extern WN **prefetch_ldsts;
00112 extern INT num_prefetch_ldsts;
00113 extern INT max_num_prefetch_ldsts;
00114
00115 extern WN **alias_classes;
00116 extern INT num_alias_class_nodes;
00117 extern INT max_alias_class_nodes;
00118
00119 extern WN **ac_internals;
00120 extern INT num_ac_internal_nodes;
00121 extern INT max_ac_internal_nodes;
00122
00123 extern "C" {
00124 extern void *C_Dep_Graph(void);
00125 extern void Depgraph_Write (void *depgraph, Output_File *fl, WN_MAP off_map);
00126 }
00127 #endif
00128
00129 #define MMAP(addr, len, prot, flags, fd, off) \
00130 mmap((void *)(addr), (size_t)(len), (int)(prot), (int)(flags), \
00131 (int)(fd), (off_t)(off))
00132
00133 #ifdef __MINGW32__
00134 #define OPEN(path, flag, mode) \
00135 open((const char *)(path), (int)(flag), (int)(mode))
00136 #else
00137 #if ! (defined(linux) || defined(BUILD_OS_DARWIN))
00138 #define MUNMAP(addr, len) \
00139 munmap((void *)(addr), (size_t)(len))
00140 #else
00141 #define MUNMAP(addr, len) \
00142 munmap((char *)(addr), (size_t)(len))
00143 #endif
00144
00145 #define OPEN(path, flag, mode) \
00146 open((const char *)(path), (int)(flag), (mode_t)(mode))
00147 #endif
00148
00149 static void (*old_sigsegv) (int);
00150 static void (*old_sigbus) (int);
00151
00152 Output_File *Current_Output = 0;
00153
00154 #if (defined(linux) || defined(BUILD_OS_DARWIN))
00155 #define MAPPED_SIZE 0x400000
00156 #endif
00157
00158 static void
00159 cleanup (Output_File *fl)
00160 {
00161 fl->output_fd = -1;
00162 if (fl->num_of_section > 0)
00163 free (fl->section_list);
00164 fl->num_of_section = 0;
00165 fl->section_list = NULL;
00166
00167 #if !defined(TARG_NVISA)
00168 MUNMAP (fl->map_addr, fl->mapped_size);
00169 #endif
00170 fl->map_addr = NULL;
00171 fl->file_size = 0;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 static void
00184 ir_bwrite_signal_handler (int sig, int err_num)
00185 {
00186 void (*old_handler) (int) = 0;
00187
00188 errno = 0;
00189 char *err_str = strerror(err_num);
00190
00191 if (Doing_mmapped_io && errno == 0)
00192 Fatal_Error ("I/O error in %s: %s", Current_Output ?
00193 Current_Output->file_name : "mmapped object",
00194 err_str);
00195 switch (sig) {
00196 #ifndef __MINGW32__
00197 case SIGBUS:
00198 old_handler = old_sigbus;
00199 break;
00200 #endif
00201 case SIGSEGV:
00202 old_handler = old_sigsegv;
00203 break;
00204 }
00205
00206 if (old_handler == SIG_DFL) {
00207
00208 #ifdef __MINGW32__
00209 raise(sig);
00210 #else
00211 kill(getpid(), sig);
00212 #endif
00213 } else if (old_handler != SIG_IGN) {
00214
00215 (*old_handler)(sig);
00216 }
00217 return;
00218
00219 }
00220
00221
00222
00223
00224
00225 #define DEFAULT_NUM_OF_SECTIONS 8
00226
00227 static Section *
00228 get_section (Elf64_Word sh_info, const char *name, Output_File *fl)
00229 {
00230 register INT i;
00231
00232 for (i = 0; i < fl->num_of_section; i++) {
00233 if ((fl->section_list[i].shdr.sh_info == sh_info) &&
00234 (strcmp (fl->section_list[i].name, name) == 0)) {
00235 fl->cur_section = fl->section_list + i;
00236 return fl->cur_section;
00237 }
00238 }
00239
00240 if (fl->num_of_section == 0) {
00241 fl->max_num_of_section = DEFAULT_NUM_OF_SECTIONS;
00242 fl->section_list =
00243 (Section *)malloc(fl->max_num_of_section * sizeof(Section));
00244 FmtAssert (fl->section_list, ("No more memory"));
00245 } else if (fl->max_num_of_section == fl->num_of_section) {
00246 fl->max_num_of_section *= 2;
00247 fl->section_list = (Section *) realloc
00248 (fl->section_list,
00249 fl->max_num_of_section * sizeof(Section));
00250 FmtAssert (fl->section_list, ("No more memory"));
00251 }
00252
00253 fl->cur_section = fl->section_list + fl->num_of_section;
00254 fl->num_of_section += 1;
00255
00256 memset (fl->cur_section, 0, sizeof(Section));
00257 fl->cur_section->name = name;
00258 fl->cur_section->shdr.sh_info = sh_info;
00259 fl->cur_section->shdr.sh_type = SHT_MIPS_WHIRL;
00260
00261 return fl->cur_section;
00262 }
00263
00264
00265 template <class Shdr>
00266 static UINT64
00267 layout_sections (Shdr& strtab_sec, Output_File *fl)
00268 {
00269 UINT64 e_shoff;
00270 Elf64_Word strtab_size = 1;
00271
00272 for (INT i = 0; i < fl->num_of_section; i++) {
00273 Section& sec = fl->section_list[i];
00274 sec.shdr.sh_name = strtab_size;
00275 strtab_size += strlen(sec.name) + 1;
00276 }
00277
00278 memset (&strtab_sec, 0, sizeof(Shdr));
00279 strtab_sec.sh_name = strtab_size;
00280 strtab_size += strlen (ELF_SHSTRTAB) + 1;
00281 strtab_sec.sh_type = SHT_STRTAB;
00282 strtab_sec.sh_size = strtab_size;
00283 strtab_sec.sh_offset = fl->file_size;
00284 fl->file_size += strtab_size;
00285 strtab_sec.sh_addralign = 1;
00286 strtab_sec.sh_entsize = 1;
00287
00288 fl->file_size = ir_b_align (fl->file_size,
00289 #ifndef __GNUC__
00290 __builtin_alignof(Shdr),
00291 #else
00292 __alignof__(Shdr),
00293 #endif
00294 0);
00295 e_shoff = fl->file_size;
00296
00297
00298 fl->file_size += sizeof(Shdr) * (fl->num_of_section + 2);
00299
00300
00301 if (fl->file_size >= fl->mapped_size)
00302 ir_b_grow_map (0, fl);
00303
00304 return e_shoff;
00305 }
00306
00307
00308 template <class ELF>
00309 static void
00310 write_output (UINT64 e_shoff, const typename ELF::Elf_Shdr& strtab_sec,
00311 Output_File *fl, const ELF& tag)
00312 {
00313 INT i;
00314 char *base_addr = fl->map_addr;
00315
00316
00317 typename ELF::Elf_Ehdr* ehdr = (typename ELF::Elf_Ehdr *) fl->map_addr;
00318 strcpy ((char *) ehdr->e_ident, ELFMAG);
00319 ehdr->e_ident[EI_CLASS] = tag.Elf_class ();
00320 ehdr->e_ident[EI_DATA] =
00321 (Host_Byte_Sex == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB);
00322 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
00323 ehdr->e_type = ET_IR;
00324 ehdr->e_machine = Get_Elf_Target_Machine();
00325 ehdr->e_version = EV_CURRENT;
00326 ehdr->e_shoff = e_shoff;
00327 ehdr->e_flags = Config_ELF_From_Target (! Use_32_Bit_Pointers, FALSE,
00328 (INT) Target_ISA);
00329 ehdr->e_ehsize = sizeof(typename ELF::Elf_Ehdr);
00330 ehdr->e_shentsize = sizeof(typename ELF::Elf_Shdr);
00331 ehdr->e_shnum = fl->num_of_section + 2;
00332 ehdr->e_shstrndx = fl->num_of_section + 1;
00333
00334
00335 char* str = base_addr + strtab_sec.sh_offset;
00336 str[0] = '\0';
00337 str++;
00338 for (i = 0; i < fl->num_of_section; i++) {
00339 strcpy (str, fl->section_list[i].name);
00340 str += strlen (str) + 1;
00341 }
00342 strcpy (str, ELF_SHSTRTAB);
00343
00344
00345 if ((INTPTR)str + strlen(ELF_SHSTRTAB) + 1 >
00346 e_shoff + (INTPTR) base_addr)
00347 ErrMsg (EC_IR_Scn_Write, "Section Header String Table", fl->file_name);
00348
00349
00350 typename ELF::Elf_Shdr* shdr =
00351 (typename ELF::Elf_Shdr *) (base_addr + e_shoff);
00352 memset (shdr, 0, sizeof(typename ELF::Elf_Shdr));
00353 shdr++;
00354 if (tag.Elf_class() == ELFCLASS64) {
00355 for (i = 0; i < fl->num_of_section; i++, shdr++)
00356 memcpy (shdr, &(fl->section_list[i].shdr),
00357 sizeof(typename ELF::Elf_Shdr));
00358 } else {
00359
00360 for (i = 0; i < fl->num_of_section; i++, shdr++) {
00361 shdr->sh_name = fl->section_list[i].shdr.sh_name;
00362 shdr->sh_type = fl->section_list[i].shdr.sh_type;
00363 shdr->sh_flags = fl->section_list[i].shdr.sh_flags;
00364 shdr->sh_addr = fl->section_list[i].shdr.sh_addr;
00365 shdr->sh_offset = fl->section_list[i].shdr.sh_offset;
00366 shdr->sh_size = fl->section_list[i].shdr.sh_size;
00367 shdr->sh_link = fl->section_list[i].shdr.sh_link;
00368 shdr->sh_info = fl->section_list[i].shdr.sh_info;
00369 shdr->sh_addralign = fl->section_list[i].shdr.sh_addralign;
00370 shdr->sh_entsize = fl->section_list[i].shdr.sh_entsize;
00371 }
00372 }
00373 memcpy (shdr, &strtab_sec, sizeof(typename ELF::Elf_Shdr));
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 #define DEFAULT_TMPDIR "/usr/tmp"
00383 #define DEFAULT_TEMPLATE "/elf_wnXXXXXX"
00384
00385 static int
00386 create_temp_file (Output_File *fl)
00387 {
00388 register const char *tmpdir;
00389 register char *path;
00390 register int fd;
00391
00392 if ((tmpdir = getenv("TMPDIR")) == 0)
00393 tmpdir = DEFAULT_TMPDIR;
00394 path = (char *) malloc (strlen(tmpdir) + strlen(DEFAULT_TEMPLATE) + 1);
00395 if (path == 0)
00396 return -1;
00397 #ifdef __MINGW32__
00398 {
00399 int mode = O_RDWR | O_CREAT | O_EXCL ;
00400 do {
00401 strcpy (path, tmpdir);
00402 strcat (path, DEFAULT_TEMPLATE);
00403 mktemp( path );
00404 } while( (fd = open(path, mode)) < 0 );
00405 }
00406 #else
00407 strcpy (path, tmpdir);
00408 strcat (path, DEFAULT_TEMPLATE);
00409 #endif
00410 fd = mkstemp (path);
00411 if (fd != -1)
00412 unlink (path);
00413
00414 fl->file_name = path;
00415 return fd;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 Output_File *
00429 WN_open_output (char *file_name)
00430 {
00431 Output_File *fl;
00432 Section *cur_section;
00433
00434 if (old_sigsegv == 0)
00435 old_sigsegv = signal (SIGSEGV, reinterpret_cast<void (*)(int)>
00436 (ir_bwrite_signal_handler));
00437
00438 #ifndef __MINGW32__
00439 if (old_sigbus == 0)
00440 old_sigbus = signal (SIGBUS, reinterpret_cast<void (*)(int)>
00441 (ir_bwrite_signal_handler));
00442 #endif
00443
00444 fl = (Output_File *)malloc(sizeof(Output_File));
00445 if (!fl) return NULL;
00446
00447 if (file_name == 0) {
00448 fl->output_fd = create_temp_file (fl);
00449 } else {
00450 fl->file_name = file_name;
00451
00452 #ifdef __MINGW32__
00453 fl->output_fd = OPEN (file_name, _O_RDWR| _O_CREAT| _O_TRUNC, _S_IREAD| _S_IWRITE);
00454 #else
00455 fl->output_fd = OPEN (file_name, O_RDWR|O_CREAT|O_TRUNC, 0666);
00456 }
00457 #endif
00458 if (fl->output_fd < 0)
00459 return NULL;
00460
00461 #if defined(linux) || defined(__APPLE__)
00462 ftruncate(fl->output_fd, MAPPED_SIZE);
00463 #elif defined(_WIN32)
00464 ftruncate(fl->output_fd, MAPPED_SIZE);
00465 #endif
00466
00467 fl->section_list = NULL;
00468 fl->cur_section = NULL;
00469 fl->num_of_section = 0;
00470
00471
00472 if (ir_b_create_map (fl) == (char *) (-1))
00473 return NULL;
00474
00475
00476 #ifdef __ALWAYS_USE_64BIT_ELF__
00477 fl->file_size = sizeof(Elf64_Ehdr);
00478 #else
00479 fl->file_size = Use_32_Bit_Pointers ?
00480 sizeof(Elf32_Ehdr) : sizeof(Elf64_Ehdr);
00481 #endif
00482
00483
00484 cur_section = get_section (WT_PU_SECTION, MIPS_WHIRL_PU_SECTION, fl);
00485
00486 fl->file_size = ir_b_align (fl->file_size, sizeof(mUINT64), 0);
00487 cur_section->shdr.sh_offset = fl->file_size;
00488
00489
00490 fl->file_size += sizeof(Elf64_Word);
00491
00492 return fl;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501 void
00502 WN_write_PU_Infos (PU_Info *pu_list, Output_File *fl)
00503 {
00504 INT32 hdr_sz;
00505 Section *cur_section = fl->cur_section;
00506
00507
00508 if (strcmp(cur_section->name, MIPS_WHIRL_PU_SECTION) != 0)
00509 ErrMsg (EC_IR_Scn_Write, "PU headers", fl->file_name);
00510
00511 fl->file_size = ir_b_align (fl->file_size, sizeof(mINT32), 0);
00512
00513
00514 *(Elf64_Word *)(fl->map_addr + cur_section->shdr.sh_offset) =
00515 (Elf64_Word)(fl->file_size - cur_section->shdr.sh_offset);
00516
00517 hdr_sz = Sizeof_PU_Infos (pu_list);
00518
00519
00520 if (fl->file_size + hdr_sz >= fl->mapped_size)
00521 ir_b_grow_map (hdr_sz, fl);
00522
00523 if (Write_PU_Infos (pu_list, fl->map_addr + fl->file_size) == -1)
00524 ErrMsg (EC_IR_Scn_Write, "PU headers", fl->file_name);
00525 fl->file_size += hdr_sz;
00526
00527 cur_section->shdr.sh_size = fl->file_size - cur_section->shdr.sh_offset;
00528
00529
00530 cur_section->shdr.sh_addralign = sizeof(mINT64);
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 void
00546 WN_write_tree (PU_Info *pu, WN_MAP off_map, Output_File *fl)
00547 {
00548 static const char *scn_name = "tree";
00549 UINT padding;
00550 Elf64_Word this_tree;
00551 WN *tree;
00552 off_t tree_base;
00553 Section *cur_section = fl->cur_section;
00554
00555
00556 if (strcmp(cur_section->name, MIPS_WHIRL_PU_SECTION) != 0 ||
00557 PU_Info_state(pu, WT_TREE) != Subsect_InMem)
00558 ErrMsg (EC_IR_Scn_Write, scn_name, fl->file_name);
00559
00560 tree = PU_Info_tree_ptr(pu);
00561
00562 #ifdef BACK_END
00563 if (Write_BE_Maps) {
00564
00565 prefetch_ldsts = NULL;
00566 num_prefetch_ldsts = 0;
00567 max_num_prefetch_ldsts = 0;
00568 }
00569
00570 if (Write_ALIAS_CLASS_Map) {
00571
00572
00573
00574 alias_classes = NULL;
00575 num_alias_class_nodes = 0;
00576 max_alias_class_nodes = 0;
00577 }
00578
00579 if (Write_AC_INTERNAL_Map) {
00580
00581
00582
00583 ac_internals = NULL;
00584 num_ac_internal_nodes = 0;
00585 max_ac_internal_nodes = 0;
00586 }
00587 #endif
00588
00589 padding = ((char *)tree) - (char *)WN_StartAddress(tree);
00590 if (padding == 0) {
00591
00592 ErrMsg (EC_IR_Scn_Write, scn_name, fl->file_name);
00593 }
00594
00595 padding += sizeof(Elf64_Word);
00596
00597 fl->file_size = ir_b_align (fl->file_size,
00598 #ifndef __GNUC__
00599 __builtin_alignof(WN),
00600 #else
00601 __alignof__(WN),
00602 #endif
00603 padding);
00604 tree_base = fl->file_size;
00605
00606 #if defined(KEY) && !defined(FRONT_END) && !defined(IR_TOOLS)
00607 this_tree = ir_b_write_tree (tree, tree_base, fl, off_map, pu);
00608 #else
00609 this_tree = ir_b_write_tree (tree, tree_base, fl, off_map);
00610 #endif
00611
00612
00613 *(Elf64_Word *)(fl->map_addr + tree_base) = this_tree;
00614
00615 #ifdef BACK_END
00616
00617 if (Write_BE_Maps && num_prefetch_ldsts > 0) {
00618
00619 prefetch_ldsts[num_prefetch_ldsts] = NULL;
00620 PU_Info_subsect_ptr(pu, WT_PREFETCH) = (void *)prefetch_ldsts;
00621 Set_PU_Info_state(pu, WT_PREFETCH, Subsect_InMem);
00622 }
00623
00624 if (Write_ALIAS_CLASS_Map && num_alias_class_nodes > 0) {
00625 alias_classes[num_alias_class_nodes] = NULL;
00626 Set_PU_Info_alias_class_ptr(pu, alias_classes);
00627 Set_PU_Info_state(pu, WT_ALIAS_CLASS, Subsect_InMem);
00628 }
00629
00630 if (Write_AC_INTERNAL_Map && num_ac_internal_nodes > 0) {
00631 ac_internals[num_ac_internal_nodes] = NULL;
00632 Set_PU_Info_ac_internal_ptr(pu, ac_internals);
00633 Set_PU_Info_state(pu, WT_AC_INTERNAL, Subsect_InMem);
00634 }
00635 #endif
00636
00637 Set_PU_Info_state(pu, WT_TREE, Subsect_Written);
00638 PU_Info_subsect_size(pu, WT_TREE) = fl->file_size - tree_base;
00639 PU_Info_subsect_offset(pu, WT_TREE) =
00640 tree_base - cur_section->shdr.sh_offset;
00641
00642 Set_Max_Region_Id(0);
00643
00644 }
00645
00646
00647
00648
00649
00650
00651
00652 void
00653 WN_write_flags (INT argc, char **argv, Output_File *fl)
00654 {
00655 INT i, argv_size;
00656 off_t offset;
00657 Elf64_Word argc_buf = argc;
00658 Section *cur_section;
00659
00660 FmtAssert (argc > 0 && argv != 0, ("invalid argument to WN_write_flags()"));
00661
00662 cur_section = get_section (WT_COMP_FLAGS, MIPS_WHIRL_COMP_FLAGS, fl);
00663
00664 fl->file_size = ir_b_align (fl->file_size, sizeof(Elf64_Word), 0);
00665 cur_section->shdr.sh_offset = fl->file_size;
00666
00667
00668 ir_b_save_buf (&argc_buf, sizeof(Elf64_Word), sizeof(Elf64_Word), 0, fl);
00669
00670
00671
00672
00673
00674
00675 fl->file_size = ir_b_align (fl->file_size, sizeof(Elf64_Word), 0);
00676 argv_size = sizeof(Elf64_Word) * argc;
00677 if (fl->file_size + argv_size >= fl->mapped_size)
00678 ir_b_grow_map (argv_size, fl);
00679
00680 offset = fl->file_size;
00681 fl->file_size += argv_size;
00682
00683 for (i = 0; i < argc; i++) {
00684 INT len = strlen(argv[i]) + 1;
00685 Elf64_Word string_offset, *argv_ptr;
00686
00687 string_offset = ir_b_save_buf (argv[i], len, 0, 0, fl);
00688
00689
00690
00691 argv_ptr = (Elf64_Word *) (fl->map_addr + offset);
00692
00693 argv_ptr[i] = string_offset - cur_section->shdr.sh_offset;
00694 }
00695
00696 cur_section->shdr.sh_size = fl->file_size - cur_section->shdr.sh_offset;
00697 cur_section->shdr.sh_addralign = sizeof(Elf64_Word);
00698
00699 }
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 void
00710 WN_write_globals (Output_File *fl)
00711 {
00712 Section *cur_section = get_section (WT_GLOBALS, MIPS_WHIRL_GLOBALS, fl);
00713
00714 fl->file_size = ir_b_align (fl->file_size, sizeof(mINT64), 0);
00715 cur_section->shdr.sh_offset = fl->file_size;
00716
00717 (void) ir_b_write_global_symtab (fl->file_size, fl);
00718
00719 cur_section->shdr.sh_size = fl->file_size - cur_section->shdr.sh_offset;
00720 cur_section->shdr.sh_addralign = sizeof(mINT64);
00721
00722 }
00723
00724
00725 void
00726 WN_write_symtab (PU_Info *pu, Output_File *fl)
00727 {
00728 Section *cur_section = fl->cur_section;
00729
00730
00731 if (strcmp(cur_section->name, MIPS_WHIRL_PU_SECTION) != 0 ||
00732 PU_Info_state(pu, WT_SYMTAB) != Subsect_InMem)
00733 ErrMsg (EC_IR_Scn_Write, "local symtab", fl->file_name);
00734
00735 const SCOPE& scope =
00736 Scope_tab[PU_lexical_level (&St_Table[PU_Info_proc_sym(pu)])];
00737
00738 fl->file_size = ir_b_align (fl->file_size, sizeof(mINT64), 0);
00739 off_t symtab_base = fl->file_size;
00740
00741 (void) ir_b_write_local_symtab (scope, symtab_base, fl);
00742
00743 Set_PU_Info_state(pu, WT_SYMTAB, Subsect_Written);
00744 PU_Info_subsect_size(pu, WT_SYMTAB) = fl->file_size - symtab_base;
00745 PU_Info_subsect_offset(pu, WT_SYMTAB) =
00746 symtab_base - cur_section->shdr.sh_offset;
00747
00748 }
00749
00750 extern "C" void
00751 WN_write_strtab (const void* strtab, UINT64 size, Output_File *fl)
00752 {
00753 Section *cur_section = get_section (WT_STRTAB, MIPS_WHIRL_STRTAB, fl);
00754
00755 fl->file_size = ir_b_align (fl->file_size, sizeof(char), 0);
00756 cur_section->shdr.sh_offset = fl->file_size;
00757
00758 (void) ir_b_save_buf (strtab, size, sizeof(char), 0, fl);
00759
00760 cur_section->shdr.sh_size = fl->file_size - cur_section->shdr.sh_offset;
00761 cur_section->shdr.sh_addralign = sizeof(char);
00762
00763 }
00764
00765
00766
00767
00768
00769
00770
00771 void
00772 WN_write_dst (DST_TYPE dst, Output_File *fl)
00773 {
00774 off_t dst_base;
00775 Section *cur_section;
00776
00777 cur_section = get_section (WT_DST, MIPS_WHIRL_DST, fl);
00778
00779 fl->file_size = ir_b_align (fl->file_size, sizeof(mINT32), 0);
00780 cur_section->shdr.sh_offset = fl->file_size;
00781 dst_base = fl->file_size;
00782
00783 (void) ir_b_write_dst (dst, dst_base, fl);
00784
00785 cur_section->shdr.sh_size = fl->file_size - cur_section->shdr.sh_offset;
00786 cur_section->shdr.sh_addralign = sizeof(mINT32);
00787
00788 }
00789
00790
00791 #if defined(TARG_SL)
00792 void
00793 WN_write_isr_cg(vector<mINT32>& cg, Output_File *fl)
00794 {
00795 Section *cur_section;
00796
00797 cur_section = get_section (WT_CALLGRAPH, MIPS_WHIRL_CALLGRAPH, fl);
00798
00799 fl->file_size = ir_b_align (fl->file_size, sizeof(mINT32), 0);
00800 cur_section->shdr.sh_offset = fl->file_size;
00801
00802 UINT32 sz = sizeof(mINT32) * cg.size();
00803
00804 mINT32 *buf = (mINT32*) malloc (sz);
00805 mINT32 *ptr = buf;
00806
00807 for (vector<mINT32>::iterator iter = cg.begin();
00808 iter != cg.end(); iter++)
00809 {
00810 *(ptr++) = *iter;
00811 }
00812
00813 (void) ir_b_save_buf (buf, sz, sizeof(mINT32), 0, fl);
00814
00815 cur_section->shdr.sh_size = fl->file_size - cur_section->shdr.sh_offset;
00816 cur_section->shdr.sh_addralign = sizeof(mINT32);
00817 }
00818 #endif // TARG_SL
00819
00820
00821 #ifdef BACK_END
00822
00823 namespace
00824 {
00825
00826
00827 template <class T>
00828 void
00829 write_profile (off_t base, const T& data, Output_File* fl, mUINT32& num,
00830 mUINT32& offset) {
00831 offset =
00832 ir_b_save_buf (&(data.front()),
00833 data.size () * sizeof(typename T::value_type),
00834 #ifndef __GNUC__
00835 __builtin_alignof(typename T::value_type),
00836 #else
00837 __alignof__(typename T::value_type),
00838 #endif
00839 0, fl) - base;
00840 num = data.size ();
00841 }
00842
00843 template <class T>
00844 void
00845 write_target_profile (off_t base, T& data, Output_File* fl,
00846 mUINT32& num, mUINT32& offset,
00847 mUINT32& target_offset) {
00848 num = data.size ();
00849 fl->file_size = ir_b_align (fl->file_size, sizeof(mINT64), 0);
00850 offset = fl->file_size - base;
00851
00852 typename T::iterator first (data.begin ());
00853 while (first != data.end ()) {
00854 const vector<FB_FREQ>& freq = first->freq_targets;
00855 ir_b_save_buf (&(freq.front ()), freq.size () * sizeof(FB_FREQ),
00856 #ifndef __GNUC__
00857 __builtin_alignof(FB_FREQ),
00858 #else
00859 __alignof__(FB_FREQ),
00860 #endif
00861 0, fl);
00862 ++first;
00863 }
00864
00865 target_offset = fl->file_size - base;
00866 first = data.begin ();
00867 while (first != data.end ()) {
00868 INT32 num = first->freq_targets.size ();
00869 ir_b_save_buf (&num, sizeof(INT32), sizeof(INT32), 0, fl);
00870 ++first;
00871 }
00872 }
00873 }
00874
00875
00876 void
00877 WN_write_feedback (PU_Info* pu, Output_File* fl)
00878 {
00879 Is_True (PU_Info_state (pu, WT_FEEDBACK) == Subsect_InMem,
00880 ("Missing Feedback Section"));
00881
00882 Section *cur_section = fl->cur_section;
00883
00884
00885 if (strcmp(cur_section->name, MIPS_WHIRL_PU_SECTION) != 0)
00886 ErrMsg (EC_IR_Scn_Write, "feedback", fl->file_name);
00887
00888 fl->file_size = ir_b_align (fl->file_size,
00889 #ifndef __GNUC__
00890 __builtin_alignof(Pu_Hdr),
00891 #else
00892 __alignof__(Pu_Hdr),
00893 #endif
00894 0);
00895 off_t feedback_base = fl->file_size;
00896
00897 if (Cur_PU_Feedback == NULL) {
00898
00899
00900
00901
00902
00903
00904 Elf64_Word size = PU_Info_subsect_offset (pu, WT_FEEDBACK);
00905 (void) ir_b_save_buf (PU_Info_feedback_ptr (pu), size,
00906 #ifndef __GNUC__
00907 __builtin_alignof(Pu_Hdr),
00908 #else
00909 __alignof__(Pu_Hdr),
00910 #endif
00911 0, fl);
00912
00913 Set_PU_Info_state (pu, WT_FEEDBACK, Subsect_Written);
00914 PU_Info_subsect_size (pu, WT_FEEDBACK) = size;
00915 PU_Info_subsect_offset (pu, WT_FEEDBACK) =
00916 feedback_base - cur_section->shdr.sh_offset;
00917 return;
00918 }
00919
00920
00921
00922 fl->file_size += sizeof(Pu_Hdr);
00923 fl->file_size = ir_b_align (fl->file_size, sizeof(mINT64), 0);
00924
00925 Pu_Hdr pu_hdr;
00926 PU_Profile_Handle pu_handle;
00927
00928 pu_hdr.pu_checksum = Convert_Feedback_Info (Cur_PU_Feedback,
00929 PU_Info_tree_ptr (pu),
00930 pu_handle);
00931 #ifdef KEY
00932 pu_hdr.pu_size = 0;
00933 pu_hdr.runtime_fun_address = Cur_PU_Feedback->Get_Runtime_Func_Addr();
00934 #endif
00935
00936 pu_hdr.pu_name_index = 0;
00937 pu_hdr.pu_file_offset = 0;
00938
00939 write_profile (feedback_base, pu_handle.Get_Invoke_Table (), fl,
00940 pu_hdr.pu_num_inv_entries, pu_hdr.pu_inv_offset);
00941
00942 write_profile (feedback_base, pu_handle.Get_Branch_Table (), fl,
00943 pu_hdr.pu_num_br_entries, pu_hdr.pu_br_offset);
00944
00945 write_target_profile (feedback_base, pu_handle.Get_Switch_Table (), fl,
00946 pu_hdr.pu_num_switch_entries,
00947 pu_hdr.pu_switch_offset,
00948 pu_hdr.pu_switch_target_offset);
00949
00950 Is_True (pu_handle.Get_Compgoto_Table ().size () == 0,
00951 ("Compgoto Table should be empty"));
00952
00953 write_profile (feedback_base, pu_handle.Get_Loop_Table (), fl,
00954 pu_hdr.pu_num_loop_entries,
00955 pu_hdr.pu_loop_offset);
00956
00957 write_profile (feedback_base, pu_handle.Get_Short_Circuit_Table (), fl,
00958 pu_hdr.pu_num_scircuit_entries,
00959 pu_hdr.pu_scircuit_offset);
00960
00961 write_profile (feedback_base, pu_handle.Get_Call_Table (), fl,
00962 pu_hdr.pu_num_call_entries,
00963 pu_hdr.pu_call_offset);
00964
00965 #ifdef KEY
00966 write_profile (feedback_base, pu_handle.Get_Icall_Table (), fl,
00967 pu_hdr.pu_num_icall_entries,
00968 pu_hdr.pu_icall_offset);
00969
00970 write_profile (feedback_base, pu_handle.Get_Value_Table (), fl,
00971 pu_hdr.pu_num_value_entries,
00972 pu_hdr.pu_value_offset);
00973
00974 write_profile (feedback_base, pu_handle.Get_Value_FP_Bin_Table (), fl,
00975 pu_hdr.pu_num_value_fp_bin_entries,
00976 pu_hdr.pu_value_fp_bin_offset);
00977 #endif
00978
00979 BCOPY (&pu_hdr, fl->map_addr + feedback_base, sizeof(pu_hdr));
00980
00981
00982 Set_PU_Info_state (pu, WT_FEEDBACK, Subsect_Written);
00983 PU_Info_subsect_size (pu, WT_FEEDBACK) = fl->file_size - feedback_base;
00984 PU_Info_subsect_offset (pu, WT_FEEDBACK) =
00985 feedback_base - cur_section->shdr.sh_offset;
00986
00987 }
00988
00989
00990
00991
00992
00993 void
00994 IPA_write_summary (void (*IPA_irb_write_summary) (Output_File*),
00995 Output_File *fl)
00996 {
00997 Section *cur_section;
00998
00999 cur_section = get_section(WT_IPA_SUMMARY, MIPS_WHIRL_SUMMARY, fl);
01000
01001 fl->file_size = ir_b_align(fl->file_size, sizeof(mINT64), 0);
01002 cur_section->shdr.sh_offset = fl->file_size;
01003
01004 (*IPA_irb_write_summary) (fl);
01005
01006 cur_section->shdr.sh_size = fl->file_size - cur_section->shdr.sh_offset;
01007 cur_section->shdr.sh_addralign = sizeof(mINT64);
01008
01009 }
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019 void
01020 WN_write_depgraph (PU_Info *pu, WN_MAP off_map, Output_File *fl)
01021 {
01022 void *g;
01023 off_t depgraph_base;
01024 Section *cur_section = fl->cur_section;
01025
01026 if (PU_Info_state(pu, WT_DEPGRAPH) == Subsect_Missing)
01027 return;
01028
01029
01030 if (strcmp(cur_section->name, MIPS_WHIRL_PU_SECTION) != 0 ||
01031 PU_Info_state(pu, WT_DEPGRAPH) != Subsect_InMem)
01032 ErrMsg (EC_IR_Scn_Write, "dependence graph", fl->file_name);
01033
01034 g = PU_Info_depgraph_ptr(pu);
01035
01036 fl->file_size = ir_b_align(fl->file_size, sizeof(mINT32), 0);
01037 depgraph_base = fl->file_size;
01038
01039 Depgraph_Write(g, fl, off_map);
01040
01041 Set_PU_Info_state(pu, WT_DEPGRAPH, Subsect_Written);
01042 PU_Info_subsect_size(pu, WT_DEPGRAPH) = fl->file_size - depgraph_base;
01043 PU_Info_subsect_offset(pu, WT_DEPGRAPH) =
01044 depgraph_base - cur_section->shdr.sh_offset;
01045
01046 }
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 void
01060 WN_write_prefetch (PU_Info *pu, WN_MAP off_map, Output_File *fl)
01061 {
01062 WN **pf_ldsts;
01063 off_t prefetch_base;
01064 Section *cur_section = fl->cur_section;
01065 INT i;
01066 WN *node;
01067 PF_POINTER *pf_ptr;
01068 INT32 cur_offset;
01069 Elf64_Word node_offset;
01070
01071 #define PF_PTR_ADDR(offset) ((PF_POINTER *)(fl->map_addr + (offset)))
01072
01073 if (PU_Info_state(pu, WT_PREFETCH) == Subsect_Missing)
01074 return;
01075
01076
01077 if (strcmp(cur_section->name, MIPS_WHIRL_PU_SECTION) != 0 ||
01078 PU_Info_state(pu, WT_PREFETCH) != Subsect_InMem)
01079 ErrMsg (EC_IR_Scn_Write, "prefetch map", fl->file_name);
01080
01081 pf_ldsts = (WN **)PU_Info_subsect_ptr(pu, WT_PREFETCH);
01082 if (!pf_ldsts) {
01083
01084
01085 Set_PU_Info_state(pu, WT_PREFETCH, Subsect_Missing);
01086 return;
01087 }
01088
01089 fl->file_size = ir_b_align(fl->file_size, sizeof(mINT32), 0);
01090 prefetch_base = fl->file_size;
01091
01092 for (i = 0; pf_ldsts[i]; i++) {
01093
01094 node = pf_ldsts[i];
01095 pf_ptr = (PF_POINTER *) WN_MAP_Get(WN_MAP_PREFETCH, node);
01096
01097 node_offset = (Elf64_Word)WN_MAP32_Get(off_map, node);
01098 cur_offset = ir_b_save_buf((void *)&node_offset, sizeof(Elf64_Word),
01099 sizeof(Elf64_Word), 0, fl);
01100
01101 cur_offset = ir_b_save_buf((void *)pf_ptr, sizeof(PF_POINTER),
01102 #ifndef __GNUC__
01103 __builtin_alignof(PF_POINTER),
01104 #else
01105 __alignof__(PF_POINTER),
01106 #endif
01107 0, fl);
01108
01109
01110 PF_PTR_ADDR(cur_offset)->wn_pref_1L =
01111 ((pf_ptr->wn_pref_1L) ?
01112 (WN *) (INTPTR) WN_MAP32_Get(off_map, pf_ptr->wn_pref_1L) :
01113 (WN *) -1);
01114 PF_PTR_ADDR(cur_offset)->wn_pref_2L =
01115 ((pf_ptr->wn_pref_2L) ?
01116 (WN *) (INTPTR) WN_MAP32_Get(off_map, pf_ptr->wn_pref_2L) :
01117 (WN *) -1);
01118 }
01119
01120
01121 PU_Info_subsect_ptr(pu, WT_PREFETCH) = NULL;
01122 free(pf_ldsts);
01123
01124
01125 node_offset = (Elf64_Word) -1;
01126 ir_b_save_buf(&node_offset, sizeof(Elf64_Word), sizeof(Elf64_Word), 0, fl);
01127
01128 Set_PU_Info_state(pu, WT_PREFETCH, Subsect_Written);
01129 PU_Info_subsect_size(pu, WT_PREFETCH) = fl->file_size - prefetch_base;
01130 PU_Info_subsect_offset(pu, WT_PREFETCH) =
01131 prefetch_base - cur_section->shdr.sh_offset;
01132
01133 }
01134
01135
01136 template<class MAP_ENTRY_TYPE>
01137 static inline MAP_ENTRY_TYPE
01138 WN_MAP_retrieve(WN_MAP, WN *, MAP_ENTRY_TYPE);
01139
01140 static inline INT32
01141 WN_MAP_retrieve(WN_MAP wn_map, WN *wn, INT32)
01142 {
01143 return WN_MAP32_Get(wn_map, wn);
01144 }
01145
01146 static inline INT64
01147 WN_MAP_retrieve(WN_MAP wn_map, WN *wn, INT64)
01148 {
01149 return WN_MAP64_Get(wn_map, wn);
01150 }
01151
01152 static inline void *
01153 WN_MAP_retrieve(WN_MAP wn_map, WN *wn, void *)
01154 {
01155 return WN_MAP_Get(wn_map, wn);
01156 }
01157
01158
01159
01160 template<class MAP_ENTRY_TYPE>
01161 static inline void
01162 WN_write_generic_map(PU_Info *pu,
01163 WN_MAP off_map,
01164 Output_File *fl,
01165 INT32 subsection_type,
01166 WN_MAP value_map,
01167 const char *subsection_name,
01168 MAP_ENTRY_TYPE)
01169 {
01170 WN **nodes_represented;
01171 off_t mapping_base;
01172 Elf64_Word node_offset;
01173 INT i;
01174
01175 if (PU_Info_state (pu, subsection_type) == Subsect_Missing)
01176 return;
01177
01178 if (strcmp (fl->cur_section->name, MIPS_WHIRL_PU_SECTION) != 0 ||
01179 PU_Info_state(pu, subsection_type) != Subsect_InMem) {
01180 ErrMsg (EC_IR_Scn_Write, subsection_name, fl->file_name);
01181 }
01182
01183 nodes_represented = (WN **) PU_Info_subsect_ptr (pu, subsection_type);
01184 if (!nodes_represented) {
01185 Set_PU_Info_state(pu, subsection_type, Subsect_Missing);
01186 return;
01187 }
01188
01189 fl->file_size = ir_b_align (fl->file_size, sizeof(mINT64), 0);
01190 mapping_base = fl->file_size;
01191
01192 for (i = 0; nodes_represented[i]; i++) {
01193 WN *node = nodes_represented[i];
01194 MAP_ENTRY_TYPE map_value = WN_MAP_retrieve(value_map,
01195 node,
01196 (MAP_ENTRY_TYPE) 0);
01197 if (map_value != (MAP_ENTRY_TYPE) 0) {
01198 node_offset = WN_MAP32_Get(off_map, node);
01199 (void) ir_b_save_buf ((void*) &node_offset, sizeof(Elf64_Word),
01200 sizeof(Elf64_Word), 0, fl);
01201 (void) ir_b_save_buf ((void *) &map_value,
01202 sizeof(MAP_ENTRY_TYPE),
01203 sizeof(MAP_ENTRY_TYPE),
01204 0,
01205 fl);
01206 }
01207 }
01208
01209 PU_Info_subsect_ptr(pu, subsection_type) = NULL;
01210
01211 free(nodes_represented);
01212
01213
01214 node_offset = -1;
01215 ir_b_save_buf(&node_offset, sizeof(Elf64_Word), sizeof(Elf64_Word), 0, fl);
01216
01217 Set_PU_Info_state(pu, subsection_type, Subsect_Written);
01218 PU_Info_subsect_size(pu, subsection_type) = fl->file_size - mapping_base;
01219 PU_Info_subsect_offset(pu, subsection_type) =
01220 mapping_base - fl->cur_section->shdr.sh_offset;
01221 }
01222
01223 void
01224 WN_write_INT32_map(PU_Info *pu,
01225 WN_MAP off_map,
01226 Output_File *fl,
01227 INT32 subsection_type,
01228 WN_MAP value_map,
01229 const char *subsection_name)
01230 {
01231 WN_write_generic_map(pu, off_map, fl, subsection_type, value_map,
01232 subsection_name, (INT32) 0);
01233 }
01234
01235 void
01236 WN_write_voidptr_map(PU_Info *pu,
01237 WN_MAP off_map,
01238 Output_File *fl,
01239 INT32 subsection_type,
01240 WN_MAP value_map,
01241 const char *subsection_name)
01242 {
01243 WN_write_generic_map(pu, off_map, fl, subsection_type, value_map,
01244 subsection_name, (void *) 0);
01245 }
01246
01247 void
01248 IPA_copy_PU (PU_Info *pu, char *section_base, Output_File *outfile)
01249 {
01250 char *subsect;
01251 off_t base;
01252 char buffer [sizeof (WN)];
01253 WN *dummy = (WN *) &buffer [0];;
01254 INT padding;
01255 Subsect_State state;
01256
01257
01258 if (strcmp(outfile->cur_section->name, MIPS_WHIRL_PU_SECTION) != 0)
01259 ErrMsg (EC_IR_Scn_Write, "PU", outfile->file_name);
01260
01261
01262 state = PU_Info_state(pu, WT_SYMTAB);
01263 if (state == Subsect_Exists)
01264 Set_PU_Info_state(pu, WT_SYMTAB, Subsect_Written);
01265 else if (state != Subsect_Written)
01266 ErrMsg (EC_IR_Scn_Write, "symtab", outfile->file_name);
01267 subsect = section_base + PU_Info_subsect_offset(pu, WT_SYMTAB);
01268 outfile->file_size = ir_b_align(outfile->file_size, sizeof(mINT64), 0);
01269 base = outfile->file_size;
01270 ir_b_save_buf(subsect, PU_Info_subsect_size(pu, WT_SYMTAB),
01271 sizeof(mINT64), 0, outfile);
01272
01273 PU_Info_subsect_offset(pu, WT_SYMTAB) =
01274 base - outfile->cur_section->shdr.sh_offset;
01275
01276
01277 WN_set_opcode(dummy, OPC_FUNC_ENTRY);
01278 padding = (char *)dummy - (char *)WN_StartAddress(dummy) +
01279 sizeof(Elf64_Word);
01280
01281
01282 state = PU_Info_state(pu, WT_TREE);
01283 if (state == Subsect_Exists)
01284 Set_PU_Info_state(pu, WT_TREE, Subsect_Written);
01285 else if (state != Subsect_Written)
01286 ErrMsg (EC_IR_Scn_Write, "tree", outfile->file_name);
01287 subsect = section_base + PU_Info_subsect_offset(pu, WT_TREE);
01288 outfile->file_size = ir_b_align(outfile->file_size,
01289 #ifndef __GNUC__
01290 __builtin_alignof(WN),
01291 #else
01292 __alignof__(WN),
01293 #endif
01294 padding);
01295 base = outfile->file_size;
01296 ir_b_save_buf(subsect, PU_Info_subsect_size(pu, WT_TREE),
01297 #ifndef __GNUC__
01298 __builtin_alignof(WN),
01299 #else
01300 __alignof__(WN),
01301 #endif
01302 padding, outfile);
01303 PU_Info_subsect_offset(pu, WT_TREE) =
01304 base - outfile->cur_section->shdr.sh_offset;
01305
01306
01307 state = PU_Info_state(pu, WT_DEPGRAPH);
01308 if (state != Subsect_Missing) {
01309 if (state == Subsect_Exists)
01310 Set_PU_Info_state(pu, WT_DEPGRAPH, Subsect_Written);
01311 else if (state != Subsect_Written)
01312 ErrMsg (EC_IR_Scn_Write, "depgraph", outfile->file_name);
01313 subsect = section_base + PU_Info_subsect_offset(pu, WT_DEPGRAPH);
01314 outfile->file_size = ir_b_align(outfile->file_size, sizeof(mINT32), 0);
01315 base = outfile->file_size;
01316 ir_b_save_buf(subsect, PU_Info_subsect_size(pu, WT_DEPGRAPH),
01317 sizeof(mINT32), 0, outfile);
01318 PU_Info_subsect_offset(pu, WT_DEPGRAPH) =
01319 base - outfile->cur_section->shdr.sh_offset;
01320 }
01321
01322
01323 state = PU_Info_state(pu, WT_PREFETCH);
01324 if (state != Subsect_Missing) {
01325 if (state == Subsect_Exists)
01326 Set_PU_Info_state(pu, WT_PREFETCH, Subsect_Written);
01327 else if (state != Subsect_Written)
01328 ErrMsg (EC_IR_Scn_Write, "prefetch", outfile->file_name);
01329 subsect = section_base + PU_Info_subsect_offset(pu, WT_PREFETCH);
01330 outfile->file_size = ir_b_align(outfile->file_size, sizeof(mINT32), 0);
01331 base = outfile->file_size;
01332 ir_b_save_buf(subsect, PU_Info_subsect_size(pu, WT_PREFETCH),
01333 sizeof(mINT32), 0, outfile);
01334 PU_Info_subsect_offset(pu, WT_PREFETCH) =
01335 base - outfile->cur_section->shdr.sh_offset;
01336 }
01337
01338 }
01339
01340 #endif
01341
01342
01343 void
01344 WN_write_revision (Output_File *fl)
01345 {
01346 Section *cur_section;
01347 int length = strlen (Whirl_Revision);
01348
01349 cur_section = get_section (0, ELF_COMMENT, fl);
01350
01351 cur_section->shdr.sh_offset = fl->file_size;
01352
01353 ir_b_save_buf (Whirl_Revision, length+1, 0, 0, fl);
01354
01355 cur_section->shdr.sh_size = fl->file_size - cur_section->shdr.sh_offset;
01356 cur_section->shdr.sh_addralign = 1;
01357
01358 cur_section->shdr.sh_type = SHT_PROGBITS;
01359
01360 }
01361
01362
01363 void
01364 WN_close_output (Output_File *fl)
01365 {
01366 if (fl->output_fd < 0)
01367 ErrMsg (EC_IR_Close, fl->file_name, EBADF);
01368
01369 #ifndef __ALWAYS_USE_64BIT_ELF__
01370 if (Use_32_Bit_Pointers) {
01371 Elf32_Shdr strtab_sec;
01372 UINT64 offset = layout_sections (strtab_sec, fl);
01373 write_output (offset, strtab_sec, fl, ELF32());
01374 } else
01375 #endif
01376 {
01377 Elf64_Shdr strtab_sec;
01378 UINT64 e_shoff = layout_sections (strtab_sec, fl);
01379 write_output (e_shoff, strtab_sec, fl, ELF64());
01380 }
01381
01382 #ifdef _WIN32
01383 UnmapViewOfFile(fl->map_addr);
01384 CloseHandle(fl->mapHd);
01385 if (_chsize(fl->output_fd, fl->file_size))
01386 ErrMsg (EC_IR_Close, fl->file_name, GetLastError ());
01387 #else
01388
01389 MUNMAP(fl->map_addr, fl->mapped_size);
01390 if (ftruncate(fl->output_fd, fl->file_size) != 0)
01391 ErrMsg (EC_IR_Close, fl->file_name, errno);
01392 #endif
01393
01394 close (fl->output_fd);
01395 cleanup (fl);
01396
01397 }
01398
01399 void
01400 WN_close_file (void *this_fl)
01401 {
01402 Output_File *fl = (Output_File *)this_fl;
01403 if (fl->output_fd < 0)
01404 ErrMsg (EC_IR_Close, fl->file_name, EBADF);
01405
01406 #ifdef _WIN32
01407 UnmapViewOfFile(fl->map_addr);
01408 CloseHandle(fl->mapHd);
01409 if (_chsize(fl->output_fd, fl->file_size))
01410 ErrMsg (EC_IR_Close, fl->file_name, GetLastError());
01411 #else
01412 MUNMAP(fl->map_addr, fl->mapped_size);
01413 if (ftruncate(fl->output_fd, fl->file_size) != 0)
01414 ErrMsg (EC_IR_Close, fl->file_name, errno);
01415 #endif
01416
01417 close (fl->output_fd);
01418 cleanup (fl);
01419
01420 }
01421
01422
01423 #ifndef OWN_ERROR_PACKAGE
01424
01425
01426
01427
01428
01429
01430 static Output_File *ir_output;
01431
01432 void
01433 Write_PU_Info (PU_Info *pu)
01434 {
01435 Temporary_Error_Phase ephase("Writing WHIRL file");
01436
01437 WN_MAP off_map = WN_MAP_UNDEFINED;
01438
01439 WN_write_symtab (pu, ir_output);
01440
01441
01442 #ifdef BACK_END
01443 if (PU_Info_state (pu, WT_FEEDBACK) == Subsect_InMem)
01444 WN_write_feedback (pu, ir_output);
01445
01446 if (Write_BE_Maps || Write_ALIAS_CLASS_Map) {
01447 Current_Map_Tab = PU_Info_maptab(pu);
01448 MEM_POOL_Push(MEM_local_nz_pool_ptr);
01449 off_map = WN_MAP32_Create(MEM_local_nz_pool_ptr);
01450 }
01451 #endif
01452
01453 WN_write_tree (pu, off_map, ir_output);
01454
01455 #ifdef BACK_END
01456 if (Write_BE_Maps || Write_ALIAS_CLASS_Map) {
01457 if (Write_BE_Maps) {
01458 WN_write_depgraph(pu, off_map, ir_output);
01459
01460
01461 WN_write_prefetch(pu, off_map, ir_output);
01462 }
01463
01464 if (Write_ALIAS_CLASS_Map) {
01465 WN_write_INT32_map(pu, off_map, ir_output, WT_ALIAS_CLASS,
01466 WN_MAP_ALIAS_CLASS, "alias class map");
01467 }
01468
01469 WN_MAP_Delete(off_map);
01470 MEM_POOL_Pop(MEM_local_nz_pool_ptr);
01471 }
01472
01473 #endif // BACK_END
01474 }
01475
01476
01477 Output_File *
01478 Open_Output_Info (char *output_file)
01479 {
01480 Set_Error_Phase ("Writing WHIRL file" );
01481 ir_output = WN_open_output (output_file);
01482 if (!ir_output) {
01483 ErrMsg (EC_IR_Create, output_file, errno);
01484 }
01485 return ir_output;
01486 }
01487
01488 #if defined(KEY) && defined(BACK_END)
01489 #include "be_ipa_util.h"
01490 #endif
01491
01492 void
01493 Write_Global_Info (PU_Info *pu_tree)
01494 {
01495 Set_Error_Phase ("Writing WHIRL file" );
01496 WN_write_PU_Infos (pu_tree, ir_output);
01497
01498
01499 WN_write_globals (ir_output);
01500
01501 WN_write_dst(Current_DST, ir_output);
01502
01503 WN_write_strtab(Index_To_Str (0), STR_Table_Size (), ir_output);
01504
01505 #if defined(KEY) && defined(BACK_END)
01506 if (Mod_Ref_Info_Table_Size() != 0)
01507 IPA_write_summary (IPA_irb_write_mod_ref_info, ir_output);
01508 #endif
01509
01510 }
01511
01512 void
01513 Close_Output_Info (void)
01514 {
01515 WN_write_revision (ir_output);
01516
01517 WN_close_output(ir_output);
01518 }
01519
01520
01521 extern "C" void
01522 WN_write_elf_symtab (const void* symtab, UINT64 size, UINT64 entsize,
01523 UINT align, Output_File* fl)
01524 {
01525
01526 Section* elf_strtab = get_section (0, ELF_STRTAB, fl);
01527 Section* whirl_strtab = get_section (WT_STRTAB, MIPS_WHIRL_STRTAB, fl);
01528 elf_strtab->shdr = whirl_strtab->shdr;
01529 elf_strtab->shdr.sh_type = SHT_STRTAB;
01530 elf_strtab->shdr.sh_info = 0;
01531
01532 UINT strtab_idx = elf_strtab - fl->section_list + 1;
01533
01534 Section* cur_section = get_section (0, ELF_SYMTAB, fl);
01535
01536 fl->file_size = ir_b_align (fl->file_size, align, 0);
01537 cur_section->shdr.sh_offset = fl->file_size;
01538
01539 (void) ir_b_save_buf (symtab, size, align, 0, fl);
01540
01541 cur_section->shdr.sh_type = SHT_SYMTAB;
01542 cur_section->shdr.sh_size = fl->file_size - cur_section->shdr.sh_offset;
01543 cur_section->shdr.sh_addralign = align;
01544 cur_section->shdr.sh_link = strtab_idx;
01545 cur_section->shdr.sh_entsize = entsize;
01546 }
01547
01548 #endif // OWN_ERROR_PACKAGE
01549
01550