LibJClass Reference Manual |
---|
Code Disassembly — Functions for code disassembly.
#include <jclass/bytecode.h> #define OP_LENGTH_UNPREDICTABLE enum OperandType; enum ArrayType; typedef TableSwitchOperand; typedef LookupSwitchOperand; #define MAX_LEGAL_OPCODE const char* jclass_code_instruction_name (uint8_t opcode); uint8_t jclass_code_instruction_ops (uint8_t opcode); uint8_t jclass_code_instruction_ops_length (uint8_t opcode); OperandType jclass_code_instruction_op_type (uint8_t opcode, int operand_number, int is_wide); int8_t jclass_code_read_byte (uint8_t *code, uint32_t *pc); uint8_t jclass_code_read_ubyte (uint8_t *code, uint32_t *pc); int16_t jclass_code_read_short (uint8_t *code, uint32_t *pc); uint16_t jclass_code_read_ushort (uint8_t *code, uint32_t *pc); int32_t jclass_code_read_int (uint8_t *code, uint32_t *pc); TableSwitchOperand* jclass_code_read_tableswitch (uint8_t *code, uint32_t *pc); LookupSwitchOperand* jclass_code_read_lookupswitch (uint8_t *code, uint32_t *pc); void jclass_code_lookupswitch_operand_free (LookupSwitchOperand *operand); void jclass_code_tableswitch_operand_free (TableSwitchOperand *operand); #define JCLASS_CODE_ALIGN_PC (pc) const char* jclass_code_array_name (uint8_t array_number);
Credits Information for the instructions was obtained from http://mrl.nyu.edu/~meyer/jvmref/ref-Java.html
#define OP_LENGTH_UNPREDICTABLE 0x10
The length of the operands is unpredictable.
typedef enum { OP_TYPE_NONE, OP_TYPE_BYTE, OP_TYPE_UNSIGNED_BYTE, OP_TYPE_BYTE_ARRAY_TYPE, OP_TYPE_BYTE_CONSTANT_INDEX, OP_TYPE_UNSIGNED_BYTE_USELESS, OP_TYPE_SHORT, OP_TYPE_UNSIGNED_SHORT, OP_TYPE_SHORT_OFFSET, OP_TYPE_SHORT_CLASS_INDEX, OP_TYPE_SHORT_METHOD_INDEX, OP_TYPE_SHORT_FIELD_INDEX, OP_TYPE_SHORT_CONSTANT_INDEX, OP_TYPE_INT, OP_TYPE_INT_OFFSET, OP_TYPE_INSTRUCTION, OP_TYPE_TABLESWITCH, OP_TYPE_LOOKUPSWITCH, OP_TYPE_ERROR } OperandType;
Operand types.
OP_TYPE_NONE | No operand. |
OP_TYPE_BYTE | The operand is a signed byte. |
OP_TYPE_UNSIGNED_BYTE | The operand is an unsigned byte. |
OP_TYPE_BYTE_ARRAY_TYPE | The operand is an unsigned byte representing a primitive array type. Possible values are listed in the ArrayType enum. You can also use the jclass_code_array_name() function to get a string with the name. |
OP_TYPE_BYTE_CONSTANT_INDEX | The operand is an unsigned byte index in the constant pool for a constant. |
OP_TYPE_UNSIGNED_BYTE_USELESS | The operand is an unsigned byte which is useless. See the documentation for the invokeinterface instruction to see what I mean. |
OP_TYPE_SHORT | The operand is a signed short integer. |
OP_TYPE_UNSIGNED_SHORT | The operand is an unsigned short integer. |
OP_TYPE_SHORT_OFFSET | The operand is a short offset from the pc of the instruction. |
OP_TYPE_SHORT_CLASS_INDEX | The operand is a short integer which is the index of a class in the constant pool. |
OP_TYPE_SHORT_METHOD_INDEX | The operand is a short integer which is the index of a method in the constant pool. |
OP_TYPE_SHORT_FIELD_INDEX | The operand is a short integer which is the index of a field in the constant pool. |
OP_TYPE_SHORT_CONSTANT_INDEX | The operand is a short integer which is the index of a constant in the constant pool. |
OP_TYPE_INT | The operand is a 32-bit signed integer. |
OP_TYPE_INT_OFFSET | The operand is a signed integer offset from the pc of th instruction. |
OP_TYPE_INSTRUCTION | The operand is an instruction (See wide instruction). |
OP_TYPE_TABLESWITCH | The operand is a tableswitch. It is always aligned at a 4-byte boundary. The "page" or whatever you want to call it starts at the first byte of the code. |
OP_TYPE_LOOKUPSWITCH | The operand is a lookupswitch. It is always aligned at a 4-byte boundary. |
OP_TYPE_ERROR | Some kind of error occured. |
typedef enum { ARRAY_TYPE_BOOLEAN = 4, ARRAY_TYPE_CHAR, ARRAY_TYPE_FLOAT, ARRAY_TYPE_DOUBLE, ARRAY_TYPE_BYTE, ARRAY_TYPE_SHORT, ARRAY_TYPE_INT, ARRAY_TYPE_LONG } ArrayType;
Primitive array type values. This enumeration is used in the newarray instruction to indicate the type of the primitive array. The operand is OP_TYPE_BYTE_ARRAY_TYPE.
ARRAY_TYPE_BOOLEAN | boolean array. |
ARRAY_TYPE_CHAR | char array. |
ARRAY_TYPE_FLOAT | float array. |
ARRAY_TYPE_DOUBLE | double array. |
ARRAY_TYPE_BYTE | byte array. |
ARRAY_TYPE_SHORT | short array. |
ARRAY_TYPE_INT | int array. |
ARRAY_TYPE_LONG | long array. |
typedef struct { int32_t num_pairs; uint32_t default_target; int32_t low_value; uint32_t* target; } TableSwitchOperand;
Operand for the tableswitch instruction.
typedef struct { int32_t num_pairs; uint32_t default_target; uint32_t* value; uint32_t* target; } LookupSwitchOperand;
Operand for the lookupswitch instruction.
const char* jclass_code_instruction_name (uint8_t opcode);
Gives the name of the instruction with the given opcode. The string returned is from an internal table so don't try to free it. If the opcode is illegal it returns NULL.
opcode : | The opcode for the instruction. |
Returns : | A constant string with the mnemonic for the instruction. |
uint8_t jclass_code_instruction_ops (uint8_t opcode);
Gives the number of the operands for the instruction. If the opcode is illegal it returns 0.
opcode : | The opcode for the instruction. |
Returns : | The number of operands. |
uint8_t jclass_code_instruction_ops_length (uint8_t opcode);
Gives the length of the operands for the instruction in bytes. If the instruction is widened multiply this number by 2. If the opcode is illegal it returns 0. If the length cannot be predicted it returns OP_LENGTH_UNPREDICTABLE.
opcode : | The opcode for the instruction. |
Returns : | The length of the operands in bytes. |
OperandType jclass_code_instruction_op_type (uint8_t opcode, int operand_number, int is_wide);
Gives the type of the given operand. If an inconsistency is detected such as asking for the wide form of an instruction that does not have one it returns OP_TYPE_ERROR.
opcode : | The opcode for the instruction. |
operand_number : | The number of the operand (starting from 0) to get its type. |
is_wide : | Set to 1 if the instruction is widened, 0 otherwise. |
Returns : | An OperandType enum for the type of the operand. |
int8_t jclass_code_read_byte (uint8_t *code, uint32_t *pc);
Reads a signed byte operand and increments the pc by the length of the operand.
code : | The code array. |
pc : | A pointer to the PC counter. |
Returns : | The signed byte at the current pc. |
uint8_t jclass_code_read_ubyte (uint8_t *code, uint32_t *pc);
Reads an unsigned byte operand and increments the pc by the length of the operand.
code : | The code array. |
pc : | A pointer to the PC counter. |
Returns : | The unsigned byte at the current pc. |
int16_t jclass_code_read_short (uint8_t *code, uint32_t *pc);
Reads a short operand and increments the pc by the length of the operand.
code : | The code array. |
pc : | A pointer to the PC counter. |
Returns : | The short at the current pc. |
uint16_t jclass_code_read_ushort (uint8_t *code, uint32_t *pc);
Reads an unsigned short operand and increments the pc by the length of the operand.
code : | The code array. |
pc : | A pointer to the PC. |
Returns : | The unsigned short at the current pc. |
int32_t jclass_code_read_int (uint8_t *code, uint32_t *pc);
Reads an integer operand and increments the pc by the length of the operand.
code : | The code array. |
pc : | A pointer to the program counter. |
Returns : | The integer at the current pc. |
TableSwitchOperand* jclass_code_read_tableswitch (uint8_t *code, uint32_t *pc);
Reads a tableswitch operand and increments the pc by the length of the operand.
code : | The code array. |
pc : | A pointer to the PC. |
Returns : | A TableSwitch structure allocated with malloc. |
LookupSwitchOperand* jclass_code_read_lookupswitch (uint8_t *code, uint32_t *pc);
Reads a lookupswitch operand and increments the pc by the length of the operand.
code : | The code array. |
pc : | A pointer to the PC. |
Returns : | A newly created LookupSwitch structure. |
void jclass_code_lookupswitch_operand_free (LookupSwitchOperand *operand);
Frees a LookupSwitch operand.
operand : | The LookupSwitch operand to free. |
void jclass_code_tableswitch_operand_free (TableSwitchOperand *operand);
Frees a TableSwitch operand.
operand : | The TableSwitch operand to free. |
#define JCLASS_CODE_ALIGN_PC(pc) (((pc) % 4) ? (((pc) + 4) - ((pc) % 4)) : (pc))
Aligns the PC at a 4-byte boundary. Useful for tableswitch and lookupswitch.
Example 1. Read a tableswitch operand
pc = JCLASS_CODE_ALIGN_PC(pc); /* get default target offset */ default_target = jclass_code_read_int(code->code, &pc); /* low */ low = jclass_code_read_int(code->code, &pc); /* high */ high = jclass_code_read_int(code->code, &pc); /* store the targets in an array */ target = (uint32*) malloc(sizeof(uint32) * ((high - low) + 1)); for(count = 0; count < (high - low) + 1; count++) target[count] = instruction_pc + jclass_code_read_int(code->code, &pc);
pc : | The current pc. |
<< Attributes | Class Loader >> |