79 if(index==0 || index>=constant_pool.size())
81 error() <<
"invalid constant pool index (" << index <<
")" <<
eom;
85 return constant_pool[index];
101 bytecodes.resize(256);
104 assert(p->opcode<bytecodes.size());
105 bytecodes[p->opcode].mnemonic=p->mnemonic;
106 bytecodes[p->opcode].format=p->format;
113 void rfields(classt &parsed_class);
114 void rmethods(classt &parsed_class);
115 void rmethod(classt &parsed_class);
131 for(std::size_t i=0; i<bytes; i++)
135 error() <<
"unexpected end of bytecode file" <<
eom;
145 for(
size_t i=0; i<bytes; i++)
149 error() <<
"unexpected end of bytecode file" <<
eom;
179 #define CONSTANT_Class 7 180 #define CONSTANT_Fieldref 9 181 #define CONSTANT_Methodref 10 182 #define CONSTANT_InterfaceMethodref 11 183 #define CONSTANT_String 8 184 #define CONSTANT_Integer 3 185 #define CONSTANT_Float 4 186 #define CONSTANT_Long 5 187 #define CONSTANT_Double 6 188 #define CONSTANT_NameAndType 12 189 #define CONSTANT_Utf8 1 190 #define CONSTANT_MethodHandle 15 191 #define CONSTANT_MethodType 16 192 #define CONSTANT_InvokeDynamic 18 194 #define VTYPE_INFO_TOP 0 195 #define VTYPE_INFO_INTEGER 1 196 #define VTYPE_INFO_FLOAT 2 197 #define VTYPE_INFO_LONG 3 198 #define VTYPE_INFO_DOUBLE 4 199 #define VTYPE_INFO_ITEM_NULL 5 200 #define VTYPE_INFO_UNINIT_THIS 6 201 #define VTYPE_INFO_OBJECT 7 202 #define VTYPE_INFO_UNINIT 8 211 catch(
const char *message)
217 catch(
const std::string &message)
232 #define ACC_PUBLIC 0x0001 233 #define ACC_PRIVATE 0x0002 234 #define ACC_PROTECTED 0x0004 235 #define ACC_STATIC 0x0008 236 #define ACC_FINAL 0x0010 237 #define ACC_SYNCHRONIZED 0x0020 238 #define ACC_BRIDGE 0x0040 239 #define ACC_VARARGS 0x0080 240 #define ACC_NATIVE 0x0100 241 #define ACC_ABSTRACT 0x0400 242 #define ACC_STRICT 0x0800 243 #define ACC_SYNTHETIC 0x1000 244 #define ACC_ENUM 0x4000 249 #define UNUSED __attribute__((unused)) 260 if(magic!=0xCAFEBABE)
268 error() <<
"unexpected major version" <<
eom;
301 for(std::size_t j=0; j<attributes_count; j++)
343 for(
const auto &var : m.local_variable_table)
353 if(src.
id()==ID_code)
361 else if(src.
id()==ID_symbol)
366 const typet &element_type=
367 static_cast<const typet &
>(src.
find(ID_C_element_type));
373 else if(src.
id()==ID_struct)
379 else if(src.
id()==ID_pointer)
386 if(constant_pool_count==0)
388 error() <<
"invalid constant_pool_count" <<
eom;
394 for(constant_poolt::iterator
437 error() <<
"invalid double entry" <<
eom;
449 for(std::string::iterator s_it=s.begin(); s_it!=s.end(); s_it++)
461 error() <<
"unknown constant pool entry (" << it->tag <<
")" 468 for(constant_poolt::iterator
497 exprt fieldref(
"fieldref", type);
499 fieldref.
set(ID_component_name, name_entry.
s);
527 exprt virtual_function(ID_virtual_function, type);
528 virtual_function.
set(ID_component_name, component_name);
529 virtual_function.
set(ID_C_class, class_name);
530 virtual_function.
set(ID_C_base_name, name_entry.
s);
531 virtual_function.
set(ID_identifier, identifier);
533 it->expr=virtual_function;
540 exprt string_literal(ID_java_string_literal);
542 it->expr=string_literal;
572 it->expr.id(
"nameandtype");
578 it->expr.id(
"methodhandle");
584 it->expr.id(
"methodtype");
590 it->expr.id(
"invokedynamic");
593 it->expr.type()=type;
606 for(std::size_t i=0; i<interfaces_count; i++)
615 for(std::size_t i=0; i<fields_count; i++)
637 for(std::size_t j=0; j<attributes_count; j++)
657 size_t bytecode_index=0;
659 for(address=0; address<code_length; address++)
661 bool wide_instruction=
false;
662 u4 start_of_instruction=address;
668 wide_instruction=
true;
676 instruction.
address=start_of_instruction;
715 instruction.
args.push_back(
724 instruction.
args.push_back(
772 u4 base_offset=address;
775 while(((address+1)&3)!=0) {
read_u1(); address++; }
779 instruction.
args.push_back(
787 for(std::size_t i=0; i<npairs; i++)
791 instruction.
args.push_back(
793 instruction.
args.push_back(
802 size_t base_offset=address;
805 while(((address+1)&3)!=0) {
read_u1(); address++; }
809 instruction.
args.push_back(
822 for(
s4 i=low_value; i<=high_value; i++)
826 instruction.
args.push_back(
838 instruction.
args.push_back(
855 case T_INT: t.
id(ID_int);
break;
873 throw "unknown JVM bytecode instruction";
878 if(address!=code_length)
880 error() <<
"bytecode length mismatch" <<
eom;
892 if(attribute_name==
"Code")
902 for(std::size_t e=0; e<exception_table_length; e++)
918 for(std::size_t j=0; j<attributes_count; j++)
924 for(methodt::instructionst::iterator
929 if(!it->source_location.get_line().empty())
930 line_number=it->source_location.get_line();
931 else if(!line_number.
empty())
932 it->source_location.set_line(line_number);
942 method.
instructions.begin()->source_location.get_line());
944 else if(attribute_name==
"RuntimeInvisibleAnnotations" ||
945 attribute_name==
"RuntimeVisibleAnnotations")
960 if(attribute_name==
"RuntimeInvisibleAnnotations" ||
961 attribute_name==
"RuntimeVisibleAnnotations")
976 if(attribute_name==
"LineNumberTable")
979 typedef std::map<unsigned,
980 methodt::instructionst::iterator> instruction_mapt;
981 instruction_mapt instruction_map;
983 for(methodt::instructionst::iterator
988 instruction_map[it->address]=it;
993 for(std::size_t i=0; i<line_number_table_length; i++)
999 instruction_mapt::const_iterator it=
1000 instruction_map.find(start_pc);
1002 if(it!=instruction_map.end())
1003 it->second->source_location.set_line(line_number);
1006 else if(attribute_name==
"LocalVariableTable")
1008 u2 local_variable_table_length=
read_u2();
1012 for(std::size_t i=0; i<local_variable_table_length; i++)
1028 else if(attribute_name==
"StackMapTable")
1034 for(
size_t i=0; i<stack_map_entries; i++)
1037 if(0<=frame_type && frame_type<=63)
1043 else if(64<=frame_type && frame_type<=127)
1053 else if(frame_type==247)
1065 else if(248<=frame_type && frame_type<=250)
1073 else if(frame_type==251)
1082 else if(252<=frame_type && frame_type<=254)
1084 size_t new_locals=(size_t) (frame_type-251);
1090 for(
size_t k=0; k<new_locals; k++)
1099 else if(frame_type==255)
1106 for(
size_t k=0; k<(size_t) number_locals; k++)
1116 for(
size_t k=0; k<(size_t) number_stack_items; k++)
1126 throw "error: unknown stack frame type encountered";
1169 throw "error: unknown verification type info encountered";
1182 annotations.push_back(annotation);
1198 element_value_pairs.resize(num_element_value_pairs);
1200 for(
auto &element_value_pair : element_value_pairs)
1203 element_value_pair.element_name=
pool_entry(element_name_index).
s;
1242 for(std::size_t i=0; i<num_values; i++)
1275 if(attribute_name==
"SourceFile")
1281 size_t last_index=fqn.find_last_of(
".");
1282 if(last_index==std::string::npos)
1286 std::string package_name=fqn.substr(0, last_index+1);
1287 std::replace(package_name.begin(), package_name.end(),
'.',
'/');
1288 const std::string &full_file_name=
1290 sourcefile_name=full_file_name;
1293 for(methodst::iterator m_it=parsed_class.
methods.begin();
1294 m_it!=parsed_class.
methods.end();
1297 m_it->source_location.set_file(sourcefile_name);
1298 for(instructionst::iterator i_it=m_it->instructions.begin();
1299 i_it!=m_it->instructions.end();
1302 if(!i_it->source_location.get_line().empty())
1303 i_it->source_location.set_file(sourcefile_name);
1307 else if(attribute_name==
"RuntimeInvisibleAnnotations" ||
1308 attribute_name==
"RuntimeVisibleAnnotations")
1320 for(std::size_t j=0; j<methods_count; j++)
1324 #define ACC_PUBLIC 0x0001 1325 #define ACC_PRIVATE 0x0002 1326 #define ACC_PROTECTED 0x0004 1327 #define ACC_STATIC 0x0008 1328 #define ACC_FINAL 0x0010 1329 #define ACC_SUPER 0x0020 1330 #define ACC_VOLATILE 0x0040 1331 #define ACC_TRANSIENT 0x0080 1332 #define ACC_INTERFACE 0x0200 1333 #define ACC_ABSTRACT 0x0400 1334 #define ACC_SYNTHETIC 0x1000 1335 #define ACC_ANNOTATION 0x2000 1336 #define ACC_ENUM 0x4000 1364 for(std::size_t j=0; j<attributes_count; j++)
1369 std::istream &istream,
1374 java_bytecode_parser.
in=&istream;
1377 bool parser_result=java_bytecode_parser.
parse();
1381 return parser_result;
1385 const std::string &
file,
1389 std::ifstream
in(file, std::ios::binary);
1394 message.
error() <<
"failed to open input file `" #define VTYPE_INFO_OBJECT
The type of an expression.
Fixed-width bit-vector with unsigned binary interpretation.
void rinterfaces(classt &parsed_class)
const std::string & id2string(const irep_idt &d)
void set_java_bytecode_index(const irep_idt &index)
void rRuntimeAnnotation_attribute(annotationst &)
#define CONSTANT_Methodref
constant_exprt to_expr() const
#define CONSTANT_MethodType
pool_entryt & pool_entry(u2 index)
void rmethod(classt &parsed_class)
bool java_bytecode_parse(std::istream &istream, java_bytecode_parse_treet &parse_tree, message_handlert &message_handler)
source_locationt source_location
exception_tablet exception_table
java_bytecode_parse_treet::annotationst annotationst
void rmethods(classt &parsed_class)
#define CONSTANT_InterfaceMethodref
struct bytecode_infot const bytecode_info[]
An expression denoting a type.
java_bytecode_parse_treet parse_tree
#define VTYPE_INFO_DOUBLE
const componentst & components() const
#define CONSTANT_Fieldref
exprt & constant(u2 index)
#define VTYPE_INFO_ITEM_NULL
static mstreamt & eom(mstreamt &m)
static ieee_float_spect double_precision()
void relement_value_pairs(annotationt::element_value_pairst &)
#define CONSTANT_MethodHandle
instructionst instructions
std::vector< annotationt > annotationst
const irep_idt & id() const
typet java_type_from_string(const std::string &src)
java_bytecode_parse_treet::instructiont instructiont
const symbol_typet & to_symbol_type(const typet &type)
Cast a generic typet to a symbol_typet.
void unpack(const mp_integer &i)
A reference into the symbol table.
std::vector< pool_entryt > constant_poolt
#define VTYPE_INFO_UNINIT
#define CONSTANT_NameAndType
Fixed-width bit-vector with two's complement interpretation.
verification_type_info_type type
java_bytecode_parse_treet::classt classt
API to expression classes.
const irep_idt & get(const irep_namet &name) const
void set_line(const irep_idt &line)
static ieee_float_spect single_precision()
std::vector< instructiont > instructionst
#define VTYPE_INFO_UNINIT_THIS
virtual void set_message_handler(message_handlert &_message_handler)
void rbytecode(methodt::instructionst &)
void skip_bytes(std::size_t bytes)
u8 read_bytes(size_t bytes)
void rclass_attribute(classt &parsed_class)
void rmethod_attribute(methodt &method)
void get_class_refs_rec(const typet &)
bool has_prefix(const std::string &s, const std::string &prefix)
const struct_typet & to_struct_type(const typet &type)
Cast a generic typet to a struct_typet.
void relement_value_pair(annotationt::element_value_pairt &)
std::list< methodt > methodst
java_bytecode_parse_treet::classt::fieldst fieldst
std::vector< element_value_pairt > element_value_pairst
void rfields(classt &parsed_class)
std::vector< bytecodet > bytecodes
stack_map_tablet stack_map_table
element_value_pairst element_value_pairs
java_bytecode_parse_treet::annotationt annotationt
constant_poolt constant_pool
Base class for all expressions.
#define VTYPE_INFO_INTEGER
java_bytecode_parse_treet::methodt::instructionst instructionst
source_locationt source_location
const parameterst & parameters() const
java_bytecode_parse_treet::fieldt fieldt
void read_verification_type_info(methodt::verification_type_infot &)
void swap(java_bytecode_parse_treet &other)
java_bytecode_parse_treet::methodt methodt
const typet type_entry(u2 index)
const code_typet & to_code_type(const typet &type)
Cast a generic typet to a code_typet.
void rcode_attribute(methodt &method)
local_variable_tablet local_variable_table
void rRuntimeAnnotation(annotationt &)
const typet & subtype() const
java_bytecode_parse_treet::classt::methodst methodst
symbol_typet java_classname(const std::string &id)
message_handlert * message_handler
const irept & find(const irep_namet &name) const
#define CONSTANT_InvokeDynamic
const typet & return_type() const
void rfield_attribute(fieldt &)
const irep_idt & get_identifier() const
void set(const irep_namet &name, const irep_idt &value)
std::list< fieldt > fieldst