aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2001-10-30 11:34:46 +0000
committerNick Clifton <nickc@redhat.com>2001-10-30 11:34:46 +0000
commite0e8c97fe9c3fbbadba39b18b433cb84aa7ac8fc (patch)
tree23bf4aefd61ecc72b8b8530a89dab089fc5a2b67
parentb7209cb4ed7852044e3ec55daec11e9f693e401c (diff)
downloadfsf-binutils-gdb-e0e8c97fe9c3fbbadba39b18b433cb84aa7ac8fc.zip
fsf-binutils-gdb-e0e8c97fe9c3fbbadba39b18b433cb84aa7ac8fc.tar.gz
fsf-binutils-gdb-e0e8c97fe9c3fbbadba39b18b433cb84aa7ac8fc.tar.bz2
Set the LMA based on the p_paddr of the segment that contains it.
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf.c34
2 files changed, 29 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index bb2dc4c..0a131cf 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2001-10-30 Richard Earnshaw (rearnsha@arm.com)
+
+ * elf.c (_bfd_elf_make_section_from_shdr): Set the LMA based on the
+ p_paddr of the segment that contains it.
+
2001-10-29 Kazu Hirata <kazu@hxi.com>
* README: Fix a typo.
diff --git a/bfd/elf.c b/bfd/elf.c
index 16c6fcb..cf51607 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -40,6 +40,7 @@ SECTION
#include "libbfd.h"
#define ARCH_SIZE 0
#include "elf-bfd.h"
+#include "libiberty.h"
static INLINE struct elf_segment_map *make_mapping
PARAMS ((bfd *, asection **, unsigned int, unsigned int, boolean));
@@ -466,7 +467,7 @@ setup_group (abfd, hdr, newsect)
while (--n_elt != 0)
if ((++idx)->shdr == hdr)
{
- asection *s;
+ asection *s = NULL;
/* We are a member of this group. Go looking through
other members to see if any others are linked via
@@ -599,7 +600,7 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name)
};
int i;
- for (i = sizeof (debug_sec_names) / sizeof (debug_sec_names[0]); i--;)
+ for (i = ARRAY_SIZE (debug_sec_names); i--;)
if (strncmp (name, debug_sec_names[i], strlen (debug_sec_names[i])) == 0)
break;
@@ -643,17 +644,30 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name)
phdr = elf_tdata (abfd)->phdr;
for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
{
+ /* This section is part of this segment if its file
+ offset plus size lies within the segment's memory
+ span and, if the section is loaded, the extent of the
+ loaded data lies within the extent of the segment.
+ If the p_paddr field is not set, we don't alter the
+ LMA. */
if (phdr->p_type == PT_LOAD
- && phdr->p_vaddr != phdr->p_paddr
- && phdr->p_vaddr <= hdr->sh_addr
- && (phdr->p_vaddr + phdr->p_memsz
- >= hdr->sh_addr + hdr->sh_size)
+ && phdr->p_paddr
+ && (bfd_vma) hdr->sh_offset >= phdr->p_offset
+ && (hdr->sh_offset + hdr->sh_size
+ <= phdr->p_offset + phdr->p_memsz)
&& ((flags & SEC_LOAD) == 0
- || (phdr->p_offset <= (bfd_vma) hdr->sh_offset
- && (phdr->p_offset + phdr->p_filesz
- >= hdr->sh_offset + hdr->sh_size))))
+ || (phdr->p_offset + phdr->p_filesz
+ >= hdr->sh_offset + hdr->sh_size)))
{
- newsect->lma += phdr->p_paddr - phdr->p_vaddr;
+ /* We used to do a relative adjustment here, but
+ that doesn't work if the segment is packed with
+ code from multiple VMAs. Instead we calculate
+ the LMA absoultely, based on the LMA of the
+ segment (it is assumed that the segment will
+ contain sections with contiguous LMAs, even if
+ the VMAs are not). */
+ newsect->lma = phdr->p_paddr
+ + hdr->sh_offset - phdr->p_offset;
break;
}
}