00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #define __STDC_LIMIT_MACROS
00045 #include <stdint.h>
00046 #ifdef USE_PCH
00047 #include "common_com_pch.h"
00048 #endif
00049 #pragma hdrstop
00050 #include <unistd.h>
00051 #ifdef __MINGW32__
00052 #include <WINDOWS.h>
00053 #else
00054 #include <sys/mman.h>
00055 #endif
00056 #include <errno.h>
00057 #if defined(BUILD_OS_DARWIN)
00058 #include "darwin_elf.h"
00059 #else
00060 #include <elf.h>
00061 #endif
00062 #include <sys/elf_whirl.h>
00063
00064 #ifndef USE_STANDARD_TYPES
00065 #define USE_STANDARD_TYPES
00066 #endif
00067
00068 #include "defs.h"
00069 #include "erglob.h"
00070 #include "errors.h"
00071 #include "opcode.h"
00072 #include "mempool.h"
00073 #include "wn.h"
00074 #include "wn_map.h"
00075 #include "strtab.h"
00076 #include "symtab.h"
00077 #include "irbdata.h"
00078 #define USE_DST_INTERNALS
00079 #include "dwarf_DST_mem.h"
00080 #include "pu_info.h"
00081 #include "ir_bwrite.h"
00082 #include "ir_bcom.h"
00083
00084
00085 #define MAPPED_SIZE 0x400000
00086 #define INIT_TMP_MAPPED_SIZE MAPPED_SIZE
00087
00088 #ifdef BACK_END
00089 #define DEFAULT_NUM_OF_PREFETCHES 64
00090 WN **prefetch_ldsts;
00091 INT num_prefetch_ldsts;
00092 INT max_num_prefetch_ldsts;
00093
00094 #define DEFAULT_NUM_ALIAS_CLASSES 128
00095 WN **alias_classes;
00096 INT num_alias_class_nodes;
00097 INT max_alias_class_nodes;
00098
00099 #define DEFAULT_NUM_AC_INTERNALS 128
00100 WN **ac_internals;
00101 INT num_ac_internal_nodes;
00102 INT max_ac_internal_nodes;
00103 #endif
00104
00105 #ifndef __GNUC__
00106 #define __ALIGNOF(x) __builtin_alignof(x)
00107 #else
00108 #define __ALIGNOF(x) __alignof__(x)
00109 #endif // __GNUC__
00110
00111 const char *Whirl_Revision = WHIRL_REVISION;
00112
00113
00114
00115
00116 void *IPAA_Local_Map = NULL;
00117
00118 #if defined(KEY) && defined(BACK_END)
00119 #include "be_ipa_util.h"
00120 MOD_REF_INFO_TAB Mod_Ref_Info_Table;
00121 #endif
00122
00123 BOOL Doing_mmapped_io = FALSE;
00124
00125
00126
00127
00128
00129
00130
00131
00132 extern off_t
00133 ir_b_save_buf (const void *buf, Elf64_Word size, UINT32 align,
00134 UINT32 padding, Output_File *fl)
00135 {
00136 Current_Output = fl;
00137
00138 off_t file_size = ir_b_align (fl->file_size, align, padding);
00139
00140 if (file_size + size >= fl->mapped_size)
00141 ir_b_grow_map (file_size + size - fl->file_size, fl);
00142
00143 Doing_mmapped_io = TRUE;
00144 memcpy (fl->map_addr + file_size, buf, size);
00145 Doing_mmapped_io = FALSE;
00146 fl->file_size = file_size + size;
00147 return file_size + padding;
00148 }
00149
00150
00151
00152 extern off_t
00153 ir_b_copy_file (const void *buf, Elf64_Word size, void *tmpfl)
00154 {
00155 Output_File* fl = (Output_File*)tmpfl;
00156
00157 Current_Output = fl;
00158
00159 if (size >= fl->mapped_size)
00160 ir_b_grow_map (size, fl);
00161
00162 Doing_mmapped_io = TRUE;
00163 memcpy (fl->map_addr, buf, size);
00164 Doing_mmapped_io = FALSE;
00165 fl->file_size = size;
00166 return size;
00167 }
00168
00169
00170 static void
00171 save_buf_at_offset (const void *buf, Elf64_Word size, off_t offset,
00172 Output_File *fl)
00173 {
00174 Is_True (offset + size <= fl->mapped_size, ("Invalid buffer size"));
00175
00176 Doing_mmapped_io = TRUE;
00177 memcpy (fl->map_addr + offset, buf, size);
00178 Doing_mmapped_io = FALSE;
00179 }
00180
00181
00182
00183 static off_t
00184 ir_b_reserve_space (Elf64_Word size, unsigned int align, Output_File *fl)
00185 {
00186 off_t file_size = ir_b_align (fl->file_size, align, 0);
00187
00188 if (file_size + size >= fl->mapped_size)
00189 ir_b_grow_map (file_size + size - fl->file_size, fl);
00190
00191 fl->file_size = file_size + size;
00192 return file_size;
00193 }
00194
00195 #ifndef __MINGW32__
00196
00197
00198
00199
00200
00201 char *
00202 ir_b_grow_map (Elf64_Word min_size, Output_File *fl)
00203 {
00204 Is_True (fl->map_addr != 0, ("output file not yet mapped"));
00205
00206 if (munmap (fl->map_addr, fl->mapped_size) == -1)
00207 ErrMsg (EC_IR_Write, fl->file_name, errno);
00208 min_size += fl->file_size;
00209 while (fl->mapped_size < min_size) {
00210 if (fl->mapped_size < MAPPED_SIZE)
00211 fl->mapped_size = MAPPED_SIZE;
00212 else
00213 fl->mapped_size += MAPPED_SIZE;
00214 }
00215 #if !(defined(linux) || defined(BUILD_OS_DARWIN) || defined(__APPLE__))
00216 fl->map_addr = (char *) mmap (0, fl->mapped_size, PROT_READ|PROT_WRITE,
00217 MAP_SHARED|MAP_AUTOGROW, fl->output_fd, 0);
00218 #else
00219 fl->map_addr = (char *) mmap (0, fl->mapped_size, PROT_READ|PROT_WRITE,
00220 MAP_SHARED, fl->output_fd, 0);
00221
00222 if (ftruncate(fl->output_fd, fl->mapped_size))
00223 ErrMsg (EC_IR_Write, fl->file_name, strerror(errno));
00224 #endif
00225
00226 if (fl->map_addr == (char *) (-1))
00227 ErrMsg (EC_IR_Write, fl->file_name, strerror(errno));
00228
00229 return fl->map_addr;
00230 }
00231
00232 #else
00233
00234 #include<windows.h>
00235 #include<io.h>
00236
00237
00238
00239
00240
00241 char *
00242 ir_b_grow_map (Elf64_Word min_size, Output_File *fl)
00243 {
00244 char errBuf[100];
00245 Is_True (fl->map_addr != 0, ("output file not yet mapped"));
00246 if(!UnmapViewOfFile(fl->map_addr) || !CloseHandle(fl->mapHd))
00247 ErrMsg (EC_IR_Write, fl->file_name, strerror(errno));
00248 min_size += fl->file_size;
00249 while (fl->mapped_size < min_size) {
00250 if (fl->mapped_size < MAPPED_SIZE)
00251 fl->mapped_size = MAPPED_SIZE;
00252 else
00253 fl->mapped_size += MAPPED_SIZE;
00254 }
00255
00256 if(_chsize(fl->output_fd, fl->mapped_size)){
00257 FormatMessage(0,NULL, GetLastError(),0, errBuf, 100, NULL);
00258 ErrMsg (EC_IR_Write, fl->file_name, errBuf);
00259 }
00260 if( (fl->mapHd = CreateFileMapping((HANDLE)_get_osfhandle(fl->output_fd),
00261 NULL, PAGE_READWRITE, 0, fl->mapped_size, fl->file_name))== NULL){
00262 FormatMessage(0,NULL, GetLastError(),0, errBuf, 100, NULL);
00263 ErrMsg (EC_IR_Write, fl->file_name, errBuf);
00264 }
00265
00266 if ( (fl->map_addr = (char *)MapViewOfFileEx(fl->mapHd,
00267 FILE_MAP_WRITE,0,0, fl->mapped_size, 0)) == NULL){
00268 FormatMessage(0,NULL, GetLastError(),0, errBuf, 100, NULL);
00269 ErrMsg (EC_IR_Write, fl->file_name, errBuf);
00270 }
00271 if (fl->map_addr == (char *) (-1))
00272 ErrMsg (EC_IR_Write, fl->file_name, errBuf);
00273 return fl->map_addr;
00274 }
00275
00276
00277 #endif
00278
00279
00280 extern char *
00281 ir_b_create_map (Output_File *fl)
00282 {
00283 int fd = fl->output_fd;
00284 fl->mapped_size = INIT_TMP_MAPPED_SIZE;
00285 #ifdef __MINGW32__
00286 {
00287 char errBuf[100];
00288
00289 if( (fl->mapHd = CreateFileMapping((HANDLE)_get_osfhandle(fl->output_fd), NULL, PAGE_READWRITE, 0,
00290 fl->mapped_size, NULL))
00291 == NULL){
00292 INT err = GetLastError();
00293 FormatMessage(0,NULL, err,0, errBuf, 100, NULL);
00294 ErrMsg (EC_IR_Write, fl->file_name, errBuf);
00295 }
00296 if( (fl->map_addr = (char *)MapViewOfFileEx(fl->mapHd, FILE_MAP_WRITE,
00297 0,0,fl->mapped_size, 0)) == NULL){
00298 FormatMessage(0,NULL, GetLastError(),0, errBuf, 100, NULL);
00299 ErrMsg (EC_IR_Write, fl->file_name, errBuf);
00300 }
00301 }
00302 #else
00303 #if !defined(linux) && !defined(__APPLE__)
00304 fl->map_addr = (char *) mmap (0, fl->mapped_size, PROT_READ|PROT_WRITE,
00305 MAP_SHARED|MAP_AUTOGROW, fd, 0);
00306 #else
00307 fl->map_addr = (char *) mmap (0, fl->mapped_size, PROT_READ|PROT_WRITE,
00308 MAP_SHARED, fd, 0);
00309 #endif
00310 #endif
00311 return fl->map_addr;
00312 }
00313
00314
00315
00316 #if defined(KEY) && !defined(FRONT_END) && !defined(IR_TOOLS)
00317
00318
00319 #define IPA_get_symbol_file_array (*IPA_get_symbol_file_array_p)
00320 #define Get_Node_From_PU (*Get_Node_From_PU_p)
00321 #include <ipc_file.h>
00322
00323 extern IP_FILE_HDR_TABLE IP_File_header;
00324 IP_FILE_HDR_TABLE *IP_File_header_p;
00325 #define IP_File_header (*IP_File_header_p)
00326
00327 #include <ipo_tlog_utils.h>
00328 #include <ipa_cg.h>
00329
00330 extern off_t
00331 ir_b_write_tree (WN *node, off_t base_offset, Output_File *fl, WN_MAP off_map, PU_Info *pu)
00332 #else
00333 extern off_t
00334 ir_b_write_tree (WN *node, off_t base_offset, Output_File *fl, WN_MAP off_map)
00335 #endif
00336 {
00337 register OPCODE opcode;
00338 off_t node_offset;
00339 char *real_addr;
00340 INT32 size = WN_Size_and_StartAddress (node, (void **) &real_addr);
00341
00342 #define WN_ADDR(offset) ((WN *)(fl->map_addr + offset))
00343
00344 node_offset = ir_b_save_buf (real_addr, size, __ALIGNOF(WN),
00345 (char *)(node) - real_addr, fl);
00346
00347 opcode = (OPCODE) WN_opcode (node);
00348
00349 #ifdef BACK_END
00350 if (off_map != WN_MAP_UNDEFINED &&
00351 (Write_BE_Maps ||
00352 Write_ALIAS_CLASS_Map ||
00353 Write_AC_INTERNAL_Map)) {
00354
00355 BOOL set_offset = FALSE;
00356 OPERATOR opr = OPCODE_operator(opcode);
00357
00358 if (Write_BE_Maps) {
00359 if (opr == OPR_PREFETCH || opr == OPR_PREFETCHX ||
00360 OPCODE_is_load (opcode) || OPCODE_is_store (opcode))
00361 set_offset = TRUE;
00362
00363
00364 if (WN_MAP_Get(WN_MAP_PREFETCH, node)) {
00365
00366
00367 if (num_prefetch_ldsts == 0) {
00368 max_num_prefetch_ldsts = DEFAULT_NUM_OF_PREFETCHES;
00369 prefetch_ldsts =
00370 (WN **)MEM_POOL_Alloc (Malloc_Mem_Pool, max_num_prefetch_ldsts * sizeof(WN*));
00371 FmtAssert (prefetch_ldsts,
00372 ("No more memory for allocation."));
00373 } else if (max_num_prefetch_ldsts == num_prefetch_ldsts + 1) {
00374 max_num_prefetch_ldsts *= 2;
00375 prefetch_ldsts =
00376 (WN **)realloc(prefetch_ldsts,
00377 max_num_prefetch_ldsts * sizeof(WN*));
00378 FmtAssert (prefetch_ldsts,
00379 ("No more memory for allocation."));
00380 }
00381 prefetch_ldsts[num_prefetch_ldsts] = node;
00382 num_prefetch_ldsts += 1;
00383 }
00384 }
00385
00386 if (Write_ALIAS_CLASS_Map) {
00387 if (OPCODE_is_store (opcode) ||
00388 OPCODE_is_load (opcode) ||
00389 (opr == OPR_LDA ) ||
00390 opr == OPR_PARM) {
00391 set_offset = TRUE;
00392 }
00393
00394 if (WN_MAP32_Get (WN_MAP_ALIAS_CLASS, node) != 0) {
00395 if (alias_classes == NULL) {
00396 max_alias_class_nodes = DEFAULT_NUM_ALIAS_CLASSES;
00397 alias_classes = (WN **) malloc (max_alias_class_nodes *
00398 sizeof(WN *));
00399 FmtAssert (alias_classes != NULL, ("No more memory."));
00400 } else if (max_alias_class_nodes == num_alias_class_nodes + 1) {
00401 max_alias_class_nodes *= 2;
00402 alias_classes = (WN **) realloc(alias_classes,
00403 max_alias_class_nodes *
00404 sizeof(WN **));
00405 FmtAssert(alias_classes != NULL, ("No more memory."));
00406 }
00407 alias_classes[num_alias_class_nodes++] = node;
00408 }
00409 }
00410
00411 if (Write_AC_INTERNAL_Map) {
00412 if (opr == OPR_ILOAD ||
00413 opr == OPR_MLOAD ||
00414 opr == OPR_PARM ||
00415 opr == OPR_ISTORE ||
00416 opr == OPR_MSTORE) {
00417 set_offset = TRUE;
00418 }
00419
00420 if (WN_MAP_Get (WN_MAP_AC_INTERNAL, node) != NULL) {
00421 if (ac_internals == NULL) {
00422 max_ac_internal_nodes = DEFAULT_NUM_AC_INTERNALS;
00423 ac_internals = (WN **) malloc (max_ac_internal_nodes *
00424 sizeof(WN *));
00425 FmtAssert (ac_internals != NULL, ("No more memory."));
00426 } else if (max_ac_internal_nodes == num_ac_internal_nodes + 1) {
00427 max_ac_internal_nodes *= 2;
00428 ac_internals = (WN **) realloc(ac_internals,
00429 max_ac_internal_nodes *
00430 sizeof(WN **));
00431 FmtAssert(ac_internals != NULL, ("No more memory."));
00432 }
00433 ac_internals[num_ac_internal_nodes++] = node;
00434 }
00435 }
00436
00437 if (set_offset)
00438 WN_MAP32_Set(off_map, node, node_offset - base_offset);
00439
00440 }
00441 #endif
00442 #if defined(KEY) && !defined(FRONT_END) && !defined(IR_TOOLS)
00443
00444 if (Get_ipa_tlog_phase() == PHASE_IPA && WN_operator(node) == OPR_REGION
00445 && WN_region_is_EH (node) && WN_block_empty (WN_region_pragmas (node)))
00446 {
00447 FmtAssert (pu, ("Null pu info"));
00448
00449 IPA_NODE * cg_node = Get_Node_From_PU (pu);
00450 Is_True (cg_node, ("Null ipa node"));
00451
00452 if (!cg_node->Is_PU_Write_Complete() && !cg_node->EHinfo_Updated())
00453 {
00454
00455
00456 Is_True (PU_src_lang (cg_node->Get_PU()) & PU_CXX_LANG,
00457 ("Exception region in non-C++ PU"));
00458
00459 int sym_size;
00460 SUMMARY_SYMBOL * sym_array = IPA_get_symbol_file_array (cg_node->File_Header(), sym_size);
00461 Is_True (sym_array != NULL, ("Missing SUMMARY_SYMBOL section"));
00462 INITV_IDX types = INITV_next (INITV_blk (INITO_val (WN_ereg_supp (node))));
00463 for (; types; types = INITV_next (types))
00464 {
00465 if (INITV_kind (types) == INITVKIND_ZERO)
00466 continue;
00467 int index = TCON_uval (INITV_tc_val (types));
00468 if (index <= 0) continue;
00469 ST_IDX new_idx = sym_array[index].St_idx();
00470 INITV_IDX next = INITV_next (types);
00471 INITV_Set_VAL (Initv_Table[types], Enter_tcon (
00472 Host_To_Targ (MTYPE_U4, new_idx)), 1);
00473 Set_INITV_next (types, next);
00474 }
00475 }
00476 }
00477 #endif
00478
00479
00480 if (opcode == OPC_BLOCK) {
00481 register off_t prev, this_node;
00482
00483 if (WN_first(node) == 0) {
00484 WN_first(WN_ADDR(node_offset)) = (WN *) -1;
00485 WN_last(WN_ADDR(node_offset)) = (WN *) -1;
00486 } else {
00487 register WN *wn = WN_first (node);
00488 #if defined(KEY) && !defined(FRONT_END) && !defined(IR_TOOLS)
00489 prev = ir_b_write_tree(wn, base_offset, fl, off_map, pu);
00490 #else
00491 prev = ir_b_write_tree(wn, base_offset, fl, off_map);
00492 #endif
00493 WN_first(WN_ADDR(node_offset)) = (WN *) (INTPTR) prev;
00494
00495 while (wn = WN_next(wn)) {
00496 #if defined(KEY) && !defined(FRONT_END) && !defined(IR_TOOLS)
00497 this_node = ir_b_write_tree(wn, base_offset, fl, off_map, pu);
00498 #else
00499 this_node = ir_b_write_tree(wn, base_offset, fl, off_map);
00500 #endif
00501
00502 WN_next(WN_ADDR(prev + base_offset)) = (WN *) (INTPTR) this_node;
00503 WN_prev(WN_ADDR(this_node + base_offset)) = (WN *)(INTPTR)prev;
00504 prev = this_node;
00505 }
00506
00507 WN_last(WN_ADDR(node_offset)) = (WN *) (INTPTR) prev;
00508 }
00509 } else if (!OPCODE_is_leaf(opcode)) {
00510 register int i;
00511
00512 for (i = 0; i < WN_kid_count(node); i++) {
00513 register off_t kid;
00514
00515 if (WN_kid(node, i) == 0) {
00516 WN_kid(WN_ADDR(node_offset), i) = (WN *) -1;
00517 } else {
00518 #if defined(KEY) && !defined(FRONT_END) && !defined(IR_TOOLS)
00519 kid = ir_b_write_tree (WN_kid(node, i), base_offset,
00520 fl, off_map, pu);
00521 #else
00522 kid = ir_b_write_tree (WN_kid(node, i), base_offset,
00523 fl, off_map);
00524 #endif
00525 WN_kid(WN_ADDR(node_offset), i) = (WN *) (INTPTR) kid;
00526 }
00527 }
00528 }
00529
00530 if (OPCODE_has_next_prev(opcode)) {
00531
00532 WN_prev(WN_ADDR(node_offset)) = (WN *) -1;
00533 WN_next(WN_ADDR(node_offset)) = (WN *) -1;
00534 }
00535
00536 return node_offset - base_offset;
00537 }
00538
00539
00540
00541
00542
00543 template <class T>
00544 struct WRITE_TABLE_OP
00545 {
00546 Output_File *fl;
00547
00548 void operator () (UINT, T *t, UINT size) const {
00549 (void) ir_b_save_buf (t, size * sizeof(T), __ALIGNOF(T), 0, fl);
00550 }
00551
00552 WRITE_TABLE_OP (Output_File *_fl) : fl (_fl) {}
00553 };
00554
00555
00556 template <class TABLE>
00557 static off_t
00558 write_table (TABLE& fld, off_t base_offset,
00559 Output_File *fl)
00560 {
00561 off_t cur_offset = ir_b_align (fl->file_size, __ALIGNOF(typename TABLE::base_type),
00562 0);
00563 fl->file_size = ir_b_align (fl->file_size, __ALIGNOF(typename TABLE::base_type), 0);
00564
00565 #ifndef __GNUC__
00566 const WRITE_TABLE_OP<TABLE::base_type> write_table_op(fl);
00567 #else
00568 const WRITE_TABLE_OP<typename TABLE::base_type> write_table_op(fl);
00569 #endif
00570
00571 For_all_blocks (fld, write_table_op);
00572
00573 return cur_offset - base_offset;
00574 }
00575
00576
00577 static off_t
00578 write_file_info (off_t base_offset, Output_File *fl)
00579 {
00580 off_t cur_offset = ir_b_align (fl->file_size, __ALIGNOF(FILE_INFO), 0);
00581 ir_b_save_buf (&File_info, sizeof(File_info), __ALIGNOF(File_info), 0, fl);
00582
00583 return cur_offset - base_offset;
00584 }
00585
00586
00587
00588 off_t
00589 ir_b_write_global_symtab (off_t base_offset, Output_File *fl)
00590 {
00591 GLOBAL_SYMTAB_HEADER_TABLE gsymtab;
00592
00593
00594
00595 const off_t symtab_offset =
00596 ir_b_reserve_space (sizeof(gsymtab), sizeof(mUINT64), fl);
00597
00598 off_t cur_offset;
00599 UINT i = 0;
00600 const UINT idx = GLOBAL_SYMTAB;
00601
00602 cur_offset = write_file_info (symtab_offset, fl);
00603 gsymtab.header[i++].Init (cur_offset, sizeof(FILE_INFO),
00604 sizeof(FILE_INFO), __ALIGNOF(FILE_INFO),
00605 SHDR_FILE);
00606
00607 cur_offset = write_table (*(Scope_tab[idx].st_tab), symtab_offset, fl);
00608 gsymtab.header[i++].Init (cur_offset,
00609 Scope_tab[idx].st_tab->Size () * sizeof(ST),
00610 sizeof(ST), __ALIGNOF(ST), SHDR_ST);
00611
00612
00613
00614 cur_offset = write_table (Ty_tab, symtab_offset, fl);
00615 gsymtab.header[i++].Init (cur_offset, Ty_tab.Size () * sizeof(TY),
00616 sizeof(TY), __ALIGNOF(TY), SHDR_TY);
00617
00618 cur_offset = write_table (Pu_Table, symtab_offset, fl);
00619 gsymtab.header[i++].Init (cur_offset, Pu_Table.Size () * sizeof(PU),
00620 sizeof(PU), __ALIGNOF(PU), SHDR_PU);
00621
00622 cur_offset = write_table (Fld_Table, symtab_offset, fl);
00623 gsymtab.header[i++].Init (cur_offset, Fld_Table.Size () * sizeof(FLD),
00624 sizeof(FLD), __ALIGNOF(FLD), SHDR_FLD);
00625
00626 cur_offset = write_table (Arb_Table, symtab_offset, fl);
00627 gsymtab.header[i++].Init (cur_offset, Arb_Table.Size () * sizeof(ARB),
00628 sizeof(ARB), __ALIGNOF(ARB), SHDR_ARB);
00629
00630 cur_offset = write_table (Tylist_Table, symtab_offset, fl);
00631 gsymtab.header[i++].Init (cur_offset,
00632 Tylist_Table.Size () * sizeof(TYLIST),
00633 sizeof(TYLIST), __ALIGNOF(TYLIST), SHDR_TYLIST);
00634
00635 cur_offset = write_table (Tcon_Table, symtab_offset, fl);
00636 gsymtab.header[i++].Init (cur_offset, Tcon_Table.Size () * sizeof(TCON),
00637 sizeof(TCON), __ALIGNOF(TCON), SHDR_TCON);
00638
00639 cur_offset = ir_b_save_buf (TCON_strtab_buffer (), TCON_strtab_size (),
00640 1, 0, fl) - symtab_offset;
00641 gsymtab.header[i++].Init (cur_offset, TCON_strtab_size (), 1, 1, SHDR_STR);
00642
00643 cur_offset = write_table (*(Scope_tab[idx].inito_tab), symtab_offset, fl);
00644 gsymtab.header[i++].Init (cur_offset,
00645 Scope_tab[idx].inito_tab->Size () * sizeof(INITO),
00646 sizeof(INITO), __ALIGNOF(INITO), SHDR_INITO);
00647
00648 cur_offset = write_table (Initv_Table, symtab_offset, fl);
00649 gsymtab.header[i++].Init (cur_offset, Initv_Table.Size () * sizeof(INITV),
00650 sizeof(INITV), __ALIGNOF(INITV), SHDR_INITV);
00651
00652 cur_offset = write_table (Blk_Table, symtab_offset, fl);
00653 gsymtab.header[i++].Init (cur_offset, Blk_Table.Size () * sizeof(BLK),
00654 sizeof(BLK), __ALIGNOF(BLK), SHDR_BLK);
00655
00656 cur_offset = write_table (*(Scope_tab[idx].st_attr_tab), symtab_offset, fl);
00657 gsymtab.header[i++].Init (cur_offset,
00658 Scope_tab[idx].st_attr_tab->Size () * sizeof(ST_ATTR),
00659 sizeof(ST_ATTR), __ALIGNOF(ST_ATTR), SHDR_ST_ATTR);
00660
00661 save_buf_at_offset (&gsymtab, sizeof(gsymtab), symtab_offset, fl);
00662
00663 return symtab_offset - base_offset;
00664
00665 }
00666
00667 off_t
00668 ir_b_write_local_symtab (const SCOPE& pu, off_t base_offset, Output_File *fl)
00669 {
00670 LOCAL_SYMTAB_HEADER_TABLE symtab;
00671
00672 const off_t symtab_offset =
00673 ir_b_reserve_space (sizeof(symtab), sizeof(mUINT64), fl);
00674
00675 UINT i = 0;
00676 off_t cur_offset;
00677
00678 cur_offset = write_table (*pu.st_tab, symtab_offset, fl);
00679 symtab.header[i++].Init (cur_offset, pu.st_tab->Size () * sizeof(ST),
00680 sizeof(ST), __ALIGNOF(ST), SHDR_ST);
00681
00682 cur_offset = write_table (*pu.label_tab, symtab_offset, fl);
00683 symtab.header[i++].Init (cur_offset, pu.label_tab->Size () * sizeof(LABEL),
00684 sizeof(LABEL), __ALIGNOF(LABEL), SHDR_LABEL);
00685
00686 cur_offset = write_table (*pu.preg_tab, symtab_offset, fl);
00687 symtab.header[i++].Init (cur_offset, pu.preg_tab->Size () * sizeof(PREG),
00688 sizeof(PREG), __ALIGNOF(PREG), SHDR_PREG);
00689
00690 cur_offset = write_table (*pu.inito_tab, symtab_offset, fl);
00691 symtab.header[i++].Init (cur_offset, pu.inito_tab->Size () * sizeof(INITO),
00692 sizeof(INITO), __ALIGNOF(INITO), SHDR_INITO);
00693
00694 cur_offset = write_table (*pu.st_attr_tab, symtab_offset, fl);
00695 symtab.header[i++].Init (cur_offset, pu.st_attr_tab->Size () * sizeof(ST_ATTR),
00696 sizeof(ST_ATTR), __ALIGNOF(ST_ATTR), SHDR_ST_ATTR);
00697
00698 save_buf_at_offset (&symtab, sizeof(symtab), symtab_offset, fl);
00699
00700 return symtab_offset - base_offset;
00701
00702 }
00703
00704
00705
00706 extern off_t
00707 ir_b_write_dst (DST_TYPE dst, off_t base_offset, Output_File *fl)
00708 {
00709 off_t cur_offset;
00710 DST_BLOCK_IDX i;
00711 block_header *dst_blocks;
00712 Current_DST = dst;
00713
00714 dst_blocks = ((DST_Type *)dst)->dst_blocks;
00715 FOREACH_DST_BLOCK(i) {
00716
00717 cur_offset = ir_b_save_buf (dst_blocks[i].offset,
00718 dst_blocks[i].size, __ALIGNOF(INT64), 0, fl);
00719
00720 dst_blocks[i].offset = (char*)(INTPS)(cur_offset - base_offset);
00721 }
00722 FOREACH_DST_BLOCK(i) {
00723 cur_offset = ir_b_save_buf
00724 ((char*)&dst_blocks[i], sizeof(block_header),
00725 __ALIGNOF(block_header), 0, fl);
00726 }
00727 cur_offset = ir_b_save_buf
00728 ((char*)&((DST_Type *)dst)->last_block_header, sizeof(mINT32),
00729 __ALIGNOF(INT32), 0, fl);
00730 return cur_offset - base_offset;
00731 }
00732
00733 #if defined(KEY) && defined(BACK_END)
00734
00735 #define HEADER_ADDR(offset) \
00736 ((Elf64_Word*)(fl->map_addr + offset))
00737
00738
00739
00740 void
00741 IPA_irb_write_mod_ref_info(Output_File *fl)
00742 {
00743 INT offset, header_loc;
00744
00745 INT offset_mod_ref = 0;
00746
00747 Elf64_Word temp;
00748
00749 INT size = Mod_Ref_Info_Table_Size();
00750
00751 FmtAssert (size, ("IPA_irb_write_mod_ref_info: No MOD/REF information"));
00752
00753 INT cur_sec_disp = fl->file_size;
00754
00755
00756 header_loc = (INT) ir_b_save_buf(&temp, sizeof(Elf64_Word),
00757 sizeof(INT64),0,fl);
00758
00759
00760
00761
00762 offset_mod_ref = ir_b_save_buf (
00763 &Mod_Ref_Info_Table[0].pu_idx,
00764 sizeof(PU_IDX),
00765 sizeof(INT64),
00766 0,
00767 fl);
00768
00769
00770 ir_b_save_buf (&Mod_Ref_Info_Table[0].size,
00771 sizeof(mUINT32),
00772 0,
00773 0,
00774 fl);
00775
00776
00777 ir_b_save_buf (Mod_Ref_Info_Table[0].mod,
00778 Mod_Ref_Info_Table[0].size,
00779 0,
00780 0,
00781 fl);
00782
00783
00784 ir_b_save_buf (Mod_Ref_Info_Table[0].ref,
00785 Mod_Ref_Info_Table[0].size,
00786 0,
00787 0,
00788 fl);
00789
00790 for (INT i=1; i<size; i++)
00791 {
00792 ir_b_save_buf (&Mod_Ref_Info_Table[i].pu_idx,
00793 sizeof(PU_IDX), 0, 0, fl);
00794
00795 ir_b_save_buf (&Mod_Ref_Info_Table[i].size,
00796 sizeof(mUINT32), 0, 0, fl);
00797
00798 ir_b_save_buf (Mod_Ref_Info_Table[i].mod,
00799 Mod_Ref_Info_Table[i].size, 0, 0, fl);
00800
00801 ir_b_save_buf (Mod_Ref_Info_Table[i].ref,
00802 Mod_Ref_Info_Table[i].size, 0, 0, fl);
00803 }
00804
00805 offset_mod_ref = offset_mod_ref - cur_sec_disp;
00806
00807 BE_SUMMARY_HEADER header;
00808 offset = (INT)ir_b_save_buf(&header, sizeof(BE_SUMMARY_HEADER),
00809 sizeof(INT64), 0, fl);
00810
00811 *(HEADER_ADDR(header_loc)) = offset - cur_sec_disp;
00812 BE_SUMMARY_HEADER *header_addr =
00813 (BE_SUMMARY_HEADER *)(fl->map_addr + offset);
00814
00815 header_addr->offset = offset_mod_ref;
00816 header_addr->size = size;
00817 header_addr->entsize = sizeof(pu_mod_ref_info);
00818 }
00819 #endif