This is the mail archive of the binutils@sources.redhat.com 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]

Problem with objcopy phdrs and patch


I've run into problems with objcopy mapping PHDRS into a segment from a file that did not originally map PHDRS into a segment. This only occurs when removing the last section from an object file on configurations with small MAXPAGESIZE.

I tracked the problem down to a FIXME in elf.c:5241
        /* Only set up the segments if there are no more SEC_ALLOC
           sections.  FIXME: This won't do the right thing if objcopy is
           used to remove the last SEC_ALLOC section, since objcopy
           won't call this routine in that case.  */

The problem is that the PHDRS are not copied from the input file, and when they are recreated, the default algorithm that regenerates the segments can map the FILEHDR and PHDRS into the first segment.

I was hoping to be able to reuse the "bfd_copy_private_bfd_data" hook to be able to copy PHDRS. However, the PHDRs must be set up before setting section content and objcopy calls "bfd_copy_private_bfd_data" late (ref objcopy.c:1485).
/* Allow the BFD backend to copy any private data it understands
from the input BFD to the output BFD. This is done last to
permit the routine to look at the filtered symbol table, which is
important for the ECOFF code at least. */


I'm proposing a new bfd interface "bfd_copy_private_header_data" that should be called after setting up section data for each of the sections that will copy over phdr data. I'm including a proposed patch for binutils and bfd and a Changelog for each.

I did not see a mechanism in the binutils testsuite to cleanly call the gnu linker, so I'm including a manual testcase to demonstrate the failure. Use an elf target with small page sizes like avr-elf.
> cat simple.s
.section .first_data, "a"
.p2align 2
.word 0x1000
.section .second_data, "a"
.p2align 2
.word 0x2000
> cat simple.t
MEMORY { MEM : ORIGIN = 0x40000000, LENGTH = 0x5000 }
PHDRS { P1 PT_LOAD; }
SECTIONS {
.text : { *(.literal .text) } > MEM : P1
.data : { *(.data) } > MEM : P1
.bss : { *(.bss) } > MEM : P1
.first_data : { *(.first_data) } > MEM :P1
.second_data : { *(.second_data) } > MEM :P1
}


> as -o simple.o simple.s
> ld -T simple.t -o simple.exe simple.o
> objcopy -j .first_data simple.exe simple-first.bfd
> objdump -p simple-first.bfd | grep "LOAD off.*0x00000000"

On failure, this will generate one line indicating the first PHDR that maps FILEHDR and PHDR in the first segment at a virtual address just before the defined MEM address. It passes if no line is generated.




binutils ChangeLog


2004-05-05 David Heine <dlheine@tensilica.com>

    * objcopy.c (setup_bfd_headers): New function.
    (copy_object): Call setup_bfd_headers.


bfd ChangeLog


2004-05-05 David Heine <dlheine@tensilica.com>

    * bfd.c (bfd_copy_private_header_data): Define.
    * elf-bfd.h (_bfd_elf_copy_private_header_data): Declare.
    * elf.c (_bfd_elf_copy_private_section_data): Remove code to set up
    segments by calling copy_private_bfd_data.
    (_bfd_elf_copy_private_header_data): Define.
    * elf-xxtarget.h (bfd_elfNN_bfd_copy_private_header_data): Define.
    * libbfd-in.h (_bfd_generic_bfd_copy_private_header_data): Define.
    * targets.c (BFD_JUMP_TABLE_COPY): Add
    _bfd_copy_private_header_data.
    * bfd-in2.h: Regenerate.
    * libbfd.h: Regenerate.


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