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