boot decompressor code error
Brian Murphy
brian at murphy.dk
Wed Nov 3 04:27:38 EDT 2010
On Wed, Nov 3, 2010 at 9:16 AM, Brian Murphy <brian at murphy.dk> wrote:
> 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
>
I gave no evidence in my earlier mail.
Here is some. The zlib_fixedtables function allocates what looks like much
stack space before making two memcpys. lenfix and distfix are static const.
extract of misc.c from -save-temps:
.global zlib_fixedtables
.type zlib_fixedtables, %function
zlib_fixedtables:
@ args = 0, pretend = 0, frame = 2176
@ frame_needed = 1, uses_anonymous_args = 0
mov ip, sp
stmfd sp!, {r4, r5, r6, r7, r8, fp, ip, lr, pc}
sub sp, sp, #2176
sub fp, ip, #4
sub sp, sp, #4
ldr r4, .L228
ldr r8, .L228+4
.LPIC10:
add r4, pc, r4
sub r7, fp, #2208
sub r7, r7, #4
add r8, r4, r8
mov r5, r0
sub r6, fp, #164
mov r1, r8
mov r2, #2048
mov r0, r7
bl memcpy(PLT)
add r1, r8, #2048
mov r2, #128
mov r0, r6
bl memcpy(PLT)
mov r3, #9
ldr r0, .L228+8
str r3, [r5, #80]
mov r3, #5
str r3, [r5, #84]
add r0, r4, r0
mov r1, r7
mov r2, r6
/Brian
More information about the linux-arm-kernel
mailing list