> > Is anyone familiar enough to suggest the interfaces for such a
> > module? :)
> 
> AFAICT, the verifier has the most simple possible interface: a static
> method called verify() which takes a bytearray representing a class. It
> throws ClassFormatError when the class does not pass verification.

Besides the bytes of the classfile itself, the verifier needs access
to the type hirearchy (e.g. to check that bytecode is statically type
safe) as well as the class loader associated with the given classfile
as verification of one class will typically cause others to be loaded
and linked as well.

Furthermore, according to the spec there are four steps to
verification, only the second of which takes a the full array of bytes
from a classfile and is the one that would typically throw a
ClassFormatError if a classfile is malformed.  I believe that this
pass more naturally fits as an element of the class loader and not of
the "verifier" module itself.

The third step, referred to as "bytecode verification" (e.g. the pass
that ensures static type correctness in the bytecode, that jumps don't
go into the middle of multi-byte instructions, that the JSR stuff is
alright, etc. etc.) is executed lazily during linking (not loading),
at which point the bytes of the classfile will probably not be in
memory as they started (e.g. they would have been replaced by some
object representation).  This step would throw VerifyErrors rather
than ClassFormatErrors.


So if we're talking about bytecode verification, then the interface
representing that module requires:
- a class representation, including the bytecode array for each method
(so something different than java.lang.Class)
- the class loader responsible for loading that class, which is used
to get other classes for type checking.

which is still a relatively simple interface, but a little more
involved than first hinted at.


> The tricky bits on this arer how to get it bootstrapped 8if written in
> java) so that it can verify system classes needed to initialize itself.
> I'm not sure of the gory details of the spec, but I guess a gcj-compiled
> version could take care of initial bootstrapping during VM
> initialization, until the verifier itself can be loaded and initialized,
> and then the java one would take charge. In this way one source module
> would do.
> 
> I'm not sure how this tricky issue is solved in the different VMs:
> - no verifier
> - naive verifier (just size, simple consistency checks) in C/C++
> - complete verifier
> - no verification of bootclasspath

No bytecode verification of the bootclasspath (though pass 2 still
happens, which does the basic consistency checks) is an option often
taken and I think a pretty good one.  Verification is provided for
classfiles that you don't trust, and if you're running a JVM you
probably should trust whatever standard library you've chosen (e.g.
classpath).

That said, if we're going for a truly pluggable interface it would be
worthwhile to explore the minimum number of classes that must
necessarily go into this set to avoid having two verifier
implementations; one at the bootstrap level and one for everything
else, so those classes would not be verified while everything else
might be (depending on what flags were sent to the VM upon execution;
e.g. -noverify).


cheers,
-Rob

Reply via email to