2006-02-10  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/2258
	* elf.c (copy_private_bfd_data): Renamed to ...
	(rewrite_elf_program_header): This.
	(copy_elf_program_header): New function.
	(copy_private_bfd_data): Likewise.

binutils/

2006-02-10  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/2258
	* readelf.c (process_program_headers): Use
	ELF_IS_SECTION_IN_SEGMENT_MEMORY.

include/elf/

2006-02-10  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/2258
	* internal.h (ELF_IS_SECTION_IN_SEGMENT_FILE): New.
	(ELF_IS_SECTION_IN_SEGMENT_MEMORY): Likewise.
This commit is contained in:
H.J. Lu 2006-02-10 15:04:19 +00:00
parent 70e45ad9bb
commit 84d1d6507c
6 changed files with 229 additions and 28 deletions

View File

@ -1,4 +1,12 @@
2006-01-26 Nathan Sidwell <nathan@codesourcery.com>
2006-02-10 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/2258
* elf.c (copy_private_bfd_data): Renamed to ...
(rewrite_elf_program_header): This.
(copy_elf_program_header): New function.
(copy_private_bfd_data): Likewise.
2006-02-07 Nathan Sidwell <nathan@codesourcery.com>
* archures.c (bfd_mach_mcf5200, bfd_mach_mcf5206e,
bfd_mach_mcf5307, bfd_mach_mcf5407, bfd_mach_mcf528x,

191
bfd/elf.c
View File

@ -5045,10 +5045,10 @@ _bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
return idx;
}
/* Copy private BFD data. This copies any program header information. */
/* Rewrite program header information. */
static bfd_boolean
copy_private_bfd_data (bfd *ibfd, bfd *obfd)
rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
{
Elf_Internal_Ehdr *iehdr;
struct elf_segment_map *map;
@ -5064,13 +5064,6 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
unsigned int phdr_adjust_num = 0;
const struct elf_backend_data *bed;
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
return TRUE;
if (elf_tdata (ibfd)->phdr == NULL)
return TRUE;
bed = get_elf_backend_data (ibfd);
iehdr = elf_elfheader (ibfd);
@ -5630,6 +5623,186 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
return TRUE;
}
/* Copy ELF program header information. */
static bfd_boolean
copy_elf_program_header (bfd *ibfd, bfd *obfd)
{
Elf_Internal_Ehdr *iehdr;
struct elf_segment_map *map;
struct elf_segment_map *map_first;
struct elf_segment_map **pointer_to_map;
Elf_Internal_Phdr *segment;
unsigned int i;
unsigned int num_segments;
bfd_boolean phdr_included = FALSE;
iehdr = elf_elfheader (ibfd);
map_first = NULL;
pointer_to_map = &map_first;
num_segments = elf_elfheader (ibfd)->e_phnum;
for (i = 0, segment = elf_tdata (ibfd)->phdr;
i < num_segments;
i++, segment++)
{
asection *section;
unsigned int section_count;
bfd_size_type amt;
Elf_Internal_Shdr *this_hdr;
/* FIXME: Do we need to copy PT_NULL segment? */
if (segment->p_type == PT_NULL)
continue;
/* Compute how many sections are in this segment. */
for (section = ibfd->sections, section_count = 0;
section != NULL;
section = section->next)
{
this_hdr = &(elf_section_data(section)->this_hdr);
if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
section_count++;
}
/* Allocate a segment map big enough to contain
all of the sections we have selected. */
amt = sizeof (struct elf_segment_map);
if (section_count != 0)
amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
map = bfd_alloc (obfd, amt);
if (map == NULL)
return FALSE;
/* Initialize the fields of the output segment map with the
input segment. */
map->next = NULL;
map->p_type = segment->p_type;
map->p_flags = segment->p_flags;
map->p_flags_valid = 1;
map->p_paddr = segment->p_paddr;
map->p_paddr_valid = 1;
/* Determine if this segment contains the ELF file header
and if it contains the program headers themselves. */
map->includes_filehdr = (segment->p_offset == 0
&& segment->p_filesz >= iehdr->e_ehsize);
map->includes_phdrs = 0;
if (! phdr_included || segment->p_type != PT_LOAD)
{
map->includes_phdrs =
(segment->p_offset <= (bfd_vma) iehdr->e_phoff
&& (segment->p_offset + segment->p_filesz
>= ((bfd_vma) iehdr->e_phoff
+ iehdr->e_phnum * iehdr->e_phentsize)));
if (segment->p_type == PT_LOAD && map->includes_phdrs)
phdr_included = TRUE;
}
if (section_count != 0)
{
unsigned int isec = 0;
for (section = ibfd->sections;
section != NULL;
section = section->next)
{
this_hdr = &(elf_section_data(section)->this_hdr);
if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
map->sections[isec++] = section->output_section;
}
}
map->count = section_count;
*pointer_to_map = map;
pointer_to_map = &map->next;
}
elf_tdata (obfd)->segment_map = map_first;
return TRUE;
}
/* Copy private BFD data. This copies or rewrites ELF program header
information. */
static bfd_boolean
copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
Elf_Internal_Phdr *segment;
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
return TRUE;
if (elf_tdata (ibfd)->phdr == NULL)
return TRUE;
if (ibfd->xvec == obfd->xvec)
{
/* Check if any sections in the input BFD covered by ELF program
header are changed. */
asection *section, *osec;
unsigned int i, num_segments;
Elf_Internal_Shdr *this_hdr;
/* Initialize the segment mark field. */
for (section = obfd->sections; section != NULL;
section = section->next)
section->segment_mark = FALSE;
num_segments = elf_elfheader (ibfd)->e_phnum;
for (i = 0, segment = elf_tdata (ibfd)->phdr;
i < num_segments;
i++, segment++)
{
for (section = ibfd->sections;
section != NULL; section = section->next)
{
/* We mark the output section so that we know it comes
from the input BFD. */
osec = section->output_section;
if (osec)
osec->segment_mark = TRUE;
/* Check if this section is covered by the segment. */
this_hdr = &(elf_section_data(section)->this_hdr);
if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
{
/* FIXME: Check if its output section is changed or
removed. What else do we need to check? */
if (osec == NULL
|| section->flags != osec->flags
|| section->lma != osec->lma
|| section->vma != osec->vma
|| section->size != osec->size
|| section->rawsize != osec->rawsize
|| section->alignment_power != osec->alignment_power)
goto rewrite;
}
}
}
/* Check to see if any output section doesn't come from the
input BFD. */
for (section = obfd->sections; section != NULL;
section = section->next)
{
if (section->segment_mark == FALSE)
goto rewrite;
else
section->segment_mark = FALSE;
}
return copy_elf_program_header (ibfd, obfd);
}
rewrite:
return rewrite_elf_program_header (ibfd, obfd);
}
/* Initialize private output section information from input section. */
bfd_boolean

View File

@ -1,3 +1,9 @@
2006-02-10 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/2258
* readelf.c (process_program_headers): Use
ELF_IS_SECTION_IN_SEGMENT_MEMORY.
2006-02-09 Eric Botcazou <ebotcazou@libertysurf.fr>
* configure.in (CHECK_DECLS): Add snprintf and vsnprintf.

View File

@ -3447,24 +3447,7 @@ process_program_headers (FILE *file)
for (j = 1; j < elf_header.e_shnum; j++, section++)
{
if (section->sh_size > 0
/* PT_TLS segment contains only SHF_TLS sections. */
&& (segment->p_type != PT_TLS
|| (section->sh_flags & SHF_TLS) != 0)
/* Compare allocated sections by VMA, unallocated
sections by file offset. */
&& (section->sh_flags & SHF_ALLOC
? (section->sh_addr >= segment->p_vaddr
&& section->sh_addr + section->sh_size
<= segment->p_vaddr + segment->p_memsz)
: ((bfd_vma) section->sh_offset >= segment->p_offset
&& (section->sh_offset + section->sh_size
<= segment->p_offset + segment->p_filesz)))
/* .tbss is special. It doesn't contribute memory space
to normal segments. */
&& (!((section->sh_flags & SHF_TLS) != 0
&& section->sh_type == SHT_NOBITS)
|| segment->p_type == PT_TLS))
if (ELF_IS_SECTION_IN_SEGMENT_MEMORY(section, segment))
printf ("%s ", SECTION_NAME (section));
}

View File

@ -1,3 +1,9 @@
2006-02-10 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/2258
* internal.h (ELF_IS_SECTION_IN_SEGMENT_FILE): New.
(ELF_IS_SECTION_IN_SEGMENT_MEMORY): Likewise.
2006-02-07 Nathan Sidwell <nathan@codesourcery.com>
* m68k.h (EF_CPU32, EF_M68000, EF_CFV4E): Rename to ...

View File

@ -251,4 +251,29 @@ struct elf_segment_map
asection *sections[1];
};
/* Decide if the given sec_hdr is in the given segment in file. */
#define ELF_IS_SECTION_IN_SEGMENT_FILE(sec_hdr, segment) \
(sec_hdr->sh_size > 0 \
/* PT_TLS segment contains only SHF_TLS sections. */ \
&& (segment->p_type != PT_TLS \
|| (sec_hdr->sh_flags & SHF_TLS) != 0) \
/* Compare allocated sec_hdrs by VMA, unallocated sec_hdrs \
by file offset. */ \
&& (sec_hdr->sh_flags & SHF_ALLOC \
? (sec_hdr->sh_addr >= segment->p_vaddr \
&& sec_hdr->sh_addr + sec_hdr->sh_size \
<= segment->p_vaddr + segment->p_memsz) \
: ((bfd_vma) sec_hdr->sh_offset >= segment->p_offset \
&& (sec_hdr->sh_offset + sec_hdr->sh_size \
<= segment->p_offset + segment->p_filesz))))
/* Decide if the given sec_hdr is in the given segment in memory. */
#define ELF_IS_SECTION_IN_SEGMENT_MEMORY(sec_hdr, segment) \
(ELF_IS_SECTION_IN_SEGMENT_FILE (sec_hdr, segment) \
/* .tbss is special. It doesn't contribute memory space to \
normal segments. */ \
&& (!((sec_hdr->sh_flags & SHF_TLS) != 0 \
&& sec_hdr->sh_type == SHT_NOBITS) \
|| segment->p_type == PT_TLS))
#endif /* _ELF_INTERNAL_H */