Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ir_bcom.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 #ifdef USE_PCH
00037 #include "common_com_pch.h"
00038 #endif /* USE_PCH */
00039 #pragma hdrstop
00040 #include <unistd.h>                 /* for unlink() */
00041 #include <sys/mman.h>               /* for mmap() */
00042 #include <string.h>                 /* for strerror() */
00043 #include <errno.h>                  /* for errno */
00044 #include <elf.h>                    /* for all Elf stuff */
00045 #include <sys/elf_whirl.h>          /* for WHIRL sections' sh_info */
00046 
00047 // Solaric CC workaround
00048 // no big deal, just to fix a compiler warning
00049 #ifndef USE_STANDARD_TYPES
00050 #define USE_STANDARD_TYPES          /* override unwanted defines in "defs.h" */
00051 #endif
00052 
00053 #include "defs.h"
00054 #include "alignof.h"                /* for ALIGNOF() */
00055 #include "erglob.h"
00056 #include "errors.h"                 /* for ErrMsg() */
00057 #include "opcode.h"
00058 #include "mempool.h"
00059 #include "wn.h"
00060 #include "wn_map.h"
00061 #include "strtab.h"                 /* for strtab */
00062 #include "symtab.h"                 /* for symtab */
00063 #include "irbdata.h"                /* for inito */
00064 #define USE_DST_INTERNALS
00065 #include "dwarf_DST_mem.h"          /* for dst */
00066 #include "pu_info.h"
00067 #include "ir_bwrite.h"
00068 #include "ir_bcom.h"
00069 #include <vector>
00070 
00071 /* For 4K page, each kernel page maps to 4Mbytes user address space */
00072 #define MAPPED_SIZE             0x400000
00073 #define INIT_TMP_MAPPED_SIZE    MAPPED_SIZE
00074 
00075 #ifdef BACK_END
00076 #define DEFAULT_NUM_OF_PREFETCHES 64
00077 WN **prefetch_ldsts;
00078 INT num_prefetch_ldsts;
00079 INT max_num_prefetch_ldsts;
00080 
00081 #define DEFAULT_NUM_ALIAS_CLASSES 128
00082 WN **alias_classes;
00083 INT num_alias_class_nodes;
00084 INT max_alias_class_nodes;
00085 
00086 #define DEFAULT_NUM_AC_INTERNALS 128
00087 WN **ac_internals;
00088 INT num_ac_internal_nodes;
00089 INT max_ac_internal_nodes;
00090 #endif
00091 
00092 
00093 char *Whirl_Revision = WHIRL_REVISION;
00094 
00095 /* This variable is used by IPAA to pass its local map information
00096  * to ir_bwrite.c, and by ir_bread.c to pass it to WOPT:
00097  */
00098 void *IPAA_Local_Map = NULL;
00099 
00100 BOOL Doing_mmapped_io = FALSE;
00101 
00102 /* copy a block of memory into the temporary file.
00103  * "align" is the alignment requirement, which must be a power of 2.
00104  * "padding" is the byte offset from the beginning of the buffer that the
00105  * alignment requirement applies.
00106  *
00107  * It returns the file offset corresponding to buf + padding.
00108  */
00109 extern Elf64_Word
00110 ir_b_save_buf (const void *buf, Elf64_Word size, unsigned int align,
00111                unsigned int padding, Output_File *fl)
00112 {
00113     Current_Output = fl;
00114 
00115     off_t file_size = ir_b_align (fl->file_size, align, padding);
00116 
00117     if (file_size + size >= fl->mapped_size)
00118         ir_b_grow_map (file_size + size - fl->file_size, fl);
00119 
00120     Doing_mmapped_io = TRUE;
00121     (void *)memcpy(fl->map_addr + file_size, buf, size);
00122     Doing_mmapped_io = FALSE;
00123 
00124     fl->file_size = file_size + size;
00125     return file_size + padding;
00126 } /* ir_b_save_buf */
00127 
00128 /* copy a file into the temporary file.
00129  */
00130 extern Elf64_Word
00131 ir_b_copy_file (const void *buf, Elf64_Word size, void *tmpfl)
00132 {
00133     Output_File* fl = (Output_File*)tmpfl;
00134 
00135     Current_Output = fl;
00136 
00137     if (size >= fl->mapped_size)
00138         ir_b_grow_map (size, fl);
00139     
00140     Doing_mmapped_io = TRUE;
00141     memcpy (fl->map_addr, buf, size);
00142     Doing_mmapped_io = FALSE;
00143     fl->file_size = size;
00144     return size;
00145 } // ir_b_copy_file 
00146 
00147 
00148 static void
00149 save_buf_at_offset (const void *buf, Elf64_Word size, off_t offset,
00150                     Output_File *fl)
00151 {
00152     Is_True (offset + size <= fl->mapped_size, ("Invalid buffer size"));
00153 
00154     Doing_mmapped_io = TRUE;
00155     memcpy (fl->map_addr + offset, buf, size);
00156     Doing_mmapped_io = FALSE;
00157 } // save_buf_at_offset
00158 
00159 // similar to ir_b_save_buf, except that no actual copying is done, but
00160 // file space is reserved.
00161 static Elf64_Word
00162 ir_b_reserve_space (Elf64_Word size, unsigned int align, Output_File *fl)
00163 {
00164     off_t file_size = ir_b_align (fl->file_size, align, 0);
00165 
00166     if (file_size + size >= fl->mapped_size)
00167         ir_b_grow_map (file_size + size - fl->file_size, fl);
00168 
00169     fl->file_size = file_size + size;
00170     return file_size;
00171 } // ir_b_reserve_space
00172 
00173 
00174 /* increase the mmap size.  It is faster if we first unmap the region and
00175  * then map it again with a larger size.  The overhead for maintaining
00176  * multiple regions (by the kernel) outweighs that of extra system calls.
00177  * Also, we get a contiguous address space for the file this way.
00178  */
00179 char *
00180 ir_b_grow_map (Elf64_Word min_size, Output_File *fl)
00181 {
00182     Is_True (fl->map_addr != 0, ("output file not yet mapped"));
00183 
00184     if (munmap (fl->map_addr, fl->mapped_size) == -1)
00185         ErrMsg (EC_IR_Write, fl->file_name, errno);
00186     min_size += fl->file_size;
00187     while (fl->mapped_size < min_size) {
00188         if (fl->mapped_size < MAPPED_SIZE)
00189             fl->mapped_size = MAPPED_SIZE;
00190         else
00191             fl->mapped_size += MAPPED_SIZE;
00192     }
00193 
00194 #if defined(__sgi)
00195     // Only SGI supports 'MAP_AUTOGROW' for mmap()
00196     fl->map_addr = (char *) mmap (0, fl->mapped_size, PROT_READ|PROT_WRITE,
00197                                   MAP_SHARED|MAP_AUTOGROW, fl->output_fd, 0); 
00198 #else
00199     // mmap() normally cannot automatically increase file size, so we
00200     // allocate some space using ftruncate().  SGI's mmap() can avoid
00201     // this. cf. use of ftruncate() in ir_bwrite.cxx.
00202     if (ftruncate(fl->output_fd, fl->mapped_size)) {
00203         ErrMsg (EC_IR_Write, fl->file_name, strerror(errno));
00204     }
00205     fl->map_addr = (char *) mmap (0, fl->mapped_size, PROT_READ|PROT_WRITE,
00206                                   MAP_SHARED, fl->output_fd, 0); 
00207 #endif    
00208     
00209     if (fl->map_addr == (char *) (-1))
00210         ErrMsg (EC_IR_Write, fl->file_name, strerror(errno));
00211 
00212     return fl->map_addr;
00213 } /* ir_b_grow_map */
00214 
00215 extern char *
00216 ir_b_create_map (Output_File *fl)
00217 {
00218     int fd = fl->output_fd;
00219     fl->mapped_size = INIT_TMP_MAPPED_SIZE;
00220 
00221 #if defined(__sgi)
00222     // Only SGI supports 'MAP_AUTOGROW' for mmap()
00223     fl->map_addr = (char *) mmap (0, fl->mapped_size, PROT_READ|PROT_WRITE,
00224                                   MAP_SHARED|MAP_AUTOGROW, fl->output_fd, 0);
00225 #else
00226     fl->map_addr = (char *) mmap (0, fl->mapped_size, PROT_READ|PROT_WRITE,
00227                                   MAP_SHARED, fl->output_fd, 0);
00228 #endif
00229     
00230     return fl->map_addr;
00231 } /* ir_b_create_map */
00232 
00233 
00234 WN *staticNode;
00235 
00236 /* Walk the tree and copy it to contiguous memory block in the temp. file */
00237 extern Elf64_Word
00238 ir_b_write_tree (WN *node, off_t base_offset, Output_File *fl, WN_MAP off_map)
00239 {
00240     register OPCODE opcode;
00241     Elf64_Word node_offset;
00242     char *real_addr;
00243 
00244     if (node == staticNode) abort();
00245 
00246     INT32 size = WN_Size_and_StartAddress (node, (void **) &real_addr);
00247 
00248 #define WN_ADDR(offset) ((WN *)(fl->map_addr + offset))
00249 
00250     node_offset = ir_b_save_buf (real_addr, size, ALIGNOF(WN),
00251                                  (char *)(node) - real_addr, fl); 
00252 
00253     opcode = (OPCODE) WN_opcode (node);
00254 
00255 #ifdef BACK_END
00256     if (off_map != WN_MAP_UNDEFINED &&
00257         (Write_BE_Maps ||
00258          Write_ALIAS_CLASS_Map ||
00259          Write_AC_INTERNAL_Map)) {
00260         /* save node_offset for use when writing maps */
00261         BOOL set_offset = FALSE;
00262         OPERATOR opr = OPCODE_operator(opcode);
00263 
00264         if (Write_BE_Maps) {
00265             if (opr == OPR_PREFETCH || opr == OPR_PREFETCHX ||
00266                 OPCODE_is_load (opcode) || OPCODE_is_store (opcode))
00267                 set_offset = TRUE;
00268 
00269             /* check if the WN has a prefetch pointer */
00270             if (WN_MAP_Get(WN_MAP_PREFETCH, node)) {
00271                 /* make sure the prefetch_ldsts array is big enough to hold the
00272                    lds and sts plus one extra slot to mark the end */
00273                 if (num_prefetch_ldsts == 0) {
00274                     max_num_prefetch_ldsts = DEFAULT_NUM_OF_PREFETCHES;
00275                     prefetch_ldsts =
00276                         (WN **)malloc(max_num_prefetch_ldsts * sizeof(WN*));
00277                     FmtAssert (prefetch_ldsts,
00278                                ("No more memory for allocation."));
00279                 } else if (max_num_prefetch_ldsts == num_prefetch_ldsts + 1) {
00280                     max_num_prefetch_ldsts *= 2;
00281                     prefetch_ldsts =
00282                         (WN **)realloc(prefetch_ldsts,
00283                                        max_num_prefetch_ldsts * sizeof(WN*));
00284                     FmtAssert (prefetch_ldsts,
00285                                ("No more memory for allocation."));
00286                 }
00287                 prefetch_ldsts[num_prefetch_ldsts] = node;
00288                 num_prefetch_ldsts += 1;
00289             }
00290         }
00291             
00292         if (Write_ALIAS_CLASS_Map) {
00293             if (OPCODE_is_store (opcode) ||
00294                 OPCODE_is_load (opcode) ||
00295                 (opr == OPR_LDA /* && LDA_has_ac_map_set(node) */) ||
00296                 opr == OPR_PARM) {
00297               set_offset = TRUE;
00298             }
00299 
00300             if (WN_MAP32_Get (WN_MAP_ALIAS_CLASS, node) != 0) {
00301                 if (alias_classes == NULL) {
00302                     max_alias_class_nodes = DEFAULT_NUM_ALIAS_CLASSES;
00303                     alias_classes = (WN **) malloc (max_alias_class_nodes *
00304                                                     sizeof(WN *));
00305                     FmtAssert (alias_classes != NULL, ("No more memory."));
00306                 } else if (max_alias_class_nodes == num_alias_class_nodes + 1) {
00307                     max_alias_class_nodes *= 2;
00308                     alias_classes = (WN **) realloc(alias_classes,
00309                                                     max_alias_class_nodes *
00310                                                     sizeof(WN **));
00311                     FmtAssert(alias_classes != NULL, ("No more memory."));
00312                 }
00313                 alias_classes[num_alias_class_nodes++] = node;
00314             }
00315         }
00316         
00317         if (Write_AC_INTERNAL_Map) {
00318             if (opr == OPR_ILOAD  ||
00319                 opr == OPR_MLOAD  ||
00320                 opr == OPR_PARM   ||
00321                 opr == OPR_ISTORE ||
00322                 opr == OPR_PSTORE ||   
00323                 opr == OPR_MSTORE) {
00324               set_offset = TRUE;
00325             }
00326 
00327             if (WN_MAP_Get (WN_MAP_AC_INTERNAL, node) != NULL) {
00328                 if (ac_internals == NULL) {
00329                     max_ac_internal_nodes = DEFAULT_NUM_AC_INTERNALS;
00330                     ac_internals = (WN **) malloc (max_ac_internal_nodes *
00331                                                    sizeof(WN *));
00332                     FmtAssert (ac_internals != NULL, ("No more memory."));
00333                 } else if (max_ac_internal_nodes == num_ac_internal_nodes + 1) {
00334                     max_ac_internal_nodes *= 2;
00335                     ac_internals = (WN **) realloc(ac_internals,
00336                                                    max_ac_internal_nodes *
00337                                                    sizeof(WN **));
00338                     FmtAssert(ac_internals != NULL, ("No more memory."));
00339                 }
00340                 ac_internals[num_ac_internal_nodes++] = node;
00341             }
00342         }
00343 
00344         if (set_offset)
00345             WN_MAP32_Set(off_map, node, node_offset - base_offset);
00346 
00347     }
00348 #endif /* BACK_END */
00349 
00350 
00351     if (opcode == OPC_BLOCK) {
00352         register Elf64_Word prev, this_node;
00353 
00354         if (WN_first(node) == 0) {
00355             WN_first(WN_ADDR(node_offset)) = (WN *) -1;
00356             WN_last(WN_ADDR(node_offset)) = (WN *) -1;
00357         } else {
00358             register WN *wn = WN_first (node);
00359             prev = ir_b_write_tree(wn, base_offset, fl, off_map);
00360             WN_first(WN_ADDR(node_offset)) = (WN *) prev;
00361 
00362             while (wn = WN_next(wn)) {
00363                 this_node = ir_b_write_tree(wn, base_offset, fl, off_map);
00364                 /* fill in the correct next/prev offsets (in place of -1) */
00365                 WN_next(WN_ADDR(prev + base_offset)) = (WN *) this_node;
00366                 WN_prev(WN_ADDR(this_node + base_offset)) = (WN *) prev;
00367                 prev = this_node;
00368             }
00369 
00370             WN_last(WN_ADDR(node_offset)) = (WN *) prev;
00371         }
00372     } else if (!OPCODE_is_leaf(opcode)) {
00373         register int i;
00374 
00375         for (i = 0; i < WN_kid_count(node); i++) {
00376             register Elf64_Word kid;
00377 
00378             if (WN_kid(node, i) == 0) {
00379                 WN_kid(WN_ADDR(node_offset), i) = (WN *) -1;
00380             } else {
00381                 kid = ir_b_write_tree (WN_kid(node, i), base_offset,
00382                                        fl, off_map);
00383                 WN_kid(WN_ADDR(node_offset), i) = (WN *) kid;
00384             }
00385         }
00386     }
00387 
00388     if (OPCODE_has_next_prev(opcode)) {
00389         /* just set the default values for now */
00390         WN_prev(WN_ADDR(node_offset)) = (WN *) -1;
00391         WN_next(WN_ADDR(node_offset)) = (WN *) -1;
00392     }
00393 
00394     return node_offset - base_offset;
00395 } /* ir_b_write_tree */
00396 
00397 
00398 /*------------ symtab routines ---------------*/
00399 
00400 // function object for writing out various symbol tables
00401 template <class T>
00402 struct WRITE_TABLE_OP
00403 {
00404     Output_File *fl;
00405 
00406     void operator () (UINT, T *t, UINT size) const {
00407         (void) ir_b_save_buf (t, size * sizeof(T), ALIGNOF(T), 0, fl); 
00408     }
00409 
00410     WRITE_TABLE_OP (Output_File *_fl) : fl (_fl) {}
00411 }; // WRITE_TABLE_OP
00412 
00413 
00414 template <class TABLE>
00415 Elf64_Word
00416 write_table (TABLE& fld, off_t base_offset,
00417              Output_File *fl)
00418 {
00419     off_t cur_offset = ir_b_align (fl->file_size, 
00420                                    ALIGNOF(typename TABLE::base_type), 0);
00421     fl->file_size = ir_b_align (fl->file_size, 
00422                                 ALIGNOF(typename TABLE::base_type), 0);
00423     
00424     const WRITE_TABLE_OP<typename TABLE::base_type> write_table_op(fl);
00425 
00426     For_all_blocks (fld, write_table_op);
00427     return cur_offset - base_offset;
00428 } // write_table
00429 
00430 
00431 static Elf64_Word
00432 write_file_info (off_t base_offset, Output_File *fl)
00433 {
00434     off_t cur_offset = ir_b_align (fl->file_size, ALIGNOF(FILE_INFO), 0);
00435 
00436     ir_b_save_buf (&File_info, sizeof(File_info), ALIGNOF(FILE_INFO), 0, fl);
00437 
00438     return cur_offset - base_offset;
00439 } // write_file_info
00440 
00441 
00442 // write a global symtab:  
00443 Elf64_Word
00444 ir_b_write_global_symtab (off_t base_offset, Output_File *fl)
00445 {
00446     GLOBAL_SYMTAB_HEADER_TABLE gsymtab;
00447 
00448     // should use __builtin_alignof(gsymtab) instead of sizeof(mUINT64),
00449     // but our frontend has a bug and fails to compile it. 
00450     const Elf64_Word symtab_offset =
00451         ir_b_reserve_space (sizeof(gsymtab), sizeof(mUINT64), fl);
00452 
00453     Elf64_Word cur_offset;
00454     UINT i = 0;
00455     const UINT idx = GLOBAL_SYMTAB;
00456 
00457     cur_offset = write_file_info (symtab_offset, fl);
00458     gsymtab.header[i++].Init (cur_offset, sizeof(FILE_INFO),
00459                               sizeof(FILE_INFO), ALIGNOF(FILE_INFO),
00460                               SHDR_FILE);
00461 
00462     cur_offset = write_table (*(Scope_tab[idx].st_tab), symtab_offset, fl);
00463     gsymtab.header[i++].Init (cur_offset,
00464                               Scope_tab[idx].st_tab->Size () * sizeof(ST),
00465                               sizeof(ST), ALIGNOF(ST), SHDR_ST);
00466 
00467     // call fix_array_ty?
00468 
00469     cur_offset = write_table (Ty_tab, symtab_offset, fl);
00470     gsymtab.header[i++].Init (cur_offset, Ty_tab.Size () * sizeof(TY),
00471                               sizeof(TY), ALIGNOF(TY), SHDR_TY);
00472 
00473     cur_offset = write_table (Pu_Table, symtab_offset, fl);
00474     gsymtab.header[i++].Init (cur_offset, Pu_Table.Size () * sizeof(PU),
00475                               sizeof(PU), ALIGNOF(PU), SHDR_PU);
00476 
00477     cur_offset = write_table (Fld_Table, symtab_offset, fl);
00478     gsymtab.header[i++].Init (cur_offset, Fld_Table.Size () * sizeof(FLD),
00479                               sizeof(FLD), ALIGNOF(FLD), SHDR_FLD);
00480 
00481     cur_offset = write_table (Arb_Table, symtab_offset, fl);
00482     gsymtab.header[i++].Init (cur_offset, Arb_Table.Size () * sizeof(ARB),
00483                               sizeof(ARB), ALIGNOF(ARB), SHDR_ARB);
00484 
00485     cur_offset = write_table (Tylist_Table, symtab_offset, fl);
00486     gsymtab.header[i++].Init (cur_offset,
00487                               Tylist_Table.Size () * sizeof(TYLIST),
00488                               sizeof(TYLIST), ALIGNOF(TYLIST), SHDR_TYLIST); 
00489 
00490     cur_offset = write_table (Tcon_Table, symtab_offset, fl);
00491     gsymtab.header[i++].Init (cur_offset, Tcon_Table.Size () * sizeof(TCON),
00492                               sizeof(TCON), ALIGNOF(TCON), SHDR_TCON); 
00493 
00494     cur_offset = ir_b_save_buf (TCON_strtab_buffer (), TCON_strtab_size (),
00495                                 1, 0, fl) - symtab_offset;
00496     gsymtab.header[i++].Init (cur_offset, TCON_strtab_size (), 1, 1, SHDR_STR);
00497 
00498     cur_offset = write_table (*(Scope_tab[idx].inito_tab), symtab_offset, fl);
00499     gsymtab.header[i++].Init (cur_offset,
00500                               Scope_tab[idx].inito_tab->Size () * sizeof(INITO),
00501                               sizeof(INITO), ALIGNOF(INITO), SHDR_INITO);
00502 
00503     cur_offset = write_table (Initv_Table, symtab_offset, fl);
00504     gsymtab.header[i++].Init (cur_offset, Initv_Table.Size () * sizeof(INITV),
00505                               sizeof(INITV), ALIGNOF(INITV), SHDR_INITV); 
00506 
00507     cur_offset = write_table (Blk_Table, symtab_offset, fl);
00508     gsymtab.header[i++].Init (cur_offset, Blk_Table.Size () * sizeof(BLK),
00509                               sizeof(BLK), ALIGNOF(BLK), SHDR_BLK); 
00510 
00511     cur_offset = write_table (*(Scope_tab[idx].st_attr_tab), symtab_offset, fl);
00512     gsymtab.header[i++].Init (cur_offset,
00513                               Scope_tab[idx].st_attr_tab->Size () * sizeof(ST_ATTR),
00514                               sizeof(ST_ATTR), ALIGNOF(ST_ATTR), SHDR_ST_ATTR);
00515 
00516     save_buf_at_offset (&gsymtab, sizeof(gsymtab), symtab_offset, fl);
00517 
00518     return symtab_offset - base_offset;
00519 
00520 } // ir_b_write_global_symtab
00521 
00522 Elf64_Word
00523 ir_b_write_local_symtab (const SCOPE& pu, off_t base_offset, Output_File *fl)
00524 {
00525 
00526     LOCAL_SYMTAB_HEADER_TABLE symtab;
00527 
00528     const Elf64_Word symtab_offset =
00529         ir_b_reserve_space (sizeof(symtab), sizeof(mUINT64), fl);
00530 
00531     UINT i = 0;
00532     Elf64_Word cur_offset;
00533     cur_offset = write_table (*pu.st_tab, symtab_offset, fl);
00534     symtab.header[i++].Init (cur_offset, pu.st_tab->Size () * sizeof(ST),
00535                              sizeof(ST), ALIGNOF(ST), SHDR_ST);
00536 
00537     cur_offset = write_table (*pu.label_tab, symtab_offset, fl);
00538     symtab.header[i++].Init (cur_offset, pu.label_tab->Size () * sizeof(LABEL),
00539                              sizeof(LABEL), ALIGNOF(LABEL), SHDR_LABEL); 
00540 
00541     cur_offset = write_table (*pu.preg_tab, symtab_offset, fl);
00542     symtab.header[i++].Init (cur_offset, pu.preg_tab->Size () * sizeof(PREG),
00543                              sizeof(PREG), ALIGNOF(PREG), SHDR_PREG);
00544 
00545     cur_offset = write_table (*pu.inito_tab, symtab_offset, fl);
00546     symtab.header[i++].Init (cur_offset, pu.inito_tab->Size () * sizeof(INITO),
00547                              sizeof(INITO), ALIGNOF(INITO), SHDR_INITO);
00548     
00549     cur_offset = write_table (*pu.st_attr_tab, symtab_offset, fl);
00550     symtab.header[i++].Init (cur_offset, pu.st_attr_tab->Size () * sizeof(ST_ATTR),  
00551                                 sizeof(ST_ATTR), ALIGNOF(ST_ATTR), SHDR_ST_ATTR);
00552 
00553     save_buf_at_offset (&symtab, sizeof(symtab), symtab_offset, fl);
00554 
00555     return symtab_offset - base_offset;
00556 
00557 } // ir_b_write_local_symtab
00558 
00559 
00560 /* write blocks of data, then block headers, then # blocks */
00561 extern Elf64_Word
00562 ir_b_write_dst (DST_TYPE dst, off_t base_offset, Output_File *fl)
00563 {
00564   vector<char *> savedOffsets;
00565   Elf64_Word cur_offset;
00566   DST_BLOCK_IDX i;
00567   block_header *dst_blocks;
00568   Current_DST = dst;
00569   
00570   dst_blocks = ((DST_Type *)dst)->dst_blocks;
00571   FOREACH_DST_BLOCK(i) {
00572     /* may have 64-bit data fields, so align at 8 bytes */
00573     savedOffsets.push_back(dst_blocks[i].offset);
00574     cur_offset = ir_b_save_buf (dst_blocks[i].offset, 
00575                                 dst_blocks[i].size, ALIGNOF(INT64), 0, fl);
00576     dst_blocks[i].offset = (char*)(cur_offset - base_offset);
00577   } 
00578   FOREACH_DST_BLOCK(i) {
00579     cur_offset = ir_b_save_buf
00580       ((char*)&dst_blocks[i], sizeof(block_header),
00581        ALIGNOF(block_header), 0, fl);
00582   } 
00583   cur_offset = ir_b_save_buf
00584     ((char*)&((DST_Type *)dst)->last_block_header, sizeof(mINT32), 
00585      ALIGNOF(INT32), 0, fl);
00586 
00587 
00588   // restore dst_blocks offsets
00589   FOREACH_DST_BLOCK(i) {
00590     dst_blocks[i].offset = savedOffsets[i];
00591   }
00592   
00593   return cur_offset - base_offset;
00594 }
00595 
00596 
00597 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines