Skip to content

LLVM compiled binutils seg faults #11539

@llvmbot

Description

@llvmbot
Bugzilla Link 11167
Resolution INVALID
Resolved on Oct 19, 2011 21:15
Version 2.8
OS MacOS X
Attachments Object file generated by LLVM for dis-buf.c of binutils 2.21
Reporter LLVM Bugzilla Contributor

Extended Description

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;
39
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);
46
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 /Users/btm/Temp/binutils-git/binutils/opcodes/wvfe-dis.c:76

(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 ../../../binutils/opcodes/dis-buf.c

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillainvalidResolved as invalid, i.e. not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions