public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Vidya Praveen <childbear0@gmail.com>
To: binutils@sourceware.org
Cc: childbear0@gmail.com, vidya.praveen@atmel.com
Subject: [PATCH, AVR] Fix PR13410 (reformatted)
Date: Tue, 31 Jan 2012 19:46:00 -0000	[thread overview]
Message-ID: <4F284509.2020408@gmail.com> (raw)

[Resending as the previous email was not properly formatted. Please ignore
the previous email]


One of the two conditions that determines the candidates for relaxation
(from JMP/CALL to rjmp/rcall),

            /* If the distance is within -4094..+4098 inclusive, then we can
               relax this jump/call.  +4098 because the call/jump target
               will be closer after the relaxation.  */
            if ((int) gap >= -4094 && (int) gap <= 4098)
              distance_short_enough = 1;

checks for the range of distance -4094..+4098 inclusive. There are two issues
here.

The first issue is that the range should have been -4094 to +4097 (since we
shrink by 2 bytes, we can consider a longer range than the original -4096 to
+4095).

The second issue is the primary reason for the failure reported in this PR.
During the relaxation (elf32_avr_relax_section) of JMP/CALL to rjmp/rcall, some
cases where we don't want to modify the ordering, 'nop's are inserted instead
of deleting bytes:

                if (!strcmp (sec->name,".vectors")
                    || !strcmp (sec->name,".jumptables"))
                  {
                    /* Let's insert a nop.  */
                    bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 2);
                    bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 3);
                  }
                else
                  {
                    /* Delete two bytes of data.  */
                    if (!elf32_avr_relax_delete_bytes (abfd, sec,
                                                       irel->r_offset + 2, 2))
                      goto error_return;

                    /* That will change things, so, we should relax again.
                       Note that this is not required, and it may be slow.  */
                    *again = TRUE;
                  }

While this is fine, the condition mentioned above that qualifies the candidates
doesn't consider the situation where we don't shrink. That is, if the section is
.vectors or .jumptables, we still check for -4094..+4098 range which assumes
shrink. Causing larger offsets slipping through and which later found to be
overflowing!

I have fixed this issue and the following patch should fix this. I have tested
with multiple testcases including the one that is presented here.

OK for trunk?

Regards
Vidya Praveen, Atmel India




2012-02-01  Vidya Praveen <childbear0@gmail.com>

        PR bfd/13410
        * bfd/elf32-avr.c (elf32_avr_relax_section): Correct the range
        for qualifying candidates for relaxation

--- bfd/elf32-avr.c     2012-01-24 14:11:41.000000000 +0530
+++ bfd/elf32-avr.c     2012-01-31 20:30:26.000000000 +0530
@@ -1659,6 +1659,15 @@
   Elf_Internal_Sym *isymbuf = NULL;
   struct elf32_avr_link_hash_table *htab;

+  /* if true, do not shrink by deleting bytes while relaxing.Such shrinking can
+    can cause issues for sections such as .vectors and .jumptables.Instead fill
+    with nop instructions */
+  bfd_boolean shrinkable = TRUE;
+
+  if (!strcmp (sec->name,".vectors")
+      || !strcmp (sec->name,".jumptables"))
+    shrinkable = FALSE;
+
   if (link_info->relocatable)
     (*link_info->callbacks->einfo)
       (_("%P%F: --relax and -r may not be used together\n"));
@@ -1815,10 +1824,12 @@
             /* Compute the distance from this insn to the branch target.  */
             gap = value - dot;

-            /* If the distance is within -4094..+4098 inclusive, then we can
-               relax this jump/call.  +4098 because the call/jump target
+            /* If the distance is within -4094..+4097 inclusive, then we can
+               relax this jump/call.  +4097 because the call/jump target
                will be closer after the relaxation.  */
-            if ((int) gap >= -4094 && (int) gap <= 4098)
+            if (!shrinkable && ((int) gap >= -4096 && (int) gap <= 4095))
+              distance_short_enough = 1;
+            else if (shrinkable && ((int) gap >= -4094 && (int) gap <= 4097))
               distance_short_enough = 1;

             /* Here we handle the wrap-around case.  E.g. for a 16k device
@@ -1895,8 +1906,7 @@
                 /* Check for the vector section. There we don't want to
                    modify the ordering!  */

-                if (!strcmp (sec->name,".vectors")
-                    || !strcmp (sec->name,".jumptables"))
+                if (!shrinkable)
                   {
                     /* Let's insert a nop.  */
                     bfd_put_8 (abfd, 0x00, contents + irel->r_offset + 2);

                 reply	other threads:[~2012-01-31 19:46 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F284509.2020408@gmail.com \
    --to=childbear0@gmail.com \
    --cc=binutils@sourceware.org \
    --cc=vidya.praveen@atmel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).