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>
|
Tue May 26 19:37:47 1998 Stan Cox <scox@equinox.cygnus.com>
|
||||||
|
|
||||||
* elf32-sparc.c (_bfd_sparc_elf_howto_table, sparc_reloc_map,
|
* 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.
|
* elf-bfd.h (elf_linker_section_t): Make alignment unsigned.
|
||||||
(struct elf_obj_tdata): Make cverdefs and cverrefs unsigned.
|
(struct elf_obj_tdata): Make cverdefs and cverrefs unsigned.
|
||||||
* elf.c (assign_file_positions_for_segments): Always set adjust.
|
* elf.c (assign_file_positions_for_segments): Always set adjust.
|
||||||
|
start-sanitize-d30v
|
||||||
* elf32-d30v.c (bfd_elf_d30v_reloc): Initialize tmp_addr. Fully
|
* elf32-d30v.c (bfd_elf_d30v_reloc): Initialize tmp_addr. Fully
|
||||||
parenthesize expression.
|
parenthesize expression.
|
||||||
|
end-sanitize-d30v
|
||||||
* elf32-m32r.c (m32r_elf_relocate_section): Always initialize h.
|
* elf32-m32r.c (m32r_elf_relocate_section): Always initialize h.
|
||||||
(m32r_elf_object_p): Return a value.
|
(m32r_elf_object_p): Return a value.
|
||||||
(m32r_elf_print_private_bfd_data): Change fprintf format string.
|
(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;
|
flags = sec->flags;
|
||||||
align = 1 << bfd_get_section_alignment (abfd, sec);
|
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)
|
if (p->p_type == PT_LOAD)
|
||||||
{
|
{
|
||||||
bfd_vma adjust;
|
bfd_vma adjust;
|
||||||
|
@ -3291,6 +3305,8 @@ copy_private_bfd_data (ibfd, obfd)
|
||||||
m->p_type = p->p_type;
|
m->p_type = p->p_type;
|
||||||
m->p_flags = p->p_flags;
|
m->p_flags = p->p_flags;
|
||||||
m->p_flags_valid = 1;
|
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 = p->p_paddr;
|
||||||
m->p_paddr_valid = 1;
|
m->p_paddr_valid = 1;
|
||||||
|
|
||||||
|
@ -3305,9 +3321,19 @@ copy_private_bfd_data (ibfd, obfd)
|
||||||
isec = 0;
|
isec = 0;
|
||||||
for (s = ibfd->sections; s != NULL; s = s->next)
|
for (s = ibfd->sections; s != NULL; s = s->next)
|
||||||
{
|
{
|
||||||
if (((s->vma >= p->p_vaddr
|
boolean matching_lma = false;
|
||||||
&& (s->vma + s->_raw_size <= p->p_vaddr + p->p_memsz
|
boolean lma_conflict = false;
|
||||||
|| s->vma + s->_raw_size <= p->p_vaddr + p->p_filesz))
|
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_vaddr == 0
|
||||||
&& p->p_filesz > 0
|
&& p->p_filesz > 0
|
||||||
&& (s->flags & SEC_HAS_CONTENTS) != 0
|
&& (s->flags & SEC_HAS_CONTENTS) != 0
|
||||||
|
@ -3315,10 +3341,37 @@ copy_private_bfd_data (ibfd, obfd)
|
||||||
&& ((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)))
|
||||||
&& (s->flags & SEC_ALLOC) != 0
|
&& (s->flags & SEC_ALLOC) != 0
|
||||||
&& s->output_section != NULL)
|
&& os != NULL)
|
||||||
{
|
{
|
||||||
m->sections[isec] = s->output_section;
|
m->sections[isec] = os;
|
||||||
++isec;
|
++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);
|
BFD_ASSERT (isec == csecs);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue