diff options
author | Maciej W. Rozycki <macro@linux-mips.org> | 2011-11-15 13:10:06 +0000 |
---|---|---|
committer | Maciej W. Rozycki <macro@linux-mips.org> | 2011-11-15 13:10:06 +0000 |
commit | 426a3c129d4230cee150f0928e73234ffd222699 (patch) | |
tree | b1231f640ea5bc3c419506e2466414013ddb2670 | |
parent | fcb8c5a0deaa082bd10193c10bc9ceff48a02f95 (diff) | |
download | gdb-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/ChangeLog | 7 | ||||
-rw-r--r-- | gas/write.c | 21 |
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; |