@ -4525,51 +4525,53 @@ copy_private_bfd_data (ibfd, obfd)
maxpagesize = get_elf_backend_data ( obfd ) - > maxpagesize ;
maxpagesize = get_elf_backend_data ( obfd ) - > maxpagesize ;
/* Returns the end address of the segment + 1. */
/* Returns the end address of the segment + 1. */
# define SEGMENT_END(segment, start) \
# define SEGMENT_END(segment, start) \
( start + ( segment - > p_memsz > segment - > p_filesz \
( start + ( segment - > p_memsz > segment - > p_filesz \
? segment - > p_memsz : segment - > p_filesz ) )
? segment - > p_memsz : segment - > p_filesz ) )
/* Returns true if the given section is contained within
/* Returns true if the given section is contained within
the given segment . VMA addresses are compared . */
the given segment . VMA addresses are compared . */
# define IS_CONTAINED_BY_VMA(section, segment) \
# define IS_CONTAINED_BY_VMA(section, segment) \
( section - > vma > = segment - > p_vaddr \
( section - > vma > = segment - > p_vaddr \
& & ( section - > vma + section - > _raw_size ) \
& & ( section - > vma + section - > _raw_size \
< = ( SEGMENT_END ( segment , segment - > p_vaddr ) ) )
< = ( SEGMENT_END ( segment , segment - > p_vaddr ) ) ) )
/* Returns true if the given section is contained within
/* Returns true if the given section is contained within
the given segment . LMA addresses are compared . */
the given segment . LMA addresses are compared . */
# define IS_CONTAINED_BY_LMA(section, segment, base) \
# define IS_CONTAINED_BY_LMA(section, segment, base) \
( section - > lma > = base \
( section - > lma > = base \
& & ( section - > lma + section - > _raw_size ) \
& & ( section - > lma + section - > _raw_size \
< = SEGMENT_END ( segment , base ) )
< = SEGMENT_END ( segment , base ) ) )
/* Returns true if the given section is contained within the
/* Returns true if the given section is contained within the
given segment . Filepos addresses are compared in an elf
given segment . Filepos addresses are compared in an elf
backend function . */
backend function . */
# define IS_CONTAINED_BY_FILEPOS(sec, seg, bed) \
# define IS_CONTAINED_BY_FILEPOS(sec, seg, bed) \
( bed - > is_contained_by_filepos \
( bed - > is_contained_by_filepos \
& & ( * bed - > is_contained_by_filepos ) ( sec , seg ) )
& & ( * bed - > is_contained_by_filepos ) ( sec , seg ) )
/* Special case: corefile "NOTE" section containing regs, prpsinfo etc. */
/* Special case: corefile "NOTE" section containing regs, prpsinfo etc. */
# define IS_COREFILE_NOTE(p, s) \
# define IS_COREFILE_NOTE(p, s) \
( p - > p_type = = PT_NOTE \
( p - > p_type = = PT_NOTE \
& & bfd_get_format ( ibfd ) = = bfd_core \
& & bfd_get_format ( ibfd ) = = bfd_core \
& & s - > vma = = 0 & & s - > lma = = 0 \
& & s - > vma = = 0 & & s - > lma = = 0 \
& & ( bfd_vma ) s - > filepos > = p - > p_offset \
& & ( bfd_vma ) s - > filepos > = p - > p_offset \
& & ( bfd_vma ) s - > filepos + s - > _raw_size \
& & ( ( bfd_vma ) s - > filepos + s - > _raw_size \
< = p - > p_offset + p - > p_filesz )
< = p - > p_offset + p - > p_filesz ) )
/* The complicated case when p_vaddr is 0 is to handle the Solaris
/* The complicated case when p_vaddr is 0 is to handle the Solaris
linker , which generates a PT_INTERP section with p_vaddr and
linker , which generates a PT_INTERP section with p_vaddr and
p_memsz set to 0. */
p_memsz set to 0. */
# define IS_SOLARIS_PT_INTERP(p, s) \
# define IS_SOLARIS_PT_INTERP(p, s) \
( p - > p_vaddr = = 0 \
( p - > p_vaddr = = 0 \
& & p - > p_filesz > 0 \
& & p - > p_paddr = = 0 \
& & ( s - > flags & SEC_HAS_CONTENTS ) ! = 0 \
& & p - > p_memsz = = 0 \
& & s - > _raw_size > 0 \
& & p - > p_filesz > 0 \
& & ( bfd_vma ) s - > filepos > = p - > p_offset \
& & ( s - > flags & SEC_HAS_CONTENTS ) ! = 0 \
& & ( ( bfd_vma ) s - > filepos + s - > _raw_size \
& & s - > _raw_size > 0 \
< = p - > p_offset + p - > p_filesz ) )
& & ( bfd_vma ) s - > filepos > = p - > p_offset \
& & ( ( bfd_vma ) s - > filepos + s - > _raw_size \
< = p - > p_offset + p - > p_filesz ) )
/* Decide if the given section should be included in the given segment.
/* Decide if the given section should be included in the given segment.
A section will be included if :
A section will be included if :
@ -4579,10 +4581,9 @@ copy_private_bfd_data (ibfd, obfd)
3. There is an output section associated with it ,
3. There is an output section associated with it ,
4. The section has not already been allocated to a previous segment . */
4. The section has not already been allocated to a previous segment . */
# define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \
# define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed) \
( ( ( ( ( segment - > p_paddr \
( ( ( ( segment - > p_paddr \
? IS_CONTAINED_BY_LMA ( section , segment , segment - > p_paddr ) \
? IS_CONTAINED_BY_LMA ( section , segment , segment - > p_paddr ) \
: IS_CONTAINED_BY_VMA ( section , segment ) ) \
: IS_CONTAINED_BY_VMA ( section , segment ) ) \
| | IS_SOLARIS_PT_INTERP ( segment , section ) ) \
& & ( section - > flags & SEC_ALLOC ) ! = 0 ) \
& & ( section - > flags & SEC_ALLOC ) ! = 0 ) \
| | IS_COREFILE_NOTE ( segment , section ) \
| | IS_COREFILE_NOTE ( segment , section ) \
| | ( IS_CONTAINED_BY_FILEPOS ( section , segment , bed ) \
| | ( IS_CONTAINED_BY_FILEPOS ( section , segment , bed ) \
@ -4591,12 +4592,13 @@ copy_private_bfd_data (ibfd, obfd)
& & ! section - > segment_mark )
& & ! section - > segment_mark )
/* Returns true iff seg1 starts after the end of seg2. */
/* Returns true iff seg1 starts after the end of seg2. */
# define SEGMENT_AFTER_SEGMENT(seg1, seg2) \
# define SEGMENT_AFTER_SEGMENT(seg1, seg2) \
( seg1 - > p_vaddr > = SEGMENT_END ( seg2 , seg2 - > p_vaddr ) )
( seg1 - > p_vaddr > = SEGMENT_END ( seg2 , seg2 - > p_vaddr ) )
/* Returns true iff seg1 and seg2 overlap. */
/* Returns true iff seg1 and seg2 overlap. */
# define SEGMENT_OVERLAPS(seg1, seg2) \
# define SEGMENT_OVERLAPS(seg1, seg2) \
( ! ( SEGMENT_AFTER_SEGMENT ( seg1 , seg2 ) | | SEGMENT_AFTER_SEGMENT ( seg2 , seg1 ) ) )
( ! ( SEGMENT_AFTER_SEGMENT ( seg1 , seg2 ) \
| | SEGMENT_AFTER_SEGMENT ( seg2 , seg1 ) ) )
/* Initialise the segment mark field. */
/* Initialise the segment mark field. */
for ( section = ibfd - > sections ; section ! = NULL ; section = section - > next )
for ( section = ibfd - > sections ; section ! = NULL ; section = section - > next )
@ -4605,7 +4607,7 @@ copy_private_bfd_data (ibfd, obfd)
/* Scan through the segments specified in the program header
/* Scan through the segments specified in the program header
of the input BFD . For this first scan we look for overlaps
of the input BFD . For this first scan we look for overlaps
in the loadable segments . These can be created by weird
in the loadable segments . These can be created by weird
parameters to objcopy . */
parameters to objcopy . Also , fix some solaris weirdness . */
for ( i = 0 , segment = elf_tdata ( ibfd ) - > phdr ;
for ( i = 0 , segment = elf_tdata ( ibfd ) - > phdr ;
i < num_segments ;
i < num_segments ;
i + + , segment + + )
i + + , segment + + )
@ -4613,6 +4615,16 @@ copy_private_bfd_data (ibfd, obfd)
unsigned int j ;
unsigned int j ;
Elf_Internal_Phdr * segment2 ;
Elf_Internal_Phdr * segment2 ;
if ( segment - > p_type = = PT_INTERP )
for ( section = ibfd - > sections ; section ; section = section - > next )
if ( IS_SOLARIS_PT_INTERP ( segment , section ) )
{
/* Mininal change so that the normal section to segment
assigment code will work . */
segment - > p_vaddr = section - > vma ;
break ;
}
if ( segment - > p_type ! = PT_LOAD )
if ( segment - > p_type ! = PT_LOAD )
continue ;
continue ;