зеркало из https://github.com/mozilla/pluotsorbet.git
415 строки
14 KiB
HTML
415 строки
14 KiB
HTML
<html>
|
|
<head>
|
|
<title>Jasmin User Guide</title>
|
|
<link href="style.css" rel="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
<table>
|
|
<tr><td width=550>
|
|
<center>
|
|
<p><img src=jasmin_icon.jpg></p>
|
|
<p>
|
|
<div class="h1">JasminXT Syntax</div>
|
|
Daniel Reynaud, Mart 2006
|
|
</p>
|
|
</center>
|
|
|
|
<h1>About This Document</h1>
|
|
|
|
This guide describes the rules and syntax used in JasminXT, the extension of
|
|
the Jasmin language in version 2.0. If you are new to Jasmin, you should
|
|
refer to the Jasmin user guide. Note that this document doesn't
|
|
explain the Java Virtual Machine itself, or give syntax notes for
|
|
every instruction known to Jasmin. See the Java Virtual Machine specification
|
|
for more information on the JVM.<p>
|
|
|
|
|
|
<h1>Why a new Jasmin language ?</h1>
|
|
|
|
<p>
|
|
Jasmin is the de-facto standard Java assembly language. It is useful to explore
|
|
the possibilities of bytecode, but it does not offer a real low level control
|
|
over the produced output. Therefore it is not suitable to generate test cases
|
|
for virtual machines or bytecode verifier. This new version of the Jasmin
|
|
language, called JasminXT, provides optional directives and other syntax
|
|
updates to have more control over the output and to stick with the latest
|
|
changes of the Java language.</p>
|
|
|
|
<p>JasminXT has been defined for the tinapoc project. The purpose of the tinapoc
|
|
project is to create a reliable Java reverse engineering toolkit. See the tinapoc
|
|
homepage for more information : <a href="http://tinapoc.sourceforge.net/">http://tinapoc.sourceforge.net/</a></p>
|
|
|
|
<h1>Summary of the new features</h1>
|
|
<p>
|
|
<b>Since 2.4 :</b><br>
|
|
<li> accept 'd'-suffix in float constant (no attempt cast to float)
|
|
<li> redesign to dynamic compiler class creation
|
|
<li> some cosmetic bugfixes
|
|
<br><br>
|
|
<b>Since 2.3 :</b><br>
|
|
<li> added 'wide'-aliases to two-face instructions
|
|
<br><br>
|
|
<b>Since 2.2 :</b><br>
|
|
<li> some bug fixes in the diagnostic
|
|
<li> added support for attribute StackMapTable (directive .stack) described in JDK1.6
|
|
<li> added keyword 'use' to directive .stack
|
|
<li> added support for \uXXXX escape sequence in the names (just as in the Java)
|
|
<li> instruction ldc_w always generates wide index
|
|
<li> changed syntaxes of the non-standard identifiers (or overloaded keywords), now it hasto be signgle quoted and can't be empty
|
|
<br><br>
|
|
<b>Since 2.1 :</b><br>
|
|
<li> some bug fixes with string and number parsing
|
|
<li> added support for \uXXXX escape sequences
|
|
<li> added support for access flags ACC_STRICT (fpstrict) and ACC_SYNTHETIC (synthetic)
|
|
<li> added signatures for local variables support
|
|
<li> several .debug directives are permitted
|
|
<li> added the invokedynamic instruction
|
|
<li> improved the syntax of the StackMap attribute (.stack directive)
|
|
<li> new command-line option -e to support different encodings
|
|
<li> added support for non-standard identifiers in double-quotes
|
|
<li> fields can now be defined on multiple lines
|
|
<li> new directives have been included : .inner, .attribute, .deprecated, .annotation
|
|
<br><br>
|
|
<b>Since 2.0 :</b><br><br>
|
|
<li>use of offsets for branch targets, local variable visibility and exception handlers. The offsets can either be absolute or relative :<br>
|
|
<pre>
|
|
goto 12 ; absolute offset : go to bytecode at offset 12
|
|
goto +5 ; relative offset : go 12 bytes forward
|
|
goto -8 ; relative offset : go 8 bytes backwards
|
|
</pre>
|
|
|
|
<li>the following access flags are now supported : ACC_ENUM, ACC_ANNOTATION, ACC_BRIDGE and ACC_VARARGS<br>
|
|
|
|
<li>the .bytecode directive has been added, to set the bytecode version in the class file.<br>
|
|
Example : <pre>.bytecode 49.0</pre><br>
|
|
|
|
<li>it is now possible to add a SourceDebugExtension attribute to the class with the following directive :<br>
|
|
<pre>.debug "some string here"</pre><br>
|
|
|
|
<li>same thing for the EnclosingMethod attribute :<br>
|
|
<pre>.enclosing method "some/package/Foo/someMethod(I)V"</pre><br>
|
|
|
|
<li>support for the Signature attribute (in the classes, methods and fields) :<br>
|
|
<pre>.signature "<my::own>Signature()"
|
|
.field myField Ljava/lang/String; signature "<my::own>Signature()"</pre><br>
|
|
|
|
<li>support for the StackMap attribute, using the .stack directive in a method definition<br>
|
|
|
|
<li>it is now possible to give the offset of an instruction before the instruction itself, like in the following code snippet :<br>
|
|
<pre>
|
|
0: aload_0
|
|
1: invokespecial java/lang/Object/<init>()V
|
|
4: aload_0
|
|
5: ldc2_w 3.14159
|
|
</pre>
|
|
</p>
|
|
|
|
|
|
|
|
|
|
<h1>JasminXT File Format</h1>
|
|
<p>
|
|
This new version is an extension of the existing Jasmin language, therefore old
|
|
Jasmin files should still compile correctly with newer versions of Jasmin.
|
|
JasminXT is supported by Jasmin 2.0 or higher. <b>Changes in Jasmin 2.4 are in bold.</b></p>
|
|
|
|
<p>
|
|
In the rest of this document, words between '[' and ']' are optional. The
|
|
syntax of a JasminXT file is the following :</p>
|
|
|
|
<pre>
|
|
<jas_file> {
|
|
<jasmin_header>
|
|
[<field>]*
|
|
[<method>]*
|
|
}
|
|
</pre>
|
|
|
|
<h1>JasminXT Header</h1>
|
|
<pre>
|
|
<jasmin_header> {
|
|
[.bytecode <x.y>]
|
|
[.source <sourcefile>]
|
|
<class_spec>
|
|
<super_spec>
|
|
<implements>
|
|
[.signature "<signature>"]
|
|
[.enclosing method <method_name>]
|
|
[.debug "<debug_source_extension>"]*
|
|
[.inner class [<access>] [<name>] [inner <classname>] [outer <name>]]*
|
|
[.inner interface [<access>] [<name>] [inner <classname>] [outer <name>]]*
|
|
}
|
|
|
|
example :
|
|
.bytecode 49.0
|
|
.source hello.j
|
|
.class hello
|
|
.super java/lang/Object
|
|
.signature "<my::own>Signature()"
|
|
.enclosing method foo/bar/Whatever/someMethod()</pre>
|
|
.debug "this string will be included in the SourceDebugExtension attribute"
|
|
.debug "this string too"
|
|
|
|
<p>The .bytecode directive sets the version of the bytecode in the class file.</p>
|
|
|
|
<p>The .signature directive, when used in the header of the Jasmin file, sets the
|
|
Signature attribute for the class (the argument is a string between double
|
|
quotes)</p>
|
|
|
|
<p>The .enclosing directive sets the EnclosingMethod attribute for the class. The
|
|
argument is a supposed to be a method name, but it can be any string between
|
|
double quotes.</p>
|
|
|
|
<p>The .debug directive sets the SourceDebugExtension attribute for the class (the
|
|
argument is also a string between double quotes)</p>
|
|
|
|
|
|
|
|
<h1>JasminXT Class, Super Class and Interfaces Definition</h1>
|
|
<pre>
|
|
<class_spec> {
|
|
.class <access_spec> <class_name>
|
|
}
|
|
</pre>
|
|
|
|
<p>where <access_spec> is any number of words taken from this list : public,
|
|
private, protected, static, final, synchronized, native, final, super,
|
|
interface, abstract, annotation, enum, bridge/volatile, transient/varargs</p>
|
|
|
|
<p>and <class_name> is the fully qualified internal form of the class, such as
|
|
my/package/MyClass</p><br>
|
|
|
|
|
|
<pre>
|
|
<super_spec> {
|
|
.super <class_name>
|
|
}
|
|
</pre>
|
|
|
|
<pre>
|
|
<implements> {
|
|
.implements <class_name>*
|
|
}
|
|
</pre>
|
|
<p>
|
|
The .super and .implements directives have not been modified in JasminXT<br>
|
|
The .implements directive can be repeated in order to implement multiple interfaces</p><br>
|
|
|
|
|
|
|
|
<h1>JasminXT Field Definition</h1>
|
|
<pre>
|
|
<field> {
|
|
.field <access_spec> <field_name> <descriptor> [signature <signature>]
|
|
[ = <value> ]
|
|
|
|
|
.field <access_spec> <field_name> <descriptor> [signature <signature>]
|
|
[ = <value> ]
|
|
[<field_attribute>]*
|
|
.end field
|
|
(...)
|
|
}
|
|
</pre>
|
|
<p>
|
|
If present, the Signature attribute will be set in the class file for this field with the given
|
|
quoted string as an argument.</p>
|
|
|
|
|
|
<pre>
|
|
<field_attribute> {
|
|
.deprecated
|
|
| .attribute <name> <file_name>
|
|
| .signature <signature>
|
|
| .annotation (...)
|
|
}
|
|
</pre>
|
|
|
|
(see below for the definition of the annotation and the attribute directives)
|
|
|
|
|
|
|
|
<p>examples :
|
|
<pre>.field enum myField Ljava/lang/String; signature "<my::own>Signature()" = "val"</pre>
|
|
<pre>.field static hello_string Ljava/lang/String;
|
|
.signature "mySignature"
|
|
.deprecated
|
|
.end field</pre>
|
|
</p>
|
|
|
|
|
|
<h1>JasminXT Method Definition</h1>
|
|
The general format of a method definition has not changed in JasminXT.
|
|
|
|
<pre>
|
|
<method> {
|
|
.method <access_spec> <method_name> <descriptor>
|
|
<statement>*
|
|
.end method
|
|
}
|
|
</pre>
|
|
|
|
|
|
<h1>JasminXT Method Statements</h1>
|
|
<pre>
|
|
<statement> {
|
|
.limit stack <integer>
|
|
| .limit locals <integer>
|
|
| .line <integer>
|
|
| .var <var_number> is <var_name> <descriptor> [signature <sign>] from <label1> to <label2>
|
|
| .var <var_number> is <var_name> <descriptor> [signature <sign>] from <offset1> to <offset2>
|
|
| .throws <classname>
|
|
| .catch <classname> from <label1> to <label2> using <label3>
|
|
| .catch <classname> from <offset1> to <offset2> using <offset3>
|
|
| .signature "<signature>"
|
|
| .stack
|
|
[offset {<pc> | <label>}]
|
|
[locals <verification_type> [<verification_arg>]]
|
|
(...)
|
|
[stack <verification_type> [<verification_arg>]]
|
|
(...)
|
|
.end stack
|
|
| .stack use [n] locals
|
|
(...)
|
|
.end stack
|
|
| <instruction> [<instruction_args>]
|
|
| <Label>:
|
|
| .deprecated
|
|
| <generic> ; see below for the use of generic attributes
|
|
}
|
|
</pre>
|
|
<p>
|
|
In Jasmin XT you can now use offsets instead of labels for the local variable
|
|
definitions and for the exception handlers definitions.</p>
|
|
|
|
<p>The .signature sets the Signature attribute for this method with the given
|
|
quoted string.<p>
|
|
|
|
<p>You can now also define StackMap (or StackMapTable) attributes using
|
|
the .stack directive. <pc> is an offset in the local bytecode array.
|
|
<verification_type> is one of the following keywords : Top, Integer,
|
|
Float, Long, Double, Null, UninitializedThis, Object or Uninitialized. Object
|
|
takes a <classname> as a parameter. Uninitialized takes an integer or a
|
|
label as a parameter. Also, jasmin allows to use "short" notation. The
|
|
'.stack use [n] locals' directive results in copy first <n> values from
|
|
previous .stack directive. If <n> is omitted, all values are copied.</p>
|
|
|
|
<p>NOTE: If bytecode version is 50 or above jasmin generates StackMapTable
|
|
attribute in accordance with specification of the new 'ClassFile Format'
|
|
edition. If bytecode version is 49 or below jasmin generate StakMap attribute
|
|
in accordance with CLDC specification.<p>
|
|
|
|
examples :
|
|
<pre>
|
|
.stack
|
|
offset 16
|
|
locals Null
|
|
locals Top
|
|
locals Object allo
|
|
stack Uninitialized 12
|
|
.end stack
|
|
|
|
.stack
|
|
; offset is not specified, the offset of the current opcode will be used
|
|
locals Null
|
|
locals Top
|
|
locals Object allo
|
|
stack Uninitialized Label0
|
|
.end stack
|
|
</pre>
|
|
<p>
|
|
This statement defines a single stack map frame. All the stack map frames
|
|
defined in a method are then aggregated and form the StackMap attribute for the
|
|
method. The last example my be wrote at the short notation as:</p>
|
|
|
|
<pre>
|
|
.stack use locals
|
|
stack Uninitialized Label0
|
|
.end stack
|
|
</pre>
|
|
<p>
|
|
|
|
|
|
|
|
<h1>JasminXT Instructions</h1>
|
|
<pre>
|
|
<instruction> {
|
|
[<pc>:] <opcode> [<instruction_args>]
|
|
}
|
|
</pre>
|
|
|
|
<p>
|
|
The main change in JasminXT is that it is now possible to put the offset of the
|
|
instruction before the opcode (the <pc>: statement). The pc is processed as a
|
|
label, therefore you can virtually put any number as the pc but it won't change
|
|
the actual pc of the bytecode.</p>
|
|
|
|
<p>
|
|
Another update is that it is now possible to use offsets (both relative and
|
|
absolute) as branch targets instead of labels. The offset is considered to be
|
|
relative if it begins with '$+' or '$-'.</p>
|
|
|
|
example :
|
|
<pre>
|
|
goto n ; absolute offset : go to the bytecode labelled n
|
|
goto $+n ; relative offset : go n bytes forward (from the offset of this goto)
|
|
goto $-n ; relative offset : go n bytes backwards
|
|
</pre>
|
|
|
|
<p>
|
|
If something hasn't been documented here, it means that it hasn't changed, so
|
|
you can still refer to the Jasmin <a href="guide.html">user guide</a></p>
|
|
|
|
<p>
|
|
<b>Added '_w' aliase to [adfli]-load/store, iinc and ret instructions (e.g. aload - aload_w).
|
|
Using '_w' postfix guarantees wide-form of byte-code generation</b></p>
|
|
|
|
<h1>Generic Attributes</h1>
|
|
Generic attributes are supported in class/field/method definitions as follows :
|
|
<pre><generic> = {
|
|
.attribute <name> <file_name>
|
|
}</pre>
|
|
|
|
<name> is the name of the attribute and <file_name> is the name of the file containing the data of the attribute (between double quotes). If the generic attribute is in the body of the method, the following logic is used : if it is the first statement in the method, the attribute will be added as a method attribute, otherwise it will be added as a Code attribute.
|
|
|
|
<h1>Annotations</h1>
|
|
Thanks to Iouri Kharon for implementing this. Here are his explanations :<br>
|
|
|
|
<p>Added a new directive .annotation to create the AnnotationDefault,
|
|
RuntimeVisibleAnnotation, RuntimeInvisibleAnnotation,
|
|
RuntimeVisibeParameterAnnotation, RuntimeInvisibleParameterAnnotation
|
|
attributes. The directive arguments are verified to have valid values
|
|
and correct signatures.<br>
|
|
Complex (nested) annotations are supported as well as arrays of them.<br>
|
|
The generic format is:
|
|
<pre>
|
|
<annotation> = {
|
|
.annotation visible <classname>
|
|
| .annotation invisible <classname>>
|
|
| .annotation visibleparam <paramnum> <classname>
|
|
| .annotation invisibleparam <paramnum> <classname>
|
|
| .annotation default
|
|
........
|
|
.end annotation
|
|
|
|
Field format (except AnnotationDefault):
|
|
|
|
<name> <signchar> = <value>*
|
|
| <name> @ = .annotation
|
|
........
|
|
.end annotation
|
|
}
|
|
</pre>
|
|
|
|
AnnotationDefault supports only one field and the <name> tag is not used.
|
|
Nested annotations must be with the <name> tag and can have any number
|
|
of fields. Besides, 'empty annotation' is forbidden for AnnotationDefault.
|
|
Lastly, AnnotationDefault can be used only once for each method.
|
|
Other annotation types can be used many times and will accumulate information.</p>
|
|
|
|
<hr><address>Copyright (c) Daniel Reynaud, Mart 2006</address>
|
|
<hr>
|
|
<a href="http://jasmin.sourceforge.net">Jasmin Home</a>
|
|
</td></tr></table>
|
|
</body>
|
|
</html>
|