bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug binutils/16336] New: objcopy generates wrong ELF program headers


From: vpappas at gmail dot com
Subject: [Bug binutils/16336] New: objcopy generates wrong ELF program headers
Date: Tue, 17 Dec 2013 23:16:24 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=16336

            Bug ID: 16336
           Summary: objcopy generates wrong ELF program headers
           Product: binutils
           Version: 2.25 (HEAD)
            Status: NEW
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: vpappas at gmail dot com

While copying an object file (elf32-x86-64) using:

objcopy -O elf64-x86-64 --no-change-warnings --change-start 0x55500000000
--change-section-address .btt+0x55500000000 --change-section-address
.note.gnu.build-id+0x55500000000 --change-section-address
.note.ABI-tag+0x55500000000 --change-section-address .init+0x55500000000
--change-section-address .text+0x55500000000 --change-section-address
__libc_freeres_fn+0x55500000000 --change-section-address
__libc_thread_freeres_fn+0x55500000000 --change-section-address
.fini+0x55500000000 --change-section-address .rela.plt+0x55500000000
--change-section-address .plt+0x55500000000 --change-section-address
.rodata+0x66600000000 --change-section-address
__libc_thread_subfreeres+0x66600000000 --change-section-address
__libc_subfreeres+0x66600000000 --change-section-address
__libc_atexit+0x66600000000 --change-section-address .eh_frame+0x66600000000
--change-section-address .gcc_except_table+0x66600000000
--change-section-address .tdata+0x66600000000 --change-section-address
.tbss+0x66600000000 --change-section-address .init_array+0x66600000000
--change-section-address .fini_array+0x66600000000 --change-section-address
.data.rel.ro+0x66600000000 --change-section-address .jcr+0x66600000000
--change-section-address .got+0x66600000000 --change-section-address
.got.plt+0x66600000000 --change-section-address .data+0x66600000000
--change-section-address .bss+0x66600000000 --change-section-address
__libc_freeres_ptrs+0x66600000000 a.out a.out2

I noticed that some sections that appear in more than one segments, do not
(like .tdata and .note.*).

Here is the output of readelf -l for the original file:

Elf file type is EXEC (Executable file)
Entry point 0x60b6
There are 6 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x051c9 0x051c9 R   0x200000
  LOAD           0x0051cc 0x000051cc 0x000051cc 0x7930d 0x7930d R E 0x200000
  LOAD           0x080000 0x00080000 0x00080000 0x24bff 0x24bff R   0x200000
  LOAD           0x0a5000 0x002a5000 0x002a5000 0x01fb4 0x8053c4 RW  0x200000
  NOTE           0x0051cc 0x000051cc 0x000051cc 0x00044 0x00044 R   0x4
  TLS            0x0a5000 0x002a5000 0x002a5000 0x00010 0x00028 RW  0x4

 Section to Segment mapping:
  Segment Sections...
   00     .btt 
   01     .note.gnu.build-id .note.ABI-tag .init .text __libc_freeres_fn
__libc_thread_freeres_fn .fini 
   02     .rodata __libc_subfreeres __libc_atexit __libc_thread_subfreeres
.eh_frame .gcc_except_table 
   03     .tdata .init_array .fini_array .data.rel.ro .data .bss
__libc_freeres_ptrs 
   04     .note.gnu.build-id .note.ABI-tag 
   05     .tdata .tbss 


and the new file:

Elf file type is EXEC (Executable file)
Entry point 0x555000060b6
There are 6 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000055500000000 0x0000055500000f0c
                 0x00000000000051c9 0x00000000000051c9  R      200000
  LOAD           0x00000000000051cc 0x00000555000051cc 0x00000555000051cc
                 0x000000000007930d 0x000000000007930d  R E    200000
  LOAD           0x0000000000080000 0x0000066600080000 0x0000066600080000
                 0x0000000000024bff 0x0000000000024bff  R      200000
  LOAD           0x00000000000a5000 0x00000666002a5000 0x00000666002a5000
                 0x0000000000001fb4 0x00000000008053c4  RW     200000
  NOTE           0x0000000000000000 0x0000000000000000 0x00000000000051cc
                 0x0000000000000000 0x0000000000000000  R      8
  TLS            0x0000000000000000 0x0000000000000000 0x00000000002a5000
                 0x0000000000000000 0x0000000000000000  RW     8

 Section to Segment mapping:
  Segment Sections...
   00     .btt 
   01     .note.gnu.build-id .note.ABI-tag .init .text __libc_freeres_fn
__libc_thread_freeres_fn .fini 
   02     .rodata __libc_subfreeres __libc_atexit __libc_thread_subfreeres
.eh_frame .gcc_except_table 
   03     .tdata .init_array .fini_array .data.rel.ro .data .bss
__libc_freeres_ptrs 
   04     
   05     


I checked the code in binutils and found out that these sections where filtered
in rewrite_elf_program_header (bfd/elf.c:5472). The problem seems to be the way
a check is performed in the IS_SECTION_IN_INPUT_SEGMENT macro (used by
INCLUDE_SECTION_IN_SEGMENT), where according to its comments: "The section has
not already been allocated to a previous segment". It seems this check should
be refined to don't allow a section to be allocated to more than one PT_LOAD
segments.

The following small patch seems to work (at least for my case) and does not
break any tests in 'make check':

diff --git a/bfd/elf.c b/bfd/elf.c
index b589e60..ae29d5d 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -5581,7 +5581,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
           : segment->p_vaddr != section->vma)                          \
        || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic")   \
           == 0))                                                       \
-   && !section->segment_mark)
+   && (!section->segment_mark || segment->p_type != PT_LOAD))

 /* If the output section of a section in the input segment is NULL,
    it is removed from the corresponding output segment.   */


thanks!
vasilis

-- 
You are receiving this mail because:
You are on the CC list for the bug.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]