Partial fix for PR 15929 - Change physical address of segment when its
sections' LMAs have changed.
This commit is contained in:
parent
1793f86d75
commit
e5fc780949
2 changed files with 65 additions and 5 deletions
|
@ -1,3 +1,8 @@
|
|||
Fri May 29 09:58:08 1998 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* elf.c (copy_private_bfd_data): Adjust physical address of
|
||||
segment in output BFD to contain LMAs of its sections.
|
||||
|
||||
Tue May 26 19:37:47 1998 Stan Cox <scox@equinox.cygnus.com>
|
||||
|
||||
* elf32-sparc.c (_bfd_sparc_elf_howto_table, sparc_reloc_map,
|
||||
|
@ -520,8 +525,10 @@ Fri Mar 27 16:06:02 1998 Ian Lance Taylor <ian@cygnus.com>
|
|||
* elf-bfd.h (elf_linker_section_t): Make alignment unsigned.
|
||||
(struct elf_obj_tdata): Make cverdefs and cverrefs unsigned.
|
||||
* elf.c (assign_file_positions_for_segments): Always set adjust.
|
||||
start-sanitize-d30v
|
||||
* elf32-d30v.c (bfd_elf_d30v_reloc): Initialize tmp_addr. Fully
|
||||
parenthesize expression.
|
||||
end-sanitize-d30v
|
||||
* elf32-m32r.c (m32r_elf_relocate_section): Always initialize h.
|
||||
(m32r_elf_object_p): Return a value.
|
||||
(m32r_elf_print_private_bfd_data): Change fprintf format string.
|
||||
|
|
63
bfd/elf.c
63
bfd/elf.c
|
@ -2595,6 +2595,20 @@ assign_file_positions_for_segments (abfd)
|
|||
flags = sec->flags;
|
||||
align = 1 << bfd_get_section_alignment (abfd, sec);
|
||||
|
||||
/* The section may have artificial alignment forced by a
|
||||
link script. Notice this case by the gap between the
|
||||
cumulative phdr vma and the section's vma. */
|
||||
if (p->p_vaddr + p->p_memsz < sec->vma)
|
||||
{
|
||||
bfd_vma adjust = sec->vma - (p->p_vaddr + p->p_memsz);
|
||||
|
||||
p->p_memsz += adjust;
|
||||
off += adjust;
|
||||
voff += adjust;
|
||||
if ((flags & SEC_LOAD) != 0)
|
||||
p->p_filesz += adjust;
|
||||
}
|
||||
|
||||
if (p->p_type == PT_LOAD)
|
||||
{
|
||||
bfd_vma adjust;
|
||||
|
@ -3291,6 +3305,8 @@ copy_private_bfd_data (ibfd, obfd)
|
|||
m->p_type = p->p_type;
|
||||
m->p_flags = p->p_flags;
|
||||
m->p_flags_valid = 1;
|
||||
/* Default to using the physical address of the segment
|
||||
in the input BFD. */
|
||||
m->p_paddr = p->p_paddr;
|
||||
m->p_paddr_valid = 1;
|
||||
|
||||
|
@ -3305,9 +3321,19 @@ copy_private_bfd_data (ibfd, obfd)
|
|||
isec = 0;
|
||||
for (s = ibfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
if (((s->vma >= p->p_vaddr
|
||||
&& (s->vma + s->_raw_size <= p->p_vaddr + p->p_memsz
|
||||
|| s->vma + s->_raw_size <= p->p_vaddr + p->p_filesz))
|
||||
boolean matching_lma = false;
|
||||
boolean lma_conflict = false;
|
||||
bfd_vma suggested_lma = 0;
|
||||
asection * os;
|
||||
|
||||
#define is_contained_by(addr, len, bottom, phdr) \
|
||||
((addr) >= (bottom) \
|
||||
&& ( ((addr) + (len)) <= ((bottom) + (phdr)->p_memsz) \
|
||||
|| ((addr) + (len)) <= ((bottom) + (phdr)->p_filesz)))
|
||||
|
||||
os = s->output_section;
|
||||
|
||||
if ((is_contained_by (s->vma, s->_raw_size, p->p_vaddr, p)
|
||||
|| (p->p_vaddr == 0
|
||||
&& p->p_filesz > 0
|
||||
&& (s->flags & SEC_HAS_CONTENTS) != 0
|
||||
|
@ -3315,10 +3341,37 @@ copy_private_bfd_data (ibfd, obfd)
|
|||
&& ((bfd_vma) s->filepos + s->_raw_size
|
||||
<= p->p_offset + p->p_filesz)))
|
||||
&& (s->flags & SEC_ALLOC) != 0
|
||||
&& s->output_section != NULL)
|
||||
&& os != NULL)
|
||||
{
|
||||
m->sections[isec] = s->output_section;
|
||||
m->sections[isec] = os;
|
||||
++isec;
|
||||
|
||||
/* Match up the physical address of the segment with the
|
||||
LMA addresses of its sections. */
|
||||
|
||||
if (is_contained_by (os->lma, os->_raw_size, m->p_paddr, p))
|
||||
matching_lma = true;
|
||||
else if (suggested_lma == 0)
|
||||
suggested_lma = os->lma;
|
||||
else if
|
||||
(! is_contained_by (os->lma, os->_raw_size, suggested_lma, p))
|
||||
lma_conflict = true;
|
||||
}
|
||||
|
||||
if (matching_lma)
|
||||
{
|
||||
if (suggested_lma)
|
||||
(*_bfd_error_handler)
|
||||
(_("Warning: Some sections' LMAs lie outside their segment's physical address\n"));
|
||||
}
|
||||
else if (lma_conflict)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("Warning: Cannot change segment's physical address to contain all of its sections' LMAs\n"));
|
||||
}
|
||||
else if (suggested_lma)
|
||||
{
|
||||
m->p_paddr = suggested_lma;
|
||||
}
|
||||
}
|
||||
BFD_ASSERT (isec == csecs);
|
||||
|
|
Loading…
Add table
Reference in a new issue