Add support for ARM ELF Mapping symbols
authorNick Clifton <nickc@redhat.com>
Thu, 13 Nov 2003 14:19:01 +0000 (14:19 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 13 Nov 2003 14:19:01 +0000 (14:19 +0000)
gas/ChangeLog
gas/config/tc-arm.c
gas/config/tc-arm.h
gas/doc/c-arm.texi
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/arm.exp
gas/testsuite/gas/arm/mapping.d [new file with mode: 0644]
gas/testsuite/gas/arm/mapping.s [new file with mode: 0644]

index 2b52cde8f57407430c195dc904ae1f7462718fd4..cfe80e4faf222e47577ee106735934ebe46eb706 100644 (file)
@@ -1,3 +1,17 @@
+2003-11-13  Nick Clifton  <nickc@redhat.com>
+
+       * tc-arm.c (mapping_state): New function.  Emit a mapping
+       symbol if necessary.
+        (arm_elf_change_section): New function.  Intercept section
+       changes and generate mapping symbols.
+        (s_bss): Likewise.
+        (s_arm_elf_cons): Likewise.
+        (opcode_select): Choose the correct mapping state.
+        (md_assemble): Likewise.
+        * tc-arm.h (md_elf_section_change_hook): Define.
+        * doc/c-arm.texi (ARM Mapping Symbols): New node.
+       * NEWS: Mention new feature.
+
 2003-11-12  Daniel Jacobowitz  <drow@mvista.com>
 
        * Makefile.am (install, install-info, RECURSIVE_TARGETS): Define.
index 5117a257d3b5d39901e980b0205cae37a8da7fa9..bdfa05ce9941a0907f03e8b1856f60ae89adb0ab 100644 (file)
@@ -2646,6 +2646,178 @@ validate_offset_imm (val, hwse)
   return val;
 }
 
+\f
+#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):
+
+      4.4.7 Mapping and tagging symbols
+
+      A section of an ARM ELF file can contain a mixture of ARM code,
+      Thumb code, and data.  There are inline transitions between code
+      and data at literal pool boundaries. There can also be inline
+      transitions between ARM code and Thumb code, for example in
+      ARM-Thumb inter-working veneers.  Linkers, machine-level
+      debuggers, profiling tools, and disassembly tools need to map
+      images accurately. For example, setting an ARM breakpoint on a
+      Thumb location, or in a literal pool, can crash the program
+      being debugged, ruining the debugging session.
+
+      ARM ELF entities are mapped (see section 4.4.7.1 below) and
+      tagged (see section 4.4.7.2 below) using local symbols (with
+      binding STB_LOCAL).  To assist consumers, mapping and tagging
+      symbols should be collated first in the symbol table, before
+      other symbols with binding STB_LOCAL.
+
+      To allow properly collated mapping and tagging symbols to be
+      skipped by consumers that have no interest in them, the first
+      such symbol should have the name $m and its st_value field equal
+      to the total number of mapping and tagging symbols (including
+      the $m) in the symbol table.
+
+      4.4.7.1 Mapping symbols
+
+      $a    Labels the first byte of a sequence of ARM instructions.
+            Its type is STT_FUNC.
+
+      $d    Labels the first byte of a sequence of data items.
+            Its type is STT_OBJECT.
+
+      $t    Labels the first byte of a sequence of Thumb instructions.
+            Its type is STT_FUNC.
+
+      This list of mapping symbols may be extended in the future.
+
+      Section-relative mapping symbols
+
+      Mapping symbols defined in a section define a sequence of
+      half-open address intervals that cover the address range of the
+      section. Each interval starts at the address defined by a
+      mapping symbol, and continues up to, but not including, the
+      address defined by the next (in address order) mapping symbol or
+      the end of the section. A corollary is that there must be a
+      mapping symbol defined at the beginning of each section.
+      Consumers can ignore the size of a section-relative mapping
+      symbol. Producers can set it to 0.
+
+      Absolute mapping symbols
+
+      Because of the need to crystallize a Thumb address with the
+      Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
+      STT_FUNC defined in section SHN_ABS) need to be mapped with $a
+      or $t.
+
+      The extent of a mapping symbol defined in SHN_ABS is [st_value,
+      st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
+      where [x, y) denotes the half-open address range from x,
+      inclusive, to y, exclusive.
+
+      In the absence of a mapping symbol, a consumer can interpret a
+      function symbol with an odd value as the Thumb code address
+      obtained by clearing the least significant bit of the
+      value. This interpretation is deprecated, and it may not work in
+      the future.
+
+   Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
+   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_DATA;
+  symbolS * symbolP;
+  const char * symname;
+  int type;
+
+  if (mapstate == state)
+    /* The mapping symbol has already been emitted.
+       There is nothing else to do.  */
+    return;
+
+  mapstate = state;
+
+  switch (state)
+    {
+    case MAP_DATA:
+      symname = "$d";
+      type = BSF_OBJECT;
+      break;
+    case MAP_ARM:
+      symname = "$a";
+      type = BSF_FUNCTION;
+      break;
+    case MAP_THUMB:
+      symname = "$t";
+      type = BSF_FUNCTION;
+      break;
+    default:
+      abort ();
+    }
+
+  symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
+  symbol_table_insert (symbolP);
+  symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
+  
+  switch (state)
+    {
+    case MAP_ARM:
+      THUMB_SET_FUNC (symbolP, 0);
+      ARM_SET_THUMB (symbolP, 0);
+      ARM_SET_INTERWORK (symbolP, support_interwork);
+      break;
+      
+    case MAP_THUMB:
+      THUMB_SET_FUNC (symbolP, 1);
+      ARM_SET_THUMB (symbolP, 1);
+      ARM_SET_INTERWORK (symbolP, support_interwork);
+      break;
+      
+    case MAP_DATA:
+    default:
+      return;
+    }
+}
+
+/* When we change sections we need to issue a new mapping symbol.  */
+
+static void
+arm_elf_change_section (void)
+{
+  flagword flags;
+
+  if (!SEG_NORMAL (now_seg))
+    return;
+
+  flags = bfd_get_section_flags (stdoutput, now_seg);
+
+  /* We can ignore sections that only contain debug info.  */
+  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);    
+}
+#else
+#define mapping_state(a)
+#endif /* OBJ_ELF */
+\f
+
 static void
 s_req (a)
      int a ATTRIBUTE_UNUSED;
@@ -2732,6 +2904,7 @@ s_bss (ignore)
      marking in_bss, then looking at s_skip for clues.  */
   subseg_set (bss_section, 0);
   demand_empty_rest_of_line ();
+  mapping_state (MAP_DATA);
 }
 
 static void
@@ -2970,6 +3143,7 @@ opcode_select (width)
              coming from ARM mode, which is word-aligned.  */
          record_alignment (now_seg, 1);
        }
+      mapping_state (MAP_THUMB);
       break;
 
     case 32:
@@ -2985,6 +3159,7 @@ opcode_select (width)
 
          record_alignment (now_seg, 1);
        }
+      mapping_state (MAP_ARM);
       break;
 
     default:
@@ -11681,6 +11856,7 @@ md_assemble (str)
              return;
            }
 
+         mapping_state (MAP_THUMB);
          inst.instruction = opcode->value;
          inst.size = opcode->size;
          (*opcode->parms) (p);
@@ -11706,6 +11882,7 @@ md_assemble (str)
              return;
            }
 
+          mapping_state (MAP_ARM);
          inst.instruction = opcode->value;
          inst.size = INSN_SIZE;
          (*opcode->parms) (p);
@@ -12809,6 +12986,7 @@ s_arm_elf_cons (nbytes)
   md_cons_align (nbytes);
 #endif
 
+  mapping_state (MAP_DATA);
   do
     {
       bfd_reloc_code_real_type reloc;
index 3b98b334267063d6d07a7044725557041ec465fd..ee99236d3bcae930111b72ea93a1ef3bce05f155 100644 (file)
@@ -90,6 +90,9 @@ struct fix;
 #ifdef OBJ_ELF
 # 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
+  extern void arm_elf_change_section (void);
 #endif
 
 #define TC_FORCE_RELOCATION(FIX) arm_force_relocation (FIX)
index 1108014010a04c8e37bdfc627cc1f58fef42b323..dfb5f8653d73d1e31eafcea8057b7020c768a7cf 100644 (file)
@@ -22,6 +22,7 @@
 * ARM Floating Point::       Floating Point
 * ARM Directives::           ARM Machine Directives
 * ARM Opcodes::              Opcodes
+* ARM Mapping Symbols::      Mapping Symbols
 @end menu
 
 @node ARM Options
@@ -439,3 +440,32 @@ For information on the ARM or Thumb instruction sets, see @cite{ARM
 Software Development Toolkit Reference Manual}, Advanced RISC Machines
 Ltd.
 
+@node ARM Mapping Symbols
+@section Mapping Symbols
+
+The ARM ELF specification requires that special symbols be inserted
+into object files to mark certain features:
+
+@table @code
+
+@cindex @code{$a}
+@item $a
+At the start of a region of code containing ARM instructions.
+
+@cindex @code{$t}
+@item $t
+At the start of a region of code containing THUMB instructions.
+
+@cindex @code{$d}
+@item $d
+At the start of a region of data.
+
+@end table
+
+The assembler will automatically insert these symbols for you - there
+is no need to code them yourself.  Support for tagging symbols ($b,
+$f, $p and $m) which is also mentioned in the current ARM ELF
+specification is not implemented.  This is because they have been
+dropped from the new EABI and so tools cannot rely upon their
+presence.
+
index 10365585bb9c394464340951a3ea51edf9965758..c10a1434d30149f724ea94a61e73fb4d1aa38beb 100644 (file)
@@ -1,3 +1,10 @@
+2003-11-13  Nick Clifton  <nickc@redhat.com>
+
+       * gas/arm/mapping.s: New test: Source for ARM ELF mapping
+       symbols test.
+       * gas/arm/mapping.d: New file: Expected output.
+       * gas/arm/arm.exp: Run new test.
+
 2003-11-06  Nick Clifton  <nickc@redhat.com>
 
        * gas/arm/req.s: New test file.  Check .req and .unreq psuedo ops.
index 20e51783c76a439933b0e092ddfc2376db794848..3d9685db9bfce7d135365bc50ecce4530b2278ce 100644 (file)
@@ -68,6 +68,8 @@ if {[istarget *arm*-*-*] || [istarget "xscale-*-*"]} then {
     
     if {[istarget *-*-elf*] || [istarget *-*-linux*]} then {
        run_dump_test "pic"
+
+       run_dump_test "mapping"
     }
 
     gas_test "offset.s" "" $stdoptlist "OFFSET_IMM regression"
diff --git a/gas/testsuite/gas/arm/mapping.d b/gas/testsuite/gas/arm/mapping.d
new file mode 100644 (file)
index 0000000..8102209
--- /dev/null
@@ -0,0 +1,18 @@
+#objdump: --syms
+#name: ARM Mapping Symbols
+
+# Test the generation of ARM ELF Mapping Symbols
+
+.*: +file format.*arm.*
+
+SYMBOL TABLE:
+0+00 l    d  .text     0+0 
+0+00 l    d  .data     0+0 
+0+00 l    d  .bss      0+0 
+0+00 l     F .text     0+0 \$a
+0+08 l       .text     0+0 \$t
+0+00 l     O .data     0+0 \$d
+0+00 l    d  foo       0+0 
+0+00 l       foo       0+0 \$t
+0+00 g       .text     0+0 mapping
+0+08 g       .text     0+0 thumb_mapping
diff --git a/gas/testsuite/gas/arm/mapping.s b/gas/testsuite/gas/arm/mapping.s
new file mode 100644 (file)
index 0000000..c9cee8d
--- /dev/null
@@ -0,0 +1,19 @@
+       .text
+       .arm
+       .global mapping
+mapping:
+       nop
+       bl mapping
+
+       .global thumb_mapping
+       .thumb_func
+thumb_mapping:
+       .thumb
+       nop
+       bl thumb_mapping
+       
+       .data
+       .word 0x123456
+
+       .section foo,"ax"
+       nop