X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Fdw2gencfi.c;h=a4fe8ac9196099f8049e3b650b8ea9744e1f1bb7;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=f9a0b4439eacf0305abb6a5d10b348a2a92c50bf;hpb=c68033869a714b79f20d47ca54138c13439c05c0;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index f9a0b4439e..a4fe8ac919 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -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 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)