aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf64-x86-64.c38
2 files changed, 29 insertions, 15 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 81e751c..e862c3c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2016-02-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/19542
+ * elf64-x86-64.c (elf_x86_64_convert_load): Store the estimated
+ distrances in the compressed_size field of the output section.
+
2016-02-02 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (ppc64_elf_relocate_section): Further restrict
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 88ed00e..8118c1d 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -3190,35 +3190,43 @@ elf_x86_64_convert_load (bfd *abfd, asection *sec,
}
else
{
- asection *asect;
- bfd_size_type size;
+ bfd_signed_vma distance;
/* At this point, we don't know the load addresses of TSEC
section nor SEC section. We estimate the distrance between
- SEC and TSEC. */
- size = 0;
- for (asect = sec->output_section;
- asect != NULL && asect != tsec->output_section;
- asect = asect->next)
+ SEC and TSEC. We store the estimated distrances in the
+ compressed_size field of the output section, which is only
+ used to decompress the compressed input section. */
+ if (sec->output_section->compressed_size == 0)
{
- asection *i;
- for (i = asect->output_section->map_head.s;
- i != NULL;
- i = i->map_head.s)
+ asection *asect;
+ bfd_size_type size = 0;
+ for (asect = link_info->output_bfd->sections;
+ asect != NULL;
+ asect = asect->next)
{
- size = align_power (size, i->alignment_power);
- size += i->size;
+ asection *i;
+ for (i = asect->map_head.s;
+ i != NULL;
+ i = i->map_head.s)
+ {
+ size = align_power (size, i->alignment_power);
+ size += i->size;
+ }
+ asect->compressed_size = size;
}
}
/* Don't convert GOTPCREL relocations if TSEC isn't placed
after SEC. */
- if (asect == NULL)
+ distance = (tsec->output_section->compressed_size
+ - sec->output_section->compressed_size);
+ if (distance < 0)
continue;
/* Take PT_GNU_RELRO segment into account by adding
maxpagesize. */
- if ((toff + size + maxpagesize - roff + 0x80000000)
+ if ((toff + distance + maxpagesize - roff + 0x80000000)
> 0xffffffff)
continue;
}