cfad47cfa3/tads3/vmwrtimg.h
Commiter: Nikos Chantziaras
Author: Nikos Chantziaras
Revision: cfad47cfa3
File Size: 11 KB
(June 01, 2009 20:54 UTC) Almost 3 years ago
Initial commit.
/* $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 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 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,
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 page_count, uint32 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 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 page_index,
const char *page_data, uint32 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 page_index, int mandatory,
uchar xor_mask);
void write_pool_page_bytes(const char *buf, uint32 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 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 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 */
|