aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf.c63
2 files changed, 65 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b130f55..782cae6 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf.c b/bfd/elf.c
index bb62b2b..b4bba46 100644
--- a/bfd/elf.c
+++ b/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);