예제 #1
0
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 );
		}
	}
}
예제 #2
0
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, '}' );
}
예제 #3
0
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;
}