|
|
7be9059 |
2009-10-02 Jakub Jelinek <jakub@redhat.com>
|
|
|
7be9059 |
|
|
|
7be9059 |
* dw2gencfi.c: Include dwarf2dbg.h.
|
|
|
7be9059 |
(DWARF2_FORMAT): Define if not defined.
|
|
|
7be9059 |
(dot_cfi_sections): New function.
|
|
|
7be9059 |
(cfi_pseudo_table): Handle .cfi_sections.
|
|
|
7be9059 |
(CFI_EMIT_eh_frame, CFI_EMIT_debug_frame): Define.
|
|
|
7be9059 |
(cfi_sections): New variable.
|
|
|
7be9059 |
(output_cie, output_fde, select_cie_for_fde): Add eh_frame
|
|
|
7be9059 |
argument, add supporting for outputting .debug_frame
|
|
|
7be9059 |
section.
|
|
|
7be9059 |
(cfi_change_reg_numbers): New function or macro.
|
|
|
7be9059 |
(cfi_finish): Only emit .eh_frame if
|
|
|
7be9059 |
cfi_sections & CFI_EMIT_eh_frame. Emit .debug_frame if
|
|
|
7be9059 |
cfi_sections & CFI_EMIT_debug_frame.
|
|
|
7be9059 |
* config/tc-ppc.h (md_reg_eh_frame_to_debug_frame): Define.
|
|
|
7be9059 |
* doc/as.texinfo (CFI directives): Document .cfi_sections.
|
|
|
7be9059 |
|
|
|
7be9059 |
--- gas/dw2gencfi.c 11 Sep 2009 15:27:33 -0000 1.43
|
|
|
7be9059 |
+++ gas/dw2gencfi.c 2 Oct 2009 11:33:49 -0000 1.44
|
|
|
7be9059 |
@@ -23,6 +23,7 @@
|
|
|
7be9059 |
#include "as.h"
|
|
|
7be9059 |
#include "dw2gencfi.h"
|
|
|
7be9059 |
#include "subsegs.h"
|
|
|
7be9059 |
+#include "dwarf2dbg.h"
|
|
|
7be9059 |
|
|
|
7be9059 |
#ifdef TARGET_USE_CFIPOP
|
|
|
7be9059 |
|
|
|
7be9059 |
@@ -59,6 +60,10 @@
|
|
|
7be9059 |
# define tc_cfi_frame_initial_instructions() ((void)0)
|
|
|
7be9059 |
#endif
|
|
|
7be9059 |
|
|
|
7be9059 |
+#ifndef DWARF2_FORMAT
|
|
|
7be9059 |
+# define DWARF2_FORMAT(SEC) dwarf2_format_32bit
|
|
|
7be9059 |
+#endif
|
|
|
7be9059 |
+
|
|
|
7be9059 |
#ifndef DWARF2_ADDR_SIZE
|
|
|
7be9059 |
# define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
|
|
|
7be9059 |
#endif
|
|
|
7be9059 |
@@ -386,6 +391,7 @@ cfi_add_CFA_restore_state (void)
|
|
|
7be9059 |
|
|
|
7be9059 |
static void dot_cfi (int);
|
|
|
7be9059 |
static void dot_cfi_escape (int);
|
|
|
7be9059 |
+static void dot_cfi_sections (int);
|
|
|
7be9059 |
static void dot_cfi_startproc (int);
|
|
|
7be9059 |
static void dot_cfi_endproc (int);
|
|
|
7be9059 |
static void dot_cfi_personality (int);
|
|
|
7be9059 |
@@ -402,6 +408,7 @@ static void dot_cfi_val_encoded_addr (in
|
|
|
7be9059 |
|
|
|
7be9059 |
const pseudo_typeS cfi_pseudo_table[] =
|
|
|
7be9059 |
{
|
|
|
7be9059 |
+ { "cfi_sections", dot_cfi_sections, 0 },
|
|
|
7be9059 |
{ "cfi_startproc", dot_cfi_startproc, 0 },
|
|
|
7be9059 |
{ "cfi_endproc", dot_cfi_endproc, 0 },
|
|
|
7be9059 |
{ "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa },
|
|
|
7be9059 |
@@ -864,6 +871,56 @@ dot_cfi_val_encoded_addr (int ignored AT
|
|
|
7be9059 |
demand_empty_rest_of_line ();
|
|
|
7be9059 |
}
|
|
|
7be9059 |
|
|
|
7be9059 |
+/* By default emit .eh_frame only, not .debug_frame. */
|
|
|
7be9059 |
+#define CFI_EMIT_eh_frame (1 << 0)
|
|
|
7be9059 |
+#define CFI_EMIT_debug_frame (1 << 1)
|
|
|
7be9059 |
+static int cfi_sections = CFI_EMIT_eh_frame;
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+static void
|
|
|
7be9059 |
+dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
|
|
|
7be9059 |
+{
|
|
|
7be9059 |
+ int sections = 0;
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ SKIP_WHITESPACE ();
|
|
|
7be9059 |
+ if (is_name_beginner (*input_line_pointer))
|
|
|
7be9059 |
+ while (1)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ char *name, c;
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ name = input_line_pointer;
|
|
|
7be9059 |
+ c = get_symbol_end ();
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ if (strcmp (name, ".eh_frame") == 0)
|
|
|
7be9059 |
+ sections |= CFI_EMIT_eh_frame;
|
|
|
7be9059 |
+ else if (strcmp (name, ".debug_frame") == 0)
|
|
|
7be9059 |
+ sections |= CFI_EMIT_debug_frame;
|
|
|
7be9059 |
+ else
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ *input_line_pointer = c;
|
|
|
7be9059 |
+ input_line_pointer = name;
|
|
|
7be9059 |
+ break;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ *input_line_pointer = c;
|
|
|
7be9059 |
+ SKIP_WHITESPACE ();
|
|
|
7be9059 |
+ if (*input_line_pointer == ',')
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ name = input_line_pointer++;
|
|
|
7be9059 |
+ SKIP_WHITESPACE ();
|
|
|
7be9059 |
+ if (!is_name_beginner (*input_line_pointer))
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ input_line_pointer = name;
|
|
|
7be9059 |
+ break;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+ else if (is_name_beginner (*input_line_pointer))
|
|
|
7be9059 |
+ break;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ demand_empty_rest_of_line ();
|
|
|
7be9059 |
+ cfi_sections = sections;
|
|
|
7be9059 |
+}
|
|
|
7be9059 |
+
|
|
|
7be9059 |
static void
|
|
|
7be9059 |
dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
|
|
|
7be9059 |
{
|
|
|
7be9059 |
@@ -1194,13 +1251,14 @@ encoding_size (unsigned char encoding)
|
|
|
7be9059 |
}
|
|
|
7be9059 |
|
|
|
7be9059 |
static void
|
|
|
7be9059 |
-output_cie (struct cie_entry *cie)
|
|
|
7be9059 |
+output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
|
|
|
7be9059 |
{
|
|
|
7be9059 |
symbolS *after_size_address, *end_address;
|
|
|
7be9059 |
expressionS exp;
|
|
|
7be9059 |
struct cfi_insn_data *i;
|
|
|
7be9059 |
offsetT augmentation_size;
|
|
|
7be9059 |
int enc;
|
|
|
7be9059 |
+ enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
|
|
|
7be9059 |
|
|
|
7be9059 |
cie->start_address = symbol_temp_new_now ();
|
|
|
7be9059 |
after_size_address = symbol_temp_make ();
|
|
|
7be9059 |
@@ -1211,18 +1269,35 @@ output_cie (struct cie_entry *cie)
|
|
|
7be9059 |
exp.X_op_symbol = after_size_address;
|
|
|
7be9059 |
exp.X_add_number = 0;
|
|
|
7be9059 |
|
|
|
7be9059 |
- emit_expr (&exp, 4); /* Length. */
|
|
|
7be9059 |
+ if (eh_frame || fmt == dwarf2_format_32bit)
|
|
|
7be9059 |
+ emit_expr (&exp, 4); /* Length. */
|
|
|
7be9059 |
+ else
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ if (fmt == dwarf2_format_64bit)
|
|
|
7be9059 |
+ out_four (-1);
|
|
|
7be9059 |
+ emit_expr (&exp, 8); /* Length. */
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
symbol_set_value_now (after_size_address);
|
|
|
7be9059 |
- out_four (0); /* CIE id. */
|
|
|
7be9059 |
+ if (eh_frame)
|
|
|
7be9059 |
+ out_four (0); /* CIE id. */
|
|
|
7be9059 |
+ else
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ out_four (-1); /* CIE id. */
|
|
|
7be9059 |
+ if (fmt != dwarf2_format_32bit)
|
|
|
7be9059 |
+ out_four (-1);
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
out_one (DW_CIE_VERSION); /* Version. */
|
|
|
7be9059 |
- out_one ('z'); /* Augmentation. */
|
|
|
7be9059 |
- if (cie->per_encoding != DW_EH_PE_omit)
|
|
|
7be9059 |
- out_one ('P');
|
|
|
7be9059 |
- if (cie->lsda_encoding != DW_EH_PE_omit)
|
|
|
7be9059 |
- out_one ('L');
|
|
|
7be9059 |
- out_one ('R');
|
|
|
7be9059 |
- if (cie->signal_frame)
|
|
|
7be9059 |
- out_one ('S');
|
|
|
7be9059 |
+ if (eh_frame)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ out_one ('z'); /* Augmentation. */
|
|
|
7be9059 |
+ if (cie->per_encoding != DW_EH_PE_omit)
|
|
|
7be9059 |
+ out_one ('P');
|
|
|
7be9059 |
+ if (cie->lsda_encoding != DW_EH_PE_omit)
|
|
|
7be9059 |
+ out_one ('L');
|
|
|
7be9059 |
+ out_one ('R');
|
|
|
7be9059 |
+ if (cie->signal_frame)
|
|
|
7be9059 |
+ out_one ('S');
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
out_one (0);
|
|
|
7be9059 |
out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */
|
|
|
7be9059 |
out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */
|
|
|
7be9059 |
@@ -1230,10 +1305,13 @@ output_cie (struct cie_entry *cie)
|
|
|
7be9059 |
out_one (cie->return_column);
|
|
|
7be9059 |
else
|
|
|
7be9059 |
out_uleb128 (cie->return_column);
|
|
|
7be9059 |
- augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
|
|
|
7be9059 |
- if (cie->per_encoding != DW_EH_PE_omit)
|
|
|
7be9059 |
- augmentation_size += 1 + encoding_size (cie->per_encoding);
|
|
|
7be9059 |
- out_uleb128 (augmentation_size); /* Augmentation size. */
|
|
|
7be9059 |
+ if (eh_frame)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
|
|
|
7be9059 |
+ if (cie->per_encoding != DW_EH_PE_omit)
|
|
|
7be9059 |
+ augmentation_size += 1 + encoding_size (cie->per_encoding);
|
|
|
7be9059 |
+ out_uleb128 (augmentation_size); /* Augmentation size. */
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
if (cie->per_encoding != DW_EH_PE_omit)
|
|
|
7be9059 |
{
|
|
|
7be9059 |
offsetT size = encoding_size (cie->per_encoding);
|
|
|
7be9059 |
@@ -1274,23 +1352,28 @@ output_cie (struct cie_entry *cie)
|
|
|
7be9059 |
#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
|
|
|
7be9059 |
enc |= DW_EH_PE_pcrel;
|
|
|
7be9059 |
#endif
|
|
|
7be9059 |
- out_one (enc);
|
|
|
7be9059 |
+ if (eh_frame)
|
|
|
7be9059 |
+ out_one (enc);
|
|
|
7be9059 |
|
|
|
7be9059 |
if (cie->first)
|
|
|
7be9059 |
for (i = cie->first; i != cie->last; i = i->next)
|
|
|
7be9059 |
output_cfi_insn (i);
|
|
|
7be9059 |
|
|
|
7be9059 |
- frag_align (2, DW_CFA_nop, 0);
|
|
|
7be9059 |
+ frag_align (align, DW_CFA_nop, 0);
|
|
|
7be9059 |
symbol_set_value_now (end_address);
|
|
|
7be9059 |
}
|
|
|
7be9059 |
|
|
|
7be9059 |
static void
|
|
|
7be9059 |
output_fde (struct fde_entry *fde, struct cie_entry *cie,
|
|
|
7be9059 |
- struct cfi_insn_data *first, int align)
|
|
|
7be9059 |
+ bfd_boolean eh_frame, struct cfi_insn_data *first,
|
|
|
7be9059 |
+ int align)
|
|
|
7be9059 |
{
|
|
|
7be9059 |
symbolS *after_size_address, *end_address;
|
|
|
7be9059 |
expressionS exp;
|
|
|
7be9059 |
offsetT augmentation_size;
|
|
|
7be9059 |
+ enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
|
|
|
7be9059 |
+ int offset_size;
|
|
|
7be9059 |
+ int addr_size;
|
|
|
7be9059 |
|
|
|
7be9059 |
after_size_address = symbol_temp_make ();
|
|
|
7be9059 |
end_address = symbol_temp_make ();
|
|
|
7be9059 |
@@ -1299,35 +1382,63 @@ output_fde (struct fde_entry *fde, struc
|
|
|
7be9059 |
exp.X_add_symbol = end_address;
|
|
|
7be9059 |
exp.X_op_symbol = after_size_address;
|
|
|
7be9059 |
exp.X_add_number = 0;
|
|
|
7be9059 |
- emit_expr (&exp, 4); /* Length. */
|
|
|
7be9059 |
+ if (eh_frame || fmt == dwarf2_format_32bit)
|
|
|
7be9059 |
+ offset_size = 4;
|
|
|
7be9059 |
+ else
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ if (fmt == dwarf2_format_64bit)
|
|
|
7be9059 |
+ out_four (-1);
|
|
|
7be9059 |
+ offset_size = 8;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+ emit_expr (&exp, offset_size); /* Length. */
|
|
|
7be9059 |
symbol_set_value_now (after_size_address);
|
|
|
7be9059 |
|
|
|
7be9059 |
- exp.X_add_symbol = after_size_address;
|
|
|
7be9059 |
- exp.X_op_symbol = cie->start_address;
|
|
|
7be9059 |
- emit_expr (&exp, 4); /* CIE offset. */
|
|
|
7be9059 |
+ if (eh_frame)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ exp.X_add_symbol = after_size_address;
|
|
|
7be9059 |
+ exp.X_op_symbol = cie->start_address;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+ else
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ exp.X_op = O_symbol;
|
|
|
7be9059 |
+ exp.X_add_symbol = cie->start_address;
|
|
|
7be9059 |
+ exp.X_op_symbol = NULL;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+ emit_expr (&exp, offset_size); /* CIE offset. */
|
|
|
7be9059 |
|
|
|
7be9059 |
+ if (eh_frame)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
#if CFI_DIFF_EXPR_OK
|
|
|
7be9059 |
- exp.X_add_symbol = fde->start_address;
|
|
|
7be9059 |
- exp.X_op_symbol = symbol_temp_new_now ();
|
|
|
7be9059 |
- emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
|
|
|
7be9059 |
+ exp.X_add_symbol = fde->start_address;
|
|
|
7be9059 |
+ exp.X_op_symbol = symbol_temp_new_now ();
|
|
|
7be9059 |
+ emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
|
|
|
7be9059 |
#else
|
|
|
7be9059 |
- exp.X_op = O_symbol;
|
|
|
7be9059 |
- exp.X_add_symbol = fde->start_address;
|
|
|
7be9059 |
- exp.X_op_symbol = NULL;
|
|
|
7be9059 |
+ exp.X_op = O_symbol;
|
|
|
7be9059 |
+ exp.X_add_symbol = fde->start_address;
|
|
|
7be9059 |
+ exp.X_op_symbol = NULL;
|
|
|
7be9059 |
#ifdef tc_cfi_emit_pcrel_expr
|
|
|
7be9059 |
- tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
|
|
|
7be9059 |
+ tc_cfi_emit_pcrel_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
|
|
|
7be9059 |
#else
|
|
|
7be9059 |
- emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
|
|
|
7be9059 |
+ emit_expr (&exp, DWARF2_FDE_RELOC_SIZE); /* Code offset. */
|
|
|
7be9059 |
#endif
|
|
|
7be9059 |
- exp.X_op = O_subtract;
|
|
|
7be9059 |
#endif
|
|
|
7be9059 |
+ addr_size = DWARF2_FDE_RELOC_SIZE;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+ else
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ exp.X_add_symbol = fde->start_address;
|
|
|
7be9059 |
+ addr_size = DWARF2_ADDR_SIZE (stdoutput);
|
|
|
7be9059 |
+ emit_expr (&exp, addr_size);
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
|
|
|
7be9059 |
+ exp.X_op = O_subtract;
|
|
|
7be9059 |
exp.X_add_symbol = fde->end_address;
|
|
|
7be9059 |
exp.X_op_symbol = fde->start_address; /* Code length. */
|
|
|
7be9059 |
- emit_expr (&exp, DWARF2_FDE_RELOC_SIZE);
|
|
|
7be9059 |
+ emit_expr (&exp, addr_size);
|
|
|
7be9059 |
|
|
|
7be9059 |
augmentation_size = encoding_size (fde->lsda_encoding);
|
|
|
7be9059 |
- out_uleb128 (augmentation_size); /* Augmentation size. */
|
|
|
7be9059 |
+ if (eh_frame)
|
|
|
7be9059 |
+ out_uleb128 (augmentation_size); /* Augmentation size. */
|
|
|
7be9059 |
|
|
|
7be9059 |
if (fde->lsda_encoding != DW_EH_PE_omit)
|
|
|
7be9059 |
{
|
|
|
7be9059 |
@@ -1356,7 +1467,8 @@ output_fde (struct fde_entry *fde, struc
|
|
|
7be9059 |
}
|
|
|
7be9059 |
|
|
|
7be9059 |
static struct cie_entry *
|
|
|
7be9059 |
-select_cie_for_fde (struct fde_entry *fde, struct cfi_insn_data **pfirst)
|
|
|
7be9059 |
+select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
|
|
|
7be9059 |
+ struct cfi_insn_data **pfirst, int align)
|
|
|
7be9059 |
{
|
|
|
7be9059 |
struct cfi_insn_data *i, *j;
|
|
|
7be9059 |
struct cie_entry *cie;
|
|
|
7be9059 |
@@ -1477,12 +1589,56 @@ select_cie_for_fde (struct fde_entry *fd
|
|
|
7be9059 |
|
|
|
7be9059 |
cie->last = i;
|
|
|
7be9059 |
*pfirst = i;
|
|
|
7be9059 |
-
|
|
|
7be9059 |
- output_cie (cie);
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ output_cie (cie, eh_frame, align);
|
|
|
7be9059 |
|
|
|
7be9059 |
return cie;
|
|
|
7be9059 |
}
|
|
|
7be9059 |
|
|
|
7be9059 |
+#ifdef md_reg_eh_frame_to_debug_frame
|
|
|
7be9059 |
+static void
|
|
|
7be9059 |
+cfi_change_reg_numbers (struct cfi_insn_data *insn)
|
|
|
7be9059 |
+{
|
|
|
7be9059 |
+ for (; insn; insn = insn->next)
|
|
|
7be9059 |
+ switch (insn->insn)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ case DW_CFA_advance_loc:
|
|
|
7be9059 |
+ case DW_CFA_def_cfa_offset:
|
|
|
7be9059 |
+ case DW_CFA_remember_state:
|
|
|
7be9059 |
+ case DW_CFA_restore_state:
|
|
|
7be9059 |
+ case DW_CFA_GNU_window_save:
|
|
|
7be9059 |
+ case CFI_escape:
|
|
|
7be9059 |
+ break;
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ case DW_CFA_def_cfa:
|
|
|
7be9059 |
+ case DW_CFA_offset:
|
|
|
7be9059 |
+ insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
|
|
|
7be9059 |
+ break;
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ case DW_CFA_def_cfa_register:
|
|
|
7be9059 |
+ case DW_CFA_undefined:
|
|
|
7be9059 |
+ case DW_CFA_same_value:
|
|
|
7be9059 |
+ case DW_CFA_restore:
|
|
|
7be9059 |
+ insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
|
|
|
7be9059 |
+ break;
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ case DW_CFA_register:
|
|
|
7be9059 |
+ insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
|
|
|
7be9059 |
+ insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
|
|
|
7be9059 |
+ break;
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ case CFI_val_encoded_addr:
|
|
|
7be9059 |
+ insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
|
|
|
7be9059 |
+ break;
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ default:
|
|
|
7be9059 |
+ abort ();
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+}
|
|
|
7be9059 |
+#else
|
|
|
7be9059 |
+#define cfi_change_reg_numbers(insn) do { } while (0)
|
|
|
7be9059 |
+#endif
|
|
|
7be9059 |
+
|
|
|
7be9059 |
void
|
|
|
7be9059 |
cfi_finish (void)
|
|
|
7be9059 |
{
|
|
|
7be9059 |
@@ -1493,38 +1649,80 @@ cfi_finish (void)
|
|
|
7be9059 |
if (all_fde_data == 0)
|
|
|
7be9059 |
return;
|
|
|
7be9059 |
|
|
|
7be9059 |
- /* Open .eh_frame section. */
|
|
|
7be9059 |
- cfi_seg = subseg_new (".eh_frame", 0);
|
|
|
7be9059 |
- bfd_set_section_flags (stdoutput, cfi_seg,
|
|
|
7be9059 |
- SEC_ALLOC | SEC_LOAD | SEC_DATA
|
|
|
7be9059 |
- | DWARF2_EH_FRAME_READ_ONLY);
|
|
|
7be9059 |
- subseg_set (cfi_seg, 0);
|
|
|
7be9059 |
- record_alignment (cfi_seg, EH_FRAME_ALIGNMENT);
|
|
|
7be9059 |
+ if ((cfi_sections & CFI_EMIT_eh_frame) != 0)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ /* Open .eh_frame section. */
|
|
|
7be9059 |
+ cfi_seg = subseg_new (".eh_frame", 0);
|
|
|
7be9059 |
+ bfd_set_section_flags (stdoutput, cfi_seg,
|
|
|
7be9059 |
+ SEC_ALLOC | SEC_LOAD | SEC_DATA
|
|
|
7be9059 |
+ | DWARF2_EH_FRAME_READ_ONLY);
|
|
|
7be9059 |
+ subseg_set (cfi_seg, 0);
|
|
|
7be9059 |
+ record_alignment (cfi_seg, EH_FRAME_ALIGNMENT);
|
|
|
7be9059 |
|
|
|
7be9059 |
#ifdef md_fix_up_eh_frame
|
|
|
7be9059 |
- md_fix_up_eh_frame (cfi_seg);
|
|
|
7be9059 |
+ md_fix_up_eh_frame (cfi_seg);
|
|
|
7be9059 |
#endif
|
|
|
7be9059 |
|
|
|
7be9059 |
- /* Make sure check_eh_frame doesn't do anything with our output. */
|
|
|
7be9059 |
- save_flag_traditional_format = flag_traditional_format;
|
|
|
7be9059 |
- flag_traditional_format = 1;
|
|
|
7be9059 |
+ /* Make sure check_eh_frame doesn't do anything with our output. */
|
|
|
7be9059 |
+ save_flag_traditional_format = flag_traditional_format;
|
|
|
7be9059 |
+ flag_traditional_format = 1;
|
|
|
7be9059 |
|
|
|
7be9059 |
- for (fde = all_fde_data; fde ; fde = fde->next)
|
|
|
7be9059 |
+ for (fde = all_fde_data; fde ; fde = fde->next)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ struct cfi_insn_data *first;
|
|
|
7be9059 |
+ struct cie_entry *cie;
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ if (fde->end_address == NULL)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
|
|
|
7be9059 |
+ fde->end_address = fde->start_address;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ cie = select_cie_for_fde (fde, TRUE, &first, 2);
|
|
|
7be9059 |
+ output_fde (fde, cie, TRUE, first,
|
|
|
7be9059 |
+ fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ flag_traditional_format = save_flag_traditional_format;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ if ((cfi_sections & CFI_EMIT_debug_frame) != 0)
|
|
|
7be9059 |
{
|
|
|
7be9059 |
- struct cfi_insn_data *first;
|
|
|
7be9059 |
- struct cie_entry *cie;
|
|
|
7be9059 |
+ struct cie_entry *cie, *cie_next;
|
|
|
7be9059 |
+ int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
|
|
|
7be9059 |
|
|
|
7be9059 |
- if (fde->end_address == NULL)
|
|
|
7be9059 |
+ for (cie = cie_root; cie; cie = cie_next)
|
|
|
7be9059 |
{
|
|
|
7be9059 |
- as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
|
|
|
7be9059 |
- fde->end_address = fde->start_address;
|
|
|
7be9059 |
+ cie_next = cie->next;
|
|
|
7be9059 |
+ free ((void *) cie);
|
|
|
7be9059 |
}
|
|
|
7be9059 |
+ cie_root = NULL;
|
|
|
7be9059 |
|
|
|
7be9059 |
- cie = select_cie_for_fde (fde, &first);
|
|
|
7be9059 |
- output_fde (fde, cie, first, fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
|
|
|
7be9059 |
- }
|
|
|
7be9059 |
+ /* Open .debug_frame section. */
|
|
|
7be9059 |
+ cfi_seg = subseg_new (".debug_frame", 0);
|
|
|
7be9059 |
+ bfd_set_section_flags (stdoutput, cfi_seg,
|
|
|
7be9059 |
+ SEC_READONLY | SEC_DEBUGGING);
|
|
|
7be9059 |
+ subseg_set (cfi_seg, 0);
|
|
|
7be9059 |
+ record_alignment (cfi_seg, alignment);
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ for (fde = all_fde_data; fde ; fde = fde->next)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ struct cfi_insn_data *first;
|
|
|
7be9059 |
+ struct cie_entry *cie;
|
|
|
7be9059 |
|
|
|
7be9059 |
- flag_traditional_format = save_flag_traditional_format;
|
|
|
7be9059 |
+ if (fde->end_address == NULL)
|
|
|
7be9059 |
+ {
|
|
|
7be9059 |
+ as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
|
|
|
7be9059 |
+ fde->end_address = fde->start_address;
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+
|
|
|
7be9059 |
+ fde->per_encoding = DW_EH_PE_omit;
|
|
|
7be9059 |
+ fde->lsda_encoding = DW_EH_PE_omit;
|
|
|
7be9059 |
+ cfi_change_reg_numbers (fde->data);
|
|
|
7be9059 |
+ cie = select_cie_for_fde (fde, FALSE, &first, alignment);
|
|
|
7be9059 |
+ output_fde (fde, cie, FALSE, first, alignment);
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
+ }
|
|
|
7be9059 |
}
|
|
|
7be9059 |
|
|
|
7be9059 |
#else /* TARGET_USE_CFIPOP */
|
|
|
7be9059 |
--- gas/config/tc-ppc.h 5 Sep 2009 07:56:24 -0000 1.40
|
|
|
7be9059 |
+++ gas/config/tc-ppc.h 2 Oct 2009 11:33:50 -0000 1.41
|
|
|
7be9059 |
@@ -249,6 +249,12 @@ extern int ppc_parse_name (const char *,
|
|
|
7be9059 |
#define md_cleanup() ppc_cleanup ()
|
|
|
7be9059 |
extern void ppc_cleanup (void);
|
|
|
7be9059 |
|
|
|
7be9059 |
+/* ppc uses different register numbers between .eh_frame and .debug_frame.
|
|
|
7be9059 |
+ This macro translates the .eh_frame register numbers to .debug_frame
|
|
|
7be9059 |
+ register numbers. */
|
|
|
7be9059 |
+#define md_reg_eh_frame_to_debug_frame(regno) \
|
|
|
7be9059 |
+ ((regno) == 70 ? 64 /* cr2 */ : (regno))
|
|
|
7be9059 |
+
|
|
|
7be9059 |
#define TARGET_USE_CFIPOP 1
|
|
|
7be9059 |
|
|
|
7be9059 |
#define tc_cfi_frame_initial_instructions ppc_cfi_frame_initial_instructions
|
|
|
7be9059 |
--- gas/doc/as.texinfo 29 Sep 2009 14:17:09 -0000 1.210
|
|
|
7be9059 |
+++ gas/doc/as.texinfo 2 Oct 2009 11:33:50 -0000 1.211
|
|
|
7be9059 |
@@ -4197,6 +4197,15 @@ undefined.
|
|
|
7be9059 |
Each expression is assembled into the next byte.
|
|
|
7be9059 |
|
|
|
7be9059 |
@node CFI directives
|
|
|
7be9059 |
+@section @code{.cfi_sections @var{section_list}}
|
|
|
7be9059 |
+@cindex @code{cfi_sections} directive
|
|
|
7be9059 |
+@code{.cfi_sections} may be used to specify whether CFI directives
|
|
|
7be9059 |
+should emit @code{.eh_frame} section and/or @code{.debug_frame} section.
|
|
|
7be9059 |
+If @var{section_list} is @code{.eh_frame}, @code{.eh_frame} is emitted,
|
|
|
7be9059 |
+if @var{section_list} is @code{.debug_frame}, @code{.debug_frame} is emitted.
|
|
|
7be9059 |
+To emit both use @code{.eh_frame, .debug_frame}. The default if this
|
|
|
7be9059 |
+directive is not used is @code{.cfi_sections .eh_frame}.
|
|
|
7be9059 |
+
|
|
|
7be9059 |
@section @code{.cfi_startproc [simple]}
|
|
|
7be9059 |
@cindex @code{cfi_startproc} directive
|
|
|
7be9059 |
@code{.cfi_startproc} is used at the beginning of each function that
|