[FFmpeg-devel] [PATCH] ac3_parser type punning fix

David DeHaven dave
Sun Oct 19 18:44:23 CEST 2008


On Oct 19, 2008, at 8:05 AM, Michael Niedermayer wrote:

> On Sun, Oct 19, 2008 at 11:26:29AM +0100, M?ns Rullg?rd wrote:
>> Michael Niedermayer <michaelni at gmx.at> writes:
>>
>>> On Sat, Oct 18, 2008 at 10:44:16PM -0700, David DeHaven wrote:
>>>>
>>>>> Nothing major, I just applied the same fix that was applied to
>>>>> aac_parser.c recently...
>>>>>
>>>>> -DrD-
>>>>> <ac3_parser.patch>
>>>>
>>>> I think there was confusion about the whole point of this patch...
>>>>
>>>> On the four x86 based machine/OS combos I built and tested on  
>>>> (i686-pc-
>>>> mingw32, 2x i686-pc-linux, i686-apple-darwin), gcc with  
>>>> optimizations
>>>> at more than -O0 would produce machine code that would *only*  
>>>> byteswap
>>>> 32 of the 64 bits in the "state" variable passed to both aac_sync  
>>>> and
>>>> ac3_sync leading to complete and utter misinterpretation of the  
>>>> header
>>>> information. The result: at the *least* would be that it reported  
>>>> the
>>>> wrong information to stdout, at worst it would crash due to  
>>>> having the
>>>> wrong codec parameters. I can't honestly believe that noone else  
>>>> has
>>>> seen this problem, especially considering aac_sync has been already
>>>> fixed unless that was simply a "compiler warning" fix.
>>>>
>>>> I can provide disassembly snippets if you need further  
>>>> convincing...
>>>
>>> I have no doubt that gcc generates wrong code i also have no doubt  
>>> that
>>> the code breaks strict aliassing rules.
>>> The doubt i have is the relation, so to convince me first tell us  
>>> if the
>>> code works with all identical but -fno-strict-aliasing added. If not
>>> the bug is elsewhere, and this patch is hiding it.
>>
>> The C code is the same as in aac_parser, and I confirmed it was  
>> broken
>> myself.  IIRC, it is only gcc 4.3 that optimises it "incorrectly".
>> Scare quotes because the C code is what is incorrect, breaking strict
>> aliasing rules.  You accepted the same patch for the aac parser
>> without questions, so why the hesitation now?
>
> several reasons,
> 1st i tried with and without -fno-strict-aliasing
> and i get:
> -00000480 <ac3_sync>:
> +000004a0 <ac3_sync>:
> :      53                      push   %ebx
> :      83 ec 58                sub    $0x58,%esp
> :      8b 44 24 60             mov    0x60(%esp),%eax
> @@ -397,12 +404,11 @@
> :      c7 44 24 48 00 00 00    movl   $0x0,0x48(%esp)
> :      00
> :      89 04 24                mov    %eax,(%esp)
> -:      e8 fc ff ff ff          call   4cc <ac3_sync+0x4c>
> +:      e8 fc ff ff ff          call   4ec <ac3_sync+0x4c>
> :      31 d2                   xor    %edx,%edx
> :      85 c0                   test   %eax,%eax
> -:      78 43                   js     519 <ac3_sync+0x99>
> +:      78 43                   js     539 <ac3_sync+0x99>
> :      0f b7 44 24 36          movzwl 0x36(%esp),%eax
> -:      8b 54 24 6c             mov    0x6c(%esp),%edx
> :      89 43 38                mov    %eax,0x38(%ebx)
> :      8b 44 24 38             mov    0x38(%esp),%eax
> :      89 43 3c                mov    %eax,0x3c(%ebx)
> @@ -410,6 +416,7 @@
> :      c7 43 40 00 06 00 00    movl   $0x600,0x40(%ebx)
> :      89 43 34                mov    %eax,0x34(%ebx)
> :      31 c0                   xor    %eax,%eax
> +:      8b 54 24 6c             mov    0x6c(%esp),%edx
> :      80 7c 24 1c 02          cmpb   $0x2,0x1c(%esp)
> :      0f 95 c0                setne  %al
> :      89 02                   mov    %eax,(%edx)
> @@ -424,7 +431,7 @@
> :      5b                      pop    %ebx
> :      c3                      ret
>
> ------------
> now i didnt confirm that the asm was wrong, so i asked if david sees
> -fno-strict-aliasing fixing the issue he has ...
> (and above is with gcc 4.3.1)
>
> The second reason is
> #define AV_RN64(a) (*((const uint64_t*)(a)))
> #define AV_WN64(a, b) *((uint64_t*)(a)) = (b)
> ...
> #  define AV_RB64(x)    bswap_64(AV_RN64(x))
> #  define AV_WB64(p, d) AV_WN64(p, bswap_64(d))
>
> The third reason is that i have doubts this really is a strict  
> aliasing issue
> aliasing does not apply to intXY <-> int8 it just applies to things  
> not
> involving int8. Now the truth is we do mix 64 write and 32 bit read  
> with a
> int8 pointer thus our code is wrong with strict aliasing but for gcc  
> to mess
> up it has to proof that the int8 pointer written is not read as int8  
> or int64.
> Iam surprissed it does this but at the same time does then only  
> ommit half
> of the int64 code. It really could ommit all if it thought its never  
> read.
> Also gcc would have to analyze some non static and not inlined  
> functions to
> pull this trick off.
> Thats all assuming i do not miss something ...

I don't think it's necessarily a problem with strict aliasing, it's  
likely a problem (possibly a bug?) in the gcc optimizer. The problem  
also disappears if I do something with "state" argument prior to  
creating the GetBitContext, like printing the contents to stdout,  
which it why I had to start digging into assembly... I didn't dig too  
deeply as I saw the fix in aac_parser and the problem went away there,  
so I figured we could just apply it here too.

Actually, I was wrong on one count, it works fine on gcc 4.0.1 for  
i686-apple-darwin (XCode 3.0)... it was only broken on Linux and MinGW  
builds (using gcc 4.2.4, 4.3.0 and 4.3.1)

-DrD-





More information about the ffmpeg-devel mailing list