* dw2gencfi.c (DWARF2_FDE_RELOC_SIZE): New.
authorRichard Henderson <rth@redhat.com>
Thu, 21 Aug 2008 19:49:22 +0000 (19:49 +0000)
committerRichard Henderson <rth@redhat.com>
Thu, 21 Aug 2008 19:49:22 +0000 (19:49 +0000)
        (output_cie, output_fde): Use it.
        (DWARF2_EH_FRAME_READ_ONLY): New.
        (cfi_finish): Use it.

        * config/tc-hppa.h (DWARF2_FDE_RELOC_SIZE): Set to 8 for 64-bit.
        (DWARF2_CIE_DATA_ALIGNMENT): Change sign.
        (DWARF2_EH_FRAME_READ_ONLY): New.
        * config/tc-hppa.c (tc_gen_reloc): Generate pc-relative relocations
        from the results of DIFF_EXPR_OK manipulation.

gas/ChangeLog
gas/config/tc-hppa.c
gas/config/tc-hppa.h
gas/dw2gencfi.c

index 1815d7b7042e6bbb5452b192b2f4fc3fd7ed1093..91ff6db134067d88d5d48c908483855cc24b786b 100644 (file)
@@ -1,3 +1,16 @@
+2008-08-21  Richard Henderson  <rth@redhat.com>
+
+       * dw2gencfi.c (DWARF2_FDE_RELOC_SIZE): New.
+       (output_cie, output_fde): Use it.
+       (DWARF2_EH_FRAME_READ_ONLY): New.
+       (cfi_finish): Use it.
+
+       * config/tc-hppa.h (DWARF2_FDE_RELOC_SIZE): Set to 8 for 64-bit.
+       (DWARF2_CIE_DATA_ALIGNMENT): Change sign.
+       (DWARF2_EH_FRAME_READ_ONLY): New.
+       * config/tc-hppa.c (tc_gen_reloc): Generate pc-relative relocations
+       from the results of DIFF_EXPR_OK manipulation.
+
 2008-08-21  Sterling Augustine  <sterling@tensilica.com>
 
        * config/xtensa-istack.h (MAX_INSN_ARGS): Increase to 64.
index d31d527a68c59eaf75b562d4f98ce9e7c7f2aafd..f36ac2b72dd8d94ef0e368f137a04c6505528680 100644 (file)
@@ -1375,6 +1375,18 @@ tc_gen_reloc (asection *section, fixS *fixp)
 
   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+
+  /* Allow fixup_segment to recognize hand-written pc-relative relocations.
+     When we went through cons_fix_new_hppa, we classified them as complex.  */
+  /* ??? It might be better to hide this +8 stuff in tc_cfi_emit_pcrel_expr,
+     undefine DIFF_EXPR_OK, and let these sorts of complex expressions fail
+     when R_HPPA_COMPLEX == R_PARISC_UNIMPLEMENTED.  */
+  if (fixp->fx_r_type == R_HPPA_COMPLEX && fixp->fx_pcrel)
+    {
+      fixp->fx_r_type = R_HPPA_PCREL_CALL;
+      fixp->fx_offset += 8;
+    }
+
   codes = hppa_gen_reloc_type (stdoutput,
                               fixp->fx_r_type,
                               hppa_fixp->fx_r_format,
index bf5b27f4eaecd720d42cce19503f7d239ea7fb06..b53527b0c7bbf99eec28d1dc2bd28e0c9ffc89d4 100644 (file)
@@ -186,8 +186,6 @@ int hppa_fix_adjustable (struct fix *);
 
 #define elf_tc_final_processing        elf_hppa_final_processing
 void elf_hppa_final_processing (void);
-
-#define DWARF2_LINE_MIN_INSN_LENGTH 4
 #endif /* OBJ_ELF */
 
 #define md_operand(x)
@@ -213,10 +211,16 @@ extern int hppa_regname_to_dw2regnum (char *regname);
 #define DWARF2_LINE_MIN_INSN_LENGTH 4
 #define DWARF2_DEFAULT_RETURN_COLUMN 2
 #if TARGET_ARCH_SIZE == 64
-#define DWARF2_CIE_DATA_ALIGNMENT (-8)
+#define DWARF2_CIE_DATA_ALIGNMENT 8
+#define DWARF2_FDE_RELOC_SIZE 8
 #else
-#define DWARF2_CIE_DATA_ALIGNMENT (-4)
+#define DWARF2_CIE_DATA_ALIGNMENT 4
 #endif
+
+/* Due to the way dynamic linking to personality functions is handled,
+   we need to have a read-write .eh_frame section.  */
+#define DWARF2_EH_FRAME_READ_ONLY 0
+
 #endif
 
 #endif /* _TC_HPPA_H */
index d7ebf8c0ae89cc96de09f48f627a27d4a6b0b82a..520d1e1734ada55eff695af6485c4e782828bc7e 100644 (file)
 # define DWARF2_LINE_MIN_INSN_LENGTH 1
 #endif
 
+/* By default, use 32-bit relocations from .eh_frame into .text.  */
+#ifndef DWARF2_FDE_RELOC_SIZE
+# define DWARF2_FDE_RELOC_SIZE 4
+#endif
+
+/* By default, use a read-only .eh_frame section.  */
+#ifndef DWARF2_EH_FRAME_READ_ONLY
+# define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
+#endif
+
 #ifndef EH_FRAME_ALIGNMENT
 # define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
 #endif
@@ -1041,6 +1051,7 @@ output_cie (struct cie_entry *cie)
   expressionS exp;
   struct cfi_insn_data *i;
   offsetT augmentation_size;
+  int enc;
 
   cie->start_address = symbol_temp_new_now ();
   after_size_address = symbol_temp_make ();
@@ -1096,11 +1107,25 @@ output_cie (struct cie_entry *cie)
     }
   if (cie->lsda_encoding != DW_EH_PE_omit)
     out_one (cie->lsda_encoding);
+
+  switch (DWARF2_FDE_RELOC_SIZE)
+    {
+    case 2:
+      enc = DW_EH_PE_sdata2;
+      break;
+    case 4:
+      enc = DW_EH_PE_sdata4;
+      break;
+    case 8:
+      enc = DW_EH_PE_sdata8;
+      break;
+    default:
+      abort ();
+    }
 #if defined DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
-  out_one (DW_EH_PE_pcrel | DW_EH_PE_sdata4);
-#else
-  out_one (DW_EH_PE_sdata4);
+  enc |= DW_EH_PE_pcrel;
 #endif
+  out_one (enc);
 
   if (cie->first)
     for (i = cie->first; i != cie->last; i = i->next)
@@ -1135,22 +1160,22 @@ output_fde (struct fde_entry *fde, struct cie_entry *cie,
 #ifdef DIFF_EXPR_OK
   exp.X_add_symbol = fde->start_address;
   exp.X_op_symbol = symbol_temp_new_now ();
-  emit_expr (&exp, 4);                         /* Code offset.  */
+  emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);     /* Code offset.  */
 #else
   exp.X_op = O_symbol;
   exp.X_add_symbol = fde->start_address;
   exp.X_op_symbol = NULL;
 #ifdef tc_cfi_emit_pcrel_expr
-  tc_cfi_emit_pcrel_expr (&exp, 4);            /* Code offset.  */
+  tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE);         /* Code offset.  */
 #else
-  emit_expr (&exp, 4);                         /* Code offset.  */
+  emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);     /* Code offset.  */
 #endif
   exp.X_op = O_subtract;
 #endif
 
   exp.X_add_symbol = fde->end_address;
   exp.X_op_symbol = fde->start_address;                /* Code length.  */
-  emit_expr (&exp, 4);
+  emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);
 
   augmentation_size = encoding_size (fde->lsda_encoding);
   out_uleb128 (augmentation_size);             /* Augmentation size.  */
@@ -1319,7 +1344,8 @@ cfi_finish (void)
   /* Open .eh_frame section.  */
   cfi_seg = subseg_new (".eh_frame", 0);
   bfd_set_section_flags (stdoutput, cfi_seg,
-                        SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY);
+                        SEC_ALLOC | SEC_LOAD | SEC_DATA
+                        | DWARF2_EH_FRAME_READ_ONLY);
   subseg_set (cfi_seg, 0);
   record_alignment (cfi_seg, EH_FRAME_ALIGNMENT);