aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_binary.h
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2015-05-26 20:12:08 +0200
committerSverker Eriksson <[email protected]>2015-06-01 19:44:15 +0200
commit957f619382923be72835500f56e75d8bbe553892 (patch)
tree6c2c555083d48c8342dd31ec01c8ef239f448538 /erts/emulator/beam/erl_binary.h
parent9c34c2544981ff2df6ddf94b36f4a9db5d6da6b5 (diff)
downloadotp-957f619382923be72835500f56e75d8bbe553892.tar.gz
otp-957f619382923be72835500f56e75d8bbe553892.tar.bz2
otp-957f619382923be72835500f56e75d8bbe553892.zip
erts: Fix magic binary alignment on 32-bit
Caused bus error on 32-bit sparc from unaligned 64-bit word in binary_to_term trap context. Also add _UNALIGNED_ magic macros to avoid double alignment padding in NIF resources.
Diffstat (limited to 'erts/emulator/beam/erl_binary.h')
-rw-r--r--erts/emulator/beam/erl_binary.h18
1 files changed, 15 insertions, 3 deletions
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index 8d264d166e..6b96787d40 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -194,6 +194,9 @@ ERTS_GLB_INLINE Binary *erts_bin_nrml_alloc(Uint size);
ERTS_GLB_INLINE Binary *erts_bin_realloc_fnf(Binary *bp, Uint size);
ERTS_GLB_INLINE Binary *erts_bin_realloc(Binary *bp, Uint size);
ERTS_GLB_INLINE void erts_bin_free(Binary *bp);
+ERTS_GLB_INLINE Binary *erts_create_magic_binary_x(Uint size,
+ void (*destructor)(Binary *),
+ int unaligned);
ERTS_GLB_INLINE Binary *erts_create_magic_binary(Uint size,
void (*destructor)(Binary *));
@@ -332,21 +335,30 @@ erts_bin_free(Binary *bp)
}
ERTS_GLB_INLINE Binary *
-erts_create_magic_binary(Uint size, void (*destructor)(Binary *))
+erts_create_magic_binary_x(Uint size, void (*destructor)(Binary *),
+ int unaligned)
{
- Uint bsize = ERTS_MAGIC_BIN_SIZE(size);
+ Uint bsize = unaligned ? ERTS_MAGIC_BIN_UNALIGNED_SIZE(size)
+ : ERTS_MAGIC_BIN_SIZE(size);
Binary* bptr = erts_alloc_fnf(ERTS_ALC_T_BINARY, bsize);
ASSERT(bsize > size);
if (!bptr)
erts_alloc_n_enomem(ERTS_ALC_T2N(ERTS_ALC_T_BINARY), bsize);
ERTS_CHK_BIN_ALIGNMENT(bptr);
bptr->flags = BIN_FLAG_MAGIC;
- bptr->orig_size = ERTS_MAGIC_BIN_ORIG_SIZE(size);
+ bptr->orig_size = unaligned ? ERTS_MAGIC_BIN_UNALIGNED_ORIG_SIZE(size)
+ : ERTS_MAGIC_BIN_ORIG_SIZE(size);
erts_refc_init(&bptr->refc, 0);
ERTS_MAGIC_BIN_DESTRUCTOR(bptr) = destructor;
return bptr;
}
+ERTS_GLB_INLINE Binary *
+erts_create_magic_binary(Uint size, void (*destructor)(Binary *))
+{
+ return erts_create_magic_binary_x(size, destructor, 0);
+}
+
#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
#endif /* !__ERL_BINARY_H */