[coreboot] libpayload alloc() gcc 4.6.2 bug?

Marc Jones marcj303 at gmail.com
Tue Feb 28 23:06:30 CET 2012


I think I found a bug in gcc 4.6.2 building libpayload (current
coreboot crosstools). I would like to get confirmation that someone
else sees this and that I haven't done something wrong. Please let me
know if there is anything else I should try or post. I'm not sure how
to address this. Comments welcome.

I found this bug building tint with libpayload. libpayload is built
with defconfig and using the same coreboot crosstools gcc. The bug
happens in the first call to alloc() when the first header of the
first region is installed. The header memory location is checked,
found to be 0, and then loaded with the header. The bug is that the
original value of the location is used after the memory was updated.
It should have been reloaded. It is pretty easy to see in the
disassembly below.

The libpayload alloc function:
static void *alloc(int len)
{
       hdrtype_t header;
       void *ptr = hstart;

       /* Align the size. */
       len = (len + 3) & ~3;

       if (!len || len > 0xffffff)
               return (void *)NULL;

       /* Make sure the region is setup correctly. */
       if (!HAS_MAGIC(*((hdrtype_t *) ptr)))
               setup();

       /* Find some free space. */
       do {
               header = *((hdrtype_t *) ptr);
               int size = SIZE(header);

               if (!HAS_MAGIC(header) || size == 0) {      <---- fails
here due to *((hdrtype_t *) ptr) not being refreshed after memory
changes
                       printf("memory allocator panic. (%s%s)\n",
                              !HAS_MAGIC(header) ? " no magic " : "",
                                  size == 0 ? " size=0 " : "");

The failing asm:
0010b7c0 <alloc>:
 10b7c0:       56                      push   %esi
 10b7c1:       53                      push   %ebx
 10b7c2:       83 ec 14                sub    $0x14,%esp
 10b7c5:       8d 70 03                lea    0x3(%eax),%esi
 10b7c8:       83 e6 fc                and    $0xfffffffc,%esi
 10b7cb:       74 7c                   je     10b849 <alloc+0x89>
 10b7cd:       81 fe ff ff ff 00       cmp    $0xffffff,%esi
 10b7d3:       7f 74                   jg     10b849 <alloc+0x89>
 10b7d5:       a1 a0 5f 11 00          mov    0x115fa0,%eax      <---
load alloc header into eax
 10b7da:       89 c2                   mov    %eax,%edx          <---
moves it to edx
 10b7dc:       81 e2 00 00 00 a8       and    $0xa8000000,%edx
 10b7e2:       81 fa 00 00 00 a8       cmp    $0xa8000000,%edx
 10b7e8:       74 1d                   je     10b807 <alloc+0x47>
 10b7ea:       ba 9c 9f 11 00          mov    $0x119f9c,%edx     <--- setup()
 10b7ef:       81 ea a0 5f 11 00       sub    $0x115fa0,%edx
 10b7f5:       81 e2 ff ff ff 00       and    $0xffffff,%edx
 10b7fb:       81 ca 00 00 00 aa       or     $0xaa000000,%edx
 10b801:       89 15 a0 5f 11 00       mov    %edx,0x115fa0   <--- memory write
 10b807:       ba a0 5f 11 00          mov    $0x115fa0,%edx
 10b80c:       eb 04                   jmp    10b812 <alloc+0x52>
 10b80e:       66 90                   xchg   %ax,%ax
 10b810:       8b 02                   mov    (%edx),%eax
 10b812:       89 c1                   mov    %eax,%ecx          <----
starts using eax, but the memory was changed and not reloaded
 10b814:       81 e1 ff ff ff 00       and    $0xffffff,%ecx

This is a passing version built with the old toolchain (gcc 4.5.2):
0010b24c <alloc>:
 10b24c:       55                      push   %ebp
 10b24d:       89 e5                   mov    %esp,%ebp
 10b24f:       56                      push   %esi
 10b250:       53                      push   %ebx
 10b251:       83 c0 03                add    $0x3,%eax
 10b254:       83 e0 fc                and    $0xfffffffc,%eax
 10b257:       75 0b                   jne    10b264 <alloc+0x18>
 10b259:       31 c0                   xor    %eax,%eax
 10b25b:       8d 65 f8                lea    -0x8(%ebp),%esp
 10b25e:       5b                      pop    %ebx
 10b25f:       5e                      pop    %esi
 10b260:       c9                      leave
 10b261:       c3                      ret
 10b262:       66 90                   xchg   %ax,%ax
 10b264:       3d ff ff ff 00          cmp    $0xffffff,%eax
 10b269:       7f ee                   jg     10b259 <alloc+0xd>
 10b26b:       8b 15 00 14 11 00       mov    0x111400,%edx
<--- loads alloc header into edx.
 10b271:       89 d1                   mov    %edx,%ecx
 10b273:       81 e1 00 00 00 a8       and    $0xa8000000,%ecx
 10b279:       81 f9 00 00 00 a8       cmp    $0xa8000000,%ecx
 10b27f:       74 1f                   je     10b2a0 <alloc+0x54>
 10b281:       ba 00 14 11 00          mov    $0x111400,%edx       <--- setup()
 10b286:       f7 da                   neg    %edx
 10b288:       81 c2 fc 53 11 00       add    $0x1153fc,%edx
 10b28e:       81 e2 ff ff ff 00       and    $0xffffff,%edx
 10b294:       81 ca 00 00 00 aa       or     $0xaa000000,%edx
 10b29a:       89 15 00 14 11 00       mov    %edx,0x111400    <---
memory updated and still in edx
 10b2a0:       b9 00 14 11 00          mov    $0x111400,%ecx
 10b2a5:       eb 03                   jmp    10b2aa <alloc+0x5e>
 10b2a7:       90                      nop
 10b2a8:       8b 11                   mov    (%ecx),%edx
 10b2aa:       89 d3                   mov    %edx,%ebx          <---
edx has correct value


My failing gcc version:
$ /i386-elf-gcc -v
Using built-in specs.
COLLECT_GCC=/home/marc/git/coreboot2/payloads/tint-0.03b/./../../util/crossgcc/xgcc/bin/i386-elf-gcc
COLLECT_LTO_WRAPPER=/home/marc/devel/coreboot/util/crossgcc/xgcc/lib/gcc/i386-elf/4.6.2/lto-wrapper
Target: i386-elf
Configured with: ../gcc-4.6.2/configure --enable-multilib=yes
--prefix=/home/marc/devel/coreboot/util/crossgcc/xgcc
--libexecdir=/home/marc/devel/coreboot/util/crossgcc/xgcc/lib
--target=i386-elf --disable-werror --disable-shared --disable-libssp
--disable-bootstrap --disable-nls --disable-libquadmath --with-newlib
--enable-lto --enable-languages=c
--with-gmp=/home/marc/devel/coreboot/util/crossgcc/xgcc
--with-mpfr=/home/marc/devel/coreboot/util/crossgcc/xgcc
--with-mpc=/home/marc/devel/coreboot/util/crossgcc/xgcc
--with-libelf=/home/marc/devel/coreboot/util/crossgcc/xgcc
--with-pkgversion='coreboot toolchain v1.07 November 1st, 2011'
Thread model: single
gcc version 4.6.2 (coreboot toolchain v1.07 November 1st, 2011)

tint.elf and objdump -D files attached.

 My git repo if you would like try this exact code:
 git://git.se-eng.com/coreboot.git

Questions or comments?

Marc


-- 
http://se-eng.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tint-gcc462bug.tar.gz
Type: application/x-gzip
Size: 479907 bytes
Desc: not available
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20120228/14b0163a/attachment.gz>


More information about the coreboot mailing list