[Spice-devel] [PATCH] demarshall: Add safe method for unaligned byte access.

Frediano Ziglio fziglio at redhat.com
Wed Nov 25 06:04:58 PST 2015


> 
> Usefull for ARM. Enable with "USE_MEMCPY" define.
>  Should be better to add "--use-memcpy" to configure.ac
> 
> Signed-off-by: Anton D. Kachalov <mouse at yandex-team.ru>

Are you sure there are not other way except memcpy?

> ---
>  python_modules/demarshal.py | 29 +++++++++++++++++++----------
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/python_modules/demarshal.py b/python_modules/demarshal.py
> index 209eafc..158acd6 100644
> --- a/python_modules/demarshal.py
> +++ b/python_modules/demarshal.py
> @@ -47,17 +47,25 @@ def write_parser_helpers(writer):
>              type = "%sint%d" % (sign, size)
>              swap = "SPICE_BYTESWAP%d" % size
>              if size == 8:
> -                writer.macro("read_%s" % type, "ptr", "(*((%s_t *)(ptr)))" %
> type)
> -                writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr)
> = val" % (type))
> +                writer.macro("read_%s" % type, "val, ptr", "*(val) =
> (*((%s_t *)(ptr)))" % type)
> +                writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr)
> = *val" % (type))
>              else:
> -                writer.macro("read_%s" % type, "ptr", "((%s_t)%s(*((%s_t
> *)(ptr))))" % (type, swap, utype))
> -                writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr)
> = %s((%s_t)val)" % (utype, swap, utype))
> +                writer.macro("read_%s" % type, "val, ptr", "*(val) =
> ((%s_t)%s(*((%s_t *)(ptr))))" % (type, swap, utype))
> +                writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr)
> = %s(*(%s_t)val)" % (utype, swap, utype))
>      writer.writeln("#else")
> +    writer.writeln("#ifdef USE_MEMCPY")
>      for size in [8, 16, 32, 64]:
>          for sign in ["", "u"]:
>              type = "%sint%d" % (sign, size)
> -            writer.macro("read_%s" % type, "ptr", "(*((%s_t *)(ptr)))" %
> type)
> -            writer.macro("write_%s" % type, "ptr, val", "(*((%s_t *)(ptr)))
> = val" % type)
> +            writer.macro("read_%s" % type, "val, ptr", "memcpy(val, ptr,
> sizeof(%s_t))" % type)
> +            writer.macro("write_%s" % type, "ptr, val", "memcpy(ptr, val,
> sizeof(%s_t))" % type)
> +    writer.writeln("#else")
> +    for size in [8, 16, 32, 64]:
> +        for sign in ["", "u"]:
> +            type = "%sint%d" % (sign, size)
> +            writer.macro("read_%s" % type, "val, ptr", "*(val) = (*((%s_t
> *)(ptr)))" % type)
> +            writer.macro("write_%s" % type, "ptr, val", "(*((%s_t *)(ptr)))
> = *val" % type)
> +    writer.writeln("#endif")
>      writer.writeln("#endif")
>  
>      for size in [8, 16, 32, 64]:
> @@ -67,7 +75,7 @@ def write_parser_helpers(writer):
>              ctype = "%s_t" % type
>              scope = writer.function("SPICE_GNUC_UNUSED consume_%s" % type,
>              ctype, "uint8_t **ptr", True)
>              scope.variable_def(ctype, "val")
> -            writer.assign("val", "read_%s(*ptr)" % type)
> +            writer.statement("read_%s(&val, *ptr)" % type)
>              writer.increment("*ptr", size // 8)
>              writer.statement("return val")
>              writer.end_block()
> @@ -96,7 +104,7 @@ def write_read_primitive(writer, start, container, name,
> scope):
>      var = "%s__value" % (name.replace(".", "_"))
>      if not scope.variable_defined(var):
>          scope.variable_def(m.member_type.c_type(), var)
> -    writer.assign(var, "read_%s(pos)" % (m.member_type.primitive_type()))
> +    writer.statement("read_%s(&%s, pos)" % (m.member_type.primitive_type(),
> var))
>      return var
>  
>  def write_write_primitive(writer, start, container, name, val):
> @@ -105,7 +113,8 @@ def write_write_primitive(writer, start, container, name,
> val):
>      writer.assign("pos", start + " + " + container.get_nw_offset(m, "",
>      "__nw_size"))
>  
>      var = "%s__value" % (name)
> -    writer.statement("write_%s(pos, %s)" % (m.member_type.primitive_type(),
> val))
> +    writer.assign(var, val)
> +    writer.statement("write_%s(pos, &%s)" % (m.member_type.primitive_type(),
> var))
>      return var
>  
>  def write_read_primitive_item(writer, item, scope):
> @@ -114,7 +123,7 @@ def write_read_primitive_item(writer, item, scope):
>      writer.error_check("pos + %s > message_end" %
>      item.type.get_fixed_nw_size())
>      var = "%s__value" % (item.subprefix.replace(".", "_"))
>      scope.variable_def(item.type.c_type(), var)
> -    writer.assign(var, "read_%s(pos)" % (item.type.primitive_type()))
> +    writer.statement("read_%s(&%s, pos)" % (item.type.primitive_type(),
> var))
>      return var
>  
>  class ItemInfo:

Passing pointers for every read_* and write_* function will lead to aliasing
and worst executable for most architectures. You should write these function
without requiring to pass pointers.
Use functions is macros are not enough powerful.

Frediano


More information about the Spice-devel mailing list