This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Problem with objcopy phdrs and patch
- From: David Heine <dlheine at tensilica dot com>
- To: binutils at sources dot redhat dot com
- Date: Wed, 05 May 2004 12:01:47 -0700
- Subject: Problem with objcopy phdrs and patch
- Organization: Tensilica, Inc
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.