diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index af2747a77e2d..7bc6a04874a6 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -492,16 +492,28 @@ static int load_code(LoaderState* stp) * Use bit masks to quickly find the most specific of the * the possible specific instructions associated with this * specific instruction. + * + * Note that currently only instructions having no more + * than 6 operands are supported. */ int specific, arity, arg, i; Uint32 mask[3] = {0, 0, 0}; - arity = gen_opc[tmp_op->op].arity; + if (num_specific != 0) { + /* The `bs_append` instruction made obsolete in + * Erlang/OTP 28 has 8 operands. Therefore, the if + * statement preventing the loop that follows to be + * entered is necessary to prevent writing beyond the + * last entry of the mask array. */ + arity = gen_opc[tmp_op->op].arity; - for (arg = 0; arg < arity; arg++) { - int type = tmp_op->a[arg].type; + ASSERT(2 * (sizeof(mask) / sizeof(mask[0])) >= arity); - mask[arg / 2] |= (1u << type) << ((arg % 2) << 4); + for (arg = 0; arg < arity; arg++) { + int type = tmp_op->a[arg].type; + + mask[arg / 2] |= (1u << type) << ((arg % 2) << 4); + } } specific = gen_opc[tmp_op->op].specific; @@ -567,7 +579,7 @@ static int load_code(LoaderState* stp) * No specific operations and no transformations means that * the instruction is obsolete. */ - if (num_specific == 0 && gen_opc[tmp_op->op].transform == -1) { + if (num_specific == 0 && gen_opc[tmp_op->op].transform == 0) { BeamLoadError0(stp, PLEASE_RECOMPILE); } diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c index 6319cf7ee136..ba04d623530d 100644 --- a/erts/emulator/beam/erl_message.c +++ b/erts/emulator/beam/erl_message.c @@ -171,7 +171,10 @@ erts_cleanup_offheap_list(struct erl_off_heap_header* first) erts_bin_release(u.br->val); break; case FUN_REF_SUBTAG: - if (erts_refc_dectest(&(u.fref->entry)->refc, 0) == 0) { + /* The pointer to the fun entry can be NULL if loading + * was aborted because of an invalid BEAM file. */ + if (u.fref->entry && + erts_refc_dectest(&(u.fref->entry)->refc, 0) == 0) { erts_erase_fun_entry(u.fref->entry); } break;