gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gas / dw2gencfi.c
index f9a0b4439eacf0305abb6a5d10b348a2a92c50bf..a4fe8ac9196099f8049e3b650b8ea9744e1f1bb7 100644 (file)
@@ -1,5 +1,5 @@
 /* dw2gencfi.c - Support for generating Dwarf2 CFI information.
-   Copyright (C) 2003-2018 Free Software Foundation, Inc.
+   Copyright (C) 2003-2020 Free Software Foundation, Inc.
    Contributed by Michal Ludvig <mludvig@suse.cz>
 
    This file is part of GAS, the GNU Assembler.
@@ -225,37 +225,37 @@ emit_expr_encoded (expressionS *exp, int encoding, bfd_boolean emit_encoding)
 static char *
 get_debugseg_name (segT seg, const char *base_name)
 {
-  const char *name;
+  const char * name;
+  const char * dollar;
+  const char * dot;
 
   if (!seg)
-    name = "";
-  else
-    {
-      const char * dollar;
-      const char * dot;
+    return concat (base_name, NULL);
 
-      name = bfd_get_section_name (stdoutput, seg);
+  name = bfd_section_name (seg);
 
-      dollar = strchr (name, '$');
-      dot = strchr (name + 1, '.');
+  if (name == NULL || *name == 0)
+    return concat (base_name, NULL);
+       
+  dollar = strchr (name, '$');
+  dot = strchr (name + 1, '.');
 
-      if (!dollar && !dot)
-       {
-         if (!strcmp (base_name, ".eh_frame_entry")
-             && strcmp (name, ".text") != 0)
-           return concat (base_name, ".", name, NULL);
+  if (!dollar && !dot)
+    {
+      if (!strcmp (base_name, ".eh_frame_entry")
+         && strcmp (name, ".text") != 0)
+       return concat (base_name, ".", name, NULL);
 
-         name = "";
-       }
-      else if (!dollar)
-       name = dot;
-      else if (!dot)
-       name = dollar;
-      else if (dot < dollar)
-       name = dot;
-      else
-       name = dollar;
+      name = "";
     }
+  else if (!dollar)
+    name = dot;
+  else if (!dot)
+    name = dollar;
+  else if (dot < dollar)
+    name = dot;
+  else
+    name = dollar;
 
   return concat (base_name, name, NULL);
 }
@@ -281,7 +281,7 @@ is_now_linkonce_segment (void)
   if (compact_eh)
     return now_seg;
 
-  if ((bfd_get_section_flags (stdoutput, now_seg)
+  if ((bfd_section_flags (now_seg)
        & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
          | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
          | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0)
@@ -306,16 +306,16 @@ make_debug_seg (segT cseg, char *name, int sflags)
   if (!cseg)
     flags = 0;
   else
-    flags = bfd_get_section_flags (stdoutput, cseg)
-      & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
-        | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
-        | SEC_LINK_DUPLICATES_SAME_CONTENTS);
+    flags = (bfd_section_flags (cseg)
+            & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
+               | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
+               | SEC_LINK_DUPLICATES_SAME_CONTENTS));
 
   /* Add standard section flags.  */
   flags |= sflags;
 
   /* Apply possibly linked once flags to new generated segment, too.  */
-  if (!bfd_set_section_flags (stdoutput, r, flags))
+  if (!bfd_set_section_flags (r, flags))
     as_bad (_("bfd_set_section_flags: %s"),
            bfd_errmsg (bfd_get_error ()));
 
@@ -726,6 +726,7 @@ const pseudo_typeS cfi_pseudo_table[] =
     { "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
     { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
     { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
+    { "cfi_negate_ra_state", dot_cfi, DW_CFA_AARCH64_negate_ra_state },
     { "cfi_escape", dot_cfi_escape, 0 },
     { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
     { "cfi_personality", dot_cfi_personality, 0 },
@@ -1359,7 +1360,7 @@ get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
   else
     {
       cseg = subseg_new (base, 0);
-      bfd_set_section_flags (stdoutput, cseg, flags);
+      bfd_set_section_flags (cseg, flags);
     }
   record_alignment (cseg, align);
   return cseg;
@@ -1598,7 +1599,9 @@ output_cfi_insn (struct cfi_insn_data *insn)
            addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
            addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
 
-           if (scaled <= 0x3F)
+           if (scaled == 0)
+             ;
+           else if (scaled <= 0x3F)
              out_one (DW_CFA_advance_loc + scaled);
            else if (scaled <= 0xFF)
              {
@@ -1628,7 +1631,12 @@ output_cfi_insn (struct cfi_insn_data *insn)
            /* The code in ehopt.c expects that one byte of the encoding
               is already allocated to the frag.  This comes from the way
               that it scans the .eh_frame section looking first for the
-              .byte DW_CFA_advance_loc4.  */
+              .byte DW_CFA_advance_loc4.  Call frag_grow with the sum of
+              room needed by frag_more and frag_var to preallocate space
+              ensuring that the DW_CFA_advance_loc4 is in the fixed part
+              of the rs_cfa frag, so that the relax machinery can remove
+              the advance_loc should it advance by zero.  */
+           frag_grow (5);
            *frag_more (1) = DW_CFA_advance_loc4;
 
            frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
@@ -1853,7 +1861,7 @@ output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
       if (fmt != dwarf2_format_32bit)
        out_four (-1);
     }
-  out_one (DW_CIE_VERSION);                    /* Version.  */
+  out_one (flag_dwarf_cie_version);            /* Version.  */
   if (eh_frame)
     {
       out_one ('z');                           /* Augmentation.  */
@@ -1869,10 +1877,23 @@ output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
   if (cie->signal_frame)
     out_one ('S');
   out_one (0);
+  if (flag_dwarf_cie_version >= 4)
+    {
+      /* For now we are assuming a flat address space with 4 or 8 byte
+         addresses.  */
+      int address_size = dwarf2_format_32bit ? 4 : 8;
+      out_one (address_size);                  /* Address size.  */
+      out_one (0);                             /* Segment size.  */
+    }
   out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH);   /* Code alignment.  */
   out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT);     /* Data alignment.  */
-  if (DW_CIE_VERSION == 1)                     /* Return column.  */
-    out_one (cie->return_column);
+  if (flag_dwarf_cie_version == 1)             /* Return column.  */
+    {
+      if ((cie->return_column & 0xff) != cie->return_column)
+       as_bad (_("return column number %d overflows in CIE version 1"),
+               cie->return_column);
+      out_one (cie->return_column);
+    }
   else
     out_uleb128 (cie->return_column);
   if (eh_frame)
This page took 0.04924 seconds and 4 git commands to generate.