This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[GAS][ARM]Use frag's thumb_mode information when available.
- From: Renlin Li <renlin dot li at arm dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: Nicholas Clifton <nickc at redhat dot com>, Marcus Shawcroft <Marcus dot Shawcroft at arm dot com>
- Date: Tue, 02 Jun 2015 10:17:07 +0100
- Subject: [GAS][ARM]Use frag's thumb_mode information when available.
- Authentication-results: sourceware.org; auth=none
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:
https://sourceware.org/ml/binutils/2015-04/msg00381.html. 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:
arm_func:
bx lr
------------> MAP_THUMB is inserted here while
finishing subseg.
.thumb_func ------------> thumb_mode is 1 while reading source
file.
.p2align 4
thumb_func:
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?
Regards,
Renlin Li
gas/ChangeLog:
2015-06-02 Renlin Li <renlin.li@arm.com>
* 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)
void
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);
break;
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);
break;
default:
break;