Add rudimentary attribute parsing support

This commit is contained in:
calcium 2024-08-19 19:58:37 -04:00
parent 002917d91c
commit 0d3abe0988
2 changed files with 161 additions and 0 deletions

109
include/Attributes.h Normal file
View File

@ -0,0 +1,109 @@
#ifndef __CAVM_ATTRIBUTES_H
#define __CAVM_ATTRIBUTES_H
#include <ClassFormat.h>
#include <SpecTypes.h>
#include <Utils/CRC32_CompileTime.hpp>
#include <cstdint>
namespace Attributes
{
enum class ClassAttributes : uint32_t
{
SOURCE_FILE = "SourceFile"_crc32,
INNER_CLASSES = "InnerClasses"_crc32,
ENCLOSING_METHOD = "EnclosingMethod"_crc32,
SOURCE_DEBUG_EXTENSION = "SourceDebugExtension"_crc32,
BOOTSTRAP_METHODS = "BootstrapMethods"_crc32,
MODULE = "Module"_crc32,
MODULE_PACKAGES = "ModulePackages"_crc32,
MODULE_MAIN_CLASS = "ModuleMainClass"_crc32,
NEST_HOST = "NestHost"_crc32,
NEST_MEMBERS = "NestMembers"_crc32,
RECORD = "Record"_crc32,
PERMITTED_SUBCLASSES = "PermittedSubclasses"_crc32,
SYNTHETIC = "Synthetic"_crc32,
DEPRECATED = "Deprecated"_crc32,
SIGNATURE = "Signature"_crc32,
RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"_crc32,
};
enum class FieldAttributes : uint32_t
{
CONSTANT_VALUE = "ConstantValue"_crc32,
SYNTHETIC = "Synthetic"_crc32,
DEPRECATED = "Deprecated"_crc32,
SIGNATURE = "Signature"_crc32,
RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"_crc32,
RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations"_crc32,
RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations"_crc32,
RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations"_crc32,
};
enum class MethodAttributes : uint32_t
{
CODE = "Code"_crc32,
EXCEPTIONS = "Exceptions"_crc32,
RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations"_crc32,
RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations"_crc32,
ANNOTATION_DEFAULT = "AnnotationDefault"_crc32,
METHOD_PARAMETERS = "MethodParameters"_crc32,
SYNTHETIC = "Synthetic"_crc32,
DEPRECATED = "Deprecated"_crc32,
SIGNATURE = "Signature"_crc32,
RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"_crc32,
RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations"_crc32,
RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations"_crc32,
RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations"_crc32,
};
enum class RecordComponentAttributes : uint32_t
{
RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"_crc32,
RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations"_crc32,
RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations"_crc32,
RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations"_crc32,
};
enum class CodeAttributes : uint32_t
{
LINE_NUMBER_TABLE = "LineNumberTable"_crc32,
LOCAL_VARIABLE_TABLE = "LocalVariableTable"_crc32,
LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable"_crc32,
STACK_MAP_TABLE = "StackMapTable"_crc32,
RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations"_crc32,
RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations"_crc32,
};
struct CODE_Attribute : BaseAttribute
{
private:
typedef struct
{
u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table;
public:
u2 max_stack;
u2 max_locals;
u4 code_length;
std::vector<uint8_t> code;
u2 exception_table_length;
std::vector<exception_table> exceptions;
u2 attributes_count;
std::vector<attribute_info> attributes;
};
struct SOURCE_FILE_Attribute : BaseAttribute
{
u2 sourcefile_index;
};
attribute_info AttributesParser(JavaClassFormat &jc);
} // namespace Attributes
#endif

52
src/AttributeParser.cpp Normal file
View File

@ -0,0 +1,52 @@
#include "ConstantPoolTags/Tags.h"
#include <Globals.h>
#include <Utils/Utils.h>
#include <Attributes.h>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <string>
#include <Utils/CRC32_CompileTime.hpp>
attribute_info Attributes::AttributesParser(JavaClassFormat& jc)
{
attribute_info ret;
ret.attribute_name_index = Utils::ReadFromStartIntoVal<uint16_t>(Globals::buffer());
ret.attribute_length = Utils::ReadFromStartIntoVal<uint32_t>(Globals::buffer());
ASSERT(ret.attribute_length.ToHostFormat() > 0);
for (int i = 0; i < ret.attribute_length.ToHostFormat(); i++)
{
ret.info.push_back(Utils::ReadFromStartIntoVal<uint8_t>(Globals::buffer(), 1));
}
std::reverse(ret.info.begin(), ret.info.end());
int idx = ret.info.data()->ToHostFormat();
ASSERT(VEC_ELEM_TYPE(jc.constant_pool[ret.attribute_name_index.ToHostFormat() - 1]) == TYPE(ConstantPoolTags::ConstantUtf8Info));
std::string str = reinterpret_cast<const char*>(std::any_cast<ConstantPoolTags::ConstantUtf8Info>(jc.constant_pool[ret.attribute_name_index.ToHostFormat() - 1]).bytes);
switch ((ClassAttributes)crc32_rec(CRC32, str.c_str()))
{
case ClassAttributes::SOURCE_FILE:
{
ASSERT(VEC_ELEM_TYPE(jc.constant_pool[idx - 1]) == TYPE(ConstantPoolTags::ConstantUtf8Info));
std::cout << "Source File: "
<< std::any_cast<ConstantPoolTags::ConstantUtf8Info>(jc.constant_pool[idx - 1]).bytes
<< std::endl;
SOURCE_FILE_Attribute attr;
// attr.
break;
}
default:
std::cerr << "Unknown attribute: \"" << str << "\"" << std::endl;
exit(EXIT_FAILURE);
}
// switch ()
return ret;
}