diff options
author | Björn Gustavsson <[email protected]> | 2016-04-13 16:22:31 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-04-14 10:38:32 +0200 |
commit | e72f710ae493cf7ba5da375632b096830df2de5c (patch) | |
tree | f539555fc91938e4a5cc96d5d8cc3f3a382f6859 /erts/include/internal/erl_printf_format.h | |
parent | 19f231024d5fc4e0e7084b6b38ca404f3368844a (diff) | |
download | otp-e72f710ae493cf7ba5da375632b096830df2de5c.tar.gz otp-e72f710ae493cf7ba5da375632b096830df2de5c.tar.bz2 otp-e72f710ae493cf7ba5da375632b096830df2de5c.zip |
Correct unpacking of 3 operands on 32-bit archictectures
0a4750f91c83 optimized unpacking by removing a mask operation
when unpacking three packed operands. Unfortunately, that optimization
is only safe on 64-bit architectures.
Here is what happens on 32-bit architectures.
The operands to be packed are 10-bit register numbers that have been
turned into byte offsets:
aaaaaaaaaa00
bbbbbbbbbb00
cccccccccc00
They can be packed into a single word like this:
30 20 10 0
| | | |
aa aaaaaaaabb bbbbbbbbcc cccccccc00
If we call the packed word P, the original operands can be
extracted like this:
C = P band 2#111111111100
B = (P bsr 10) band 2#111111111100
A = (P bsr 20) band 2#111111111100
The bug was that A was extracted without the masking:
A = P bsr 20
That would give A the value:
aaaaaaaaaaaabb
That would only be safe if the two most significant bits in B
were zeroes.
Diffstat (limited to 'erts/include/internal/erl_printf_format.h')
0 files changed, 0 insertions, 0 deletions