* gas/config/tc-arm.c (marked_pr_dependency): New bitmap, bit N
authorJulian Brown <julian@codesourcery.com>
Tue, 29 Mar 2005 16:29:09 +0000 (16:29 +0000)
committerJulian Brown <julian@codesourcery.com>
Tue, 29 Mar 2005 16:29:09 +0000 (16:29 +0000)
indicates whether personality routine index N has been output for this
section.
(mapping_state): tc_segment_info_data now struct not enum.
(arm_elf_change_section): Likewise, and marked_pr_dependency is now
handled on section change.
(create_unwind_entry): Previous code to output dependency removed.
(s_arm_unwind_fnend): Output dependency if it hasn't been done already
for this section.
* gas/config/tc-arm.h (TC_SEGMENT_INFO_TYPE): Redefined as struct
arm_segment_info_type.
(arm_segment_info_type): New struct.
* gas/testsuite/gas/arm/unwind.d: Update expected output.

gas/ChangeLog
gas/config/tc-arm.c
gas/config/tc-arm.h
gas/testsuite/gas/arm/unwind.d

index f45d925..2cc9445 100644 (file)
@@ -1,3 +1,18 @@
+2005-03-29  Julian Brown  <julian@codesourcery.com>
+
+       * config/tc-arm.c (marked_pr_dependency): New bitmap, bit N indicates
+       whether personality routine index N has been output for this section.
+       (mapping_state): tc_segment_info_data now struct not enum.
+       (arm_elf_change_section): Likewise, and marked_pr_dependency is now
+       handled on section change.
+       (create_unwind_entry): Previous code to output dependency removed.
+       (s_arm_unwind_fnend): Output dependency if it hasn't been done already
+       for this section.
+       * config/tc-arm.h (TC_SEGMENT_INFO_TYPE): Redefined as struct
+       arm_segment_info_type.
+       (arm_segment_info_type): New struct.
+       * testsuite/gas/arm/unwind.d: Update expected output.
+
 2005-03-28  Sterling Augustine  <sterling@tensilica.com>
            Bob Wilson  <bob.wilson@acm.org>
 
index 19faa62..9baf888 100644 (file)
@@ -83,6 +83,11 @@ static struct
   unsigned        sp_restored:1;
 } unwind;
 
+/* Bit N indicates that an R_ARM_NONE relocation has been output for
+   __aeabi_unwind_cpp_prN already if set. This enables dependencies to be
+   emitted only once per section, to save unnecessary bloat.  */
+static unsigned int marked_pr_dependency = 0;
+
 #endif /* OBJ_ELF */
 
 enum arm_float_abi
@@ -1347,7 +1352,7 @@ mapping_state (enum mstate state)
       abort ();
     }
 
-  seg_info (now_seg)->tc_segment_info_data = state;
+  seg_info (now_seg)->tc_segment_info_data.mapstate = state;
 
   symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
   symbol_table_insert (symbolP);
@@ -1379,6 +1384,7 @@ void
 arm_elf_change_section (void)
 {
   flagword flags;
+  segment_info_type *seginfo;
 
   /* Link an unlinked unwind index table section to the .text section.  */
   if (elf_section_type (now_seg) == SHT_ARM_EXIDX
@@ -1394,7 +1400,9 @@ arm_elf_change_section (void)
   if ((flags & SEC_ALLOC) == 0)
     return;
 
-  mapstate = seg_info (now_seg)->tc_segment_info_data;
+  seginfo = seg_info (now_seg);
+  mapstate = seginfo->tc_segment_info_data.mapstate;
+  marked_pr_dependency = seginfo->tc_segment_info_data.marked_pr_dependency;
 }
 
 int
@@ -14303,13 +14311,6 @@ create_unwind_entry (int have_data)
       fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
               BFD_RELOC_ARM_PREL31);
 
-      /* Indicate dependency to linker.  */
-        {
-          char *name = "__aeabi_unwind_cpp_pr0";
-         symbolS *pr = symbol_find_or_make (name);
-         fix_new (frag_now, where, 4, pr, 0, 1, BFD_RELOC_NONE);
-       }
-
       where += 4;
       ptr += 4;
 
@@ -14323,24 +14324,13 @@ create_unwind_entry (int have_data)
       /* Three opcodes bytes are packed into the first word.  */
       data = 0x80;
       n = 3;
-      goto emit_reloc;
+      break;
 
     case 1:
     case 2:
       /* The size and first two opcode bytes go in the first word.  */
       data = ((0x80 + unwind.personality_index) << 8) | size;
       n = 2;
-      goto emit_reloc;
-
-    emit_reloc:
-      {
-       /* Indicate dependency to linker.  */
-       char *name[] = { "__aeabi_unwind_cpp_pr0",
-                        "__aeabi_unwind_cpp_pr1",
-                        "__aeabi_unwind_cpp_pr2" };
-       symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
-       fix_new (frag_now, where, 4, pr, 0, 1, BFD_RELOC_NONE);
-      }
       break;
 
     default:
@@ -14449,6 +14439,23 @@ s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
   fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
           BFD_RELOC_ARM_PREL31);
 
+  /* Indicate dependency on EHABI-defined personality routines to the
+     linker, if it hasn't been done already.  */
+  if (unwind.personality_index >= 0 && unwind.personality_index < 3)
+    {
+      char *name[] = { "__aeabi_unwind_cpp_pr0",
+                      "__aeabi_unwind_cpp_pr1",
+                      "__aeabi_unwind_cpp_pr2" };
+      if (!(marked_pr_dependency & (1 << unwind.personality_index)))
+       {
+         symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
+         fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
+         marked_pr_dependency |= 1 << unwind.personality_index;
+         seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
+           = marked_pr_dependency;
+        }
+    }
+
   if (val)
     /* Inline exception table entry.  */
     md_number_to_chars (ptr + 4, val, 4);
index f205dff..e3c05b3 100644 (file)
@@ -170,7 +170,7 @@ struct fix;
 # define md_elf_section_type(str, len) arm_elf_section_type (str, len)
 # define GLOBAL_OFFSET_TABLE_NAME      "_GLOBAL_OFFSET_TABLE_"
 # define LOCAL_LABEL_PREFIX            '.'
-# define TC_SEGMENT_INFO_TYPE          enum mstate
+# define TC_SEGMENT_INFO_TYPE          struct arm_segment_info_type
 
 enum mstate
 {
@@ -180,6 +180,12 @@ enum mstate
   MAP_THUMB
 };
 
+struct arm_segment_info_type
+{
+  enum mstate mapstate;
+  unsigned int marked_pr_dependency;
+};
+
 /* We want .cfi_* pseudo-ops for generating unwind info.  */
 #define TARGET_USE_CFIPOP              1
 
index 3ca1626..982040b 100644 (file)
@@ -5,16 +5,15 @@
 
 RELOCATION RECORDS FOR \[.ARM.extab\]:
 OFFSET   TYPE              VALUE 
-00000000 R_ARM_NONE        __aeabi_unwind_cpp_pr1
 0000000c R_ARM_PREL31      .text
-0000000c R_ARM_NONE        __aeabi_unwind_cpp_pr0
-0000001c R_ARM_NONE        __aeabi_unwind_cpp_pr1
 
 
 RELOCATION RECORDS FOR \[.ARM.exidx\]:
 OFFSET   TYPE              VALUE 
 00000000 R_ARM_PREL31      .text
+00000000 R_ARM_NONE        __aeabi_unwind_cpp_pr0
 00000008 R_ARM_PREL31      .text.*
+00000008 R_ARM_NONE        __aeabi_unwind_cpp_pr1
 0000000c R_ARM_PREL31      .ARM.extab
 00000010 R_ARM_PREL31      .text.*
 00000014 R_ARM_PREL31      .ARM.extab.*