[LLVMbugs] [Bug 11167] New: LLVM compiled binutils seg faults

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Oct 18 07:25:01 PDT 2011


           Summary: LLVM compiled binutils seg faults
           Product: new-bugs
           Version: 2.8
          Platform: Macintosh
        OS/Version: MacOS X
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: brian-mokrzycki at uiowa.edu
                CC: llvmbugs at cs.uiuc.edu

Created an attachment (id=7474)
 --> (http://llvm.org/bugs/attachment.cgi?id=7474)
Object file generated by LLVM for dis-buf.c of binutils 2.21

I believe what I am seeing is a bug in the LLVM toolchain when compiling a
custom branch of binutils 2.21.  I am able to compile this branch (binutils
2.21) with gcc-4.2.1 (Apple build 5666 dot 3) without issue. My configuration:

Low Level Virtual Machine (http://llvm.org/):
  llvm version 2.8
  Optimized build.
  Built Mar 14 2011 (09:16:56).
  Host: x86_64-apple-darwin11
  Host CPU: penryn

On Mac OS X 10.7.2

While testing the LLVM compiled runtime of binutils, the disassembly runtime
would incur a segmentation fault.  Tracking this down with GDB, I was able to
isolate the rogue overwriting of a variable that was the source of the seg
fault.  The code in question, from dis-buf.c:30, function buffer_read_memory

 27 /* Get LENGTH bytes from info's buffer, at target address memaddr.
 28    Transfer them to myaddr.  */
 29 int
 30 buffer_read_memory (bfd_vma memaddr,
 31                     bfd_byte *myaddr,
 32                     unsigned int length,
 33                     struct disassemble_info *info)
 34 {
 35   unsigned int opb = info->octets_per_byte;
 36   unsigned int end_addr_offset = length / opb;
 37   unsigned int max_addr_offset = info->buffer_length / opb;
 38   unsigned int octets = (memaddr - info->buffer_vma) * opb;
 40   if (memaddr < info->buffer_vma
 41       || memaddr - info->buffer_vma > max_addr_offset
 42       || memaddr - info->buffer_vma + end_addr_offset > max_addr_offset)
 43     /* Out of bounds.  Use EIO because GDB uses it.  */
 44     return EIO;
 45   memcpy (myaddr, info->buffer + octets, length);
 47   return 0;
 48 }

Stepping through this function with GDB I discovered that bfd_byte *myaddr is
being overwritten line 38.  As shown in this GDB dump:

Breakpoint 3, wvfe_print_insn [inlined] () at

(gdb) s
buffer_read_memory (memaddr=0, myaddr=0x7fff5fbff560 "", length=8,
info=0x7fff5fbff908) at dis-buf.c:39
39      bfd_vma octets = (memaddr - info->buffer_vma) * opb;

(gdb) watch myaddr
Watchpoint 5: myaddr

(gdb) s
36      unsigned int end_addr_offset = length / opt;

(gdb) s
39      unsigned int octets = (memaddr - info->buffer_vma) * opb;

(gdb) s
Watchpoint 5: myaddr

Old value = (bfd_byte *) 0x7fff5fbff560 ""
New value = (bfd_byte *) 0x0
0x0000000100038db8 in buffer_read_memory (memaddr=0, myaddr=0x0, length=8,
info=0x7fff5fbff908) at dis-buf.c:39
39      unsigned int octets = (memaddr - info->buffer_vma) * opb;

 As can be seen, the variable myaddr should not be overwritten at this step nor
anywhere in this function.  The source file dis-buf.c was compiled with the
following line (where gcc points to gcc-llvm).

/bin/sh ./libtool --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I.
-I../../../binutils/opcodes  -I. -I../../../binutils/opcodes -I../bfd
-I../../../binutils/opcodes/../include -I../../../binutils/opcodes/../bfd    -W
-Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Werror -g -O2 -MT
dis-buf.lo -MD -MP -MF .deps/dis-buf.Tpo -c -o dis-buf.lo

I'm attaching the object file for dis-buf.c for disassembly purposes.  If more
information is needed please let me know.

Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

More information about the llvm-bugs mailing list