From bc14fb009508e83548714965c9eeb4f254191d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Thu, 21 Jul 2016 13:56:52 +0200 Subject: [PATCH 01/16] types for stack map table and verification info --- src/java_bytecode/java_bytecode_parse_tree.h | 39 ++++++- src/java_bytecode/java_bytecode_parser.cpp | 112 +++++++++++++++++-- 2 files changed, 142 insertions(+), 9 deletions(-) diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index 550a4ae8584..1d09010130f 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -17,6 +17,11 @@ Author: Daniel Kroening, kroening@kroening.com class java_bytecode_parse_treet { public: + typedef unsigned char u1; + typedef unsigned short u2; + typedef unsigned int u4; + typedef unsigned long long u8; + class annotationt { public: @@ -94,10 +99,42 @@ class java_bytecode_parse_treet std::string signature; std::size_t index; }; - + typedef std::vector local_variable_tablet; local_variable_tablet local_variable_table; + class verification_type_infot + { + public: + enum verification_type_info_type { TOP, INTEGER, FLOAT, LONG, DOUBLE, + ITEM_NULL, UNINITIALIZED_THIS, + OBJECT, UNINITIALIZED}; + verification_type_info_type type; + u1 tag; + u2 cpool_index; + u2 offset; + }; + + class stack_map_table_entryt + { + public: + enum stack_frame_type { SAME, SAME_LOCALS_ONE_STACK, SAME_LOCALS_ONE_STACK_EXTENDED, + CHOP, SAME_EXTENDED, APPEND, FULL}; + stack_frame_type type; + size_t offset_delta; + size_t chops; + size_t appends; + + typedef std::vector local_verification_type_infot; + typedef std::vector stack_verification_type_infot; + + local_verification_type_infot locals; + stack_verification_type_infot stack; + }; + + typedef std::vector stack_map_tablet; + stack_map_tablet stack_map_table; + virtual void output(std::ostream &out) const; inline methodt():is_native(false), is_abstract(false), is_synchronized(false) diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 6a6255ea7b4..7b233820777 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -23,6 +23,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_types.h" #include "bytecode_info.h" +#define DEBUG #ifdef DEBUG #include #endif @@ -124,6 +125,7 @@ class java_bytecode_parsert:public parsert void rmethod_attribute(methodt &method); void rfield_attribute(fieldt &); void rcode_attribute(methodt &method); + void read_verification_type_info(methodt::verification_type_infot &); void rbytecode(methodt::instructionst &); void get_class_refs(); void get_class_refs_rec(const typet &); @@ -1041,9 +1043,9 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) { u2 attribute_name_index=read_u2(); u4 attribute_length=read_u4(); - + irep_idt attribute_name=pool_entry(attribute_name_index).s; - + if(attribute_name=="LineNumberTable") { // address -> instructiont @@ -1051,13 +1053,13 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) instruction_mapt instruction_map; for(methodt::instructionst::iterator - it=method.instructions.begin(); + it=method.instructions.begin(); it!=method.instructions.end(); it++) { instruction_map[it->address]=it; } - + u2 line_number_table_length=read_u2(); for(unsigned i=0; isecond->source_location.set_line(line_number); } @@ -1076,7 +1078,7 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) else if(attribute_name=="LocalVariableTable") { u2 local_variable_table_length=read_u2(); - + method.local_variable_table.resize(local_variable_table_length); for(unsigned i=0; i Date: Thu, 21 Jul 2016 15:10:58 +0200 Subject: [PATCH 02/16] remove wrong name index / attribute read --- src/java_bytecode/java_bytecode_parser.cpp | 43 +++++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 7b233820777..2a3ece00ef6 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -26,6 +26,7 @@ Author: Daniel Kroening, kroening@kroening.com #define DEBUG #ifdef DEBUG #include +#include #endif class java_bytecode_parsert:public parsert @@ -1096,25 +1097,28 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) } else if(attribute_name=="StackMapTable") { - std::cout << "reading StackMapTable" << std::endl; - u2 attribute_name_index=read_u2(); - u4 attribute_length=read_u4(); u2 stack_map_entries=read_u2(); + std::cout << "reading StackMapTable; length: " << std::to_string(stack_map_entries) << std::endl; + method.stack_map_table.resize(stack_map_entries); for(size_t i=0; i Date: Thu, 21 Jul 2016 16:55:31 +0200 Subject: [PATCH 03/16] correctly parse complete StackMapTable --- src/java_bytecode/java_bytecode_parser.cpp | 47 +++++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 2a3ece00ef6..88132a86715 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -1107,7 +1107,7 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) { u1 frame_type=read_u1(); - std::cout << "frame type " << std::to_string(frame_type) << std::endl; + std::cout << std::to_string(i) << " th frame is of type " << std::to_string(frame_type) << std::endl; if(0 <= frame_type && frame_type <= 63) { @@ -1132,6 +1132,11 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_LOCALS_ONE_STACK_EXTENDED; method.stack_map_table[i].locals.resize(0); method.stack_map_table[i].stack.resize(1); + methodt::verification_type_infot verification_type_info; + read_verification_type_info(verification_type_info); + method.stack_map_table[i].stack[0] = verification_type_info; + u2 offset_delta = read_u2(); + method.stack_map_table[i].offset_delta = offset_delta; } else if(248 <= frame_type && frame_type <= 250) { @@ -1139,6 +1144,8 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) method.stack_map_table[i].type = methodt::stack_map_table_entryt::CHOP; method.stack_map_table[i].locals.resize(0); method.stack_map_table[i].stack.resize(0); + u2 offset_delta = read_u2(); + method.stack_map_table[i].offset_delta = offset_delta; } else if(frame_type == 251) { @@ -1147,20 +1154,48 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) u2 offset=read_u2(); method.stack_map_table[i].locals.resize(0); method.stack_map_table[i].stack.resize(0); + u2 offset_delta = read_u2(); + method.stack_map_table[i].offset_delta = offset_delta; } else if(252 <= frame_type && frame_type <= 254) { + size_t new_locals = (size_t) (frame_type - 251); std::cout << "FRAME: APPEND" << std::endl; method.stack_map_table[i].type = methodt::stack_map_table_entryt::APPEND; - method.stack_map_table[i].locals.resize(0); + method.stack_map_table[i].locals.resize(new_locals); method.stack_map_table[i].stack.resize(0); + u2 offset_delta = read_u2(); + method.stack_map_table[i].offset_delta = offset_delta; + for(size_t k = 0; k < new_locals; k++) + { + method.stack_map_table[i].locals.push_back(methodt::verification_type_infot()); + methodt::verification_type_infot &v = method.stack_map_table[i].locals.back(); + read_verification_type_info(v); + } } else if(frame_type == 255) { - std::cout << "FRAME: SAME_EXTENDED" << std::endl; - method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_EXTENDED; - method.stack_map_table[i].locals.resize(0); - method.stack_map_table[i].stack.resize(0); + std::cout << "FRAME: FULL" << std::endl; + method.stack_map_table[i].type = methodt::stack_map_table_entryt::FULL; + + u2 offset_delta = read_u2(); + u2 number_locals = read_u2(); + method.stack_map_table[i].locals.resize(number_locals); + for (size_t k = 0; k < (size_t) number_locals; k++) + { + method.stack_map_table[i].locals.push_back(methodt::verification_type_infot()); + methodt::verification_type_infot &v = method.stack_map_table[i].locals.back(); + read_verification_type_info(v); + } + + u2 number_stack_items = read_u2(); + method.stack_map_table[i].stack.resize(number_stack_items); + for (size_t k = 0; k < (size_t) number_stack_items; k++) + { + method.stack_map_table[i].stack.push_back(methodt::verification_type_infot()); + methodt::verification_type_infot &v = method.stack_map_table[i].stack.back(); + read_verification_type_info(v); + } } else throw "ERROR: unknown stack frame type encountered"; From a2d30f5d5a73bdf3b84c7e6a3690bbfed8b0e90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 22 Jul 2016 14:28:03 +0200 Subject: [PATCH 04/16] first version to fix local variable table --- .../java_bytecode_convert_method.cpp | 87 +++++++++++++++---- src/java_bytecode/java_bytecode_parse_tree.h | 2 + src/java_bytecode/java_bytecode_parser.cpp | 6 +- 3 files changed, 78 insertions(+), 17 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index eae931120c6..eda78c8d24e 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -79,21 +79,69 @@ class java_bytecode_convert_methodt:public messaget { public: symbol_exprt symbol_expr; + size_t start_pc; + size_t length; }; - - expanding_vector variables; + + typedef std::vector variablest; + expanding_vector variables; bool method_has_this; + // return corresponding reference of variable + variablet &find_variable_for_slot(unsigned number_int, size_t address, variablest &var_list) + { + size_t var_list_length = var_list.size(); + if(var_list_length > 1) + { + for(variablet &var : var_list) + { + size_t start_pc = var.start_pc; + size_t length = var.length; + if (address >= start_pc && address <= start_pc + length) + { + std::cout << "found for address " << std::to_string(address) + << " starting at " << std::to_string(start_pc) + << " length: " << std::to_string(length) << std::endl; + return var; + } + } + std::cout << "end of list reached without correct frame found" << std::endl; + return var_list[0]; + } + else if(var_list_length == 1) + return var_list[0]; + else + { + std::cout << "no local variable exists!" << std::endl; + return var_list[0]; + } + } + // JVM local variables - const exprt variable(const exprt &arg, char type_char) + const exprt variable(const exprt &arg, char type_char, size_t address) { irep_idt number=to_constant_expr(arg).get_value(); std::size_t number_int=safe_string2size_t(id2string(number)); typet t=java_type_from_char(type_char); - if(variables[number_int].symbol_expr.get_identifier().empty()) + std::cout << "getting the variable list for number " << std::to_string(number_int) << std::endl; + variablest &var_list = variables[number_int]; + + size_t var_list_length = var_list.size(); + if(var_list_length == 1) + std::cout << "only single variable" << std::endl; + else if (var_list_length > 1) + std::cout << "multiple variables (" << std::to_string(var_list_length) << ") with this index" << std::endl; + else + std::cout << "no variable with this index" << std::endl; + + // search variable in list for correct frame / address if necessary + variablet &var = find_variable_for_slot(number_int, address, var_list); + + std::cout << "look at number " << std::to_string(number_int) << std::endl; + if(var.symbol_expr.get_identifier().empty()) { // an un-named local variable irep_idt base_name="local"+id2string(number)+type_char; @@ -106,7 +154,7 @@ class java_bytecode_convert_methodt:public messaget } else { - exprt result=variables[number_int].symbol_expr; + exprt result=var.symbol_expr; if(t!=result.type()) result=typecast_exprt(result, t); return result; } @@ -231,6 +279,8 @@ void java_bytecode_convert_methodt::convert( { //const class_typet &class_type=to_class_type(class_symbol.type); + std::cout << "--------\n" << m.name << std::endl; + typet member_type=java_type_from_string(m.signature); assert(member_type.id()==ID_code); @@ -256,16 +306,23 @@ void java_bytecode_convert_methodt::convert( variables.clear(); // Do the parameters and locals in the variable table, - // which is only available when compiled with -g + // which is available when compiled with -g + // or with methods with many local variables + // in the latter case, different variables can have + // the same index, depending on the context! for(const auto & v : m.local_variable_table) { typet t=java_type_from_string(v.signature); irep_idt identifier=id2string(method_identifier)+"::"+id2string(v.name); symbol_exprt result(identifier, t); result.set(ID_C_base_name, v.name); - variables[v.index].symbol_expr=result; + size_t number_index_entries = variables[v.index].size(); + variables[v.index].resize(number_index_entries + 1); + variables[v.index][number_index_entries].symbol_expr = result; + variables[v.index][number_index_entries].start_pc = v.start_pc; + variables[v.index][number_index_entries].length = v.length; } - + // set up variables array for(std::size_t i=0, param_index=0; i < parameters.size(); ++i) @@ -290,8 +347,8 @@ void java_bytecode_convert_methodt::convert( else { // in the variable table? - base_name=variables[param_index].symbol_expr.get(ID_C_base_name); - identifier=variables[param_index].symbol_expr.get(ID_identifier); + base_name=variables[param_index][0].symbol_expr.get(ID_C_base_name); + identifier=variables[param_index][0].symbol_expr.get(ID_identifier); if(base_name.empty()) { @@ -315,7 +372,7 @@ void java_bytecode_convert_methodt::convert( // add as a JVM variable std::size_t slots=get_variable_slots(parameters[i]); - variables[param_index].symbol_expr=parameter_symbol.symbol_expr(); + variables[param_index][0].symbol_expr=parameter_symbol.symbol_expr(); param_index+=slots; } @@ -765,7 +822,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // store value into some local variable assert(op.size()==1 && results.empty()); - exprt var=variable(arg0, statement[0]); + exprt var=variable(arg0, statement[0], i_it->address); const bool is_array('a' == statement[0]); @@ -797,7 +854,7 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement==patternt("?load")) { // load a value from a local variable - results[0]=variable(arg0, statement[0]); + results[0]=variable(arg0, statement[0], i_it->address); } else if(statement=="ldc" || statement=="ldc_w" || statement=="ldc2" || statement=="ldc2_w") @@ -959,9 +1016,9 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement=="iinc") { code_assignt code_assign; - code_assign.lhs()=variable(arg0, 'i'); + code_assign.lhs()=variable(arg0, 'i', i_it->address); code_assign.rhs()=plus_exprt( - variable(arg0, 'i'), + variable(arg0, 'i', i_it->address), typecast_exprt(arg1, java_int_type())); c=code_assign; } diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index 1d09010130f..e4f841148a0 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -98,6 +98,8 @@ class java_bytecode_parse_treet irep_idt name; std::string signature; std::size_t index; + std::size_t start_pc; + std::size_t length; }; typedef std::vector local_variable_tablet; diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 88132a86715..f29cb6f877b 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -1084,8 +1084,8 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) for(unsigned i=0; i Date: Fri, 22 Jul 2016 16:36:39 +0200 Subject: [PATCH 05/16] add instruction size to get local var validity --- .../java_bytecode_convert_method.cpp | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index eda78c8d24e..59c2ea4c170 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -88,8 +88,14 @@ class java_bytecode_convert_methodt:public messaget bool method_has_this; + typedef enum instruction_sizet + { + INST_INDEX = 2, INST_INDEX_CONST = 3 + } instruction_sizet; + // return corresponding reference of variable - variablet &find_variable_for_slot(unsigned number_int, size_t address, variablest &var_list) + variablet &find_variable_for_slot(unsigned number_int, size_t address, + variablest &var_list, instruction_sizet inst_size) { size_t var_list_length = var_list.size(); if(var_list_length > 1) @@ -98,15 +104,16 @@ class java_bytecode_convert_methodt:public messaget { size_t start_pc = var.start_pc; size_t length = var.length; - if (address >= start_pc && address <= start_pc + length) + if (address + (size_t) inst_size >= start_pc && address <= start_pc + length) { std::cout << "found for address " << std::to_string(address) << " starting at " << std::to_string(start_pc) - << " length: " << std::to_string(length) << std::endl; + << " length: " << std::to_string(length) + << var.symbol_expr << std::endl; return var; } } - std::cout << "end of list reached without correct frame found" << std::endl; + std::cout << "end of list reached, address " << std::to_string(address) << std::endl; return var_list[0]; } else if(var_list_length == 1) @@ -119,7 +126,7 @@ class java_bytecode_convert_methodt:public messaget } // JVM local variables - const exprt variable(const exprt &arg, char type_char, size_t address) + const exprt variable(const exprt &arg, char type_char, size_t address, instruction_sizet inst_size) { irep_idt number=to_constant_expr(arg).get_value(); @@ -138,7 +145,7 @@ class java_bytecode_convert_methodt:public messaget std::cout << "no variable with this index" << std::endl; // search variable in list for correct frame / address if necessary - variablet &var = find_variable_for_slot(number_int, address, var_list); + variablet &var = find_variable_for_slot(number_int, address, var_list, inst_size); std::cout << "look at number " << std::to_string(number_int) << std::endl; if(var.symbol_expr.get_identifier().empty()) @@ -525,7 +532,7 @@ codet java_bytecode_convert_methodt::convert_instructions( stackt stack; bool done; }; - + typedef std::map address_mapt; address_mapt address_map; std::set targets; @@ -822,7 +829,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // store value into some local variable assert(op.size()==1 && results.empty()); - exprt var=variable(arg0, statement[0], i_it->address); + exprt var=variable(arg0, statement[0], i_it->address, INST_INDEX); const bool is_array('a' == statement[0]); @@ -854,7 +861,7 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement==patternt("?load")) { // load a value from a local variable - results[0]=variable(arg0, statement[0], i_it->address); + results[0]=variable(arg0, statement[0], i_it->address, INST_INDEX); } else if(statement=="ldc" || statement=="ldc_w" || statement=="ldc2" || statement=="ldc2_w") @@ -1016,9 +1023,9 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement=="iinc") { code_assignt code_assign; - code_assign.lhs()=variable(arg0, 'i', i_it->address); + code_assign.lhs()=variable(arg0, 'i', i_it->address, INST_INDEX_CONST); code_assign.rhs()=plus_exprt( - variable(arg0, 'i', i_it->address), + variable(arg0, 'i', i_it->address, INST_INDEX_CONST), typecast_exprt(arg1, java_int_type())); c=code_assign; } From a7475e05bf56b7df2999a02eaf9a11c643265000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 25 Jul 2016 11:27:17 +0200 Subject: [PATCH 06/16] correct vector resizing for param_index --- .../java_bytecode_convert_class.cpp | 2 ++ .../java_bytecode_convert_method.cpp | 30 +++++++++++-------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 0236202bd52..a6aac111ecc 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -116,6 +116,8 @@ void java_bytecode_convert_classt::convert(const classt &c) throw 0; } + std::cout << "-----------\nclass: " << c.name << std::endl; + // now do fields for(const auto & it : c.fields) convert(*class_symbol, it); diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 59c2ea4c170..c2c18d8294a 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -312,11 +312,23 @@ void java_bytecode_convert_methodt::convert( variables.clear(); - // Do the parameters and locals in the variable table, - // which is available when compiled with -g - // or with methods with many local variables - // in the latter case, different variables can have - // the same index, depending on the context! + // set up variables array + for(std::size_t i=0, param_index=0; + i < parameters.size(); ++i) + { + std::cout << "parameter " << std::to_string(param_index) << " " << parameters[i] << std::endl; + variables[param_index].resize(1); + param_index+=get_variable_slots(parameters[i]); + } + + // Do the parameters and locals in the variable table, which is available when + // compiled with -g or for methods with many local variables in the latter + // case, different variables can have the same index, depending on the + // context. + // + // to calculate which variable to use, one uses the address of the instruction + // that uses the variable, the size of the instruction and the start_pc / + // length values in the local variable table for(const auto & v : m.local_variable_table) { typet t=java_type_from_string(v.signature); @@ -329,14 +341,6 @@ void java_bytecode_convert_methodt::convert( variables[v.index][number_index_entries].start_pc = v.start_pc; variables[v.index][number_index_entries].length = v.length; } - - // set up variables array - for(std::size_t i=0, param_index=0; - i < parameters.size(); ++i) - { - variables[param_index]; - param_index+=get_variable_slots(parameters[i]); - } // assign names to parameters for(std::size_t i=0, param_index=0; From b7736ba05d7a5f09cd0f9c0311b93893974e3ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 25 Jul 2016 11:38:14 +0200 Subject: [PATCH 07/16] cleanup debug output --- .../java_bytecode_convert_class.cpp | 2 -- .../java_bytecode_convert_method.cpp | 30 +++---------------- src/java_bytecode/java_bytecode_parser.cpp | 16 +--------- 3 files changed, 5 insertions(+), 43 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index a6aac111ecc..0236202bd52 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -116,8 +116,6 @@ void java_bytecode_convert_classt::convert(const classt &c) throw 0; } - std::cout << "-----------\nclass: " << c.name << std::endl; - // now do fields for(const auto & it : c.fields) convert(*class_symbol, it); diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index c2c18d8294a..cb140804556 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -105,26 +105,16 @@ class java_bytecode_convert_methodt:public messaget size_t start_pc = var.start_pc; size_t length = var.length; if (address + (size_t) inst_size >= start_pc && address <= start_pc + length) - { - std::cout << "found for address " << std::to_string(address) - << " starting at " << std::to_string(start_pc) - << " length: " << std::to_string(length) - << var.symbol_expr << std::endl; - return var; - } + return var; } - std::cout << "end of list reached, address " << std::to_string(address) << std::endl; - return var_list[0]; + throw ("end of list reached, address " + std::to_string(address) + " not found"); } else if(var_list_length == 1) return var_list[0]; else - { - std::cout << "no local variable exists!" << std::endl; - return var_list[0]; - } + throw ("local variable " + std::to_string(number_int) + " not found"); } - + // JVM local variables const exprt variable(const exprt &arg, char type_char, size_t address, instruction_sizet inst_size) { @@ -133,21 +123,12 @@ class java_bytecode_convert_methodt:public messaget std::size_t number_int=safe_string2size_t(id2string(number)); typet t=java_type_from_char(type_char); - std::cout << "getting the variable list for number " << std::to_string(number_int) << std::endl; variablest &var_list = variables[number_int]; - size_t var_list_length = var_list.size(); - if(var_list_length == 1) - std::cout << "only single variable" << std::endl; - else if (var_list_length > 1) - std::cout << "multiple variables (" << std::to_string(var_list_length) << ") with this index" << std::endl; - else - std::cout << "no variable with this index" << std::endl; // search variable in list for correct frame / address if necessary variablet &var = find_variable_for_slot(number_int, address, var_list, inst_size); - std::cout << "look at number " << std::to_string(number_int) << std::endl; if(var.symbol_expr.get_identifier().empty()) { // an un-named local variable @@ -286,8 +267,6 @@ void java_bytecode_convert_methodt::convert( { //const class_typet &class_type=to_class_type(class_symbol.type); - std::cout << "--------\n" << m.name << std::endl; - typet member_type=java_type_from_string(m.signature); assert(member_type.id()==ID_code); @@ -316,7 +295,6 @@ void java_bytecode_convert_methodt::convert( for(std::size_t i=0, param_index=0; i < parameters.size(); ++i) { - std::cout << "parameter " << std::to_string(param_index) << " " << parameters[i] << std::endl; variables[param_index].resize(1); param_index+=get_variable_slots(parameters[i]); } diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index f29cb6f877b..90f38ba5b96 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -23,10 +23,8 @@ Author: Daniel Kroening, kroening@kroening.com #include "java_types.h" #include "bytecode_info.h" -#define DEBUG #ifdef DEBUG #include -#include #endif class java_bytecode_parsert:public parsert @@ -1101,26 +1099,19 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) { u2 stack_map_entries=read_u2(); - std::cout << "reading StackMapTable; length: " << std::to_string(stack_map_entries) << std::endl; - method.stack_map_table.resize(stack_map_entries); for(size_t i=0; i Date: Mon, 25 Jul 2016 12:16:29 +0200 Subject: [PATCH 08/16] correct parameter names --- .../java_bytecode_convert_method.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index cb140804556..f42ccfdf70d 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -122,9 +122,7 @@ class java_bytecode_convert_methodt:public messaget std::size_t number_int=safe_string2size_t(id2string(number)); typet t=java_type_from_char(type_char); - variablest &var_list = variables[number_int]; - size_t var_list_length = var_list.size(); // search variable in list for correct frame / address if necessary variablet &var = find_variable_for_slot(number_int, address, var_list, inst_size); @@ -291,14 +289,6 @@ void java_bytecode_convert_methodt::convert( variables.clear(); - // set up variables array - for(std::size_t i=0, param_index=0; - i < parameters.size(); ++i) - { - variables[param_index].resize(1); - param_index+=get_variable_slots(parameters[i]); - } - // Do the parameters and locals in the variable table, which is available when // compiled with -g or for methods with many local variables in the latter // case, different variables can have the same index, depending on the @@ -320,6 +310,14 @@ void java_bytecode_convert_methodt::convert( variables[v.index][number_index_entries].length = v.length; } + // set up variables array + for(std::size_t i=0, param_index=0; + i < parameters.size(); ++i) + { + variables[param_index].resize(1); + param_index+=get_variable_slots(parameters[i]); + } + // assign names to parameters for(std::size_t i=0, param_index=0; i < parameters.size(); ++i) From 2da74439398bb0268b095ea0ce74e281e5ea30d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 25 Jul 2016 12:24:49 +0200 Subject: [PATCH 09/16] correct upper bound for variable search in frame --- src/java_bytecode/java_bytecode_convert_method.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index f42ccfdf70d..2e46777ad9c 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -104,7 +104,7 @@ class java_bytecode_convert_methodt:public messaget { size_t start_pc = var.start_pc; size_t length = var.length; - if (address + (size_t) inst_size >= start_pc && address <= start_pc + length) + if (address + (size_t) inst_size >= start_pc && address < start_pc + length) return var; } throw ("end of list reached, address " + std::to_string(address) + " not found"); From 321999a074e5de478386f1e752ed0282007c6b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Mon, 25 Jul 2016 12:33:33 +0200 Subject: [PATCH 10/16] mark two unused vars --- src/java_bytecode/java_bytecode_parser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index 90f38ba5b96..a9f16bd9e5b 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -1141,7 +1141,7 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) else if(frame_type == 251) { method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_EXTENDED; - u2 offset=read_u2(); + UNUSED u2 offset=read_u2(); method.stack_map_table[i].locals.resize(0); method.stack_map_table[i].stack.resize(0); u2 offset_delta = read_u2(); @@ -1166,7 +1166,7 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) { method.stack_map_table[i].type = methodt::stack_map_table_entryt::FULL; - u2 offset_delta = read_u2(); + UNUSED u2 offset_delta = read_u2(); u2 number_locals = read_u2(); method.stack_map_table[i].locals.resize(number_locals); for (size_t k = 0; k < (size_t) number_locals; k++) From 831d7b2dac8c0af337942ec89f209233f99b88fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Wed, 27 Jul 2016 23:49:55 +0200 Subject: [PATCH 11/16] support local variables without name --- src/java_bytecode/java_bytecode_convert_method.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 2e46777ad9c..d2fc12dac66 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -112,7 +112,12 @@ class java_bytecode_convert_methodt:public messaget else if(var_list_length == 1) return var_list[0]; else - throw ("local variable " + std::to_string(number_int) + " not found"); + { + // return reference to unnamed local variable + variablet var; + variablet &v = var; + return v; + } } // JVM local variables From 2fba88ac1d9d31f0df10631c18b93b11fa5a984e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Thu, 28 Jul 2016 14:19:15 +0200 Subject: [PATCH 12/16] correct StackMapFrame parsing two types of stack map frames were parsed incorrectly, leading to class file parsing errors --- src/java_bytecode/java_bytecode_parser.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index a9f16bd9e5b..f8c650a2c37 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -1125,9 +1125,9 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) method.stack_map_table[i].locals.resize(0); method.stack_map_table[i].stack.resize(1); methodt::verification_type_infot verification_type_info; + u2 offset_delta = read_u2(); read_verification_type_info(verification_type_info); method.stack_map_table[i].stack[0] = verification_type_info; - u2 offset_delta = read_u2(); method.stack_map_table[i].offset_delta = offset_delta; } else if(248 <= frame_type && frame_type <= 250) @@ -1141,7 +1141,6 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) else if(frame_type == 251) { method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_EXTENDED; - UNUSED u2 offset=read_u2(); method.stack_map_table[i].locals.resize(0); method.stack_map_table[i].stack.resize(0); u2 offset_delta = read_u2(); @@ -1165,8 +1164,8 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) else if(frame_type == 255) { method.stack_map_table[i].type = methodt::stack_map_table_entryt::FULL; - - UNUSED u2 offset_delta = read_u2(); + u2 offset_delta = read_u2(); + method.stack_map_table[i].offset_delta = offset_delta; u2 number_locals = read_u2(); method.stack_map_table[i].locals.resize(number_locals); for (size_t k = 0; k < (size_t) number_locals; k++) @@ -1175,7 +1174,6 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) methodt::verification_type_infot &v = method.stack_map_table[i].locals.back(); read_verification_type_info(v); } - u2 number_stack_items = read_u2(); method.stack_map_table[i].stack.resize(number_stack_items); for (size_t k = 0; k < (size_t) number_stack_items; k++) From 5d2e576788742708279d789487ab46b5b648fe05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Thu, 28 Jul 2016 14:55:19 +0200 Subject: [PATCH 13/16] fix return of stack memory reference --- src/java_bytecode/java_bytecode_convert_method.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index d2fc12dac66..24c782c51ae 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -114,9 +114,8 @@ class java_bytecode_convert_methodt:public messaget else { // return reference to unnamed local variable - variablet var; - variablet &v = var; - return v; + var_list.resize(1); + return var_list[0]; } } From 1ad3e8c525ea84b546d6bbaf0202f3744f075c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 29 Jul 2016 10:19:47 +0200 Subject: [PATCH 14/16] define local variable with maximal scope adds a new local variable with maximal scope to list of variables --- src/java_bytecode/java_bytecode_convert_method.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 24c782c51ae..ee44fa7c344 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -25,6 +25,8 @@ Author: Daniel Kroening, kroening@kroening.com #include "bytecode_info.h" #include "java_types.h" +#include + namespace { class patternt { @@ -107,13 +109,22 @@ class java_bytecode_convert_methodt:public messaget if (address + (size_t) inst_size >= start_pc && address < start_pc + length) return var; } - throw ("end of list reached, address " + std::to_string(address) + " not found"); + // add unnamed local variable to end of list at this index + // with scope from 0 to INT_MAX + // as it is at the end of the vector, it will only be taken into account + // if no other variable is valid + size_t list_length = var_list.size(); + var_list.resize(list_length + 1); + var_list[list_length].start_pc = 0; + var_list[list_length].length = std::numeric_limits::max(); + return var_list[list_length]; } else if(var_list_length == 1) return var_list[0]; else { // return reference to unnamed local variable + // if no local variable is defined for this index var_list.resize(1); return var_list[0]; } From 53622754da44179ec8f0cfb033f124c98f1fde20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 5 Aug 2016 09:39:18 +0200 Subject: [PATCH 15/16] take into account comments --- src/java_bytecode/bytecode_info.h | 6 + src/java_bytecode/java_bytecode_parse_tree.h | 7 +- src/java_bytecode/java_bytecode_parser.cpp | 223 +++++++++---------- 3 files changed, 119 insertions(+), 117 deletions(-) diff --git a/src/java_bytecode/bytecode_info.h b/src/java_bytecode/bytecode_info.h index 538de94ebb1..1b3d8ea3aef 100644 --- a/src/java_bytecode/bytecode_info.h +++ b/src/java_bytecode/bytecode_info.h @@ -1,3 +1,5 @@ +#pragma once + // http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings // The 'result_type' is one of the following: @@ -38,3 +40,7 @@ struct bytecode_infot extern struct bytecode_infot const bytecode_info[]; +typedef unsigned char u1; +typedef unsigned short u2; +typedef unsigned int u4; +typedef unsigned long long u8; diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index e4f841148a0..aed96ed957c 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -14,14 +14,11 @@ Author: Daniel Kroening, kroening@kroening.com #include #include +#include "bytecode_info.h" + class java_bytecode_parse_treet { public: - typedef unsigned char u1; - typedef unsigned short u2; - typedef unsigned int u4; - typedef unsigned long long u8; - class annotationt { public: diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index f8c650a2c37..73f9bd82a7b 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -49,11 +49,6 @@ class java_bytecode_parsert:public parsert java_bytecode_parse_treet parse_tree; - typedef unsigned char u1; - typedef unsigned short u2; - typedef unsigned int u4; - typedef unsigned long long u8; - struct pool_entryt { u1 tag; @@ -194,6 +189,16 @@ class java_bytecode_parsert:public parsert #define CONSTANT_MethodType 16 #define CONSTANT_InvokeDynamic 18 +#define VTYPE_INFO_TOP 0 +#define VTYPE_INFO_INTEGER 1 +#define VTYPE_INFO_FLOAT 2 +#define VTYPE_INFO_LONG 3 +#define VTYPE_INFO_DOUBLE 4 +#define VTYPE_INFO_ITEM_NULL 5 +#define VTYPE_INFO_UNINIT_THIS 6 +#define VTYPE_INFO_OBJECT 7 +#define VTYPE_INFO_UNINIT 8 + /*******************************************************************\ Function: java_bytecode_parsert::parse @@ -1105,84 +1110,84 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) { u1 frame_type=read_u1(); if(0 <= frame_type && frame_type <= 63) - { - method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME; - method.stack_map_table[i].locals.resize(0); - method.stack_map_table[i].stack.resize(0); - } + { + method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME; + method.stack_map_table[i].locals.resize(0); + method.stack_map_table[i].stack.resize(0); + } else if(64 <= frame_type && frame_type <= 127) - { - method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_LOCALS_ONE_STACK; - method.stack_map_table[i].locals.resize(0); - method.stack_map_table[i].stack.resize(1); - methodt::verification_type_infot verification_type_info; - read_verification_type_info(verification_type_info); - method.stack_map_table[i].stack[0] = verification_type_info; - } + { + method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_LOCALS_ONE_STACK; + method.stack_map_table[i].locals.resize(0); + method.stack_map_table[i].stack.resize(1); + methodt::verification_type_infot verification_type_info; + read_verification_type_info(verification_type_info); + method.stack_map_table[i].stack[0] = verification_type_info; + } else if(frame_type == 247) - { - method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_LOCALS_ONE_STACK_EXTENDED; - method.stack_map_table[i].locals.resize(0); - method.stack_map_table[i].stack.resize(1); - methodt::verification_type_infot verification_type_info; - u2 offset_delta = read_u2(); - read_verification_type_info(verification_type_info); - method.stack_map_table[i].stack[0] = verification_type_info; - method.stack_map_table[i].offset_delta = offset_delta; - } + { + method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_LOCALS_ONE_STACK_EXTENDED; + method.stack_map_table[i].locals.resize(0); + method.stack_map_table[i].stack.resize(1); + methodt::verification_type_infot verification_type_info; + u2 offset_delta = read_u2(); + read_verification_type_info(verification_type_info); + method.stack_map_table[i].stack[0] = verification_type_info; + method.stack_map_table[i].offset_delta = offset_delta; + } else if(248 <= frame_type && frame_type <= 250) - { - method.stack_map_table[i].type = methodt::stack_map_table_entryt::CHOP; - method.stack_map_table[i].locals.resize(0); - method.stack_map_table[i].stack.resize(0); - u2 offset_delta = read_u2(); - method.stack_map_table[i].offset_delta = offset_delta; - } + { + method.stack_map_table[i].type = methodt::stack_map_table_entryt::CHOP; + method.stack_map_table[i].locals.resize(0); + method.stack_map_table[i].stack.resize(0); + u2 offset_delta = read_u2(); + method.stack_map_table[i].offset_delta = offset_delta; + } else if(frame_type == 251) - { - method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_EXTENDED; - method.stack_map_table[i].locals.resize(0); - method.stack_map_table[i].stack.resize(0); - u2 offset_delta = read_u2(); - method.stack_map_table[i].offset_delta = offset_delta; - } + { + method.stack_map_table[i].type = methodt::stack_map_table_entryt::SAME_EXTENDED; + method.stack_map_table[i].locals.resize(0); + method.stack_map_table[i].stack.resize(0); + u2 offset_delta = read_u2(); + method.stack_map_table[i].offset_delta = offset_delta; + } else if(252 <= frame_type && frame_type <= 254) + { + size_t new_locals = (size_t) (frame_type - 251); + method.stack_map_table[i].type = methodt::stack_map_table_entryt::APPEND; + method.stack_map_table[i].locals.resize(new_locals); + method.stack_map_table[i].stack.resize(0); + u2 offset_delta = read_u2(); + method.stack_map_table[i].offset_delta = offset_delta; + for(size_t k = 0; k < new_locals; k++) { - size_t new_locals = (size_t) (frame_type - 251); - method.stack_map_table[i].type = methodt::stack_map_table_entryt::APPEND; - method.stack_map_table[i].locals.resize(new_locals); - method.stack_map_table[i].stack.resize(0); - u2 offset_delta = read_u2(); - method.stack_map_table[i].offset_delta = offset_delta; - for(size_t k = 0; k < new_locals; k++) - { - method.stack_map_table[i].locals.push_back(methodt::verification_type_infot()); - methodt::verification_type_infot &v = method.stack_map_table[i].locals.back(); - read_verification_type_info(v); - } + method.stack_map_table[i].locals.push_back(methodt::verification_type_infot()); + methodt::verification_type_infot &v = method.stack_map_table[i].locals.back(); + read_verification_type_info(v); } + } else if(frame_type == 255) + { + method.stack_map_table[i].type = methodt::stack_map_table_entryt::FULL; + u2 offset_delta = read_u2(); + method.stack_map_table[i].offset_delta = offset_delta; + u2 number_locals = read_u2(); + method.stack_map_table[i].locals.resize(number_locals); + for (size_t k = 0; k < (size_t) number_locals; k++) + { + method.stack_map_table[i].locals.push_back(methodt::verification_type_infot()); + methodt::verification_type_infot &v = method.stack_map_table[i].locals.back(); + read_verification_type_info(v); + } + u2 number_stack_items = read_u2(); + method.stack_map_table[i].stack.resize(number_stack_items); + for (size_t k = 0; k < (size_t) number_stack_items; k++) { - method.stack_map_table[i].type = methodt::stack_map_table_entryt::FULL; - u2 offset_delta = read_u2(); - method.stack_map_table[i].offset_delta = offset_delta; - u2 number_locals = read_u2(); - method.stack_map_table[i].locals.resize(number_locals); - for (size_t k = 0; k < (size_t) number_locals; k++) - { - method.stack_map_table[i].locals.push_back(methodt::verification_type_infot()); - methodt::verification_type_infot &v = method.stack_map_table[i].locals.back(); - read_verification_type_info(v); - } - u2 number_stack_items = read_u2(); - method.stack_map_table[i].stack.resize(number_stack_items); - for (size_t k = 0; k < (size_t) number_stack_items; k++) - { - method.stack_map_table[i].stack.push_back(methodt::verification_type_infot()); - methodt::verification_type_infot &v = method.stack_map_table[i].stack.back(); - read_verification_type_info(v); - } + method.stack_map_table[i].stack.push_back(methodt::verification_type_infot()); + methodt::verification_type_infot &v = method.stack_map_table[i].stack.back(); + read_verification_type_info(v); } + } else throw "ERROR: unknown stack frame type encountered"; } @@ -1194,46 +1199,40 @@ void java_bytecode_parsert::rcode_attribute(methodt &method) void java_bytecode_parsert::read_verification_type_info(methodt::verification_type_infot& v) { u1 tag = read_u1(); - if(tag == 0) - { - v.type=methodt::verification_type_infot::TOP; - } - else if(tag == 1) - { - v.type=methodt::verification_type_infot::INTEGER; - } - else if(tag == 2) - { - v.type=methodt::verification_type_infot::FLOAT; - } - else if(tag == 3) - { - v.type=methodt::verification_type_infot::LONG; - } - else if(tag == 4) - { - v.type=methodt::verification_type_infot::DOUBLE; - } - else if(tag == 5) - { - v.type=methodt::verification_type_infot::ITEM_NULL; - } - else if(tag == 6) - { - v.type=methodt::verification_type_infot::UNINITIALIZED_THIS; - } - else if(tag == 7) - { - v.type=methodt::verification_type_infot::OBJECT; - v.cpool_index=read_u2(); - } - else if(tag == 8) - { - v.type=methodt::verification_type_infot::UNINITIALIZED; - v.offset=read_u2(); - } - else + switch(tag) + { + case VTYPE_INFO_TOP: + v.type=methodt::verification_type_infot::TOP; + break; + case VTYPE_INFO_INTEGER: + v.type=methodt::verification_type_infot::INTEGER; + break; + case VTYPE_INFO_FLOAT: + v.type=methodt::verification_type_infot::FLOAT; + break; + case VTYPE_INFO_LONG: + v.type=methodt::verification_type_infot::LONG; + break; + case VTYPE_INFO_DOUBLE: + v.type=methodt::verification_type_infot::DOUBLE; + break; + case VTYPE_INFO_ITEM_NULL: + v.type=methodt::verification_type_infot::ITEM_NULL; + break; + case VTYPE_INFO_UNINIT_THIS: + v.type=methodt::verification_type_infot::UNINITIALIZED_THIS; + break; + case VTYPE_INFO_OBJECT: + v.type=methodt::verification_type_infot::OBJECT; + v.cpool_index=read_u2(); + break; + case VTYPE_INFO_UNINIT: + v.type=methodt::verification_type_infot::UNINITIALIZED; + v.offset=read_u2(); + break; + default: throw "ERROR: unknown verification type info encountered"; + } } /*******************************************************************\ From c390de1fce9fbb6de935cc97cf5ccb9dfabc45c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20G=C3=BCdemann?= Date: Fri, 5 Aug 2016 10:43:21 +0200 Subject: [PATCH 16/16] more precise int types for u1/2/4/8 --- src/java_bytecode/bytecode_info.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/java_bytecode/bytecode_info.h b/src/java_bytecode/bytecode_info.h index 1b3d8ea3aef..6376893ab14 100644 --- a/src/java_bytecode/bytecode_info.h +++ b/src/java_bytecode/bytecode_info.h @@ -1,5 +1,7 @@ #pragma once +#include + // http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings // The 'result_type' is one of the following: @@ -40,7 +42,7 @@ struct bytecode_infot extern struct bytecode_infot const bytecode_info[]; -typedef unsigned char u1; -typedef unsigned short u2; -typedef unsigned int u4; -typedef unsigned long long u8; +typedef uint8_t u1; +typedef uint16_t u2; +typedef uint32_t u4; +typedef uint64_t u8;