This is the mail archive of the mailing list for the binutils project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[GAS][ARM]Use frag's thumb_mode information when available.

Hi all,

In arm_init_frag(), thumb_mode is used to decide generate MAP_ARM or MAP_THUMB mapping symbol when aligning code. However, thumb_mode is a static variable. arm_init_frag will be called in two different stages, reading source file and writing object file.

This is not a problem before. But after my change here: The switch statement will always be evaluated. In this case, previous thumb_mode (decided while processing source file) will affect the correct map symbol inserting later.

For example:

        bx      lr
------------> MAP_THUMB is inserted here while finishing subseg. .thumb_func ------------> thumb_mode is 1 while reading source file.
        .p2align 4

        bx      lr

The assembly objectdump looks like this which is not correct:

00000000 <arm_func>:

   0:   e12fff1e        bx      lr
   4:   0000            movs    r0, r0
   6:   e1a0            b.n     34a <thumb_func+0x33a>
   8:   0000            movs    r0, r0
   a:   e1a0            b.n     34e <thumb_func+0x33e>
   c:   0000            movs    r0, r0
   e:   e1a0            b.n     352 <thumb_func+0x342>

00000010 <thumb_func>:

  10:   4770            bx      lr
  12:   46c0            nop                     ; (mov r8, r8)
  14:   46c0            nop                     ; (mov r8, r8)
  16:   46c0            nop                     ; (mov r8, r8)

binutils, gas, ld regression test Okay. Okay to commit?

Renlin Li


2015-06-02  Renlin Li  <>
        * config/tc-arm.c (arm_init_frag): Use frag's thumb_mode
        information when available.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 2f6fea6..3c42008 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -21030,10 +21030,14 @@ arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
 arm_init_frag (fragS * fragP, int max_chars)
+  int frag_thumb_mode;
   /* If the current ARM vs THUMB mode has not already
      been recorded into this frag then do so now.  */
   if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
-      fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
+    fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
+  frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
   /* Record a mapping symbol for alignment frags.  We will delete this
      later if the alignment ends up empty.  */
@@ -21045,7 +21049,7 @@ arm_init_frag (fragS * fragP, int max_chars)
       mapping_state_2 (MAP_DATA, max_chars);
     case rs_align_code:
-      mapping_state_2 (thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
+      mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]