]> Git Repo - binutils.git/commitdiff
* write.c (dump_section_relocs): Don't convert PC-relative relocs
authorMaciej W. Rozycki <[email protected]>
Tue, 15 Nov 2011 13:08:17 +0000 (13:08 +0000)
committerMaciej W. Rozycki <[email protected]>
Tue, 15 Nov 2011 13:08:17 +0000 (13:08 +0000)
that have an in-place addend narrower than the addresses used.

gas/ChangeLog
gas/write.c

index fa0cec6a967d7f6b83a5520b04a4956d3dc58e8a..475929e8537c9326afc7459617d5b5760b0855d6 100644 (file)
@@ -1,3 +1,8 @@
+2011-11-15  Maciej W. Rozycki  <[email protected]>
+
+       * 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  <[email protected]>
 
        * config/tc-mips.c (can_swap_branch_p): Exclude microMIPS
index cf59d7da883a0d7d716dd938e83dfd86bac56677..a1e0205f868be9d0a5781422866865091cceed4a 100644 (file)
@@ -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;
This page took 0.033118 seconds and 4 git commands to generate.