* dw2gencfi.c, dw2gencfi.h: New files.
authorAlan Modra <amodra@gmail.com>
Tue, 20 May 2003 07:58:07 +0000 (07:58 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 20 May 2003 07:58:07 +0000 (07:58 +0000)
* config/tc-i386.c (tc_x86_cfi_init): New function.
* config/tc-i386.h (TARGET_USE_CFIPOP, tc_cfi_init): New defines.
* as.c (parse_args): Set verbose flag on --verbose.
(main): Call tc_cfi_init()/cfi_finish().
* as.h (verbose): New external variable.
* read.c (pobegin): Insert CFI pops to the list.
* symbols.c (local_symbol_make): Make symbol external.
* symbols.h (local_symbol_make): New prototype.
* Makefile.am: Add dw2gencfi.[ch] files.  Run "make dep-am".
* Makefile.in: Regenerate.
* doc/as.texinfo: Added node "CFI directives" with description of
all implemented .cfi_* directives.
* doc/Makefile.in: Regenerate.
* po/POTFILES.in: Regenerate.

15 files changed:
gas/ChangeLog
gas/Makefile.am
gas/Makefile.in
gas/as.c
gas/as.h
gas/config/tc-i386.c
gas/config/tc-i386.h
gas/doc/Makefile.in
gas/doc/as.texinfo
gas/dw2gencfi.c [new file with mode: 0644]
gas/dw2gencfi.h [new file with mode: 0644]
gas/po/POTFILES.in
gas/read.c
gas/symbols.c
gas/symbols.h

index a15d38133acb081095dcad24ef556d81a1c10447..e4293522cf8b2e34fce463f14cd2ebe0e0c51013 100644 (file)
@@ -1,6 +1,25 @@
+2003-05-20  Michal Ludvig  <mludvig@suse.cz>
+
+       * dw2gencfi.c, dw2gencfi.h: New files.
+       * config/tc-i386.c (tc_x86_cfi_init): New function.
+       * config/tc-i386.h (TARGET_USE_CFIPOP, tc_cfi_init): New defines.
+       * as.c (parse_args): Set verbose flag on --verbose.
+       (main): Call tc_cfi_init()/cfi_finish().
+       * as.h (verbose): New external variable.
+       * read.c (pobegin): Insert CFI pops to the list.
+       * symbols.c (local_symbol_make): Make symbol external.
+       * symbols.h (local_symbol_make): New prototype.
+       * Makefile.am: Add dw2gencfi.[ch] files.  Run "make dep-am".
+       * Makefile.in: Regenerate.
+       * doc/as.texinfo: Added node "CFI directives" with description of
+       all implemented .cfi_* directives.
+       * doc/Makefile.in: Regenerate.
+       * po/POTFILES.in: Regenerate.
+
 2003-05-19  Svein E. Seldal  <Svein.Seldal@solidas.com>
 
-       * config/tc-tic4x.c (md_assemble): Added support for one-line parallel insns.
+       * config/tc-tic4x.c (md_assemble): Added support for one-line parallel
+       insns.
        * config/tc-tic4x.h: Added DOUBLEBAR_PARALLEL definition
 
 2003-05-18  Jason Eckhardt  <jle@rice.edu>
@@ -20,7 +39,7 @@
 2003-05-13  Hans-Peter Nilsson  <hp@axis.com>
 
        * read.c (old_buffer, old_input, old_limit): Remove variables.
-       (read_a_source_file): Delete label contin.
+       (read_a_source_file): Delete label contin.
        <handling #APP/#NO_APP>: Use an "sb" to push #APP expansion into
        input as with macros, instead of in separate old_* variables.
        Zero-terminate string being scrubbed.
 
 2003-05-02  Michael Snyder  <msnyder@redhat.com>
 
-       * write.h (FAKE_LABEL_NAME): Allow override 
+       * write.h (FAKE_LABEL_NAME): Allow override
        (for targets that like eg. a leading dot in a local label).
 
 2003-05-02  Nick Clifton  <nickc@redhat.com>
 2003-05-01  Christian Groessler <chris@groessler.org>
 
        * expr.h: Fix comments in operatorT typedef.
-       * config/tc-z8k.c: Add 2003 to copyright message.  
+       * config/tc-z8k.c: Add 2003 to copyright message.
        Fold s_segm() and s_unseg() into one function s_segm(parm) which
        decides by the parameter.
        (md_begin): Don't set linkrelax.  Only set Z8002 default if no
 
 2003-04-21  Richard Henderson  <rth@redhat.com>
 
-        * dwarf2dbg.c (get_filenum): Skip as-yet unassigned file numbers.
-        (out_file_list): Assign non-null filename after generating error.
+       * dwarf2dbg.c (get_filenum): Skip as-yet unassigned file numbers.
+       (out_file_list): Assign non-null filename after generating error.
 
 2003-04-18  Jakub Jelinek  <jakub@redhat.com>
 
 
 2003-04-01  Bob Wilson  <bob.wilson@acm.org>
 
-        * Makefile.am (CPU_TYPES): Add xtensa.
-        (TARGET_CPU_CFILES): Add config/tc-xtensa.c.
-        (TARGET_CPU_HFILES): Add config/tc-xtensa.h.
-        (xtensa-relax.o): New target.
-        Run "make dep-am".
-        * Makefile.in: Regenerate.
-        * configure.in: Handle xtensa-*-*.  Add xtensa-relax.o to
-        extra_objects for xtensa targets.
-        * configure: Regenerate.
-        * write.c (write_object_file): Add new md_post_relax_hook.
-        * config/tc-xtensa.c: New file.
-        * config/tc-xtensa.h: Likewise.
-        * config/xtensa-istack.h: Likewise.
-        * config/xtensa-relax.c: Likewise.
-        * config/xtensa-relax.h: Likewise.
-        * doc/Makefile.am (CPU_DOCS): Add c-xtensa.texi.
-        * doc/Makefile.in: Regenerate.
-        * doc/all.texi: Set new XTENSA variable.
-        * doc/as.texinfo: Set new Xtensa variable.  Describe
-        Xtensa-specific options.  Define line comment character for
-        Xtensa.  Add Xtensa processors to list of ELF targets where
-        alignment is specified in bytes.  Add new Xtensa-Dependent node.
-        Add acknowledgements for those contributing to the Xtensa port.
-        * doc/internals.texi: Describe new md_post_relax_hook.
-        * doc/c-xtensa.texi: New file.
-
+       * Makefile.am (CPU_TYPES): Add xtensa.
+       (TARGET_CPU_CFILES): Add config/tc-xtensa.c.
+       (TARGET_CPU_HFILES): Add config/tc-xtensa.h.
+       (xtensa-relax.o): New target.
+       Run "make dep-am".
+       * Makefile.in: Regenerate.
+       * configure.in: Handle xtensa-*-*.  Add xtensa-relax.o to
+       extra_objects for xtensa targets.
+       * configure: Regenerate.
+       * write.c (write_object_file): Add new md_post_relax_hook.
+       * config/tc-xtensa.c: New file.
+       * config/tc-xtensa.h: Likewise.
+       * config/xtensa-istack.h: Likewise.
+       * config/xtensa-relax.c: Likewise.
+       * config/xtensa-relax.h: Likewise.
+       * doc/Makefile.am (CPU_DOCS): Add c-xtensa.texi.
+       * doc/Makefile.in: Regenerate.
+       * doc/all.texi: Set new XTENSA variable.
+       * doc/as.texinfo: Set new Xtensa variable.  Describe
+       Xtensa-specific options.  Define line comment character for
+       Xtensa.  Add Xtensa processors to list of ELF targets where
+       alignment is specified in bytes.  Add new Xtensa-Dependent node.
+       Add acknowledgements for those contributing to the Xtensa port.
+       * doc/internals.texi: Describe new md_post_relax_hook.
+       * doc/c-xtensa.texi: New file.
 
 2003-04-01  Nick Clifton  <nickc@redhat.com>
            Richard Earnshaw  <rearnsha@arm.com>
 
 2003-03-26  Eric Christopher  <echristo@redhat.com>
 
-       * config/tc-mips.c (nopic_need_relax): Check for
-        S_IS_EXTERN.
+       * config/tc-mips.c (nopic_need_relax): Check for S_IS_EXTERN.
 
 2003-03-25  Stan Cox   <scox@redhat.com>
            Nick Clifton  <nickc@redhat.com>
 
 2003-01-23  Nick Clifton  <nickc@redhat.com>
 
-        NEWS: Announce sh2e support.
-
-       * Add sh2e support:
+       * NEWS: Announce sh2e support.
 
+       Add sh2e support:
        2002-04-02  Alexandre Oliva  <aoliva@redhat.com>
-
-               * config/tc-sh.c (md_show_usage): Added sh2e next to
-               sh3e.
-               (sh_elf_final_processing): Handle arch_sh2e.
+       * config/tc-sh.c (md_show_usage): Added sh2e next to sh3e.
+       (sh_elf_final_processing): Handle arch_sh2e.
 
 2003-01-23  Alan Modra  <amodra@bigpond.net.au>
 
 
 2003-01-01  John David Anglin  <dave.anglin@nrc.ca>
 
-        * config/obj-elf.c (special_sections): Work around HP's incorrect usage
-        of .init and .fini sections for array initializers and finalizers.
+       * config/obj-elf.c (special_sections): Work around HP's incorrect usage
+       of .init and .fini sections for array initializers and finalizers.
 
 2002-12-31  Chris Demetriou  <cgd@broadcom.com>
 
index 24d7dd2796e11cfb3870889aaabbdaeaabd52f55..264b7344b22c4fa2cb46bf671ba3f41d339d8299 100644 (file)
@@ -176,6 +176,7 @@ GAS_CFILES = \
        cond.c \
        depend.c \
        dwarf2dbg.c \
+       dw2gencfi.c \
        ecoff.c \
        ehopt.c \
        expr.c \
@@ -207,6 +208,7 @@ HFILES = \
        bit_fix.h \
        cgen.h \
        dwarf2dbg.h \
+       dw2gencfi.h \
        ecoff.h \
        emul-target.h \
        emul.h \
@@ -422,6 +424,7 @@ GENERIC_OBJS = \
        cond.o \
        depend.o \
        dwarf2dbg.o \
+       dw2gencfi.o \
        ehopt.o \
        expr.o \
        flonum-konst.o \
@@ -1098,14 +1101,13 @@ DEPTC_frv_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
 DEPTC_h8300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
   $(srcdir)/config/tc-h8300.h $(INCDIR)/coff/internal.h \
   $(INCDIR)/coff/h8300.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
-  $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h \
-  $(INCDIR)/safe-ctype.h dwarf2dbg.h 
+  $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h dwarf2dbg.h \
+  $(INCDIR)/opcode/h8300.h $(INCDIR)/safe-ctype.h
 DEPTC_h8300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
   $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h \
-  subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h \
-  $(INCDIR)/safe-ctype.h $(INCDIR)/elf/h8.h $(INCDIR)/elf/reloc-macros.h \
-  dwarf2dbg.h 
+  subsegs.h $(INCDIR)/obstack.h dwarf2dbg.h $(INCDIR)/opcode/h8300.h \
+  $(INCDIR)/safe-ctype.h $(INCDIR)/elf/h8.h $(INCDIR)/elf/reloc-macros.h
 DEPTC_h8500_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
   $(srcdir)/config/tc-h8500.h $(INCDIR)/coff/internal.h \
   $(INCDIR)/coff/h8500.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
@@ -1150,17 +1152,18 @@ DEPTC_i370_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
 DEPTC_i386_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
   $(srcdir)/config/tc-i386.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
   $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
-  dwarf2dbg.h $(INCDIR)/opcode/i386.h
+  dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/i386.h
 DEPTC_i386_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
   $(srcdir)/config/tc-i386.h $(INCDIR)/coff/internal.h \
   $(INCDIR)/coff/i386.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
-  $(INCDIR)/obstack.h dwarf2dbg.h $(INCDIR)/opcode/i386.h
+  $(INCDIR)/obstack.h dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+  $(INCDIR)/opcode/i386.h
 DEPTC_i386_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
   $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h \
   $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
-  dwarf2dbg.h $(INCDIR)/opcode/i386.h
+  dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/i386.h
 DEPTC_i860_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
   $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i860.h \
@@ -2403,13 +2406,17 @@ BMKDEP = #DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING ABOVE.
 #MKDEP    DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.
 app.o: app.c $(INCDIR)/symcat.h
 as.o: as.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
-  output-file.h sb.h macro.h dwarf2dbg.h $(BFDVER_H)
+  output-file.h sb.h macro.h dwarf2dbg.h dw2gencfi.h \
+  $(INCDIR)/elf/dwarf2.h $(BFDVER_H)
 atof-generic.o: atof-generic.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h
 bignum-copy.o: bignum-copy.c $(INCDIR)/symcat.h
 cond.o: cond.c $(INCDIR)/symcat.h macro.h sb.h $(INCDIR)/obstack.h
 depend.o: depend.c $(INCDIR)/symcat.h
 dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/symcat.h dwarf2dbg.h \
-  subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h
+  $(INCDIR)/filenames.h subsegs.h $(INCDIR)/obstack.h \
+  $(INCDIR)/elf/dwarf2.h
+dw2gencfi.o: dw2gencfi.c $(INCDIR)/symcat.h dw2gencfi.h \
+  $(INCDIR)/elf/dwarf2.h
 ecoff.o: ecoff.c $(INCDIR)/symcat.h ecoff.h
 ehopt.o: ehopt.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
   $(INCDIR)/elf/dwarf2.h
@@ -2432,7 +2439,8 @@ macro.o: macro.c $(INCDIR)/safe-ctype.h sb.h macro.h
 messages.o: messages.c $(INCDIR)/symcat.h
 output-file.o: output-file.c $(INCDIR)/symcat.h output-file.h
 read.o: read.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
-  subsegs.h $(INCDIR)/obstack.h sb.h macro.h ecoff.h
+  subsegs.h $(INCDIR)/obstack.h sb.h macro.h ecoff.h \
+  dw2gencfi.h $(INCDIR)/elf/dwarf2.h
 sb.o: sb.c sb.h
 stabs.o: stabs.c $(INCDIR)/symcat.h $(INCDIR)/obstack.h \
   subsegs.h ecoff.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
index bb645a522337d0bd279a7f9be2d5b0a81de0e4a9..de3437de2aa2930e8dd608557297184f145d9d8a 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
 
 # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
@@ -291,6 +291,7 @@ GAS_CFILES = \
        cond.c \
        depend.c \
        dwarf2dbg.c \
+       dw2gencfi.c \
        ecoff.c \
        ehopt.c \
        expr.c \
@@ -323,6 +324,7 @@ HFILES = \
        bit_fix.h \
        cgen.h \
        dwarf2dbg.h \
+       dw2gencfi.h \
        ecoff.h \
        emul-target.h \
        emul.h \
@@ -546,6 +548,7 @@ GENERIC_OBJS = \
        cond.o \
        depend.o \
        dwarf2dbg.o \
+       dw2gencfi.o \
        ehopt.o \
        expr.o \
        flonum-konst.o \
@@ -824,15 +827,14 @@ DEPTC_frv_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
 DEPTC_h8300_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
   $(srcdir)/config/tc-h8300.h $(INCDIR)/coff/internal.h \
   $(INCDIR)/coff/h8300.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
-  $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h \
-  $(INCDIR)/safe-ctype.h dwarf2dbg.h 
+  $(INCDIR)/bfdlink.h subsegs.h $(INCDIR)/obstack.h dwarf2dbg.h \
+  $(INCDIR)/opcode/h8300.h $(INCDIR)/safe-ctype.h
 
 DEPTC_h8300_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
   $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-h8300.h \
-  subsegs.h $(INCDIR)/obstack.h $(INCDIR)/opcode/h8300.h \
-  $(INCDIR)/safe-ctype.h $(INCDIR)/elf/h8.h $(INCDIR)/elf/reloc-macros.h \
-  dwarf2dbg.h 
+  subsegs.h $(INCDIR)/obstack.h dwarf2dbg.h $(INCDIR)/opcode/h8300.h \
+  $(INCDIR)/safe-ctype.h $(INCDIR)/elf/h8.h $(INCDIR)/elf/reloc-macros.h
 
 DEPTC_h8500_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
   $(srcdir)/config/tc-h8500.h $(INCDIR)/coff/internal.h \
@@ -886,19 +888,20 @@ DEPTC_i370_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
 DEPTC_i386_aout = $(INCDIR)/symcat.h $(srcdir)/config/obj-aout.h \
   $(srcdir)/config/tc-i386.h $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h \
   $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
-  dwarf2dbg.h $(INCDIR)/opcode/i386.h
+  dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/i386.h
 
 DEPTC_i386_coff = $(INCDIR)/symcat.h $(srcdir)/config/obj-coff.h \
   $(srcdir)/config/tc-i386.h $(INCDIR)/coff/internal.h \
   $(INCDIR)/coff/i386.h $(INCDIR)/coff/external.h $(BFDDIR)/libcoff.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/safe-ctype.h subsegs.h \
-  $(INCDIR)/obstack.h dwarf2dbg.h $(INCDIR)/opcode/i386.h
+  $(INCDIR)/obstack.h dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h \
+  $(INCDIR)/opcode/i386.h
 
 DEPTC_i386_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
   $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(srcdir)/config/tc-i386.h \
   $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
-  dwarf2dbg.h $(INCDIR)/opcode/i386.h
+  dwarf2dbg.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h $(INCDIR)/opcode/i386.h
 
 DEPTC_i860_elf = $(INCDIR)/symcat.h $(srcdir)/config/obj-elf.h \
   $(BFDDIR)/elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
@@ -2469,13 +2472,13 @@ itbl_test_DEPENDENCIES =  itbl-tops.o itbl-test.o \
 itbl_test_LDFLAGS = 
 as_new_OBJECTS =  app.$(OBJEXT) as.$(OBJEXT) atof-generic.$(OBJEXT) \
 bignum-copy.$(OBJEXT) cond.$(OBJEXT) depend.$(OBJEXT) \
-dwarf2dbg.$(OBJEXT) ecoff.$(OBJEXT) ehopt.$(OBJEXT) expr.$(OBJEXT) \
-flonum-copy.$(OBJEXT) flonum-konst.$(OBJEXT) flonum-mult.$(OBJEXT) \
-frags.$(OBJEXT) hash.$(OBJEXT) input-file.$(OBJEXT) \
-input-scrub.$(OBJEXT) listing.$(OBJEXT) literal.$(OBJEXT) \
-macro.$(OBJEXT) messages.$(OBJEXT) output-file.$(OBJEXT) read.$(OBJEXT) \
-sb.$(OBJEXT) stabs.$(OBJEXT) subsegs.$(OBJEXT) symbols.$(OBJEXT) \
-write.$(OBJEXT)
+dwarf2dbg.$(OBJEXT) dw2gencfi.$(OBJEXT) ecoff.$(OBJEXT) ehopt.$(OBJEXT) \
+expr.$(OBJEXT) flonum-copy.$(OBJEXT) flonum-konst.$(OBJEXT) \
+flonum-mult.$(OBJEXT) frags.$(OBJEXT) hash.$(OBJEXT) \
+input-file.$(OBJEXT) input-scrub.$(OBJEXT) listing.$(OBJEXT) \
+literal.$(OBJEXT) macro.$(OBJEXT) messages.$(OBJEXT) \
+output-file.$(OBJEXT) read.$(OBJEXT) sb.$(OBJEXT) stabs.$(OBJEXT) \
+subsegs.$(OBJEXT) symbols.$(OBJEXT) write.$(OBJEXT)
 as_new_LDFLAGS = 
 SCRIPTS =  $(noinst_SCRIPTS)
 
@@ -2494,7 +2497,7 @@ configure configure.in gdbinit.in itbl-lex.c itbl-parse.c
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
-TAR = gtar
+TAR = tar
 GZIP_ENV = --best
 SOURCES = $(itbl_test_SOURCES) $(as_new_SOURCES) $(EXTRA_as_new_SOURCES)
 OBJECTS = $(itbl_test_OBJECTS) $(as_new_OBJECTS)
@@ -2830,7 +2833,7 @@ distclean-generic:
        -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
 
 maintainer-clean-generic:
-       -test -z "itbl-lexlconfig/m68k-parsehconfig/m68k-parsecitbl-parsehitbl-parsec" || rm -f itbl-lexl config/m68k-parseh config/m68k-parsec itbl-parseh itbl-parsec
+       -test -z "itbl-lex.cconfig/m68k-parse.hconfig/m68k-parse.citbl-parse.hitbl-parse.c" || rm -f itbl-lex.c config/m68k-parse.h config/m68k-parse.c itbl-parse.h itbl-parse.c
 mostlyclean-am:  mostlyclean-hdr mostlyclean-noinstPROGRAMS \
                mostlyclean-compile mostlyclean-libtool \
                mostlyclean-tags mostlyclean-generic
@@ -3315,13 +3318,17 @@ dep-am: DEP
 #MKDEP    DO NOT PUT ANYTHING BETWEEN THIS LINE AND THE MATCHING WARNING BELOW.
 app.o: app.c $(INCDIR)/symcat.h
 as.o: as.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
-  output-file.h sb.h macro.h dwarf2dbg.h $(BFDVER_H)
+  output-file.h sb.h macro.h dwarf2dbg.h dw2gencfi.h \
+  $(INCDIR)/elf/dwarf2.h $(BFDVER_H)
 atof-generic.o: atof-generic.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h
 bignum-copy.o: bignum-copy.c $(INCDIR)/symcat.h
 cond.o: cond.c $(INCDIR)/symcat.h macro.h sb.h $(INCDIR)/obstack.h
 depend.o: depend.c $(INCDIR)/symcat.h
 dwarf2dbg.o: dwarf2dbg.c $(INCDIR)/symcat.h dwarf2dbg.h \
-  subsegs.h $(INCDIR)/obstack.h $(INCDIR)/elf/dwarf2.h
+  $(INCDIR)/filenames.h subsegs.h $(INCDIR)/obstack.h \
+  $(INCDIR)/elf/dwarf2.h
+dw2gencfi.o: dw2gencfi.c $(INCDIR)/symcat.h dw2gencfi.h \
+  $(INCDIR)/elf/dwarf2.h
 ecoff.o: ecoff.c $(INCDIR)/symcat.h ecoff.h
 ehopt.o: ehopt.c $(INCDIR)/symcat.h subsegs.h $(INCDIR)/obstack.h \
   $(INCDIR)/elf/dwarf2.h
@@ -3344,7 +3351,8 @@ macro.o: macro.c $(INCDIR)/safe-ctype.h sb.h macro.h
 messages.o: messages.c $(INCDIR)/symcat.h
 output-file.o: output-file.c $(INCDIR)/symcat.h output-file.h
 read.o: read.c $(INCDIR)/symcat.h $(INCDIR)/safe-ctype.h \
-  subsegs.h $(INCDIR)/obstack.h sb.h macro.h ecoff.h
+  subsegs.h $(INCDIR)/obstack.h sb.h macro.h ecoff.h \
+  dw2gencfi.h $(INCDIR)/elf/dwarf2.h
 sb.o: sb.c sb.h
 stabs.o: stabs.c $(INCDIR)/symcat.h $(INCDIR)/obstack.h \
   subsegs.h ecoff.h $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
index 23ed9f7825a9d0bb48c79418d735101eb43f62c1..da2e0554ea096e9c18334b7719722b634aa6ebe1 100644 (file)
--- a/gas/as.c
+++ b/gas/as.c
@@ -42,6 +42,7 @@
 #include "sb.h"
 #include "macro.h"
 #include "dwarf2dbg.h"
+#include "dw2gencfi.h"
 
 #ifdef BFD_ASSEMBLER
 #include "bfdver.h"
@@ -98,6 +99,9 @@ int chunksize = 0;
    Then the chunk sizes for gas and bfd will be reduced.  */
 int debug_memory = 0;
 
+/* Enable verbose mode.  */
+int verbose = 0;
+
 /* We build a list of defsyms as we read the options, and then define
    them after we have initialized everything.  */
 
@@ -497,6 +501,7 @@ parse_args (pargc, pargv)
 #endif
              case OPTION_VERBOSE:
                print_version_id ();
+               verbose = 1;
              break;
            }
          /* Fall through.  */
@@ -832,6 +837,10 @@ main (argc, argv)
   bfd_set_error_program_name (myname);
 #endif
 
+#ifdef TARGET_USE_CFIPOP
+  tc_cfi_init ();
+#endif
+
 #ifdef USE_EMULATIONS
   select_emulation_mode (argc, argv);
 #endif
@@ -906,6 +915,10 @@ main (argc, argv)
      assembly debugging or on behalf of the compiler, emit it now.  */
   dwarf2_finish ();
 
+#ifdef TARGET_USE_CFIPOP
+  cfi_finish ();
+#endif
+
   if (seen_at_least_1_file ()
       && (flag_always_generate_output || had_errors () == 0))
     keep_it = 1;
index cdb267adbf07bcffb4393b0901cae0ad1aa34ace..2c5a22ccde40b1661be1a77beab08d7ed1212a3c 100644 (file)
--- a/gas/as.h
+++ b/gas/as.h
@@ -474,6 +474,9 @@ extern enum debug_info_type debug_type;
 /* Maximum level of macro nesting.  */
 extern int max_macro_nest;
 
+/* Verbosity level.  */
+extern int verbose;
+
 /* Obstack chunk size.  Keep large for efficient space use, make small to
    increase malloc calls for monitoring memory allocation.  */
 extern int chunksize;
index 92540ad625d15af39c895fe884f83b3053cbf329..9a3bbbbd360b5a9d5584d99f76ca0976fa50beb5 100644 (file)
@@ -30,6 +30,7 @@
 #include "safe-ctype.h"
 #include "subsegs.h"
 #include "dwarf2dbg.h"
+#include "dw2gencfi.h"
 #include "opcode/i386.h"
 
 #ifndef REGISTER_WARNINGS
@@ -6299,3 +6300,85 @@ intel_putback_token ()
   prev_token.reg = NULL;
   prev_token.str = NULL;
 }
+
+void
+tc_x86_cfi_init (void)
+{
+  struct cfi_config cfi_config;
+
+  if (flag_code == CODE_64BIT)
+    {
+      cfi_config.addr_length = 8;
+      cfi_config.eh_align = 8;
+      cfi_config.code_align = 1;
+      cfi_config.data_align = -8;
+      cfi_config.ra_column = 0x10;
+      cfi_config.reloc_type = BFD_RELOC_64;
+    }
+  else
+    {
+      cfi_config.addr_length = 4;
+      cfi_config.eh_align = 4;
+      cfi_config.code_align = 1;
+      cfi_config.data_align = -4;
+      cfi_config.ra_column = 0x08;
+      cfi_config.reloc_type = BFD_RELOC_32;
+    }
+
+  cfi_set_config (&cfi_config);
+}
+
+unsigned long
+tc_x86_regname_to_dw2regnum (const char *regname)
+{
+  unsigned int regnum;
+  unsigned int regnames_count;
+  char *regnames_32[] =
+    {
+      "eax", "ebx", "ecx", "edx",
+      "edi", "esi", "ebp", "esp",
+      "eip"
+    };
+  char *regnames_64[] =
+    {
+      "rax", "rbx", "rcx", "rdx",
+      "rdi", "rsi", "rbp", "rsp",
+      "r8", "r9", "r10", "r11",
+      "r12", "r13", "r14", "r15",
+      "rip"
+    };
+  char **regnames;
+
+  if (flag_code == CODE_64BIT)
+    {
+      regnames = regnames_64;
+      regnames_count = sizeof (regnames_64);
+    }
+  else
+    {
+      regnames = regnames_32;
+      regnames_count = sizeof (regnames_32);
+    }
+
+  for (regnum = 0; regnum < regnames_count; regnum++)
+    if (strcmp (regname, regnames[regnum]) == 0)
+      return regnum;
+
+  as_bad (_("unknown register name '%s'"), regname);
+  return -1;
+}
+
+void
+tc_x86_frame_initial_instructions (void)
+{
+  if (flag_code == CODE_64BIT)
+    {
+      cfi_add_insn (CFA_def_cfa, tc_x86_regname_to_dw2regnum ("rsp"), 8);
+      cfi_add_insn (CFA_offset, tc_x86_regname_to_dw2regnum ("rip"), -8);
+    }
+  else
+    {
+      cfi_add_insn (CFA_def_cfa, tc_x86_regname_to_dw2regnum ("esp"), 4);
+      cfi_add_insn (CFA_offset, tc_x86_regname_to_dw2regnum ("eip"), -4);
+    }
+}
index 45c3acf626d346713743a8b8565cbe78fae214ac..aa131ba5060b1b532f28f68332160f34eab72663 100644 (file)
@@ -545,4 +545,19 @@ void i386_print_statistics PARAMS ((FILE *));
 extern void sco_id PARAMS ((void));
 #endif
 
+/* We want .cfi_* pseudo-ops for generating unwind info.  */
+#define TARGET_USE_CFIPOP
+#ifdef TARGET_USE_CFIPOP
+
+#define tc_cfi_init() tc_x86_cfi_init ()
+extern void tc_x86_cfi_init PARAMS ((void));
+
+#define tc_regname_to_dw2regnum tc_x86_regname_to_dw2regnum
+extern unsigned long tc_x86_regname_to_dw2regnum PARAMS ((const char *regname));
+
+#define tc_cfi_frame_initial_instructions tc_x86_frame_initial_instructions
+extern void tc_x86_frame_initial_instructions PARAMS ((void));
+
+#endif /* TARGET_USE_CFIPOP */
+
 #endif /* TC_I386 */
index 6b8a4e4da9b2a1557abd74d86affac36b45c663a..0a1b7a3d7087607fc888f1e05b6a880d47727cf9 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
 
 # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
@@ -195,7 +195,7 @@ DIST_COMMON =  Makefile.am Makefile.in
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
-TAR = gtar
+TAR = tar
 GZIP_ENV = --best
 all: all-redirect
 .SUFFIXES:
index dd78d68cb0b61c7a42dd3a23baa0d5c7c09fa507..720c05491e8d1e9a996632bdb80d09babc754bb5 100644 (file)
@@ -3690,6 +3690,16 @@ Some machine configurations provide additional directives.
 * Balign::                      @code{.balign @var{abs-expr} , @var{abs-expr}}
 * Byte::                        @code{.byte @var{expressions}}
 * Comm::                        @code{.comm @var{symbol} , @var{length} }
+
+* CFI directives::             @code{.cfi_startproc}
+                               @code{.cfi_endproc}
+                               @code{.cfi_def_cfa @var{register}, @var{offset}}
+                               @code{.cfi_def_cfa_register @var{register}}
+                               @code{.cfi_def_cfa_offset @var{offset}}
+                               @code{.cfi_adjust_cfa_offset @var{offset}}
+                               @code{.cfi_offset @var{register}, @var{offset}}
+                               @code{.cfi_verbose [1|0]}
+
 * Data::                        @code{.data @var{subsection}}
 @ifset COFF
 * Def::                         @code{.def @var{name}}
@@ -3966,6 +3976,48 @@ undefined.
 @code{.byte} expects zero or more expressions, separated by commas.
 Each expression is assembled into the next byte.
 
+@node CFI directives
+@section @code{.cfi_startproc}
+@cindex @code{cfi_startproc} directive
+@code{.cfi_startproc} is used at the beginning of each function that
+should have an entry in @code{.eh_frame}. It initializes some internal
+data structures and emits architecture dependent initial CFI instructions.
+Don't forget to close the function by 
+@code{.cfi_endproc}.
+
+@section @code{.cfi_endproc}
+@cindex @code{cfi_endproc} directive
+@code{.cfi_endproc} is used at the end of a function where it closes its
+unwind entry previously opened by
+@code{.cfi_startproc}. and emits it to @code{.eh_frame}.
+
+@section @code{.cfi_def_cfa @var{register}, @var{offset}}
+@code{.cfi_def_cfa} defines a rule for computing CFA as: @i{take 
+address from @var{register} and add @var{offset} to it}.
+
+@section @code{.cfi_def_cfa_register @var{register}}
+@code{.cfi_def_cfa_register} modifies a rule for computing CFA. From
+now on @var{register} will be used instead of the old one. Offset
+remains the same.
+
+@section @code{.cfi_def_cfa_offset @var{offset}}
+@code{.cfi_def_cfa_offset} modifies a rule for computing CFA. Register
+remains the same, but @var{offset} is new. Note that it is the
+absolute offset that will be added to a defined register to compute
+CFA address.
+
+@section @code{.cfi_adjust_cfa_offset @var{offset}}
+Same as @code{.cfi_def_cfa_offset} but @var{offset} is a relative
+value that is added/substracted from the previous offset.
+
+@section @code{.cfi_offset @var{register}, @var{offset}}
+Previous value of @var{register} is saved at offset @var{offset} from
+CFA. 
+
+@section @code{.cfi_verbose [1|0]}
+Switch on/off verbosity of the CFI machinery. @value{AS} will print
+lots of useful messages to standard output if you use this directive.
+
 @node Comm
 @section @code{.comm @var{symbol} , @var{length} }
 
diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c
new file mode 100644 (file)
index 0000000..f83610b
--- /dev/null
@@ -0,0 +1,721 @@
+/* dw2gencfi.c - Support for generating Dwarf2 CFI information.
+   Copyright 2003 Free Software Foundation, Inc.
+   Contributed by Michal Ludvig <mludvig@suse.cz>
+
+   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 2, 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, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#include <errno.h>
+#include "as.h"
+#include "dw2gencfi.h"
+
+/* Current target config.  */
+static struct cfi_config current_config;
+
+/* This is the main entry point to the CFI machinery.  */
+static void dot_cfi (int arg);
+
+const pseudo_typeS cfi_pseudo_table[] =
+  {
+    { "cfi_verbose", dot_cfi, CFI_verbose },
+    { "cfi_startproc", dot_cfi, CFI_startproc },
+    { "cfi_endproc", dot_cfi, CFI_endproc },
+    { "cfi_def_cfa", dot_cfi, CFA_def_cfa },
+    { "cfi_def_cfa_register", dot_cfi, CFA_def_cfa_register },
+    { "cfi_def_cfa_offset", dot_cfi, CFA_def_cfa_offset },
+    { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset },
+    { "cfi_offset", dot_cfi, CFA_offset },
+    { NULL, NULL, 0 }
+  };
+
+static const char *
+cfi_insn_str (enum cfi_insn insn)
+{
+  switch (insn)
+    {
+    case CFA_nop:
+      return "CFA_nop";
+    case CFA_set_loc:
+      return "CFA_set_loc";
+    case CFA_advance_loc1:
+      return "CFA_advance_loc1";
+    case CFA_advance_loc2:
+      return "CFA_advance_loc2";
+    case CFA_advance_loc4:
+      return "CFA_advance_loc4";
+    case CFA_offset_extended:
+      return "CFA_offset_extended";
+    case CFA_resotre_extended:
+      return "CFA_resotre_extended";
+    case CFA_undefined:
+      return "CFA_undefined";
+    case CFA_same_value:
+      return "CFA_same_value";
+    case CFA_register:
+      return "CFA_register";
+    case CFA_remember_state:
+      return "CFA_remember_state";
+    case CFA_restore_state:
+      return "CFA_restore_state";
+    case CFA_def_cfa:
+      return "CFA_def_cfa";
+    case CFA_def_cfa_register:
+      return "CFA_def_cfa_register";
+    case CFA_def_cfa_offset:
+      return "CFA_def_cfa_offset";
+    case CFA_advance_loc:
+      return "CFA_advance_loc";
+    case CFA_offset:
+      return "CFA_offset";
+    case CFA_restore:
+      return "CFA_restore";
+    default:
+      break;
+    }
+
+  return "CFA_unknown";
+}
+
+struct cfi_data
+{
+  enum cfi_insn insn;
+  long param[2];
+  struct cfi_data *next;
+};
+
+struct cfi_info
+{
+  addressT start_address;
+  addressT end_address;
+  addressT last_address;
+  const char *labelname;
+  struct cfi_data *data;
+  struct cfi_info *next;
+};
+
+static struct cfi_info *cfi_info;
+
+static struct cfi_data *
+alloc_cfi_data (void)
+{
+  return (struct cfi_data *) xcalloc (sizeof (struct cfi_info), 1);
+}
+
+static struct cfi_info *
+alloc_cfi_info (void)
+{
+  return (struct cfi_info *) xcalloc (sizeof (struct cfi_info), 1);
+}
+
+/* Parse arguments.  */
+static int
+cfi_parse_arg (long *param, int resolvereg)
+{
+  char *name, c, *p;
+  long value;
+  int retval = -1;
+  int nchars;
+
+  assert (param != NULL);
+  SKIP_WHITESPACE ();
+
+  if (sscanf (input_line_pointer, "%li%n", &value, &nchars) >= 1)
+    {
+      input_line_pointer += nchars;
+      retval = 1;
+    }
+  else if (resolvereg && (is_name_beginner (*input_line_pointer)))
+    {
+      name = input_line_pointer;
+      c = get_symbol_end ();
+      p = input_line_pointer;
+
+      if ((value = tc_regname_to_dw2regnum (name)) >= 0)
+       retval = 1;
+
+      *p = c;
+    }
+  else
+    as_bad (resolvereg ?
+           _("can't convert argument to a register number") :
+           _("can't convert argument to an integer"));
+
+  if (retval > 0)
+    *param = value;
+
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer == ',')
+    {
+      input_line_pointer++;
+      SKIP_WHITESPACE ();
+    }
+
+  return retval;
+}
+
+static int
+cfi_parse_reg (long *param)
+{
+  return cfi_parse_arg (param, 1);
+}
+
+static int
+cfi_parse_const (long *param)
+{
+  return cfi_parse_arg (param, 0);
+}
+
+void
+cfi_add_insn (enum cfi_insn insn, long param0, long param1)
+{
+  struct cfi_data *data_ptr;
+
+  if (!cfi_info->data)
+    {
+      cfi_info->data = alloc_cfi_data ();
+      data_ptr = cfi_info->data;
+    }
+  else
+    {
+      data_ptr = cfi_info->data;
+
+      while (data_ptr && data_ptr->next)
+       data_ptr = data_ptr->next;
+
+      data_ptr->next = alloc_cfi_data ();
+
+      data_ptr = data_ptr->next;
+    }
+
+  data_ptr->insn = insn;
+  data_ptr->param[0] = param0;
+  data_ptr->param[1] = param1;
+}
+
+static void
+cfi_advance_loc (void)
+{
+  addressT curr_address = frag_now_fix ();
+  if (cfi_info->last_address == curr_address)
+    return;
+  cfi_add_insn (CFA_advance_loc,
+               (long) (curr_address - cfi_info->last_address), 0);
+  cfi_info->last_address = curr_address;
+}
+
+static long
+get_current_offset (struct cfi_info *info)
+{
+  long current_offset = 0;
+  struct cfi_data *data = info->data;
+
+  current_offset = 0;
+  while (data)
+    {
+      if (data->insn == CFA_def_cfa)
+       current_offset = data->param[1];
+      else if (data->insn == CFA_def_cfa_offset)
+       current_offset = data->param[0];
+      data = data->next;
+    }
+
+  return current_offset;
+}
+
+static void
+cfi_make_insn (int arg)
+{
+  long param[2] = { 0, 0 };
+
+  if (!cfi_info)
+    {
+      as_bad (_("CFI instruction used without previous .cfi_startproc"));
+      return;
+    }
+
+  cfi_advance_loc ();
+
+  switch (arg)
+    {
+      /* Instructions that take two arguments (register, integer). */
+    case CFA_offset:
+    case CFA_def_cfa:
+      if (cfi_parse_reg (&param[0]) < 0)
+       {
+         as_bad (_("first argument to %s is not a register"),
+                 cfi_insn_str (arg));
+         return;
+       }
+      if (cfi_parse_const (&param[1]) < 0)
+       {
+         as_bad (_("second argument to %s is not a number"),
+                 cfi_insn_str (arg));
+         return;
+       }
+      break;
+
+      /* Instructions that take one register argument.  */
+    case CFA_def_cfa_register:
+      if (cfi_parse_reg (&param[0]) < 0)
+       {
+         as_bad (_("argument to %s is not a register"), cfi_insn_str (arg));
+         return;
+       }
+      break;
+
+      /* Instructions that take one integer argument.  */
+    case CFA_def_cfa_offset:
+      if (cfi_parse_const (&param[0]) < 0)
+       {
+         as_bad (_("argument to %s is not a number"), cfi_insn_str (arg));
+         return;
+       }
+      break;
+
+      /* Special handling for pseudo-instruction.  */
+    case CFI_adjust_cfa_offset:
+      if (cfi_parse_const (&param[0]) < 0)
+       {
+         as_bad (_("argument to %s is not a number"),
+                   ".cfi_adjust_cfa_offset");
+         return;
+       }
+      param[0] += get_current_offset (cfi_info);
+      arg = CFA_def_cfa_offset;
+      break;
+
+    default:
+      as_bad (_("unknown CFI instruction %d (%s)"), arg, cfi_insn_str (arg));
+      return;
+    }
+  cfi_add_insn (arg, param[0], param[1]);
+}
+
+static symbolS *
+cfi_get_label (void)
+{
+  char symname[40], *symbase=".Llbl_cfi";
+  symbolS *symbolP;
+  unsigned int i = 0;
+
+  snprintf (symname, sizeof (symname), "%s_0x%lx",
+           symbase, (long) frag_now_fix ());
+  while ((symbolP = symbol_find (symname)))
+    {
+      if ((S_GET_VALUE (symbolP) == frag_now_fix ())
+         && (S_GET_SEGMENT (symbolP) == now_seg))
+       {
+         return symbolP;
+       }
+      snprintf (symname, sizeof (symname), "%s_0x%lx_%u",
+               symbase, (long) frag_now_fix (), i++);
+    }
+  symbolP = (symbolS *) local_symbol_make (symname, now_seg,
+                                          (valueT) frag_now_fix (),
+                                          frag_now);
+  return symbolP;
+}
+
+static void
+dot_cfi_startproc (void)
+{
+  if (cfi_info)
+    {
+      as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
+      return;
+    }
+
+  cfi_info = alloc_cfi_info ();
+
+  cfi_info->start_address = frag_now_fix ();
+  cfi_info->last_address = cfi_info->start_address;
+  cfi_info->labelname = S_GET_NAME (cfi_get_label ());
+
+#ifdef tc_cfi_frame_initial_instructions
+  tc_cfi_frame_initial_instructions ();
+#endif
+}
+
+#define cfi_is_advance_insn(insn)                              \
+  ((insn >= CFA_set_loc && insn <= CFA_advance_loc4)           \
+   || insn == CFA_advance_loc)
+
+enum data_types
+  {
+    t_ascii = 0,
+    t_byte = 1,
+    t_half = 2,
+    t_long = 4,
+    t_quad = 8,
+    t_uleb128 = 0x10,
+    t_sleb128 = 0x11
+  };
+
+/* Output CFI instructions to the file.  */
+
+static int
+output_data (char **p, unsigned long *size, enum data_types type, long value)
+{
+  char *ptr = *p;
+  unsigned int ret_size;
+
+  switch (type)
+    {
+    case t_byte:
+      ret_size = 1;
+      break;
+    case t_half:
+      ret_size = 2;
+      break;
+    case t_long:
+      ret_size = 4;
+      break;
+    case t_quad:
+    case t_uleb128:
+    case t_sleb128:
+      ret_size = 8;
+      break;
+    default:
+      as_warn (_("unknown type %d"), type);
+      return 0;
+    }
+
+  if (*size < ret_size)
+    {
+      as_bad (_("output_data buffer is too small"));
+      return 0;
+    }
+
+  switch (type)
+    {
+    case t_byte:
+      *ptr = (char) value;
+      if (verbose)
+       printf ("\t.byte\t0x%x\n", (unsigned char) *ptr);
+      break;
+    case t_half:
+      *(short *) ptr = (short) value & 0xFFFF;
+      if (verbose)
+       printf ("\t.half\t0x%x\n", (unsigned short) *ptr);
+      break;
+    case t_long:
+      *(int *) ptr = (int) value & 0xFFFFFFFF;
+      if (verbose)
+       printf ("\t.long\t0x%x\n", (unsigned int) *ptr);
+      break;
+    case t_quad:
+      *(long long *) ptr = (long long) value & 0xFFFFFFFF;
+      if (verbose)
+       printf ("\t.quad\t0x%x\n", (unsigned int) *ptr);
+      break;
+    case t_uleb128:
+    case t_sleb128:
+      ret_size = output_leb128 (ptr, value, type == t_sleb128);
+      if (verbose)
+       printf ("\t.%s\t0x%lx\n",
+               type == t_sleb128 ? "sleb128" : "uleb128",
+               value);
+      break;
+    default:
+      as_warn ("unknown type %d", type);
+      return 0;
+    }
+
+  *size -= ret_size;
+  *p += ret_size;
+
+  return ret_size;
+}
+
+static int
+cfi_output_insn (struct cfi_data *data, char **buf, unsigned long *buf_size)
+{
+  char **pbuf = buf, *orig_buf = *buf;
+  unsigned long size;
+
+  if (!data || !buf)
+    as_fatal (_("cfi_output_insn called with NULL pointer"));
+
+  switch (data->insn)
+    {
+    case CFA_advance_loc:
+      if (verbose)
+       printf ("\t# %s(%ld)\n", cfi_insn_str (data->insn),
+               data->param[0]);
+      if (data->param[0] <= 0x3F)
+       {
+         output_data (pbuf, buf_size, t_byte, CFA_advance_loc +
+                      (data->param[0] / current_config.code_align));
+       }
+      else if (data->param[0] <= 0xFF)
+       {
+         output_data (pbuf, buf_size, t_byte, CFA_advance_loc1);
+         output_data (pbuf, buf_size, t_byte,
+                      data->param[0] / current_config.code_align);
+       }
+      else if (data->param[0] <= 0xFFFF)
+       {
+         output_data (pbuf, buf_size, t_byte, CFA_advance_loc2);
+         output_data (pbuf, buf_size, t_half,
+                      data->param[0] / current_config.code_align);
+       }
+      else
+       {
+         output_data (pbuf, buf_size, t_byte, CFA_advance_loc4);
+         output_data (pbuf, buf_size, t_long,
+                      data->param[0] / current_config.code_align);
+       }
+      break;
+
+    case CFA_def_cfa:
+      if (verbose)
+       printf ("\t# CFA_def_cfa(%ld,%ld)\n", data->param[0], data->param[1]);
+      output_data (pbuf, buf_size, t_byte, CFA_def_cfa);
+      output_data (pbuf, buf_size, t_uleb128, data->param[0]);
+      output_data (pbuf, buf_size, t_uleb128, data->param[1]);
+      break;
+
+    case CFA_def_cfa_register:
+    case CFA_def_cfa_offset:
+      if (verbose)
+       printf ("\t# %s(%ld)\n", cfi_insn_str (data->insn),
+               data->param[0]);
+      output_data (pbuf, buf_size, t_byte, data->insn);
+      output_data (pbuf, buf_size, t_uleb128, data->param[0]);
+      break;
+
+    case CFA_offset:
+      if (verbose)
+       printf ("\t# %s(%ld,%ld)\n", cfi_insn_str (data->insn),
+               data->param[0], data->param[1]);
+
+      /* Check whether to use CFA_offset or CFA_offset_extended.  */
+      if (data->param[0] <= 0x3F)
+       output_data (pbuf, buf_size, t_byte, CFA_offset + data->param[0]);
+      else
+       {
+         output_data (pbuf, buf_size, t_byte, CFA_offset_extended);
+         output_data (pbuf, buf_size, t_uleb128, data->param[0]);
+       }
+      output_data (pbuf, buf_size, t_uleb128,
+                  data->param[1] / current_config.data_align);
+      break;
+
+    case CFA_nop:
+      if (verbose)
+       printf ("\t# CFA_nop\n");
+      output_data (pbuf, buf_size, t_byte, CFA_nop);
+      break;
+
+    default:
+      as_warn ("CFA_unknown[%d](%ld,%ld)", data->insn,
+              data->param[0], data->param[1]);
+    }
+  size = *pbuf - orig_buf;
+  *buf = *pbuf;
+  *buf_size -= size;
+  return size;
+}
+
+static void
+dot_cfi_endproc (void)
+{
+  struct cfi_data *data_ptr;
+  char *cie_buf, *fde_buf, *pbuf, *where;
+  unsigned long  buf_size, cie_size, fde_size, last_cie_offset;
+  unsigned long        fde_initloc_offset, fde_len_offset;
+  void *saved_seg, *cfi_seg;
+
+  if (! cfi_info)
+    {
+      as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
+      return;
+    }
+  cfi_info->end_address = frag_now_fix ();
+
+  /* Open .eh_frame section.  */
+  saved_seg = now_seg;
+  cfi_seg = subseg_new (".eh_frame", 0);
+  bfd_set_section_flags (stdoutput, cfi_seg,
+                        SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
+  subseg_set (cfi_seg, 0);
+
+  /* Build CIE.  */
+  cie_buf = xcalloc (1024, 1);
+  /* Skip space for CIE length.  */
+  pbuf = cie_buf + 4;
+  buf_size = 1020;
+
+  if (verbose)
+    printf ("# CIE *****\n");
+
+  /* CIE id.  */
+  output_data (&pbuf, &buf_size, t_long, 0x0);
+  /* Version.  */
+  output_data (&pbuf, &buf_size, t_byte, 1);
+  /* Augmentation.  */
+  output_data (&pbuf, &buf_size, t_byte, 0);
+  /* Code alignment.  */
+  output_data (&pbuf, &buf_size, t_uleb128, current_config.code_align);
+  /* Data alignment.  */
+  output_data (&pbuf, &buf_size, t_sleb128, current_config.data_align);
+  /* Return address column.  */
+  output_data (&pbuf, &buf_size, t_byte, current_config.ra_column);
+
+  /* Build CFI instructions.  */
+  data_ptr = cfi_info->data;
+  while (data_ptr && !cfi_is_advance_insn (data_ptr->insn))
+    {
+      cfi_output_insn (data_ptr, &pbuf, &buf_size);
+      data_ptr = data_ptr->next;
+    }
+
+  /* Align the whole data to current_config.eh_align.  */
+  cie_size = pbuf - cie_buf;
+  cie_size += current_config.eh_align - cie_size % current_config.eh_align;
+
+  /* CIE length.  */
+  pbuf = cie_buf;
+  output_data (&pbuf, &buf_size, t_long, cie_size - 4);
+
+  /* OK, we built the CIE. Let's write it to the file...  */
+  last_cie_offset = frag_now_fix ();
+  where = (unsigned char *) frag_more (cie_size);
+  memcpy (where, cie_buf, cie_size);
+
+  /* Clean up.  */
+  free (cie_buf);
+
+  /* Build the FDE...  */
+  fde_buf = xcalloc (1024, 1);
+  pbuf = fde_buf;
+  buf_size = 1024;
+
+  if (verbose)
+    {
+      printf ("# FDE: start=0x%lx, end=0x%lx, delta=%d\n",
+             (long) cfi_info->start_address,
+             (long) cfi_info->end_address,
+             (int) (cfi_info->end_address - cfi_info->start_address));
+    }
+
+  /* FDE length (t_long, 4 bytes) - will be set later.  */
+  fde_len_offset = pbuf - fde_buf;
+  pbuf += 4;
+  buf_size -= 4;
+
+  /* CIE pointer - offset from here.  */
+  output_data (&pbuf, &buf_size, t_long, cie_size + 4);
+
+  /* FDE initial location - this must be set relocatable!  */
+  fde_initloc_offset = pbuf - fde_buf;
+  output_data (&pbuf, &buf_size, current_config.addr_length,
+              cfi_info->start_address);
+
+  /* FDE address range.  */
+  output_data (&pbuf, &buf_size, current_config.addr_length,
+              cfi_info->end_address - cfi_info->start_address);
+
+  while (data_ptr)
+    {
+      cfi_output_insn (data_ptr, &pbuf, &buf_size);
+      data_ptr = data_ptr->next;
+    }
+
+  fde_size = pbuf - fde_buf;
+  fde_size += current_config.eh_align - fde_size % current_config.eh_align;
+
+  /* Now we can set FDE length.  */
+  pbuf = fde_buf + fde_len_offset;
+  buf_size = 4;
+  output_data (&pbuf, &buf_size, t_long, fde_size - 4);
+
+  /* Adjust initloc offset.  */
+  fde_initloc_offset += frag_now_fix ();
+
+  /* Copy FDE to objfile.  */
+  where = (unsigned char *) frag_more (fde_size);
+  memcpy (where, fde_buf, fde_size);
+
+  /* Set relocation for initial address.  */
+  buf_size = current_config.addr_length;
+  expressionS exp;
+  memset (&exp, 0, sizeof (exp));
+  exp.X_op = O_symbol;
+  exp.X_add_symbol = symbol_find (cfi_info->labelname);
+  fix_new_exp (frag_now, fde_initloc_offset,
+              current_config.addr_length,
+              &exp, 0, current_config.reloc_type);
+
+  /* Clean up.  */
+  free (fde_buf);
+
+  free (cfi_info);
+  cfi_info = NULL;
+
+  /* Restore previous segment.  */
+  subseg_set (saved_seg, 0);
+}
+
+void
+dot_cfi (int arg)
+{
+  long param;
+
+  switch (arg)
+    {
+    case CFI_startproc:
+      dot_cfi_startproc ();
+      break;
+    case CFI_endproc:
+      dot_cfi_endproc ();
+      break;
+    case CFA_def_cfa:
+    case CFA_def_cfa_register:
+    case CFA_def_cfa_offset:
+    case CFA_offset:
+    case CFI_adjust_cfa_offset:
+      cfi_make_insn (arg);
+      break;
+    case CFI_verbose:
+      if (cfi_parse_const (&param) >= 0)
+       verbose = (int) param;
+      else
+       verbose = 1;
+      break;
+    default:
+      as_bad (_("unknown CFI code 0x%x (%s)"), arg, cfi_insn_str (arg));
+      break;
+    }
+  ignore_rest_of_line ();
+}
+
+void
+cfi_set_config (struct cfi_config *cfg)
+{
+  assert (cfg != NULL);
+  assert (cfg->addr_length > 0);
+
+  current_config = *cfg;
+}
+
+void
+cfi_finish (void)
+{
+  if (cfi_info)
+    as_bad (_("open CFI at the end of file; missing .cfi_endproc directive"));
+}
diff --git a/gas/dw2gencfi.h b/gas/dw2gencfi.h
new file mode 100644 (file)
index 0000000..1c72454
--- /dev/null
@@ -0,0 +1,100 @@
+/* dw2gencfi.h - Support for generating Dwarf2 CFI information.
+   Copyright 2003 Free Software Foundation, Inc.
+   Contributed by Michal Ludvig <mludvig@suse.cz>
+
+   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 2, 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, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#ifndef DW2GENCFI_H
+#define DW2GENCFI_H
+
+#include "elf/dwarf2.h"
+
+struct cfi_config {
+  /* Target address length in bytes. (usually 4 or 8).
+     Round it up for archs like S/390 with 31b addresses.  */
+  unsigned int addr_length;
+
+  /* Alignment of .eh_frame blocks in bytes (usually 1, 4 or 8).  */
+  unsigned int eh_align;
+
+  /* Code alignment (1 for x86/amd64 machines, 4 or 8 for
+     RISC machines). Consult Dwarf2 standard for details.  */
+  int code_align;
+
+  /* Data (stack) alignment (-4 on x86, -8 on amd64, something
+     positive on archs where stack grows up).  Consult Dwarf2
+     standard for details.  */
+  int data_align;
+
+  /* Return address column (0x8 on x86, 0x10 on amd64).  Consult
+     Dwarf2 standard for details.  */
+  int ra_column;
+
+  /* Relocation type for init_addr FDE record. (BFD_RELOC_64
+     on amd64).  */
+  int reloc_type;
+};
+
+/* Codes of CFI instructions taken from Dwarf2 standard.  */
+enum cfi_insn {
+  CFA_nop = DW_CFA_nop,
+  CFA_set_loc = DW_CFA_set_loc,
+  CFA_advance_loc1 = DW_CFA_advance_loc1,
+  CFA_advance_loc2 = DW_CFA_advance_loc2,
+  CFA_advance_loc4 = DW_CFA_advance_loc4,
+  CFA_offset_extended = DW_CFA_offset_extended,
+  CFA_resotre_extended = DW_CFA_restore_extended,
+  CFA_undefined = DW_CFA_undefined,
+  CFA_same_value = DW_CFA_same_value,
+  CFA_register = DW_CFA_register,
+  CFA_remember_state = DW_CFA_remember_state,
+  CFA_restore_state = DW_CFA_restore_state,
+  CFA_def_cfa = DW_CFA_def_cfa,
+  CFA_def_cfa_register = DW_CFA_def_cfa_register,
+  CFA_def_cfa_offset = DW_CFA_def_cfa_offset,
+  CFA_advance_loc = DW_CFA_advance_loc,
+  CFA_offset = DW_CFA_offset,
+  CFA_restore = DW_CFA_restore,
+
+  /* These don't belong to the standard.  */
+  CFI_startproc = 0xff00,
+  CFI_endproc = 0xff01,
+  CFI_adjust_cfa_offset = 0xff10,
+  CFI_verbose = 0xffff
+};
+
+extern const pseudo_typeS cfi_pseudo_table[];
+
+/* Insert .cfi_* directives to the list of pseudo-ops.  */
+void cfi_pop_insert PARAMS ((void));
+
+/* Set/change setup of the CFI machinery.  This change won't
+   affect already generated CIEs/FDEs.  */
+void cfi_set_config PARAMS ((struct cfi_config *cfg));
+
+/* cfi_finish() is called at the end of file. It will complain if
+   the last CFI wasn't properly closed by .cfi_endproc.  */
+void cfi_finish PARAMS ((void));
+
+/* Add CFI instruction to the list of instructions
+   of the current frame. cfi_add_insn() could be used
+   in tc_cfi_frame_initial_instructions() to add instructions
+   needed for every frame (ie. those that usually go to CIE).  */
+void cfi_add_insn (enum cfi_insn insn, long param0, long param1);
+
+#endif /* DW2GENCFI_H */
index 2a25db2b78ff0cf9d50a3489e3fe8f6ef0c20b9e..f80d3017f851786a43b86c403cb707a648a6a7ba 100644 (file)
@@ -136,10 +136,15 @@ config/tc-w65.c
 config/tc-w65.h
 config/tc-xstormy16.c
 config/tc-xstormy16.h
+config/tc-xtensa.c
+config/tc-xtensa.h
 config/tc-z8k.c
 config/tc-z8k.h
 depend.c
 depend.c
+dw2gencfi.c
+dw2gencfi.c
+dw2gencfi.h
 dwarf2dbg.c
 dwarf2dbg.c
 dwarf2dbg.h
index 07f8238d073d4aed688c671cb5f5815c3551142a..d75083e546b0ff1c1db1b8cb11d4c7dbbafc7f54 100644 (file)
@@ -43,6 +43,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "obstack.h"
 #include "listing.h"
 #include "ecoff.h"
+#include "dw2gencfi.h"
 
 #ifndef TC_START_LABEL
 #define TC_START_LABEL(x,y) (x == ':')
@@ -451,6 +452,10 @@ pop_insert (table)
 #define obj_pop_insert()       pop_insert(obj_pseudo_table)
 #endif
 
+#ifndef cfi_pop_insert
+#define cfi_pop_insert()       pop_insert(cfi_pseudo_table)
+#endif
+
 static void
 pobegin ()
 {
@@ -468,6 +473,12 @@ pobegin ()
   /* Now portable ones.  Skip any that we've seen already.  */
   pop_table_name = "standard";
   pop_insert (potable);
+  
+#ifdef TARGET_USE_CFIPOP
+  pop_table_name = "cfi";
+  pop_override_ok = 1;
+  cfi_pop_insert ();
+#endif
 }
 \f
 #define HANDLE_CONDITIONAL_ASSEMBLY()                                  \
index 59658dff0d01beb51b360cb12197d5ef446160c2..416ff1a8c43b3930d0d394b77f839a4699eccb95 100644 (file)
@@ -182,8 +182,6 @@ symbol_create (name, segment, valu, frag)
 /* Local symbol support.  If we can get away with it, we keep only a
    small amount of information for local symbols.  */
 
-static struct local_symbol *local_symbol_make PARAMS ((const char *, segT,
-                                                      valueT, fragS *));
 static symbolS *local_symbol_convert PARAMS ((struct local_symbol *));
 
 /* Used for statistics.  */
@@ -205,7 +203,7 @@ static unsigned long local_symbol_conversion_count;
 
 /* Create a local symbol and insert it into the local hash table.  */
 
-static struct local_symbol *
+struct local_symbol *
 local_symbol_make (name, section, value, frag)
      const char *name;
      segT section;
index 65fb8492fd75bafb34ac9095a8049438137f923d..d3b9dd3734a971bcef32e44b02d40b07514a5633 100644 (file)
@@ -57,6 +57,8 @@ symbolS *symbol_new PARAMS ((const char *name, segT segment, valueT value,
                             fragS * frag));
 symbolS *symbol_create PARAMS ((const char *name, segT segment, valueT value,
                                fragS * frag));
+struct local_symbol *local_symbol_make PARAMS ((const char *name, segT section, 
+                                        valueT value, fragS * frag));
 symbolS *colon PARAMS ((const char *sym_name));
 void local_colon PARAMS ((int n));
 void symbol_begin PARAMS ((void));