1) Introduction

This document talks about virtual sections of code/data.  Basically a 
virtual section is like a communal definition in principle; its purpose
is that in C++ definitions in a header file can generate code or data
and we would like to have multiple instances of that code/data in different
modules, without forcing us to have seperate instances of the code/data
actually generated for each module.  For example:

class a{
	virtual void b() ;
	virtual void c() ;
	a() { } ;
} ;
main() 
{
	a s[7] ;
}
will end up creating two virtual sections... one of those will hold the
table of virtual functions (which includes pointers to b and c in this case)
and the other which will include an out-of-line constructor for a so that
the array initialization can take place smoothly.  If this class definition
is included in multiple C++ files each object file will have an instance
of the virtual sections, but the linker will combine them together and make
only one instance since these are comdefs.

2) Assembly syntax

In assembly the virtual functions table might look something like:

	segment .text
@@a@vtab segment virtual
@a@vtab:	dd	0
		dd	@a@b$qv
		dd	@a@c$qv
	segment .text

Note that the virtual segment is not actually a segment in its own right,
but is associated with the previously opened segment.  (although its data
probably ought to be maintained seperately).   The section name
for the virtual segment does not show up in the object file, only the
label it is given and the data show up there.  The final segment .text
is construed in this case to mean end putting code in the virtual section
(you could do something like TASM does and do an ENDS or something for
the section, but that seemed contrary to what NASM does in general).

3) Object records

We are going to be talking about the OMF output format since that is what
CC386 uses.  We are trying to maintain compatability with borland linker
tlink as well.

There are actually three changes to the output format that are required
for virtual section type of comdefs.  

The first is listing the label; this is done similarly to the externs 
table and also the lnames for it take up space in the externs table.  In
general you can list a bunch of labels in one record, however, the borland
tools don't seem to do this so you may want to list only one label per
record.

The second is a minor change to the A0/A1 records to reference comdefs
directly.

The third is a change to fixup records to allow reference to comdefs.  I
am not sure this is absolutely necessary but you want to do it for 
compatability with borland linkers.

a) comdef record

it is formatted like this:

1B    2B         1 B       n byte  1 or 2 byte      1 byte  1 -5 bytes
B0 | length | name length | name | type index (0) | seg # | length | cs

the seg # is the index of the segment it is in, for example if it is
1 it would take the first segment out of the segments list generated earlier
in processing the file.

the length is 1-5 bytes indicating the total length of the communal segment.
it is formatted as follows:

value range	number of bytes	allocation
0 to 127	1		this byte holds the length
0 to 64K-1	3		first byte is 81h, followed by a 16-bit number
0 to 16MB-2	4		first byte is 84h, follwoed by a 3 byte value
-2GB-1 to +2GB01 5		first byte is 88h, followed by a 4 byte value

In practice you will probably only have to support the first two of these...

The names are placed in he EXTDEF/LEXTDEF table in order of occurrance;
for compatability with borland linkers COMDEFS should preceed EXTDEFS in
the file and there should only be one comdef per record

2) modification to a0/a1 records

Each comdef will have one or more related A0/A1 records.  When an A0/A1
record refers to a comdef, the first byte of the record will be 0xC0, then
the following index will become an EXTDEF index (which referes to a comdef).
The rest of the record stays the same.  Note that such a0/a1 records
can be followed by fixup records, just like any other a0/a1 record

3) Modification to fixup records

When a fixup refers to a COMDEF, the fixup will be formatted as normal
except that the extern index in the target datum field will have 0xc0
prepended to it.  