This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

_bfd_elf_parse_eh_frame() should not assume relocation order?


Hi all,

I've stumbled on something that looks like a bug in BFD when reading .eh_frame 
sections that results in failure to create .eh_frame_hdr. The code in 
_bfd_elf_parse_eh_frame() function in bfd/elf-eh-frame.c assumes the 
relocations in cookie->rels are ordered by r_offset field; look at how the 
ENSURE_NO_RELOCS, SKIP_RELOCS and GET_RELOC macros are defined, e.g:

  /* FIXME: octets_per_byte.  */
#define ENSURE_NO_RELOCS(buf)                           \
  REQUIRE (!(cookie->rel < cookie->relend               \
             && (cookie->rel->r_offset                  \
                 < (bfd_size_type) ((buf) - ehbuf))     \
             && cookie->rel->r_info != 0))

  /* FIXME: octets_per_byte.  */
#define SKIP_RELOCS(buf)                                \
  while (cookie->rel < cookie->relend                   \
         && (cookie->rel->r_offset                      \
             < (bfd_size_type) ((buf) - ehbuf)))        \
    cookie->rel++

  /* FIXME: octets_per_byte.  */
#define GET_RELOC(buf)                                  \
  ((cookie->rel < cookie->relend                        \
    && (cookie->rel->r_offset                           \
        == (bfd_size_type) ((buf) - ehbuf)))            \
   ? cookie->rel : NULL)

The problem is that this assumption (cookie->rels being ordered by r_offset) 
may not hold. For example, with the following two assembly files:

--- qq1.s ---
.text
baz: .cfi_startproc; ret; .cfi_endproc

--- qq2.s ---
.section .init,"ax",@progbits
.globl foo; foo: .cfi_startproc; ret; .cfi_endproc
.text;
bar: .cfi_startproc; ret; .cfi_endproc

the following commands:

$ as -o qq1.o qq1.s
$ as -o qq2.o qq2.s
$ ld -r -o qq.o qq1.o qq2.o
$ ld -o qq -e foo qq.o

trigger this error message (tried with the tip of the master branch):

/work/install/bin/ld: error in qq.o(.eh_frame); no .eh_frame_hdr table will be 
created.

The problem is that after 'ld -r' linking, the resulting .rela.eh_frame is not 
sorted by the r_offset:

$ readelf -r qq.o 

Relocation section '.rela.eh_frame' at offset 0x380 contains 3 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + 
Addend
000000000050  000100000002 R_X86_64_PC32     0000000000000000 .init + 0
000000000064  000200000002 R_X86_64_PC32     0000000000000000 .text + 1
000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0

As a result, the code in _bfd_elf_parse_eh_frame() fails at REQUIRE (GET_RELOC 
(buf)) [near line 800], because cookie->rel[0] is the first relocation (with 
r_offset 0x50) while the buf pointer is at offset 0x20 (i.e., pointed to by 
cookie->rel[2]).

Is it a bug in BFD, or am I missing something?

Regards,
Alexey.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]