aboutsummaryrefslogtreecommitdiffstats
path: root/src/serd_internal.h
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2016-05-17 11:58:47 -0400
committerDavid Robillard <d@drobilla.net>2016-05-17 11:58:47 -0400
commite2d1f43bc10172272a74e2bcf2460b0dbc91aeea (patch)
treef16f51f759e9a14e7e9d3f6e0fac425200c1af68 /src/serd_internal.h
parent4177848a044eead797dfa3262c1781491cc6a56f (diff)
downloadserd-e2d1f43bc10172272a74e2bcf2460b0dbc91aeea.tar.gz
serd-e2d1f43bc10172272a74e2bcf2460b0dbc91aeea.tar.bz2
serd-e2d1f43bc10172272a74e2bcf2460b0dbc91aeea.zip
Fix unaligned memory access (UB which breaks ARM)
With this fix, the test suite runs cleanly with UBSan.
Diffstat (limited to 'src/serd_internal.h')
-rw-r--r--src/serd_internal.h34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/serd_internal.h b/src/serd_internal.h
index 20700bb8..23fd75b4 100644
--- a/src/serd_internal.h
+++ b/src/serd_internal.h
@@ -1,5 +1,5 @@
/*
- Copyright 2011-2014 David Robillard <http://drobilla.net>
+ Copyright 2011-2016 David Robillard <http://drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -123,6 +123,38 @@ serd_stack_pop(SerdStack* stack, size_t n_bytes)
stack->size -= n_bytes;
}
+static inline void*
+serd_stack_push_aligned(SerdStack* stack, size_t n_bytes, size_t align)
+{
+ // Push one byte to ensure space for a pad count
+ serd_stack_push(stack, 1);
+
+ // Push padding if necessary
+ const uint8_t pad = align - stack->size % align;
+ if (pad > 0) {
+ serd_stack_push(stack, pad);
+ }
+
+ // Set top of stack to pad count so we can properly pop later
+ stack->buf[stack->size - 1] = pad;
+
+ // Push requested space at aligned location
+ return serd_stack_push(stack, n_bytes);
+}
+
+static inline void
+serd_stack_pop_aligned(SerdStack* stack, size_t n_bytes)
+{
+ // Pop requested space down to aligned location
+ serd_stack_pop(stack, n_bytes);
+
+ // Get amount of padding from top of stack
+ const uint8_t pad = stack->buf[stack->size - 1];
+
+ // Pop padding and pad count
+ serd_stack_pop(stack, pad + 1);
+}
+
/* Bulk Sink */
typedef struct SerdBulkSinkImpl {