* elf.c (rewrite_elf_program_header): Formatting.  Add
	first_matching_lma and first_suggested_lma booleans and use
	instead of testing matching_lma and suggested_lma for zero.
This commit is contained in:
Alan Modra 2007-11-13 05:56:10 +00:00
parent af674d1d6c
commit 0067a5693a
2 changed files with 86 additions and 65 deletions

View File

@ -1,3 +1,10 @@
2007-11-13 Alan Modra <amodra@bigpond.net.au>
PR 5233
* elf.c (rewrite_elf_program_header): Formatting. Add
first_matching_lma and first_suggested_lma booleans and use
instead of testing matching_lma and suggested_lma for zero.
2007-11-12 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/5299

144
bfd/elf.c
View File

@ -5144,7 +5144,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
: segment->p_vaddr != section->vma) \
|| (strcmp (bfd_get_section_name (ibfd, section), ".dynamic") \
== 0)) \
&& ! section->segment_mark)
&& !section->segment_mark)
/* If the output section of a section in the input segment is NULL,
it is removed from the corresponding output segment. */
@ -5202,12 +5202,12 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
}
/* Determine if this segment overlaps any previous segments. */
for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2 ++)
for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2++)
{
bfd_signed_vma extra_length;
if (segment2->p_type != PT_LOAD
|| ! SEGMENT_OVERLAPS (segment, segment2))
|| !SEGMENT_OVERLAPS (segment, segment2))
continue;
/* Merge the two segments together. */
@ -5215,13 +5215,12 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
{
/* Extend SEGMENT2 to include SEGMENT and then delete
SEGMENT. */
extra_length =
SEGMENT_END (segment, segment->p_vaddr)
- SEGMENT_END (segment2, segment2->p_vaddr);
extra_length = (SEGMENT_END (segment, segment->p_vaddr)
- SEGMENT_END (segment2, segment2->p_vaddr));
if (extra_length > 0)
{
segment2->p_memsz += extra_length;
segment2->p_memsz += extra_length;
segment2->p_filesz += extra_length;
}
@ -5236,13 +5235,12 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
{
/* Extend SEGMENT to include SEGMENT2 and then delete
SEGMENT2. */
extra_length =
SEGMENT_END (segment2, segment2->p_vaddr)
- SEGMENT_END (segment, segment->p_vaddr);
extra_length = (SEGMENT_END (segment2, segment2->p_vaddr)
- SEGMENT_END (segment, segment->p_vaddr));
if (extra_length > 0)
{
segment->p_memsz += extra_length;
segment->p_memsz += extra_length;
segment->p_filesz += extra_length;
}
@ -5254,17 +5252,19 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* The second scan attempts to assign sections to segments. */
for (i = 0, segment = elf_tdata (ibfd)->phdr;
i < num_segments;
i ++, segment ++)
i++, segment++)
{
unsigned int section_count;
asection ** sections;
asection * output_section;
unsigned int isec;
bfd_vma matching_lma;
bfd_vma suggested_lma;
unsigned int j;
unsigned int section_count;
asection **sections;
asection *output_section;
unsigned int isec;
bfd_vma matching_lma;
bfd_vma suggested_lma;
unsigned int j;
bfd_size_type amt;
asection * first_section;
asection *first_section;
bfd_boolean first_matching_lma;
bfd_boolean first_suggested_lma;
if (segment->p_type == PT_NULL)
continue;
@ -5296,9 +5296,9 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* Initialise the fields of the segment map. Default to
using the physical address of the segment in the input BFD. */
map->next = NULL;
map->p_type = segment->p_type;
map->p_flags = segment->p_flags;
map->next = NULL;
map->p_type = segment->p_type;
map->p_flags = segment->p_flags;
map->p_flags_valid = 1;
/* If the first section in the input segment is removed, there is
@ -5314,10 +5314,9 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
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)
if (!phdr_included || segment->p_type != PT_LOAD)
{
map->includes_phdrs =
(segment->p_offset <= (bfd_vma) iehdr->e_phoff
@ -5336,9 +5335,9 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
something. They are allowed by the ELF spec however, so only
a warning is produced. */
if (segment->p_type == PT_LOAD)
(*_bfd_error_handler)
(_("%B: warning: Empty loadable segment detected, is this intentional ?\n"),
ibfd);
(*_bfd_error_handler) (_("%B: warning: Empty loadable segment"
" detected, is this intentional ?\n"),
ibfd);
map->count = 0;
*pointer_to_map = map;
@ -5390,6 +5389,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
isec = 0;
matching_lma = 0;
suggested_lma = 0;
first_matching_lma = TRUE;
first_suggested_lma = TRUE;
for (j = 0, section = ibfd->sections;
section != NULL;
@ -5399,7 +5400,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
{
output_section = section->output_section;
sections[j ++] = section;
sections[j++] = section;
/* The Solaris native linker always sets p_paddr to 0.
We try to catch that case here, and set it to the
@ -5407,36 +5408,42 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
p_paddr be left as zero. */
if (segment->p_paddr == 0
&& segment->p_vaddr != 0
&& (! bed->want_p_paddr_set_to_zero)
&& !bed->want_p_paddr_set_to_zero
&& isec == 0
&& output_section->lma != 0
&& (output_section->vma == (segment->p_vaddr
+ (map->includes_filehdr
? iehdr->e_ehsize
: 0)
+ (map->includes_phdrs
? (iehdr->e_phnum
* iehdr->e_phentsize)
: 0))))
&& output_section->vma == (segment->p_vaddr
+ (map->includes_filehdr
? iehdr->e_ehsize
: 0)
+ (map->includes_phdrs
? (iehdr->e_phnum
* iehdr->e_phentsize)
: 0)))
map->p_paddr = segment->p_vaddr;
/* Match up the physical address of the segment with the
LMA address of the output section. */
if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
|| IS_COREFILE_NOTE (segment, section)
|| (bed->want_p_paddr_set_to_zero &&
IS_CONTAINED_BY_VMA (output_section, segment)))
|| (bed->want_p_paddr_set_to_zero
&& IS_CONTAINED_BY_VMA (output_section, segment)))
{
if (matching_lma == 0 || output_section->lma < matching_lma)
matching_lma = output_section->lma;
if (first_matching_lma || output_section->lma < matching_lma)
{
matching_lma = output_section->lma;
first_matching_lma = FALSE;
}
/* We assume that if the section fits within the segment
then it does not overlap any other section within that
segment. */
map->sections[isec ++] = output_section;
map->sections[isec++] = output_section;
}
else if (first_suggested_lma)
{
suggested_lma = output_section->lma;
first_suggested_lma = FALSE;
}
else if (suggested_lma == 0)
suggested_lma = output_section->lma;
}
}
@ -5466,7 +5473,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
}
else
{
if (matching_lma != 0)
if (!first_matching_lma)
{
/* At least one section fits inside the current segment.
Keep it, but modify its physical address to match the
@ -5512,6 +5519,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
{
map->count = 0;
suggested_lma = 0;
first_suggested_lma = TRUE;
/* Fill the current segment with sections that fit. */
for (j = 0; j < section_count; j++)
@ -5533,17 +5541,17 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* If the first section in a segment does not start at
the beginning of the segment, then something is
wrong. */
if (output_section->lma !=
(map->p_paddr
+ (map->includes_filehdr ? iehdr->e_ehsize : 0)
+ (map->includes_phdrs
? iehdr->e_phnum * iehdr->e_phentsize
: 0)))
if (output_section->lma
!= (map->p_paddr
+ (map->includes_filehdr ? iehdr->e_ehsize : 0)
+ (map->includes_phdrs
? iehdr->e_phnum * iehdr->e_phentsize
: 0)))
abort ();
}
else
{
asection * prev_sec;
asection *prev_sec;
prev_sec = map->sections[map->count - 1];
@ -5553,11 +5561,14 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
if ((BFD_ALIGN (prev_sec->lma + prev_sec->size,
maxpagesize)
< BFD_ALIGN (output_section->lma, maxpagesize))
|| ((prev_sec->lma + prev_sec->size)
|| (prev_sec->lma + prev_sec->size
> output_section->lma))
{
if (suggested_lma == 0)
suggested_lma = output_section->lma;
if (first_suggested_lma)
{
suggested_lma = output_section->lma;
first_suggested_lma = FALSE;
}
continue;
}
@ -5568,8 +5579,11 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
sections[j] = NULL;
section->segment_mark = TRUE;
}
else if (suggested_lma == 0)
suggested_lma = output_section->lma;
else if (first_suggested_lma)
{
suggested_lma = output_section->lma;
first_suggested_lma = FALSE;
}
}
BFD_ASSERT (map->count > 0);
@ -5595,14 +5609,14 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
/* Initialise the fields of the segment map. Set the physical
physical address to the LMA of the first section that has
not yet been assigned. */
map->next = NULL;
map->p_type = segment->p_type;
map->p_flags = segment->p_flags;
map->p_flags_valid = 1;
map->p_paddr = suggested_lma;
map->p_paddr_valid = 1;
map->next = NULL;
map->p_type = segment->p_type;
map->p_flags = segment->p_flags;
map->p_flags_valid = 1;
map->p_paddr = suggested_lma;
map->p_paddr_valid = 1;
map->includes_filehdr = 0;
map->includes_phdrs = 0;
map->includes_phdrs = 0;
}
}
while (isec < section_count);