ARM mapping symbols

Bruno De Bus bdebus@elis.ugent.be
Mon Mar 8 19:57:00 GMT 2004


On Mon, 8 Mar 2004, Richard Earnshaw wrote:

> > Hi Bruno,
> > 
> > >> > The last assembled section is often a data section, so the mapping
> > >> > symbol is $d. Then arm_cleanup is called and the literal pool(s)
> > >> > is(/are) written. As the last symbol already was $d, no new symbol
> > >> > is added... 
> > >> 
> > >> Ok - but this is easily fixed by calling arm_elf_change_section()
> > >> after calling subseg_set() in arm_cleanup().  Then the correct-for-
> > >> that-section mapping symbol will be emitted, which can then be changed
> > >> by your patch to s_ltorg().
> > >
> > > I might be wrong again, but I believe this will add both a $d and a 
> > > $a symbol? 
> > 
> > Yes - is this a problem ?  I know that it is not optimal, but I
> > thought that it might be a simpler "quick hack" that adding a 'forced'
> > argument to mapping_state().
> 
> Please lets not talk about "quick hacks".  Quick hacks have a tendency to 
> breed, and before you know what's happening you have serious spaghetti to 
> untangle.
> 
> Instead, lets work out what needs doing to fix this properly.

Agreed, 

the attached patch solves the problem in a more clean fashion:

* I kept the last mapping symbol for a segment in TC_SEGMENT_INFO_TYPE as 
suggested by Nick
* Added a call to arm_elf_change_section in arm_cleanup as suggested by 
Nick
* I added a mapping state MAP_UNDEFINED as suggested by Richard (this 
avoids duplicate mapping symbols at the start of a section)
* moved the enum to tc-arm.h

* changed
#define md_elf_section_change_hook() arm_elf_change_section
to 
#define md_elf_section_change_hook() arm_elf_change_section()
in tc-arm.h ???????????????? Weird.....

* moved mapstate out of the function so we can change it when changing the 
section

It tested the example given by Richard and literal pools (both explicit 
and implicit) and they appear to work correct.... 


Hope this is acceptable....

Bruno

PS:

I applied for a copyright assignment (but the patch is really small, even 
smaller than the first one)

> R.
> 
> 
> 
-------------- next part --------------
Index: config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.163
diff -u -r1.163 tc-arm.c
--- config/tc-arm.c	18 Feb 2004 16:28:17 -0000	1.163
+++ config/tc-arm.c	8 Mar 2004 19:41:08 -0000
@@ -2823,13 +2823,6 @@
 
 
 #ifdef OBJ_ELF
-enum mstate
-{
-  MAP_DATA,
-  MAP_ARM,
-  MAP_THUMB
-};
-
 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
    (This text is taken from version B-02 of the spec):
 
@@ -2904,10 +2897,10 @@
    the EABI (which is still under development), so they are not
    implemented here.  */
 
-static void
-mapping_state (enum mstate state)
+static enum mstate mapstate = MAP_UNDEFINED;
+
+static void mapping_state (enum mstate state)
 {
-  static enum mstate mapstate = MAP_DATA;
   symbolS * symbolP;
   const char * symname;
   int type;
@@ -2933,10 +2926,15 @@
       symname = "$t";
       type = BSF_FUNCTION;
       break;
+    case MAP_UNDEFINED:
+      return;
+      
     default:
       abort ();
     }
 
+  seg_info(now_seg)->tc_segment_info_data=state;
+
   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
   symbol_table_insert (symbolP);
   symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
@@ -2977,16 +2975,7 @@
   if ((flags & SEC_ALLOC) == 0)
     return;
 
-  if (flags & SEC_CODE)
-    {
-      if (thumb_mode)
-	mapping_state (MAP_THUMB);
-      else
-	mapping_state (MAP_ARM);
-    }
-  else
-    /* This section does not contain code.  Therefore it must contain data.  */
-    mapping_state (MAP_DATA);    
+  mapstate=seg_info(now_seg)->tc_segment_info_data;
 }
 #else
 #define mapping_state(a)
@@ -3111,6 +3100,9 @@
 
   /* Align pool as you have word accesses.
      Only make a frag if we have to.  */
+
+
+  mapping_state(MAP_DATA);
   if (!need_pass_2)
     frag_align (2, 0, 0);
 
@@ -3184,6 +3176,7 @@
      This is used by gcc/config/arm/lib1funcs.asm for example
      to compile interworking support functions even if the
      target processor should not support interworking.  */
+
   if (! thumb_mode)
     {
       thumb_mode = 2;
@@ -13817,6 +13810,9 @@
     {
       /* Put it at the end of the relevent section.  */
       subseg_set (pool->section, pool->sub_section);
+#ifdef OBJ_ELF
+      arm_elf_change_section();
+#endif
       s_ltorg (0);
     }
 }
Index: config/tc-arm.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.h,v
retrieving revision 1.21
diff -u -r1.21 tc-arm.h
--- config/tc-arm.h	21 Nov 2003 00:24:40 -0000	1.21
+++ config/tc-arm.h	8 Mar 2004 19:41:08 -0000
@@ -91,9 +91,21 @@
 # define TARGET_FORMAT elf32_arm_target_format()
   extern const char * elf32_arm_target_format PARAMS ((void));
 
-# define md_elf_section_change_hook() arm_elf_change_section
+# define md_elf_section_change_hook() arm_elf_change_section()
   extern void arm_elf_change_section (void);
+
+enum mstate
+{
+  MAP_UNDEFINED=0, /* Must be zero, for seginfo in new sections */
+  MAP_DATA,
+  MAP_ARM,
+  MAP_THUMB
+};
+
+
+#define TC_SEGMENT_INFO_TYPE enum mstate
 #endif
+
 
 #define TC_FORCE_RELOCATION(FIX) arm_force_relocation (FIX)
 extern int arm_force_relocation PARAMS ((struct fix *));


More information about the Binutils mailing list