From: Indu Bhagat Date: Mon, 15 Jan 2024 09:00:19 +0000 (-0800) Subject: gas: scfidw2gen: new functionality to prepare for SCFI X-Git-Tag: upstream/2.42~71 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c02a969de74ae3118f4a66ae76860ad21603fc44;p=platform%2Fupstream%2Fbinutils.git gas: scfidw2gen: new functionality to prepare for SCFI Define a new set of handlers for CFI directives for the purpose of SCFI. The SCFI machinery ignores many of the user-specified CFI direcives when SCFI is in effect. A warning ("Warning: SCFI ignores most user-specified CFI directives") is issued once per file. The following CFI directives, however, are not ignored: - .cfi_sections - .cfi_label - .cfi_signal_frame gas/ * Makefile.am: Add new files to GAS_CFILES and HFILES. * Makefile.in: Likewise. * gas/read.c (scfi_pop_insert): New define. (pobegin): Use the SCFI handlers. * scfidw2gen.c: New file. * scfidw2gen.h: New file. --- diff --git a/gas/Makefile.am b/gas/Makefile.am index 77c92d4..2848fac 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -93,6 +93,7 @@ GAS_CFILES = \ read.c \ remap.c \ sb.c \ + scfidw2gen.c \ sframe-opt.c \ stabs.c \ subsegs.c \ @@ -128,6 +129,7 @@ HFILES = \ output-file.h \ read.h \ sb.h \ + scfidw2gen.h \ subsegs.h \ symbols.h \ tc.h \ diff --git a/gas/Makefile.in b/gas/Makefile.in index 7aee1e1..7d4fbfc 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -176,9 +176,9 @@ am__objects_1 = app.$(OBJEXT) as.$(OBJEXT) atof-generic.$(OBJEXT) \ hash.$(OBJEXT) input-file.$(OBJEXT) input-scrub.$(OBJEXT) \ listing.$(OBJEXT) literal.$(OBJEXT) macro.$(OBJEXT) \ messages.$(OBJEXT) output-file.$(OBJEXT) read.$(OBJEXT) \ - remap.$(OBJEXT) sb.$(OBJEXT) sframe-opt.$(OBJEXT) \ - stabs.$(OBJEXT) subsegs.$(OBJEXT) symbols.$(OBJEXT) \ - write.$(OBJEXT) + remap.$(OBJEXT) sb.$(OBJEXT) scfidw2gen.$(OBJEXT) \ + sframe-opt.$(OBJEXT) stabs.$(OBJEXT) subsegs.$(OBJEXT) \ + symbols.$(OBJEXT) write.$(OBJEXT) am_as_new_OBJECTS = $(am__objects_1) am__dirstamp = $(am__leading_dot)dirstamp as_new_OBJECTS = $(am_as_new_OBJECTS) @@ -592,6 +592,7 @@ GAS_CFILES = \ read.c \ remap.c \ sb.c \ + scfidw2gen.c \ sframe-opt.c \ stabs.c \ subsegs.c \ @@ -626,6 +627,7 @@ HFILES = \ output-file.h \ read.h \ sb.h \ + scfidw2gen.h \ subsegs.h \ symbols.h \ tc.h \ @@ -1348,6 +1350,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scfidw2gen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sframe-opt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stabs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subsegs.Po@am__quote@ diff --git a/gas/read.c b/gas/read.c index 753c92d..2aa5ce2 100644 --- a/gas/read.c +++ b/gas/read.c @@ -38,6 +38,7 @@ #include "obstack.h" #include "ecoff.h" #include "dw2gencfi.h" +#include "scfidw2gen.h" #include "codeview.h" #include "wchar.h" #include "filenames.h" @@ -587,6 +588,10 @@ pop_insert (const pseudo_typeS *table) #define cfi_pop_insert() pop_insert(cfi_pseudo_table) #endif +#ifndef scfi_pop_insert +#define scfi_pop_insert() pop_insert(scfi_pseudo_table) +#endif + static void pobegin (void) { @@ -607,8 +612,18 @@ pobegin (void) pop_insert (potable); /* Now CFI ones. */ - pop_table_name = "cfi"; - cfi_pop_insert (); +#if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN) + if (flag_synth_cfi) + { + pop_table_name = "scfi"; + scfi_pop_insert (); + } + else +#endif + { + pop_table_name = "cfi"; + cfi_pop_insert (); + } } static void diff --git a/gas/scfidw2gen.c b/gas/scfidw2gen.c new file mode 100644 index 0000000..1b3fb15 --- /dev/null +++ b/gas/scfidw2gen.c @@ -0,0 +1,252 @@ +/* scfidw2gen.c - Support for emission of synthesized Dwarf2 CFI. + Copyright (C) 2023 Free Software Foundation, Inc. + + This file is part of GAS, the GNU Assembler. + + GAS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GAS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include "as.h" +#include "dw2gencfi.h" +#include "subsegs.h" +#include "scfidw2gen.h" + +#if defined (TARGET_USE_SCFI) && defined (TARGET_USE_GINSN) + +static bool scfi_ignore_warn_once; + +static void +dot_scfi_ignore (int ignored ATTRIBUTE_UNUSED) +{ + gas_assert (flag_synth_cfi); + + if (!scfi_ignore_warn_once) + { + as_warn (_("SCFI ignores most user-specified CFI directives")); + scfi_ignore_warn_once = true; + } + ignore_rest_of_line (); +} + +static void +scfi_process_cfi_label (void) +{ + /* To be implemented. */ + return; +} + +static void +scfi_process_cfi_signal_frame (void) +{ + /* To be implemented. */ + return; +} + +static void +dot_scfi (int arg) +{ + switch (arg) + { + case CFI_label: + scfi_process_cfi_label (); + break; + case CFI_signal_frame: + scfi_process_cfi_signal_frame (); + break; + default: + abort (); + } +} + +const pseudo_typeS scfi_pseudo_table[] = + { + { "cfi_sections", dot_cfi_sections, 0 }, /* No ignore. */ + { "cfi_signal_frame", dot_scfi, CFI_signal_frame }, /* No ignore. */ + { "cfi_label", dot_scfi, CFI_label }, /* No ignore. */ + { "cfi_startproc", dot_scfi_ignore, 0 }, + { "cfi_endproc", dot_scfi_ignore, 0 }, + { "cfi_fde_data", dot_scfi_ignore, 0 }, + { "cfi_def_cfa", dot_scfi_ignore, 0 }, + { "cfi_def_cfa_register", dot_scfi_ignore, 0 }, + { "cfi_def_cfa_offset", dot_scfi_ignore, 0 }, + { "cfi_adjust_cfa_offset", dot_scfi_ignore, 0 }, + { "cfi_offset", dot_scfi_ignore, 0 }, + { "cfi_rel_offset", dot_scfi_ignore, 0 }, + { "cfi_register", dot_scfi_ignore, 0 }, + { "cfi_return_column", dot_scfi_ignore, 0 }, + { "cfi_restore", dot_scfi_ignore, 0 }, + { "cfi_undefined", dot_scfi_ignore, 0 }, + { "cfi_same_value", dot_scfi_ignore, 0 }, + { "cfi_remember_state", dot_scfi_ignore, 0 }, + { "cfi_restore_state", dot_scfi_ignore, 0 }, + { "cfi_window_save", dot_scfi_ignore, 0 }, + { "cfi_negate_ra_state", dot_scfi_ignore, 0 }, + { "cfi_escape", dot_scfi_ignore, 0 }, + { "cfi_personality", dot_scfi_ignore, 0 }, + { "cfi_personality_id", dot_scfi_ignore, 0 }, + { "cfi_lsda", dot_scfi_ignore, 0 }, + { "cfi_val_encoded_addr", dot_scfi_ignore, 0 }, + { "cfi_inline_lsda", dot_scfi_ignore, 0 }, + { "cfi_val_offset", dot_scfi_ignore, 0 }, + { NULL, NULL, 0 } + }; + +void +scfi_dot_cfi_startproc (const symbolS *start_sym) +{ + if (frchain_now->frch_cfi_data != NULL) + { + as_bad (_("SCFI: missing previous SCFI endproc marker")); + return; + } + + cfi_new_fde ((symbolS *)start_sym); + + cfi_set_sections (); + + frchain_now->frch_cfi_data->cur_cfa_offset = 0; + + /* By default, SCFI machinery assumes .cfi_startproc is used without + parameter simple. */ + tc_cfi_frame_initial_instructions (); + + if ((all_cfi_sections & CFI_EMIT_target) != 0) + tc_cfi_startproc (); +} + +void +scfi_dot_cfi_endproc (const symbolS *end_sym) +{ + struct fde_entry *fde_last; + + if (frchain_now->frch_cfi_data == NULL) + { + as_bad (_(".cfi_endproc without corresponding .cfi_startproc")); + return; + } + + fde_last = frchain_now->frch_cfi_data->cur_fde_data; + cfi_set_last_fde (fde_last); + + cfi_end_fde ((symbolS *)end_sym); + + if ((all_cfi_sections & CFI_EMIT_target) != 0) + tc_cfi_endproc (fde_last); +} + +void +scfi_dot_cfi (int arg, unsigned reg1, unsigned reg2, offsetT offset, + const char *name, const symbolS *advloc) +{ + if (frchain_now->frch_cfi_data == NULL) + { + as_bad (_("CFI instruction used without previous .cfi_startproc")); + return; + } + + /* If the last address was not at the current PC, advance to current. */ + if (frchain_now->frch_cfi_data->last_address != advloc) + cfi_add_advance_loc ((symbolS *)advloc); + + switch (arg) + { + case DW_CFA_offset: + cfi_add_CFA_offset (reg1, offset); + break; + + case DW_CFA_val_offset: + cfi_add_CFA_val_offset (reg1, offset); + break; + + case CFI_rel_offset: + cfi_add_CFA_offset (reg1, + offset - frchain_now->frch_cfi_data->cur_cfa_offset); + break; + + case DW_CFA_def_cfa: + cfi_add_CFA_def_cfa (reg1, offset); + break; + + case DW_CFA_register: + cfi_add_CFA_register (reg1, reg2); + break; + + case DW_CFA_def_cfa_register: + cfi_add_CFA_def_cfa_register (reg1); + break; + + case DW_CFA_def_cfa_offset: + cfi_add_CFA_def_cfa_offset (offset); + break; + + case CFI_adjust_cfa_offset: + cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset + + offset); + break; + + case DW_CFA_restore: + cfi_add_CFA_restore (reg1); + break; + + case DW_CFA_remember_state: + cfi_add_CFA_remember_state (); + break; + + case DW_CFA_restore_state: + cfi_add_CFA_restore_state (); + break; + + case CFI_label: + cfi_add_label (name); + break; + + case CFI_signal_frame: + frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1; + break; + +/* + case DW_CFA_undefined: + for (;;) + { + reg1 = cfi_parse_reg (); + cfi_add_CFA_undefined (reg1); + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + break; + ++input_line_pointer; + } + break; + + case DW_CFA_same_value: + reg1 = cfi_parse_reg (); + cfi_add_CFA_same_value (reg1); + break; + + case CFI_return_column: + reg1 = cfi_parse_reg (); + cfi_set_return_column (reg1); + break; + + case DW_CFA_GNU_window_save: + cfi_add_CFA_insn (DW_CFA_GNU_window_save); + break; + +*/ + default: + abort (); + } +} + +#endif diff --git a/gas/scfidw2gen.h b/gas/scfidw2gen.h new file mode 100644 index 0000000..b96ff48 --- /dev/null +++ b/gas/scfidw2gen.h @@ -0,0 +1,35 @@ +/* scfidw2gen.h - Support for emitting synthesized Dwarf2 CFI. + Copyright (C) 2023 Free Software Foundation, Inc. + + This file is part of GAS, the GNU Assembler. + + GAS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GAS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef SCFIDW2GEN_H +#define SCFIDW2GEN_H + +#include "as.h" +#include "dwarf2.h" + +extern const pseudo_typeS scfi_pseudo_table[]; + +void scfi_dot_cfi_startproc (const symbolS *start_sym); +void scfi_dot_cfi_endproc (const symbolS *end_sym); +void scfi_dot_cfi (int arg, unsigned reg1, unsigned reg2, offsetT offset, + const char *name, const symbolS *advloc); + +#endif +