[U-Boot] EABI 4.2
Alessandro Rubini
rubini-list at gnudd.com
Tue Mar 16 23:18:45 CET 2010
Hello.
> I have not received any updates from the gcc mailing list. Has anyone
> got any more ideas on this? Thanks!
Out of curiosity, I tried to reproduce the problem. I added EXT2 to my
binary and recompiled with eldk-4.2. As a reminder, this is the
source:
if (dirent.namelen != 0) {
char filename[dirent.namelen + 1];
ext2fs_node_t fdiro;
int type = FILETYPE_UNKNOWN;
status = ext2fs_read_file (diro,
fpos + sizeof (struct ext2_dirent),
dirent.namelen, filename);
Note that namelen is a uint8_t. What follows is the disassembled u-boot.
My comments follow each groups of lines.
a182025c: e55b2026 ldrb r2, [fp, #-38]
a1820260: e3520000 cmp r2, #0 ; 0x0
a1820264: 0a000077 beq a1820448 <ext2fs_iterate_dir+0x254>
[so r2 is namelen]
a1820268: e282300f add r3, r2, #15 ; 0xf
a182026c: e2033f7e and r3, r3, #504 ; 0x1f8
so here r3 is (namelen + 0xf) & 0x1f8 . I don't understand the "&0x1f8" since
r2 was known to be 8 bits at most.
a1820270: e50bd034 str sp, [fp, #-52]
a1820274: e063d00d rsb sp, r3, sp
stack pointer has been saved, and sp takes sp - r3. Looks fine.
a1820278: e1a041ad lsr r4, sp, #3
a182027c: e51b3030 ldr r3, [fp, #-48]
a1820280: e1a0a184 lsl sl, r4, #3
shift back and forth to align sp ("ldr r3" in the middle is fpos, used
in building arguments for ext2fs_read_file).
a1820284: e1a00007 mov r0, r7
a1820288: e2831008 add r1, r3, #8 ; 0x8
a182028c: e1a0300a mov r3, sl
a1820290: ebfffe77 bl a181fc74 <ext2fs_read_file>
So everything looks fine. I also tried a standalone program with both
a uint16_t and the official uint8_t namelen and it works fine (there
is no "& 0x1f8" any more in the assembly for 16-bit lengths). In that
test the callee has a stack pointer which is as low as needed according
to the namelen used by the caller.
Therefore, I suspect your problem can come out of
ext2fs_read_file. However, the calculations there look good to me
(actually, everybody uses them, so they must be good for normal uses).
However, in ext2fs_read_file, there might be an issue in the first
block (which "is not stored on disk but is zero filled instead"):
memset (buf, 0, blocksize - skipfirst);
should be
memset (buf, 0, blockend - skipfirst);
where blockend is == blocksize but might be shorter in the last block
of the read. So if you are reading a dirent in the first block you
might have a problem of stack overflow.
But I don't expect you'll read a dirent from first block, and even if
it was, then namelen would be zero as well. I suspect your problem is
elsewhere, although I can't imagine where, as this code doesn't look
like something that can stack overflow even if misused.
/alessandro
More information about the U-Boot
mailing list