mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-28 04:25:10 +08:00
bfd/
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:
parent
70e45ad9bb
commit
84d1d6507c
@ -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
191
bfd/elf.c
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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 ...
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user