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 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; }