aboutsummaryrefslogtreecommitdiffstats
path: root/erts/include/internal/erl_printf_format.h
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-04-13 16:22:31 +0200
committerBjörn Gustavsson <[email protected]>2016-04-14 10:38:32 +0200
commite72f710ae493cf7ba5da375632b096830df2de5c (patch)
treef539555fc91938e4a5cc96d5d8cc3f3a382f6859 /erts/include/internal/erl_printf_format.h
parent19f231024d5fc4e0e7084b6b38ca404f3368844a (diff)
downloadotp-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