1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
|
/* $Header: d:/cvsroot/tads/tads3/vmwrtimg.h,v 1.4 1999/07/11 00:46:59 MJRoberts Exp $ */
/*
* Copyright (c) 1999, 2002 Michael J. Roberts. All Rights Reserved.
*
* Please see the accompanying license file, LICENSE.TXT, for information
* on using and copying this software.
*/
/*
Name
vmwrtimg.h - T3 Image File Writer utility functions
Function
Notes
Modified
04/04/99 MJRoberts - Creation
*/
#ifndef VMWRTIMG_H
#define VMWRTIMG_H
#include "t3std.h"
#include "vmtype.h"
class CVmImageWriter
{
public:
/* create an image writer with a given output file */
CVmImageWriter(class CVmFile *fp);
/* delete the image writer */
~CVmImageWriter();
/* get the current seek location in the underlying file */
long get_pos() const;
/*
* Prepare the file: write out the fixed header information. This
* should be called once, before doing any other writing. 'vsn' is
* the image file version number to store in the file.
*/
void prepare(uint vsn, const char tool_data[4]);
/*
* Begin a block with the specified ID (a four-byte string). Writes
* the block header, and remembers where the block starts so that
* the size prefix can be stored when the block is finished. Blocks
* cannot be nested; starting a new block automatically ends the
* previous block.
*/
void begin_block(const char *block_id, int mandatory);
/*
* End the current block.
*/
void end_block();
/* write raw bytes to the image file */
void write_bytes(const char *ptr, uint32_t siz);
/*
* Write a complete entrypoint block, given the code offset of the
* entrypoint and the various table entry sizes. If a block is in
* progress, this will terminate it.
*/
void write_entrypt(uint32_t entry_ofs, size_t method_header_size,
size_t exc_entry_size, size_t line_entry_size,
size_t dbg_hdr_size, size_t dbg_lclsym_hdr_size,
size_t dbg_frame_hdr_size,
int dbg_vsn_id);
/*
* Write a complete function set dependency block, given an array of
* function set names. If a block is in progress, this will
* terminate it.
*/
void write_func_dep(const char **funcset_names, int count);
/*
* Write a complete metaclass dependency block, given an array of
* metaclass names. If a block is in progress, this will terminate
* it.
*/
void write_meta_dep(const char **metaclass_names, int count);
/*
* Write a metaclass dependency block in pieces. Call
* begin_meta_dep() with the number of metaclasses, then call
* write_meta_dep_item() to write each item, and finally call
* end_meta_dep() to finish the block.
*/
void begin_meta_dep(int count);
void write_meta_dep_item(const char *metaclass_name);
void write_meta_item_prop(uint prop_id);
void end_meta_prop_list();
void end_meta_dep();
/*
* Write a function set dependency block in pieces
*/
void begin_func_dep(int count)
{ begin_dep_block("FNSD", count); }
void write_func_dep_item(const char *funcset_name)
{ write_dep_block_item(funcset_name); }
void end_func_dep()
{ end_dep_block(); }
/*
* Write a constant pool definition block.
*/
void write_pool_def(uint pool_id, uint32_t page_count, uint32_t page_size,
int mandatory);
/*
* Fix up a constant pool definition block with the actual number of
* pages. This can be used, if desired, to wait to determine the
* actual number of pages in a given constant pool until after
* writing the pages. Since the pool definition block must precede
* the pool's first page block in the image file, it's impossible to
* wait until after writing all of the pages to write the definition
* block. Instead, the caller must write the pool definition block
* first, using a temporary placeholder value for the page_count (0
* will suffice), then write the pool pages, then use this to fix up
* the pool definition block with the actual number of pages. The
* caller must note the seek position prior to writing the pool
* definition block, so that we can seek back to that position to
* fix up the definition block.
*
* Callers need not use this function if they know the actual number
* of pages in the pool when writing the original pool definition
* block.
*/
void fix_pool_def(long def_seek_ofs, uint32_t page_count);
/*
* Write a constant/code pool page. This writes the entire page
* with its header and data in a single operation; this is the
* easiest way to write a page when the page has been fully
* constructed in a single memory block in advance.
*/
void write_pool_page(uint pool_id, uint32_t page_index,
const char *page_data, uint32_t page_data_size,
int mandatory, uchar xor_mask);
/*
* Write a constant/code pool page in pieces. These routines can be
* used when the data in the page are not contiguous in memory and
* must be written in pieces. Start by calling begin_pool_page(),
* then call write_pool_page_bytes() for each item; the items are
* written contiguously to the page. Finish by calling
* end_pool_page().
*/
void begin_pool_page(uint pool_id, uint32_t page_index, int mandatory,
uchar xor_mask);
void write_pool_page_bytes(const char *buf, uint32_t siz, uchar xor_mask);
void end_pool_page();
/*
* Write items in the symbolic names block. Start with
* begin_sym_block(), then call the write_sym_item_xxx() functions
* to write the names. Finally, call end_sym_block() when done.
*/
void begin_sym_block();
void write_sym_item_objid(const char *nm, size_t len, ulong obj_id);
void write_sym_item_propid(const char *nm, size_t len, uint prop_id);
void write_sym_item_func(const char *nm, size_t len, ulong code_ofs);
void write_sym_item(const char *nm, size_t nmlen,
const struct vm_val_t *val);
void write_sym_item_objid(const char *nm, ulong obj_id)
{ write_sym_item_objid(nm, get_strlen(nm), obj_id); }
void write_sym_item_propid(const char *nm, uint prop_id)
{ write_sym_item_propid(nm, get_strlen(nm), prop_id); }
void write_sym_item(const char *nm, const struct vm_val_t *val)
{ write_sym_item(nm, get_strlen(nm), val); }
void end_sym_block();
/*
* Write items in an OBJS (static object data) block. Start with
* begin_objs_block(), then call write_objs_bytes() repeatedly to
* write the bytes. Finally, call end_objs_block() when done.
*
* If the 'large_objects' field is set, the objects in the block use
* 32-bit size fields; otherwise the objects use 16-bit size fields.
*
* If 'trans' is true, the objects in this block are transient;
* otherwise, the objects are non-transient (i.e., persistent).
*/
void begin_objs_block(uint metaclass_idx, int large_objects, int trans);
void write_objs_bytes(const char *buf, uint32_t siz);
void end_objs_block(uint object_count);
/*
* Write the items in a SRCF (source file descriptor) block. Start
* with begin_srcf_block(), then write the file entries. For each
* entry, call begin_src_entry(), then call write_src_line_entry()
* for each source line debug record, then call end_srcf_entry().
* Call end_srcf_block() when done with all file entries.
*/
void begin_srcf_block(int count);
void begin_srcf_entry(int orig_index, const char *fname);
void write_srcf_line_entry(ulong linenum, ulong addr);
void end_srcf_entry();
void end_srcf_block();
/*
* Write the items in a GSYM (global symbol table) block. Start
* with begin_gsym_block(), then call write_gsym_entry() repeatedly
* to write the entries. Call end_gsym_block() when done.
*/
void begin_gsym_block();
void write_gsym_entry(const char *sym, size_t sym_len,
int type_id, const char *dat, size_t dat_len);
void end_gsym_block(ulong count);
/*
* Begin MHLS block, write an item, and end the block
*/
void begin_mhls_block();
void write_mhls_entry(ulong code_addr);
void end_mhls_block();
/*
* Begin/end SINI block. static_cs_ofs is the offset in the code
* segment of the first static initializer; this is useful in the
* image file because we can delete all of the code pages starting
* at this point after pre-initialization is complete.
*/
void begin_sini_block(ulong static_cs_ofs, ulong init_cnt);
void end_sini_block();
/* begin/end a MACR (macro symbols) block */
void begin_macr_block();
void end_macr_block();
/*
* Finish the file. Automatically ends the current block if a block
* is open, and writes the end-of-file marker.
*/
void finish();
/*
* get the underlying file object; for some types of blocks, it's
* simplest for the caller to write the data directly to the underlying
* file stream without any help from us
*/
class CVmFile *get_fp() const { return fp_; }
private:
/* write a generic dependency (function set, metaclass) block */
void write_dep_block(const char *block_id, const char **names, int count);
/* write a dependency block in pieces */
void begin_dep_block(const char *block_id, int count);
void write_dep_block_item(const char *nm);
void end_dep_block();
/* XOR a block of bytes with a mask and write the results to the file */
void xor_and_write_bytes(const char *p, uint32_t len, uchar xor_mask);
/* underlying file */
class CVmFile *fp_;
/*
* Seek position of start of current block. If this is zero, no
* block is currently open.
*/
long block_start_;
/* count of symbolic names written so far (for writing SYMD block) */
int symd_cnt_;
/* location of metaclass entry next-record offset */
long mcld_ofs_pos_;
/* location of metaclass property list count prefix */
long mcld_propcnt_pos_;
/* count of properties writeen in a metaclass prop list so far */
int mcld_prop_cnt_;
/* seek location of SYMD count prefix, for fixing up at end of block */
long symd_prefix_;
/* seek location of OBJS count prefix, for fixup up at end of block */
long objs_prefix_;
/* seek location of GSYM count prefix, for fixup at end of block */
long gsym_prefix_;
/* start of current SRCF file entry */
long srcf_entry_pos_;
/* count of SRCF line entries */
long srcf_line_cnt_;
/* position of SRCF line entry for the current file */
long srcf_line_pos_;
/* position of MHLS block count entry, and MHLS entry count so far */
long mhls_cnt_pos_;
ulong mhls_cnt_;
};
#endif /* VMWRTIMG_H */
|