boot decompressor code error

Brian Murphy brian at murphy.dk
Wed Nov 3 04:16:12 EDT 2010


On Fri, Oct 29, 2010 at 12:56 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Fri, Oct 29, 2010 at 12:22:47PM +0200, Brian Murphy wrote:
>> Hi,
>> There is a problem with the boot decompression code when the inflate
>> method is used on arm.
>> In fact two. The second of which is also a problem on all architectures.
>> The first, and more serious, is that static local variables seem not
>> to be supported,
>
> static local variables are no different from static global variables
> except their scope.  static local variables can only be referenced
> from within the block which they are defined and any child blocks,
> whereas static global variables can be referenced by any code in the
> same compilation unit.
>
> Their storage and initialization in both cases is identical.
>
>> this means that
>> some tables initialized as static locals point to a place in ram where
>> the tables are not.
>> The function
>>
>> static void zlib_fixedtables(struct inflate_state *state)
>>
>> includes inffixed.h which contains two static tables and
>
> Both these tables are 'const' which means they end up in the read-only
> section, and ultimately the text section of the image, not the data
> section.
>
>> int zlib_inflate(z_streamp strm, int flush)
>>
>> contains a static local "order". The second seems not to have much
>> influence on decompression
>> but the first causes images (at least of a certain size) to fail
>> decompression.
>
> Again, this is "static const unsigned short order[19] = ..." which
> because of the const, ends up in the read-only section and therefore
> the text section of the image.
>
> This is what I see from arm-linux-nm -n arch/arm/boot/compressed/vmlinux:
> ...
> 000835f0 t order.0
> 00083618 t lenfix.1
> 00083e18 t distfix.2
> ...
> which clearly shows these tables in the text section.  Also
> arm-linux-objdump -t arch/arm/boot/compressed/decompress.o shows:
> ...
> 000000fc l     O .rodata        00000026 order.0
> 00000124 l     O .rodata        00000800 lenfix.1
> 00000924 l     O .rodata        00000080 distfix.2
> ...
> which shows that these were placed into the .rodata section initially,
> as I explained above.
>
> Can you show your output from the above commands please?  Also show
> the output of:
>
> arm-linux-nm -n arch/arm/boot/compressed/vmlinux|grep '\<__bss_start\>\|\<_end\>'
>
> arm-linux-objdump --section=.got -s arch/arm/boot/compressed/vmlinux
>
> Also, are you using ZBOOT_ROM=y or =n ?
>

It looks like you were right, to some degree :). The table data is in
the image transferred to
the board but it looks like static locals are treated by the compiler
as locals and allocated on
the stack! This, of course, means that at some point they get
(partially) overwritten by newer
locals and thus corrupted.

I can't get the output you show above, the names of the local
variables get lost and they get
translated to a C followed by some numbers: thus C.41.2187.

Can I ask you which version of gcc and binutils you use?

I have tested with a gcc 4.3.4/binutils 2.19.1 compiled with buildroot and a
gcc 4.4.3/binutils  2.20.1.20100303 compiled with crosstool ng.
Both behave the same with respect to this problem.

/Brian



More information about the linux-arm-kernel mailing list