void dl_internal_patch_instance( dl_ctx_t ctx, const dl_type_desc* type, uint8_t* instance, uintptr_t base_address, uintptr_t patch_distance ) { dl_patched_ptrs patched; patched.add( instance ); if( type->flags & DL_TYPE_FLAG_IS_UNION ) { // TODO: extract to helper-function? size_t max_member_size = dl_internal_largest_member_size( ctx, type, DL_PTR_SIZE_HOST ); // find member index from union type ... uint32_t union_type = *((uint32_t*)(instance + max_member_size)); const dl_member_desc* member = dl_internal_find_member_desc_by_name_hash( ctx, type, union_type ); uint8_t* member_data = instance + member->offset[DL_PTR_SIZE_HOST]; dl_internal_patch_member( ctx, member, member_data, base_address, patch_distance, &patched ); } else { for( uint32_t member_index = 0; member_index < type->member_count; ++member_index ) { const dl_member_desc* member = dl_get_type_member( ctx, type, member_index ); uint8_t* member_data = instance + member->offset[DL_PTR_SIZE_HOST]; dl_internal_patch_member( ctx, member, member_data, base_address, patch_distance, &patched ); } } }
static void dl_txt_unpack_struct( dl_ctx_t dl_ctx, dl_txt_unpack_ctx* unpack_ctx, dl_binary_writer* writer, const dl_type_desc* type, const uint8_t* struct_data ) { dl_binary_writer_write( writer, "{\n", 2 ); unpack_ctx->indent += 2; if( type->flags & DL_TYPE_FLAG_IS_UNION ) { // TODO: check if type is not set at all ... size_t type_offset = dl_internal_union_type_offset( dl_ctx, type, DL_PTR_SIZE_HOST ); // find member index from union type ... uint32_t union_type = *((uint32_t*)(struct_data + type_offset)); const dl_member_desc* member = dl_internal_find_member_desc_by_name_hash( dl_ctx, type, union_type ); dl_txt_unpack_member( dl_ctx, unpack_ctx, writer, member, struct_data + member->offset[DL_PTR_SIZE_HOST] ); dl_binary_writer_write( writer, "\n", 1 ); } else { for( uint32_t member_index = 0; member_index < type->member_count; ++member_index ) { const dl_member_desc* member = dl_get_type_member( dl_ctx, type, member_index ); dl_txt_unpack_member( dl_ctx, unpack_ctx, writer, member, struct_data + member->offset[DL_PTR_SIZE_HOST] ); if( member_index < type->member_count - 1 ) dl_binary_writer_write( writer, ",\n", 2 ); else dl_binary_writer_write( writer, "\n", 1 ); } } if( struct_data == unpack_ctx->packed_instance ) { if( unpack_ctx->has_ptrs ) { unpack_ctx->indent += 2; dl_txt_unpack_write_indent( writer, unpack_ctx ); dl_binary_writer_write( writer, ", \"__subdata\" : {\n", 18 ); unpack_ctx->indent += 2; dl_txt_unpack_write_subdata( dl_ctx, unpack_ctx, writer, type, struct_data ); unpack_ctx->indent -= 2; dl_txt_unpack_write_indent( writer, unpack_ctx ); dl_binary_writer_write( writer, "}\n", 2 ); unpack_ctx->indent -= 2; } } unpack_ctx->indent -= 2; dl_txt_unpack_write_indent( writer, unpack_ctx ); dl_binary_writer_write_uint8( writer, '}' ); }
static dl_error_t dl_internal_instance_store( dl_ctx_t dl_ctx, const dl_type_desc* type, uint8_t* instance, CDLBinStoreContext* store_ctx ) { bool last_was_bitfield = false; dl_binary_writer_align( &store_ctx->writer, type->alignment[DL_PTR_SIZE_HOST] ); uintptr_t instance_pos = dl_binary_writer_tell( &store_ctx->writer ); if( type->flags & DL_TYPE_FLAG_IS_UNION ) { // TODO: extract to helper-function? size_t max_member_size = dl_internal_largest_member_size( dl_ctx, type, DL_PTR_SIZE_HOST ); // find member index from union type ... uint32_t union_type = *((uint32_t*)(instance + max_member_size)); const dl_member_desc* member = dl_internal_find_member_desc_by_name_hash( dl_ctx, type, union_type ); dl_error_t err = dl_internal_store_member( dl_ctx, member, instance + member->offset[DL_PTR_SIZE_HOST], store_ctx ); if( err != DL_ERROR_OK ) return err; dl_binary_writer_seek_set( &store_ctx->writer, instance_pos + max_member_size ); dl_binary_writer_align( &store_ctx->writer, 4 ); dl_binary_writer_write_uint32( &store_ctx->writer, union_type ); } else { for( uint32_t member_index = 0; member_index < type->member_count; ++member_index ) { const dl_member_desc* member = dl_get_type_member( dl_ctx, type, member_index ); if( !last_was_bitfield || member->AtomType() != DL_TYPE_ATOM_BITFIELD ) { dl_binary_writer_seek_set( &store_ctx->writer, instance_pos + member->offset[DL_PTR_SIZE_HOST] ); dl_error_t err = dl_internal_store_member( dl_ctx, member, instance + member->offset[DL_PTR_SIZE_HOST], store_ctx ); if( err != DL_ERROR_OK ) return err; } last_was_bitfield = member->AtomType() == DL_TYPE_ATOM_BITFIELD; } } return DL_ERROR_OK; }