diff options
author | Björn Gustavsson <[email protected]> | 2015-06-29 13:24:31 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-07-03 14:28:03 +0200 |
commit | dfe1c58c504531361fa3f8ed874238a9ff552640 (patch) | |
tree | 42dc0c14edb059bfb6e331ddf81f6f1f41aa3bae /erts/emulator | |
parent | 26f1810479a837ab338e7a9e3aef027a9e4b098d (diff) | |
download | otp-dfe1c58c504531361fa3f8ed874238a9ff552640.tar.gz otp-dfe1c58c504531361fa3f8ed874238a9ff552640.tar.bz2 otp-dfe1c58c504531361fa3f8ed874238a9ff552640.zip |
beam_makeops: Eliminate crash because of unsafe packing
Consider an hypothetical instruction:
do_something x x c
The loader would crash if we tried to load an instance of the
instruction with the last operand referencing a literal:
{do_something,{x,0},{x,1},{literal,{a,b,c}}}
Teach beam_makeops to turn off packing for such unsafe instructions.
Diffstat (limited to 'erts/emulator')
-rwxr-xr-x | erts/emulator/utils/beam_makeops | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops index e90ed94187..7c94546ea4 100755 --- a/erts/emulator/utils/beam_makeops +++ b/erts/emulator/utils/beam_makeops @@ -1057,6 +1057,7 @@ sub do_pack { my($packable_args) = 0; my @is_packable; # Packability (boolean) for each argument. my $wide_packing = 0; + my(@orig_args) = @args; # # Count the number of packable arguments. If we encounter any 's' or 'd' @@ -1077,6 +1078,18 @@ sub do_pack { } } elsif ($arg =~ /^[sd]/) { return ('', '', @args); + } elsif ($arg =~ /^[scq]/ and $packable_args > 0) { + # When packing, this operand will be picked up from the + # code array, put onto the packing stack, and later put + # back into a different location in the code. The problem + # is that if this operand is a literal, the original + # location in the code would have been remembered in a + # literal patch. For packing to work, we would have to + # adjust the position in the literal patch. For the + # moment, adding additional instructions to the packing + # engine to handle this does not seem worth it, so we will + # just turn off packing. + return ('', '', @args); } else { push @is_packable, 0; } |