frontend: disassemble: implement dumping the contents of classes
This commit is contained in:
@@ -196,6 +196,202 @@ static void dump_instruction(b_i32 x)
|
||||
}
|
||||
}
|
||||
|
||||
static enum ivy_status dump_class(
|
||||
struct ivy_asm_reader *object, struct ivy_asm_constpool_reader *pool,
|
||||
size_t index)
|
||||
{
|
||||
struct ivy_asm_section_reader *xcls = NULL;
|
||||
struct ivy_asm_constpool_value *class_ident = NULL;
|
||||
enum ivy_status status = ivy_asm_reader_open_section(
|
||||
object, IVY_TABLE_CLASS, index, &xcls);
|
||||
|
||||
if (status != IVY_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
const struct ivy_asm_section_info *class_info
|
||||
= ivy_asm_section_reader_get_info(xcls);
|
||||
|
||||
size_t r;
|
||||
struct ivy_bin_class class_header;
|
||||
status = ivy_asm_section_reader_read(
|
||||
xcls, 0, sizeof class_header, &class_header, &r);
|
||||
if (status != IVY_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (r != sizeof class_header) {
|
||||
status = IVY_ERR_BAD_FORMAT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = ivy_asm_constpool_reader_read_value(
|
||||
pool, b_i32_btoh(class_header.c_ident), &class_ident);
|
||||
if (status != IVY_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (class_ident->v_type != IVY_ASM_CONSTPOOL_TYPE_IDENT) {
|
||||
status = IVY_ERR_BAD_FORMAT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
char class_ident_str[128];
|
||||
ivy_ident_to_string(
|
||||
class_ident->v_ident, class_ident_str, sizeof class_ident_str);
|
||||
|
||||
printf(" * %s\n", class_ident_str);
|
||||
|
||||
struct ivy_bin_class_table_entry entry;
|
||||
size_t nr_entries
|
||||
= (class_info->s_length - sizeof class_header) / sizeof entry;
|
||||
size_t offset = sizeof class_header;
|
||||
|
||||
for (size_t i = 0; i < nr_entries; i++) {
|
||||
status = ivy_asm_section_reader_read(
|
||||
xcls, offset, sizeof entry, &entry, &r);
|
||||
if (status != IVY_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (r != sizeof entry) {
|
||||
status = IVY_ERR_BAD_FORMAT;
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" [%03zu] ", i);
|
||||
|
||||
char s[256];
|
||||
uint32_t type = b_i32_btoh(entry.e_type);
|
||||
switch (type) {
|
||||
case IVY_CLASS_TABLE_PROP: {
|
||||
printf("type:property\n");
|
||||
struct ivy_asm_constpool_value *prop_ident = NULL;
|
||||
status = ivy_asm_constpool_reader_read_value(
|
||||
pool, b_i32_btoh(entry.e_property.p_ident),
|
||||
&prop_ident);
|
||||
if (status != IVY_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (prop_ident->v_type != IVY_ASM_CONSTPOOL_TYPE_IDENT) {
|
||||
status = IVY_ERR_BAD_FORMAT;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t get = b_i32_btoh(entry.e_property.p_get);
|
||||
uint32_t set = b_i32_btoh(entry.e_property.p_set);
|
||||
|
||||
ivy_ident_to_string(prop_ident->v_ident, s, sizeof s);
|
||||
ivy_asm_constpool_value_destroy(prop_ident);
|
||||
printf(" ident:%s, get:", s);
|
||||
if (get) {
|
||||
printf("0x%" PRIx32 "[%" PRIu32 "]", get, get);
|
||||
} else {
|
||||
printf("<none>");
|
||||
}
|
||||
|
||||
printf(", set:");
|
||||
|
||||
if (set) {
|
||||
printf("0x%" PRIx32 "[%" PRIu32 "]", set, set);
|
||||
} else {
|
||||
printf("<none>");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case IVY_CLASS_TABLE_MVAR: {
|
||||
printf("type:variable\n");
|
||||
struct ivy_asm_constpool_value *var_ident = NULL;
|
||||
status = ivy_asm_constpool_reader_read_value(
|
||||
pool, b_i32_btoh(entry.e_mvar.m_ident), &var_ident);
|
||||
if (status != IVY_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (var_ident->v_type != IVY_ASM_CONSTPOOL_TYPE_IDENT) {
|
||||
status = IVY_ERR_BAD_FORMAT;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t index = b_i32_btoh(entry.e_mvar.m_index);
|
||||
ivy_ident_to_string(var_ident->v_ident, s, sizeof s);
|
||||
ivy_asm_constpool_value_destroy(var_ident);
|
||||
printf(" ident:%s, index:0x%" PRIx32
|
||||
"[%" PRIu32 "]",
|
||||
s, index, index);
|
||||
|
||||
break;
|
||||
}
|
||||
case IVY_CLASS_TABLE_MSGH: {
|
||||
printf("type:method\n");
|
||||
struct ivy_asm_constpool_value *sel = NULL;
|
||||
status = ivy_asm_constpool_reader_read_value(
|
||||
pool, b_i32_btoh(entry.e_msgh.msg_selector), &sel);
|
||||
if (status != IVY_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (sel->v_type != IVY_ASM_CONSTPOOL_TYPE_SELECTOR) {
|
||||
status = IVY_ERR_BAD_FORMAT;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t block = b_i32_btoh(entry.e_msgh.msg_block);
|
||||
ivy_selector_to_string(sel->v_sel, s, sizeof s);
|
||||
ivy_asm_constpool_value_destroy(sel);
|
||||
|
||||
printf(" selector:[%s], block:0x%" PRIx32
|
||||
"[%" PRIu32 "]",
|
||||
s, block, block);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
offset += sizeof entry;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (class_ident) {
|
||||
ivy_asm_constpool_value_destroy(class_ident);
|
||||
}
|
||||
|
||||
if (xcls) {
|
||||
ivy_asm_section_reader_close(xcls);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static enum ivy_status dump_classes(struct ivy_asm_reader *object)
|
||||
{
|
||||
struct ivy_asm_constpool_reader *pool;
|
||||
enum ivy_status status
|
||||
= ivy_asm_reader_open_constpool(object, 0, 0, &pool);
|
||||
if (status != IVY_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
printf("classes:\n");
|
||||
for (size_t i = 0;; i++) {
|
||||
status = dump_class(object, pool, i);
|
||||
if (status == IVY_ERR_NO_ENTRY) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != IVY_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
static enum ivy_status dump_constpool(struct ivy_asm_reader *object)
|
||||
{
|
||||
printf("constpool:\n");
|
||||
@@ -507,7 +703,7 @@ static int disassemble(
|
||||
}
|
||||
|
||||
if (classes) {
|
||||
printf("\nclasses:\n");
|
||||
status = dump_classes(reader);
|
||||
}
|
||||
|
||||
ivy_asm_reader_close(reader);
|
||||
@@ -558,7 +754,8 @@ B_COMMAND(CMD_DISASSEMBLE, CMD_ROOT)
|
||||
B_OPTION_SHORT_NAME('c');
|
||||
B_OPTION_LONG_NAME("classes");
|
||||
B_OPTION_DESC(
|
||||
"print the classes contained in the object file.");
|
||||
"print the classes contained in the object "
|
||||
"file.");
|
||||
}
|
||||
|
||||
B_COMMAND_OPTION(OPT_CONSTPOOL)
|
||||
|
||||
Reference in New Issue
Block a user