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. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils