File: vmwrtimg.h

package info (click to toggle)
qtads 2.1.6-1.1
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 16,156 kB
  • ctags: 18,767
  • sloc: cpp: 133,078; ansic: 26,048; xml: 18; makefile: 11
file content (311 lines) | stat: -rw-r--r-- 11,346 bytes parent folder | download | duplicates (8)
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 */