#include "FieldInfo.h" #include "Methods.h" #include #include #include #include #include #include #include #include #include #include #define JVM_STACK_SIZE 4096 int stack[JVM_STACK_SIZE]; int main(int argc, char **argv) { if (argc < 2) { std::cerr << "Usage " << argv[0] << " " << std::endl; return 1; } for (int i = 0; i < JVM_STACK_SIZE; i++) { stack[i] = 0; } std::ifstream f; JavaClassFormat jc; f.open(argv[1], std::ios::binary); ConstantPoolTags::ConstantPool cp; if (!f.is_open()) { std::cerr << "Failed to open " << argv[1] << std::endl; return 1; } // std::vector Globals::buffer(std::istreambuf_iterator(f), {}); Globals::buffer() = std::vector(std::istreambuf_iterator(f), {}); f.close(); int size = Globals::buffer().size(); jc.magic = Utils::ReadFromStartIntoVal(Globals::buffer(), 4); assert(jc.magic.ToHostFormat() == 0xcafebabe); jc.minor = Utils::ReadFromStartIntoVal(Globals::buffer(), 2); jc.major = Utils::ReadFromStartIntoVal(Globals::buffer(), 2); jc.constant_pool_count = Utils::ReadFromStartIntoVal(Globals::buffer(), 2); std::cout << "Magic: 0x" << std::hex << jc.magic.ToHostFormat() << std::endl; std::cout << "Minor: " << Utils::Hex2Int(jc.minor.ToHostFormat()) << std::endl; std::cout << "Major: " << Utils::Hex2Int(jc.major.ToHostFormat()) << std::endl; std::cout << "Constant Pool Count: " << Utils::Hex2Int(jc.constant_pool_count.ToHostFormat()) << std::endl; for (int i = 0; i < jc.constant_pool_count.ToHostFormat() - 1; i++) { ConstantPoolTags::ConstantPool cp; cp.tag = (ConstantPoolTags::Tags)Utils::ReadFromStartIntoVal(Globals::buffer(), 1); ConstantPoolTags::ConstantPoolParser(cp, jc); } jc.access_flags = Utils::ReadFromStartIntoVal(Globals::buffer(), 2); jc.this_class = Utils::ReadFromStartIntoVal(Globals::buffer(), 2); jc.super_class = Utils::ReadFromStartIntoVal(Globals::buffer(), 2); jc.interfaces_count = Utils::ReadFromStartIntoVal(Globals::buffer(), 2); assert(jc.this_class.ToHostFormat() >= 0); assert(jc.super_class.ToHostFormat() >= 0); assert(jc.constant_pool.size() > jc.this_class.ToHostFormat()); assert(jc.constant_pool[jc.this_class.ToHostFormat() - 1].tag == ConstantPoolTags::Tags::Class); if (jc.super_class.ToHostFormat() != 0) { // For a class, the value of the super_class item either must be zero or // must be a valid index into the constant_pool table. If the value of // the super_class item is nonzero, the constant_pool entry at that index // must be a CONSTANT_Class_info structure representing the direct superclass // of the class defined by this class file. Neither the direct superclass nor // any of its superclasses may have the ACC_FINAL flag set in the access_flags // item of its ClassFile structure. // FIXME: Finish implementing the above comment. assert(jc.constant_pool.size() > jc.super_class.ToHostFormat()); assert(jc.constant_pool[jc.super_class.ToHostFormat() - 1].tag == ConstantPoolTags::Tags::Class); } else { // FIXME: Implement zero super_class checks } std::cout << "Access Flags: " << jc.access_flags.ToHostFormat() << std::endl; std::cout << "This Class: " << std::dec << jc.this_class.ToHostFormat() << std::endl; std::cout << "Super Class: " << jc.super_class.ToHostFormat() << std::endl; std::cout << "Interfaces Count: " << std::dec << jc.interfaces_count.ToHostFormat() << std::endl; if (jc.access_flags.ToHostFormat() >= (int)JavaClass::ACCESS_FLAGS::ACC_MODULE) { assert(jc.access_flags.ToHostFormat() == (int)JavaClass::ACCESS_FLAGS::ACC_MODULE); // Conditions for when jc.access_flags == JavaClass::ACCESS_FLAGS::ACC_MODULE // major_version, minor_version: ≥ 53.0 (i.e., Java SE 9 and above) assert(jc.major.ToHostFormat() >= 53); assert(jc.minor.ToHostFormat() >= 0); } // std::cout << std::dec << (int)(jc.constant_pool[jc.this_class.ToHostFormat()].info.tag) << std::endl; // std::cout << "" << std::hex << size - Globals::buffer().size() << std::endl; for (int i = 0; i < jc.interfaces_count.ToHostFormat(); i++) { uint16_t data = Utils::ReadFromStartIntoVal(Globals::buffer(), 2); jc.interfaces.push_back(data); } jc.fields_count = Utils::ReadFromStartIntoVal(Globals::buffer(), 2); std::cout << "Fields Count: " << jc.fields_count.ToHostFormat() << std::endl; for (int i = 0; i < jc.fields_count.ToHostFormat(); i++) { field_info f; FieldInfo::FieldInfoParser(f, jc); } jc.methods_count = Utils::ReadFromStartIntoVal(Globals::buffer()); for (int i = 0; i < jc.methods_count.ToHostFormat(); i++) { method_info m; Methods::MethodParser(m, jc); // std::cout << std::hex << size - Globals::buffer().size() << std::endl; } for (int i = 0; i < jc.constant_pool_count.ToHostFormat() - 1; i++) { std::cout << "(" << i << ") " << (int)jc.constant_pool[i].tag << std::endl; } std::cout << &jc.constant_pool[30].info << std::endl; // delete[] ((ConstantPoolTags::ConstantUtf8Info*)(&jc.constant_pool[30].info))->bytes; // std::cout << jc.methods_count.ToHostFormat() << std::endl; return 0; }