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

Anton D. Kachalov mouse at yandex-team.ru
Wed Nov 25 05:12:25 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>
---
 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:
-- 
1.9.1


More information about the Spice-devel mailing list