diff options
author | Lukas Larsson <[email protected]> | 2019-03-27 10:51:33 +0100 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2019-04-09 14:29:10 +0200 |
commit | 0ded2cd1845020c475126c98b45e14e8c85d50eb (patch) | |
tree | 814324338da858242d6a25cd4036fd2a5566a199 | |
parent | 1e0023daa84adbb2cf68d7d9f8d0e6a0bfadf884 (diff) | |
download | otp-0ded2cd1845020c475126c98b45e14e8c85d50eb.tar.gz otp-0ded2cd1845020c475126c98b45e14e8c85d50eb.tar.bz2 otp-0ded2cd1845020c475126c98b45e14e8c85d50eb.zip |
erts: Fix buffer alignment bug in alloc_dist_obuf
Cannot do unaligned word writes on sparc!
-rw-r--r-- | erts/emulator/beam/dist.c | 27 | ||||
-rw-r--r-- | erts/emulator/beam/erl_node_tables.h | 1 |
2 files changed, 18 insertions, 10 deletions
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index a7a3fd4b1e..caef26e06c 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -775,19 +775,25 @@ void init_dist(void) static ERTS_INLINE ErtsDistOutputBuf * alloc_dist_obuf(Uint size, Uint headers) { - int i; + Uint obuf_size = sizeof(ErtsDistOutputBuf)*(headers); ErtsDistOutputBuf *obuf; - Uint obuf_size = sizeof(ErtsDistOutputBuf)*(headers) + - sizeof(byte)*size; - Binary *bin = erts_bin_drv_alloc(obuf_size); - obuf = (ErtsDistOutputBuf *) &bin->orig_bytes[size]; + Binary *bin; + byte *extp; + int i; + + bin = erts_bin_drv_alloc(obuf_size + size); erts_refc_add(&bin->intern.refc, headers - 1, 1); + + obuf = (ErtsDistOutputBuf *)&bin->orig_bytes[0]; + extp = (byte *)&bin->orig_bytes[obuf_size]; + for (i = 0; i < headers; i++) { obuf[i].bin = bin; - obuf[i].extp = (byte *)&bin->orig_bytes[0]; + obuf[i].extp = extp; #ifdef DEBUG obuf[i].dbg_pattern = ERTS_DIST_OUTPUT_BUF_DBG_PATTERN; - obuf[i].alloc_endp = obuf->extp + size; + obuf[i].ext_startp = extp; + obuf[i].alloc_endp = &extp[size]; ASSERT(bin == ErtsDistOutputBuf2Binary(obuf)); #endif } @@ -2341,7 +2347,8 @@ erts_dsig_send(ErtsDSigSendContext *ctx) (ctx->fragments-1) * ERTS_DIST_FRAGMENT_HEADER_SIZE, ctx->fragments); ctx->obuf->ext_start = &ctx->obuf->extp[0]; - ctx->obuf->ext_endp = &ctx->obuf->extp[0] + ctx->max_finalize_prepend + ctx->dhdr_ext_size; + ctx->obuf->ext_endp = &ctx->obuf->extp[0] + ctx->max_finalize_prepend + + ctx->dhdr_ext_size; /* Encode internal version of dist header */ ctx->obuf->extp = erts_encode_ext_dist_header_setup( @@ -2380,8 +2387,8 @@ erts_dsig_send(ErtsDSigSendContext *ctx) case ERTS_DSIG_SEND_PHASE_FIN: { ASSERT(ctx->obuf->extp < ctx->obuf->ext_endp); - ASSERT(((byte*)&ctx->obuf->bin->orig_bytes[0]) <= ctx->obuf->extp - ctx->max_finalize_prepend); - ASSERT(ctx->obuf->ext_endp <= ((byte*)ctx->obuf->bin->orig_bytes) + ctx->data_size + ctx->dhdr_ext_size); + ASSERT(ctx->obuf->ext_startp <= ctx->obuf->extp - ctx->max_finalize_prepend); + ASSERT(ctx->obuf->ext_endp <= (byte*)ctx->obuf->ext_startp + ctx->data_size + ctx->dhdr_ext_size); ctx->data_size = ctx->obuf->ext_endp - ctx->obuf->extp; diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h index c434926142..fc3e117463 100644 --- a/erts/emulator/beam/erl_node_tables.h +++ b/erts/emulator/beam/erl_node_tables.h @@ -95,6 +95,7 @@ enum dist_entry_state { struct ErtsDistOutputBuf_ { #ifdef DEBUG Uint dbg_pattern; + byte *ext_startp; byte *alloc_endp; #endif ErtsDistOutputBuf *next; |