aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2011-11-15 13:10:06 +0000
committerMaciej W. Rozycki <macro@linux-mips.org>2011-11-15 13:10:06 +0000
commit426a3c129d4230cee150f0928e73234ffd222699 (patch)
treeb1231f640ea5bc3c419506e2466414013ddb2670
parentfcb8c5a0deaa082bd10193c10bc9ceff48a02f95 (diff)
downloadgdb-426a3c129d4230cee150f0928e73234ffd222699.zip
gdb-426a3c129d4230cee150f0928e73234ffd222699.tar.gz
gdb-426a3c129d4230cee150f0928e73234ffd222699.tar.bz2
Apply mainline patches
2011-11-15 Maciej W. Rozycki <macro@codesourcery.com> * write.c (dump_section_relocs): Don't convert PC-relative relocs that have an in-place addend narrower than the addresses used.
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/write.c21
2 files changed, 24 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index fa8fe62..b29f95f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2011-11-15 Maciej W. Rozycki <macro@codesourcery.com>
+
+ Apply mainline patches
+ 2011-11-15 Maciej W. Rozycki <macro@codesourcery.com>
+ * write.c (dump_section_relocs): Don't convert PC-relative relocs
+ that have an in-place addend narrower than the addresses used.
+
2011-11-14 Maciej W. Rozycki <macro@codesourcery.com>
Apply mainline patches
diff --git a/gas/write.c b/gas/write.c
index cf59d7d..a1e0205 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -654,15 +654,21 @@ dump_section_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, FILE *stream)
static void
resolve_reloc_expr_symbols (void)
{
+ bfd_vma addr_mask = 1;
struct reloc_list *r;
+ /* Avoid a shift by the width of type. */
+ addr_mask <<= bfd_arch_bits_per_address (stdoutput) - 1;
+ addr_mask <<= 1;
+ addr_mask -= 1;
+
for (r = reloc_list; r; r = r->next)
{
+ reloc_howto_type *howto = r->u.a.howto;
expressionS *symval;
symbolS *sym;
bfd_vma offset, addend;
asection *sec;
- reloc_howto_type *howto;
resolve_symbol_value (r->u.a.offset_sym);
symval = symbol_get_value_expression (r->u.a.offset_sym);
@@ -709,7 +715,16 @@ resolve_reloc_expr_symbols (void)
}
else if (sym != NULL)
{
- if (S_IS_LOCAL (sym) && !symbol_section_p (sym))
+ /* Convert relocs against local symbols to refer to the
+ corresponding section symbol plus offset instead. Keep
+ PC-relative relocs of the REL variety intact though to
+ prevent the offset from overflowing the relocated field,
+ unless it has enough bits to cover the whole address
+ space. */
+ if (S_IS_LOCAL (sym) && !symbol_section_p (sym)
+ && !(howto->partial_inplace
+ && howto->pc_relative
+ && howto->src_mask != addr_mask))
{
asection *symsec = S_GET_SEGMENT (sym);
if (!(((symsec->flags & SEC_MERGE) != 0
@@ -730,8 +745,6 @@ resolve_reloc_expr_symbols (void)
sym = abs_section_sym;
}
- howto = r->u.a.howto;
-
r->u.b.sec = sec;
r->u.b.s = symbol_get_bfdsym (sym);
r->u.b.r.sym_ptr_ptr = &r->u.b.s;