OSDN Git Service

* java/io/DataInput.java: Merge with Classpath.
[pf3gnuchains/gcc-fork.git] / gcc / dwarfout.c
index 9c7cb47..d51d575 100644 (file)
    1999, 2000, 2001 Free Software Foundation, Inc.
    Contributed by Ron Guilmette (rfg@monkeys.com) of Network Computing Devices.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC 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.
+GCC 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.
 
-GNU CC 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.
+GCC 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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+/*
+
+ Notes on the GNU Implementation of DWARF Debugging Information
+ --------------------------------------------------------------
+ Last Major Update: Sun Jul 17 08:17:42 PDT 1994 by rfg@segfault.us.com
+ ------------------------------------------------------------
+
+ This file describes special and unique aspects of the GNU implementation of
+ the DWARF Version 1 debugging information language, as provided in the GNU
+ version 2.x compiler(s).
+
+ For general information about the DWARF debugging information language,
+ you should obtain the DWARF version 1.1 specification document (and perhaps
+ also the DWARF version 2 draft specification document) developed by the
+ (now defunct) UNIX International Programming Languages Special Interest Group.
+
+ To obtain a copy of the DWARF Version 1 and/or DWARF Version 2
+ specification, visit the web page for the DWARF Version 2 committee, at
+
+   http://www.eagercon.com/dwarf/dwarf2std.htm
+
+ The generation of DWARF debugging information by the GNU version 2.x C
+ compiler has now been tested rather extensively for m88k, i386, i860, and
+ Sparc targets.  The DWARF output of the GNU C compiler appears to inter-
+ operate well with the standard SVR4 SDB debugger on these kinds of target
+ systems (but of course, there are no guarantees).
+
+ DWARF 1 generation for the GNU g++ compiler is implemented, but limited.
+ C++ users should definitely use DWARF 2 instead.
+
+ Future plans for the dwarfout.c module of the GNU compiler(s) includes the
+ addition of full support for GNU FORTRAN.  (This should, in theory, be a
+ lot simpler to add than adding support for g++... but we'll see.)
+
+ Many features of the DWARF version 2 specification have been adapted to
+ (and used in) the GNU implementation of DWARF (version 1).  In most of
+ these cases, a DWARF version 2 approach is used in place of (or in addition
+ to) DWARF version 1 stuff simply because it is apparent that DWARF version
+ 1 is not sufficiently expressive to provide the kinds of information which
+ may be necessary to support really robust debugging.  In all of these cases
+ however, the use of DWARF version 2 features should not interfere in any
+ way with the interoperability (of GNU compilers) with generally available
+ "classic" (pre version 1) DWARF consumer tools (e.g. SVR4 SDB).
+
+ The DWARF generation enhancement for the GNU compiler(s) was initially
+ donated to the Free Software Foundation by Network Computing Devices.
+ (Thanks NCD!) Additional development and maintenance of dwarfout.c has
+ been largely supported (i.e. funded) by Intel Corporation.  (Thanks Intel!)
+
+ If you have questions or comments about the DWARF generation feature, please
+ send mail to me <rfg@netcom.com>.  I will be happy to investigate any bugs
+ reported and I may even provide fixes (but of course, I can make no promises).
+
+ The DWARF debugging information produced by GCC may deviate in a few minor
+ (but perhaps significant) respects from the DWARF debugging information
+ currently produced by other C compilers.  A serious attempt has been made
+ however to conform to the published specifications, to existing practice,
+ and to generally accepted norms in the GNU implementation of DWARF.
+
+     ** IMPORTANT NOTE **    ** IMPORTANT NOTE **    ** IMPORTANT NOTE **
+
+ Under normal circumstances, the DWARF information generated by the GNU
+ compilers (in an assembly language file) is essentially impossible for
+ a human being to read.  This fact can make it very difficult to debug
+ certain DWARF-related problems.  In order to overcome this difficulty,
+ a feature has been added to dwarfout.c (enabled by the -dA
+ option) which causes additional comments to be placed into the assembly
+ language output file, out to the right-hand side of most bits of DWARF
+ material.  The comments indicate (far more clearly that the obscure
+ DWARF hex codes do) what is actually being encoded in DWARF.  Thus, the
+ -dA option can be highly useful for those who must study the
+ DWARF output from the GNU compilers in detail.
+
+ ---------
+
+ (Footnote: Within this file, the term `Debugging Information Entry' will
+ be abbreviated as `DIE'.)
+
+
+ Release Notes  (aka known bugs)
+ -------------------------------
+
+ In one very obscure case involving dynamically sized arrays, the DWARF
+ "location information" for such an array may make it appear that the
+ array has been totally optimized out of existence, when in fact it
+ *must* actually exist.  (This only happens when you are using *both* -g
+ *and* -O.)  This is due to aggressive dead store elimination in the
+ compiler, and to the fact that the DECL_RTL expressions associated with
+ variables are not always updated to correctly reflect the effects of
+ GCC's aggressive dead store elimination.
+
+ -------------------------------
+
+ When attempting to set a breakpoint at the "start" of a function compiled
+ with -g1, the debugger currently has no way of knowing exactly where the
+ end of the prologue code for the function is.  Thus, for most targets,
+ all the debugger can do is to set the breakpoint at the AT_low_pc address
+ for the function.  But if you stop there and then try to look at one or
+ more of the formal parameter values, they may not have been "homed" yet,
+ so you may get inaccurate answers (or perhaps even addressing errors).
+
+ Some people may consider this simply a non-feature, but I consider it a
+ bug, and I hope to provide some GNU-specific attributes (on function
+ DIEs) which will specify the address of the end of the prologue and the
+ address of the beginning of the epilogue in a future release.
+
+ -------------------------------
+
+ It is believed at this time that old bugs relating to the AT_bit_offset
+ values for bit-fields have been fixed.
+
+ There may still be some very obscure bugs relating to the DWARF description
+ of type `long long' bit-fields for target machines (e.g. 80x86 machines)
+ where the alignment of type `long long' data objects is different from
+ (and less than) the size of a type `long long' data object.
+
+ Please report any problems with the DWARF description of bit-fields as you
+ would any other GCC bug.  (Procedures for bug reporting are given in the
+ GNU C compiler manual.)
+
+ --------------------------------
+
+ At this time, GCC does not know how to handle the GNU C "nested functions"
+ extension.  (See the GCC manual for more info on this extension to ANSI C.)
+
+ --------------------------------
+
+ The GNU compilers now represent inline functions (and inlined instances
+ thereof) in exactly the manner described by the current DWARF version 2
+ (draft) specification.  The version 1 specification for handling inline
+ functions (and inlined instances) was known to be brain-damaged (by the
+ PLSIG) when the version 1 spec was finalized, but it was simply too late
+ in the cycle to get it removed before the version 1 spec was formally
+ released to the public (by UI).
+
+ --------------------------------
+
+ At this time, GCC does not generate the kind of really precise information
+ about the exact declared types of entities with signed integral types which
+ is required by the current DWARF draft specification.
+
+ Specifically, the current DWARF draft specification seems to require that
+ the type of an non-unsigned integral bit-field member of a struct or union
+ type be represented as either a "signed" type or as a "plain" type,
+ depending upon the exact set of keywords that were used in the
+ type specification for the given bit-field member.  It was felt (by the
+ UI/PLSIG) that this distinction between "plain" and "signed" integral types
+ could have some significance (in the case of bit-fields) because ANSI C
+ does not constrain the signedness of a plain bit-field, whereas it does
+ constrain the signedness of an explicitly "signed" bit-field.  For this
+ reason, the current DWARF specification calls for compilers to produce
+ type information (for *all* integral typed entities... not just bit-fields)
+ which explicitly indicates the signedness of the relevant type to be
+ "signed" or "plain" or "unsigned".
+
+ Unfortunately, the GNU DWARF implementation is currently incapable of making
+ such distinctions.
+
+ --------------------------------
+
+
+ Known Interoperability Problems
+ -------------------------------
+
+ Although the GNU implementation of DWARF conforms (for the most part) with
+ the current UI/PLSIG DWARF version 1 specification (with many compatible
+ version 2 features added in as "vendor specific extensions" just for good
+ measure) there are a few known cases where GCC's DWARF output can cause
+ some confusion for "classic" (pre version 1) DWARF consumers such as the
+ System V Release 4 SDB debugger.  These cases are described in this section.
+
+ --------------------------------
+
+ The DWARF version 1 specification includes the fundamental type codes
+ FT_ext_prec_float, FT_complex, FT_dbl_prec_complex, and FT_ext_prec_complex.
+ Since GNU C is only a C compiler (and since C doesn't provide any "complex"
+ data types) the only one of these fundamental type codes which GCC ever
+ generates is FT_ext_prec_float.  This fundamental type code is generated
+ by GCC for the `long double' data type.  Unfortunately, due to an apparent
+ bug in the SVR4 SDB debugger, SDB can become very confused wherever any
+ attempt is made to print a variable, parameter, or field whose type was
+ given in terms of FT_ext_prec_float.
+
+ (Actually, SVR4 SDB fails to understand *any* of the four fundamental type
+ codes mentioned here.  This will fact will cause additional problems when
+ there is a GNU FORTRAN front-end.)
+
+ --------------------------------
+
+ In general, it appears that SVR4 SDB is not able to effectively ignore
+ fundamental type codes in the "implementation defined" range.  This can
+ cause problems when a program being debugged uses the `long long' data
+ type (or the signed or unsigned varieties thereof) because these types
+ are not defined by ANSI C, and thus, GCC must use its own private fundamental
+ type codes (from the implementation-defined range) to represent these types.
+
+ --------------------------------
+
+
+ General GNU DWARF extensions
+ ----------------------------
+
+ In the current DWARF version 1 specification, no mechanism is specified by
+ which accurate information about executable code from include files can be
+ properly (and fully) described.  (The DWARF version 2 specification *does*
+ specify such a mechanism, but it is about 10 times more complicated than
+ it needs to be so I'm not terribly anxious to try to implement it right
+ away.)
+
+ In the GNU implementation of DWARF version 1, a fully downward-compatible
+ extension has been implemented which permits the GNU compilers to specify
+ which executable lines come from which files.  This extension places
+ additional information (about source file names) in GNU-specific sections
+ (which should be totally ignored by all non-GNU DWARF consumers) so that
+ this extended information can be provided (to GNU DWARF consumers) in a way
+ which is totally transparent (and invisible) to non-GNU DWARF consumers
+ (e.g. the SVR4 SDB debugger).  The additional information is placed *only*
+ in specialized GNU-specific sections, where it should never even be seen
+ by non-GNU DWARF consumers.
+
+ To understand this GNU DWARF extension, imagine that the sequence of entries
+ in the .lines section is broken up into several subsections.  Each contiguous
+ sequence of .line entries which relates to a sequence of lines (or statements)
+ from one particular file (either a `base' file or an `include' file) could
+ be called a `line entries chunk' (LEC).
+
+ For each LEC there is one entry in the .debug_srcinfo section.
+
+ Each normal entry in the .debug_srcinfo section consists of two 4-byte
+ words of data as follows:
+
+        (1)    The starting address (relative to the entire .line section)
+                of the first .line entry in the relevant LEC.
+
+        (2)    The starting address (relative to the entire .debug_sfnames
+                section) of a NUL terminated string representing the
+                relevant filename.  (This filename name be either a
+                relative or an absolute filename, depending upon how the
+                given source file was located during compilation.)
+
+ Obviously, each .debug_srcinfo entry allows you to find the relevant filename,
+ and it also points you to the first .line entry that was generated as a result
+ of having compiled a given source line from the given source file.
+
+ Each subsequent .line entry should also be assumed to have been produced
+ as a result of compiling yet more lines from the same file.  The end of
+ any given LEC is easily found by looking at the first 4-byte pointer in
+ the *next* .debug_srcinfo entry.  That next .debug_srcinfo entry points
+ to a new and different LEC, so the preceding LEC (implicitly) must have
+ ended with the last .line section entry which occurs at the 2 1/2 words
+ just before the address given in the first pointer of the new .debug_srcinfo
+ entry.
+
+ The following picture may help to clarify this feature.  Let's assume that
+ `LE' stands for `.line entry'.  Also, assume that `* 'stands for a pointer.
+
+
+        .line section     .debug_srcinfo section     .debug_sfnames section
+        ----------------------------------------------------------------
+
+        LE  <---------------------- *
+        LE                         * -----------------> "foobar.c" <---
+        LE                                                             |
+        LE                                                             |
+        LE  <---------------------- *                                  |
+        LE                         * -----------------> "foobar.h" <|  |
+        LE                                                          |  |
+        LE                                                          |  |
+        LE  <---------------------- *                               |  |
+        LE                         * ----------------->  "inner.h"  |  |
+        LE                                                          |  |
+        LE  <---------------------- *                               |  |
+        LE                         * -------------------------------   |
+        LE                                                             |
+        LE                                                             |
+        LE                                                             |
+        LE                                                             |
+        LE  <---------------------- *                                  |
+        LE                         * -----------------------------------
+        LE
+        LE
+        LE
+
+ In effect, each entry in the .debug_srcinfo section points to *both* a
+ filename (in the .debug_sfnames section) and to the start of a block of
+ consecutive LEs (in the .line section).
+
+ Note that just like in the .line section, there are specialized first and
+ last entries in the .debug_srcinfo section for each object file.  These
+ special first and last entries for the .debug_srcinfo section are very
+ different from the normal .debug_srcinfo section entries.  They provide
+ additional information which may be helpful to a debugger when it is
+ interpreting the data in the .debug_srcinfo, .debug_sfnames, and .line
+ sections.
+
+ The first entry in the .debug_srcinfo section for each compilation unit
+ consists of five 4-byte words of data.  The contents of these five words
+ should be interpreted (by debuggers) as follows:
+
+        (1)    The starting address (relative to the entire .line section)
+                of the .line section for this compilation unit.
+
+        (2)    The starting address (relative to the entire .debug_sfnames
+                section) of the .debug_sfnames section for this compilation
+                unit.
+
+        (3)    The starting address (in the execution virtual address space)
+                of the .text section for this compilation unit.
+
+        (4)    The ending address plus one (in the execution virtual address
+                space) of the .text section for this compilation unit.
+
+        (5)    The date/time (in seconds since midnight 1/1/70) at which the
+                compilation of this compilation unit occurred.  This value
+                should be interpreted as an unsigned quantity because gcc
+                might be configured to generate a default value of 0xffffffff
+                in this field (in cases where it is desired to have object
+                files created at different times from identical source files
+                be byte-for-byte identical).  By default, these timestamps
+                are *not* generated by dwarfout.c (so that object files
+                compiled at different times will be byte-for-byte identical).
+                If you wish to enable this "timestamp" feature however, you
+                can simply place a #define for the symbol `DWARF_TIMESTAMPS'
+                in your target configuration file and then rebuild the GNU
+                compiler(s).
+
+ Note that the first string placed into the .debug_sfnames section for each
+ compilation unit is the name of the directory in which compilation occurred.
+ This string ends with a `/' (to help indicate that it is the pathname of a
+ directory).  Thus, the second word of each specialized initial .debug_srcinfo
+ entry for each compilation unit may be used as a pointer to the (string)
+ name of the compilation directory, and that string may in turn be used to
+ "absolutize" any relative pathnames which may appear later on in the
+ .debug_sfnames section entries for the same compilation unit.
+
+ The fifth and last word of each specialized starting entry for a compilation
+ unit in the .debug_srcinfo section may (depending upon your configuration)
+ indicate the date/time of compilation, and this may be used (by a debugger)
+ to determine if any of the source files which contributed code to this
+ compilation unit are newer than the object code for the compilation unit
+ itself.  If so, the debugger may wish to print an "out-of-date" warning
+ about the compilation unit.
+
+ The .debug_srcinfo section associated with each compilation will also have
+ a specialized terminating entry.  This terminating .debug_srcinfo section
+ entry will consist of the following two 4-byte words of data:
+
+        (1)    The offset, measured from the start of the .line section to
+                the beginning of the terminating entry for the .line section.
+
+        (2)    A word containing the value 0xffffffff.
+
+ --------------------------------
+
+ In the current DWARF version 1 specification, no mechanism is specified by
+ which information about macro definitions and un-definitions may be provided
+ to the DWARF consumer.
+
+ The DWARF version 2 (draft) specification does specify such a mechanism.
+ That specification was based on the GNU ("vendor specific extension")
+ which provided some support for macro definitions and un-definitions,
+ but the "official" DWARF version 2 (draft) specification mechanism for
+ handling macros and the GNU implementation have diverged somewhat.  I
+ plan to update the GNU implementation to conform to the "official"
+ DWARF version 2 (draft) specification as soon as I get time to do that.
+
+ Note that in the GNU implementation, additional information about macro
+ definitions and un-definitions is *only* provided when the -g3 level of
+ debug-info production is selected.  (The default level is -g2 and the
+ plain old -g option is considered to be identical to -g2.)
+
+ GCC records information about macro definitions and undefinitions primarily
+ in a section called the .debug_macinfo section.  Normal entries in the
+ .debug_macinfo section consist of the following three parts:
+
+        (1)    A special "type" byte.
+
+        (2)    A 3-byte line-number/filename-offset field.
+
+        (3)    A NUL terminated string.
+
+ The interpretation of the second and third parts is dependent upon the
+ value of the leading (type) byte.
+
+ The type byte may have one of four values depending upon the type of the
+ .debug_macinfo entry which follows.  The 1-byte MACINFO type codes presently
+ used, and their meanings are as follows:
+
+        MACINFO_start          A base file or an include file starts here.
+        MACINFO_resume         The current base or include file ends here.
+        MACINFO_define          A #define directive occurs here.
+        MACINFO_undef           A #undef directive occur here.
+
+ (Note that the MACINFO_... codes mentioned here are simply symbolic names
+ for constants which are defined in the GNU dwarf.h file.)
+
+ For MACINFO_define and MACINFO_undef entries, the second (3-byte) field
+ contains the number of the source line (relative to the start of the current
+ base source file or the current include files) when the #define or #undef
+ directive appears.  For a MACINFO_define entry, the following string field
+ contains the name of the macro which is defined, followed by its definition.
+ Note that the definition is always separated from the name of the macro
+ by at least one whitespace character.  For a MACINFO_undef entry, the
+ string which follows the 3-byte line number field contains just the name
+ of the macro which is being undef'ed.
+
+ For a MACINFO_start entry, the 3-byte field following the type byte contains
+ the offset, relative to the start of the .debug_sfnames section for the
+ current compilation unit, of a string which names the new source file which
+ is beginning its inclusion at this point.  Following that 3-byte field,
+ each MACINFO_start entry always contains a zero length NUL terminated
+ string.
+
+ For a MACINFO_resume entry, the 3-byte field following the type byte contains
+ the line number WITHIN THE INCLUDING FILE at which the inclusion of the
+ current file (whose inclusion ends here) was initiated.  Following that
+ 3-byte field, each MACINFO_resume entry always contains a zero length NUL
+ terminated string.
+
+ Each set of .debug_macinfo entries for each compilation unit is terminated
+ by a special .debug_macinfo entry consisting of a 4-byte zero value followed
+ by a single NUL byte.
+
+ --------------------------------
+
+ In the current DWARF draft specification, no provision is made for providing
+ a separate level of (limited) debugging information necessary to support
+ tracebacks (only) through fully-debugged code (e.g. code in system libraries).
+
+ A proposal to define such a level was submitted (by me) to the UI/PLSIG.
+ This proposal was rejected by the UI/PLSIG for inclusion into the DWARF
+ version 1 specification for two reasons.  First, it was felt (by the PLSIG)
+ that the issues involved in supporting a "traceback only" subset of DWARF
+ were not well understood.  Second, and perhaps more importantly, the PLSIG
+ is already having enough trouble agreeing on what it means to be "conforming"
+ to the DWARF specification, and it was felt that trying to specify multiple
+ different *levels* of conformance would only complicate our discussions of
+ this already divisive issue.  Nonetheless, the GNU implementation of DWARF
+ provides an abbreviated "traceback only" level of debug-info production for
+ use with fully-debugged "system library" code.  This level should only be
+ used for fully debugged system library code, and even then, it should only
+ be used where there is a very strong need to conserve disk space.  This
+ abbreviated level of debug-info production can be used by specifying the
+ -g1 option on the compilation command line.
+
+ --------------------------------
+
+ As mentioned above, the GNU implementation of DWARF currently uses the DWARF
+ version 2 (draft) approach for inline functions (and inlined instances
+ thereof).  This is used in preference to the version 1 approach because
+ (quite simply) the version 1 approach is highly brain-damaged and probably
+ unworkable.
+
+ --------------------------------
+
+
+ GNU DWARF Representation of GNU C Extensions to ANSI C
+ ------------------------------------------------------
+
+ The file dwarfout.c has been designed and implemented so as to provide
+ some reasonable DWARF representation for each and every declarative
+ construct which is accepted by the GNU C compiler.  Since the GNU C
+ compiler accepts a superset of ANSI C, this means that there are some
+ cases in which the DWARF information produced by GCC must take some
+ liberties in improvising DWARF representations for declarations which
+ are only valid in (extended) GNU C.
+
+ In particular, GNU C provides at least three significant extensions to
+ ANSI C when it comes to declarations.  These are (1) inline functions,
+ and (2) dynamic arrays, and (3) incomplete enum types.  (See the GCC
+ manual for more information on these GNU extensions to ANSI C.)  When
+ used, these GNU C extensions are represented (in the generated DWARF
+ output of GCC) in the most natural and intuitively obvious ways.
+
+ In the case of inline functions, the DWARF representation is exactly as
+ called for in the DWARF version 2 (draft) specification for an identical
+ function written in C++; i.e. we "reuse" the representation of inline
+ functions which has been defined for C++ to support this GNU C extension.
+
+ In the case of dynamic arrays, we use the most obvious representational
+ mechanism available; i.e. an array type in which the upper bound of
+ some dimension (usually the first and only dimension) is a variable
+ rather than a constant.  (See the DWARF version 1 specification for more
+ details.)
+
+ In the case of incomplete enum types, such types are represented simply
+ as TAG_enumeration_type DIEs which DO NOT contain either AT_byte_size
+ attributes or AT_element_list attributes.
+
+ --------------------------------
+
+
+ Future Directions
+ -----------------
+
+ The codes, formats, and other paraphernalia necessary to provide proper
+ support for symbolic debugging for the C++ language are still being worked
+ on by the UI/PLSIG.  The vast majority of the additions to DWARF which will
+ be needed to completely support C++ have already been hashed out and agreed
+ upon, but a few small issues (e.g. anonymous unions, access declarations)
+ are still being discussed.  Also, we in the PLSIG are still discussing
+ whether or not we need to do anything special for C++ templates.  (At this
+ time it is not yet clear whether we even need to do anything special for
+ these.) 
+
+ With regard to FORTRAN, the UI/PLSIG has defined what is believed to be a
+ complete and sufficient set of codes and rules for adequately representing
+ all of FORTRAN 77, and most of Fortran 90 in DWARF.  While some support for
+ this has been implemented in dwarfout.c, further implementation and testing
+ is needed.
+
+ GNU DWARF support for other languages (i.e. Pascal and Modula) is a moot
+ issue until there are GNU front-ends for these other languages.
+
+ As currently defined, DWARF only describes a (binary) language which can
+ be used to communicate symbolic debugging information from a compiler
+ through an assembler and a linker, to a debugger.  There is no clear
+ specification of what processing should be (or must be) done by the
+ assembler and/or the linker.  Fortunately, the role of the assembler
+ is easily inferred (by anyone knowledgeable about assemblers) just by
+ looking  at examples of assembly-level DWARF code.  Sadly though, the
+ allowable (or required) processing steps performed by a linker are
+ harder to infer and (perhaps) even harder to agree upon.  There are
+ several forms of very useful `post-processing' steps which intelligent
+ linkers *could* (in theory) perform on object files containing DWARF,
+ but any and all such link-time transformations are currently both disallowed
+ and unspecified.
+
+ In particular, possible link-time transformations of DWARF code which could
+ provide significant benefits include (but are not limited to):
+
+        Commonization of duplicate DIEs obtained from multiple input
+        (object) files.
+
+        Cross-compilation type checking based upon DWARF type information
+        for objects and functions.
+
+        Other possible `compacting' transformations designed to save disk
+        space and to reduce linker & debugger I/O activity.
+
+*/  
 
 #include "config.h"
 
@@ -32,12 +574,9 @@ Boston, MA 02111-1307, USA.  */
 #include "insn-config.h"
 #include "reload.h"
 #include "output.h"
-#include "dwarfout.h"
 #include "toplev.h"
 #include "tm_p.h"
-
-/* IMPORTANT NOTE: Please see the file README.DWARF for important details
-   regarding the GNU implementation of Dwarf.  */
+#include "debug.h"
 
 /* NOTE: In the comments in this file, many references are made to
    so called "Debugging Information Entries".  For the sake of brevity,
@@ -244,6 +783,24 @@ static int in_class;
 
 /* Forward declarations for functions defined in this file.  */
 
+static void dwarfout_init              PARAMS ((const char *));
+static void dwarfout_finish            PARAMS ((const char *));
+static void dwarfout_define            PARAMS ((unsigned int, const char *));
+static void dwarfout_undef             PARAMS ((unsigned int, const char *));
+static void dwarfout_start_source_file PARAMS ((unsigned, const char *));
+static void dwarfout_start_source_file_check PARAMS ((unsigned, const char *));
+static void dwarfout_end_source_file   PARAMS ((unsigned));
+static void dwarfout_end_source_file_check PARAMS ((unsigned));
+static void dwarfout_begin_block       PARAMS ((unsigned, unsigned));
+static void dwarfout_end_block         PARAMS ((unsigned, unsigned));
+static void dwarfout_end_epilogue      PARAMS ((void));
+static void dwarfout_source_line       PARAMS ((unsigned int, const char *));
+static void dwarfout_end_prologue      PARAMS ((unsigned int));
+static void dwarfout_end_function      PARAMS ((unsigned int));
+static void dwarfout_function_decl     PARAMS ((tree));
+static void dwarfout_global_decl       PARAMS ((tree));
+static void dwarfout_deferred_inline_function  PARAMS ((tree));
+static void dwarfout_file_scope_decl   PARAMS ((tree , int));
 static const char *dwarf_tag_name      PARAMS ((unsigned));
 static const char *dwarf_attr_name     PARAMS ((unsigned));
 static const char *dwarf_stack_op_name PARAMS ((unsigned));
@@ -391,15 +948,6 @@ static void retry_incomplete_types PARAMS ((void));
 #ifndef VERSION_ASM_OP
 #define VERSION_ASM_OP         "\t.version\t"
 #endif
-#ifndef UNALIGNED_SHORT_ASM_OP
-#define UNALIGNED_SHORT_ASM_OP "\t.2byte\t"
-#endif
-#ifndef UNALIGNED_INT_ASM_OP
-#define UNALIGNED_INT_ASM_OP   "\t.4byte\t"
-#endif
-#ifndef ASM_BYTE_OP
-#define ASM_BYTE_OP            "\t.byte\t"
-#endif
 #ifndef SET_ASM_OP
 #define SET_ASM_OP             "\t.set\t"
 #endif
@@ -434,38 +982,38 @@ static void retry_incomplete_types        PARAMS ((void));
 #ifndef LINE_SECTION
 #define LINE_SECTION           ".line"
 #endif
-#ifndef SFNAMES_SECTION
-#define SFNAMES_SECTION                ".debug_sfnames"
+#ifndef DEBUG_SFNAMES_SECTION
+#define DEBUG_SFNAMES_SECTION  ".debug_sfnames"
 #endif
-#ifndef SRCINFO_SECTION
-#define SRCINFO_SECTION                ".debug_srcinfo"
+#ifndef DEBUG_SRCINFO_SECTION
+#define DEBUG_SRCINFO_SECTION  ".debug_srcinfo"
 #endif
-#ifndef MACINFO_SECTION
-#define MACINFO_SECTION                ".debug_macinfo"
+#ifndef DEBUG_MACINFO_SECTION
+#define DEBUG_MACINFO_SECTION  ".debug_macinfo"
 #endif
-#ifndef PUBNAMES_SECTION
-#define PUBNAMES_SECTION       ".debug_pubnames"
+#ifndef DEBUG_PUBNAMES_SECTION
+#define DEBUG_PUBNAMES_SECTION ".debug_pubnames"
 #endif
-#ifndef ARANGES_SECTION
-#define ARANGES_SECTION                ".debug_aranges"
+#ifndef DEBUG_ARANGES_SECTION
+#define DEBUG_ARANGES_SECTION  ".debug_aranges"
 #endif
-#ifndef TEXT_SECTION
-#define TEXT_SECTION           ".text"
+#ifndef TEXT_SECTION_NAME
+#define TEXT_SECTION_NAME      ".text"
 #endif
-#ifndef DATA_SECTION
-#define DATA_SECTION           ".data"
+#ifndef DATA_SECTION_NAME
+#define DATA_SECTION_NAME      ".data"
 #endif
-#ifndef DATA1_SECTION
-#define DATA1_SECTION          ".data1"
+#ifndef DATA1_SECTION_NAME
+#define DATA1_SECTION_NAME     ".data1"
 #endif
-#ifndef RODATA_SECTION
-#define RODATA_SECTION         ".rodata"
+#ifndef RODATA_SECTION_NAME
+#define RODATA_SECTION_NAME    ".rodata"
 #endif
-#ifndef RODATA1_SECTION
-#define RODATA1_SECTION                ".rodata1"
+#ifndef RODATA1_SECTION_NAME
+#define RODATA1_SECTION_NAME   ".rodata1"
 #endif
-#ifndef BSS_SECTION
-#define BSS_SECTION            ".bss"
+#ifndef BSS_SECTION_NAME
+#define BSS_SECTION_NAME       ".bss"
 #endif
 \f
 /* Definitions of defaults for formats and names of various special
@@ -551,6 +1099,13 @@ static void retry_incomplete_types        PARAMS ((void));
 #define MACINFO_BEGIN_LABEL    "*.L_macinfo_b"
 #endif
 
+#ifndef DEBUG_ARANGES_BEGIN_LABEL
+#define DEBUG_ARANGES_BEGIN_LABEL "*.L_debug_aranges_begin"
+#endif
+#ifndef DEBUG_ARANGES_END_LABEL
+#define DEBUG_ARANGES_END_LABEL "*.L_debug_aranges_end"
+#endif
+
 #ifndef DIE_BEGIN_LABEL_FMT
 #define DIE_BEGIN_LABEL_FMT    "*.L_D%u"
 #endif
@@ -809,18 +1364,43 @@ static void retry_incomplete_types       PARAMS ((void));
 #endif
 
 \f
+/* The debug hooks structure.  */
+struct gcc_debug_hooks dwarf_debug_hooks =
+{
+  dwarfout_init,
+  dwarfout_finish,
+  dwarfout_define,
+  dwarfout_undef,
+  dwarfout_start_source_file_check,
+  dwarfout_end_source_file_check,
+  dwarfout_begin_block,
+  dwarfout_end_block,
+  debug_true_tree,             /* ignore_block */
+  dwarfout_source_line,                /* source_line */
+  dwarfout_source_line,                /* begin_prologue */
+  dwarfout_end_prologue,
+  dwarfout_end_epilogue,
+  debug_nothing_tree,          /* begin_function */
+  dwarfout_end_function,
+  dwarfout_function_decl,
+  dwarfout_global_decl,
+  dwarfout_deferred_inline_function,
+  debug_nothing_tree,          /* outlining_inline_function */
+  debug_nothing_rtx            /* label */
+};
+\f
 /************************ general utility functions **************************/
 
-inline static int
+static inline int
 is_pseudo_reg (rtl)
      register rtx rtl;
 {
   return (((GET_CODE (rtl) == REG) && (REGNO (rtl) >= FIRST_PSEUDO_REGISTER))
           || ((GET_CODE (rtl) == SUBREG)
-             && (REGNO (XEXP (rtl, 0)) >= FIRST_PSEUDO_REGISTER)));
+             && (REGNO (SUBREG_REG (rtl)) >= FIRST_PSEUDO_REGISTER)));
 }
 
-inline static tree
+static inline tree
 type_main_variant (type)
      register tree type;
 {
@@ -842,7 +1422,7 @@ type_main_variant (type)
 
 /* Return non-zero if the given type node represents a tagged type.  */
 
-inline static int
+static inline int
 is_tagged_type (type)
      register tree type;
 {
@@ -1269,7 +1849,7 @@ fundamental_type_code (type)
            && DECL_NAME (TYPE_NAME (type)) != 0
            && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
          {
-           const char *name =
+           const char *const name =
              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
 
            if (!strcmp (name, "unsigned char"))
@@ -1328,7 +1908,7 @@ fundamental_type_code (type)
            && DECL_NAME (TYPE_NAME (type)) != 0
            && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
          {
-           const char *name =
+           const char *const name =
              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
 
            /* Note that here we can run afowl of a serious bug in "classic"
@@ -1630,7 +2210,7 @@ output_mem_loc_descriptor (rtl)
           legitimate to make the Dwarf info refer to the whole register
           which contains the given subreg.  */
 
-       rtl = XEXP (rtl, 0);
+       rtl = SUBREG_REG (rtl);
        /* Drop thru.  */
 
       case REG:
@@ -1714,7 +2294,7 @@ output_loc_descriptor (rtl)
           legitimate to make the Dwarf info refer to the whole register
           which contains the given subreg.  */
 
-       rtl = XEXP (rtl, 0);
+       rtl = SUBREG_REG (rtl);
        /* Drop thru.  */
 
     case REG:
@@ -1793,7 +2373,7 @@ output_bound_representation (bound, dim_num, u_or_l)
           comprehend that a missing upper bound specification in a
           array type used for a storage class `auto' local array variable
           indicates that the upper bound is both unknown (at compile-
-          time) and unknowable (at run-time) due to optimization. */
+          time) and unknowable (at run-time) due to optimization.  */
 
        if (! optimize)
          {
@@ -1995,7 +2575,7 @@ field_byte_offset (decl)
 
      The value we deduce is then used (by the callers of this routine) to
      generate AT_location and AT_bit_offset attributes for fields (both
-     bit-fields and, in the case of AT_location, regular fields as well). */
+     bit-fields and, in the case of AT_location, regular fields as well).  */
 
   /* Figure out the bit-distance from the start of the structure to the
      "deepest" bit of the bit-field.  */
@@ -4444,7 +5024,13 @@ output_type (type, containing_scope)
              for (func_member = TYPE_METHODS (type);
                   func_member;
                   func_member = TREE_CHAIN (func_member))
-               output_decl (func_member, type);
+               {
+                 /* Don't include clones in the member list.  */
+                 if (DECL_ABSTRACT_ORIGIN (func_member))
+                   continue;
+
+                 output_decl (func_member, type);
+               }
            }
 
            --in_class;
@@ -4654,7 +5240,7 @@ output_decls_for_scope (stmt, depth)
 
 /* Is this a typedef we can avoid emitting?  */
 
-inline static int
+static inline int
 is_redundant_typedef (decl)
      register tree decl;
 {
@@ -4735,7 +5321,7 @@ output_decl (decl, containing_scope)
 
       /* If we're emitting an out-of-line copy of an inline function,
         set up to refer to the abstract instance emitted from
-        note_deferral_of_defined_inline_function.  */
+        dwarfout_deferred_inline_function.  */
       if (DECL_INLINE (decl) && ! DECL_ABSTRACT (decl)
          && ! (containing_scope && TYPE_P (containing_scope)))
        set_decl_origin_self (decl);
@@ -5042,7 +5628,62 @@ output_decl (decl, containing_scope)
     }
 }
 \f
-void
+/* Output debug information for a function.  */
+static void
+dwarfout_function_decl (decl)
+     tree decl;
+{
+  dwarfout_file_scope_decl (decl, 0);
+}
+
+/* Debug information for a global DECL.  Called from toplev.c after
+   compilation proper has finished.  */
+static void
+dwarfout_global_decl (decl)
+     tree decl;
+{
+  /* Output DWARF information for file-scope tentative data object
+     declarations, file-scope (extern) function declarations (which
+     had no corresponding body) and file-scope tagged type
+     declarations and definitions which have not yet been forced out.  */
+
+  if (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))
+    dwarfout_file_scope_decl (decl, 1);
+}
+
+/* DECL is an inline function, whose body is present, but which is not
+   being output at this point.  (We're putting that off until we need
+   to do it.)  */
+static void
+dwarfout_deferred_inline_function (decl)
+     tree decl;
+{
+  /* Generate the DWARF info for the "abstract" instance of a function
+     which we may later generate inlined and/or out-of-line instances
+     of.  */
+  if ((DECL_INLINE (decl) || DECL_ABSTRACT (decl))
+      && ! DECL_ABSTRACT_ORIGIN (decl))
+    {
+      /* The front-end may not have set CURRENT_FUNCTION_DECL, but the
+        DWARF code expects it to be set in this case.  Intuitively,
+        DECL is the function we just finished defining, so setting
+        CURRENT_FUNCTION_DECL is sensible.  */
+      tree saved_cfd = current_function_decl;
+      int was_abstract = DECL_ABSTRACT (decl);
+      current_function_decl = decl;
+
+      /* Let the DWARF code do its work.  */
+      set_decl_abstract_flags (decl, 1);
+      dwarfout_file_scope_decl (decl, 0);
+      if (! was_abstract)
+       set_decl_abstract_flags (decl, 0);
+
+      /* Reset CURRENT_FUNCTION_DECL.  */
+      current_function_decl = saved_cfd;
+    }
+}
+
+static void
 dwarfout_file_scope_decl (decl, set_finalizing)
      register tree decl;
      register int set_finalizing;
@@ -5109,7 +5750,7 @@ dwarfout_file_scope_decl (decl, set_finalizing)
             defined in this compilation unit.  */
 
          fputc ('\n', asm_out_file);
-         ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
+         ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_PUBNAMES_SECTION);
          sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number);
          ASM_OUTPUT_DWARF_ADDR (asm_out_file, label);
          ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file,
@@ -5147,7 +5788,7 @@ dwarfout_file_scope_decl (decl, set_finalizing)
                 defined in this compilation unit.  */
 
              fputc ('\n', asm_out_file);
-             ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
+             ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_PUBNAMES_SECTION);
              sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number);
              ASM_OUTPUT_DWARF_ADDR (asm_out_file, label);
              ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file,
@@ -5161,7 +5802,7 @@ dwarfout_file_scope_decl (decl, set_finalizing)
                 which is tentatively defined in this compilation unit.  */
 
              fputc ('\n', asm_out_file);
-             ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION);
+             ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_ARANGES_SECTION);
              ASM_OUTPUT_DWARF_ADDR (asm_out_file,
                              IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
              ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 
@@ -5258,9 +5899,10 @@ dwarfout_file_scope_decl (decl, set_finalizing)
 /* Output a marker (i.e. a label) for the beginning of the generated code
    for a lexical block.         */
 
-void
-dwarfout_begin_block (blocknum)
-     register unsigned blocknum;
+static void
+dwarfout_begin_block (line, blocknum)
+     unsigned int line ATTRIBUTE_UNUSED;
+     unsigned int blocknum;
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
@@ -5272,9 +5914,10 @@ dwarfout_begin_block (blocknum)
 /* Output a marker (i.e. a label) for the end of the generated code
    for a lexical block.         */
 
-void
-dwarfout_end_block (blocknum)
-     register unsigned blocknum;
+static void
+dwarfout_end_block (line, blocknum)
+     unsigned int line ATTRIBUTE_UNUSED;
+     unsigned int blocknum;
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
@@ -5287,13 +5930,15 @@ dwarfout_end_block (blocknum)
    the real body of the function begins (after parameters have been moved
    to their home locations).  */
 
-void
-dwarfout_begin_function ()
+static void
+dwarfout_end_prologue (line)
+     unsigned int line ATTRIBUTE_UNUSED;
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
   if (! use_gnu_debug_info_extensions)
     return;
+
   function_section (current_function_decl);
   sprintf (label, BODY_BEGIN_LABEL_FMT, current_funcdef_number);
   ASM_OUTPUT_LABEL (asm_out_file, label);
@@ -5302,8 +5947,9 @@ dwarfout_begin_function ()
 /* Output a marker (i.e. a label) for the point in the generated code where
    the real body of the function ends (just before the epilogue code).  */
 
-void
-dwarfout_end_function ()
+static void
+dwarfout_end_function (line)
+     unsigned int line ATTRIBUTE_UNUSED;
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
@@ -5318,7 +5964,7 @@ dwarfout_end_function ()
    for a function definition.  This gets called *after* the epilogue code
    has been generated. */
 
-void
+static void
 dwarfout_end_epilogue ()
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -5362,7 +6008,7 @@ generate_new_sfname_entry ()
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, SFNAMES_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SFNAMES_SECTION);
   sprintf (label, SFNAMES_ENTRY_LABEL_FMT, filename_table[0].number);
   ASM_OUTPUT_LABEL (asm_out_file, label);
   ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file,
@@ -5462,7 +6108,7 @@ generate_srcinfo_entry (line_entry_num, files_entry_num)
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, SRCINFO_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SRCINFO_SECTION);
   sprintf (label, LINE_ENTRY_LABEL_FMT, line_entry_num);
   ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, LINE_BEGIN_LABEL);
   sprintf (label, SFNAMES_ENTRY_LABEL_FMT, files_entry_num);
@@ -5470,10 +6116,10 @@ generate_srcinfo_entry (line_entry_num, files_entry_num)
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 }
 
-void
-dwarfout_line (filename, line)
-     register const char *filename;
-     register unsigned line;
+static void
+dwarfout_source_line (line, filename)
+     unsigned int line;
+     const char *filename;
 {
   if (debug_info_level >= DINFO_LEVEL_NORMAL
       /* We can't emit line number info for functions in separate sections,
@@ -5536,14 +6182,25 @@ generate_macinfo_entry (type_and_offset, string)
     return;
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_MACINFO_SECTION);
   fprintf (asm_out_file, "%s%s\n", UNALIGNED_INT_ASM_OP, type_and_offset);
   ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, string);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 }
 
-void
-dwarfout_start_new_source_file (filename)
+/* Wrapper for toplev.c callback to check debug info level.  */
+static void
+dwarfout_start_source_file_check (line, filename)
+     unsigned int line;
+     register const char *filename;
+{
+  if (debug_info_level == DINFO_LEVEL_VERBOSE)
+    dwarfout_start_source_file (line, filename);
+}
+
+static void
+dwarfout_start_source_file (line, filename)
+     unsigned int line ATTRIBUTE_UNUSED;
      register const char *filename;
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -5558,8 +6215,17 @@ dwarfout_start_new_source_file (filename)
   generate_macinfo_entry (type_and_offset, "");
 }
 
-void
-dwarfout_resume_previous_source_file (lineno)
+/* Wrapper for toplev.c callback to check debug info level.  */
+static void
+dwarfout_end_source_file_check (lineno)
+     register unsigned lineno;
+{
+  if (debug_info_level == DINFO_LEVEL_VERBOSE)
+    dwarfout_end_source_file (lineno);
+}
+
+static void
+dwarfout_end_source_file (lineno)
      register unsigned lineno;
 {
   char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2];
@@ -5574,7 +6240,7 @@ dwarfout_resume_previous_source_file (lineno)
    is past the initial whitespace, #, whitespace, directive-name,
    whitespace part.  */
 
-void
+static void
 dwarfout_define (lineno, buffer)
      register unsigned lineno;
      register const char *buffer;
@@ -5584,7 +6250,7 @@ dwarfout_define (lineno, buffer)
 
   if (!initialized)
     {
-      dwarfout_start_new_source_file (primary_filename);
+      dwarfout_start_source_file (0, primary_filename);
       initialized = 1;
     }
   sprintf (type_and_offset, "0x%08x+%u",
@@ -5597,7 +6263,7 @@ dwarfout_define (lineno, buffer)
    is past the initial whitespace, #, whitespace, directive-name,
    whitespace part.  */
 
-void
+static void
 dwarfout_undef (lineno, buffer)
      register unsigned lineno;
      register const char *buffer;
@@ -5611,9 +6277,8 @@ dwarfout_undef (lineno, buffer)
 
 /* Set up for Dwarf output at the start of compilation.         */
 
-void
-dwarfout_init (asm_out_file, main_input_filename)
-     register FILE *asm_out_file;
+static void
+dwarfout_init (main_input_filename)
      register const char *main_input_filename;
 {
   /* Remember the name of the primary input file.  */
@@ -5652,14 +6317,14 @@ dwarfout_init (asm_out_file, main_input_filename)
   /* Output a starting label for the .text section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, TEXT_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, TEXT_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, TEXT_BEGIN_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 
   /* Output a starting label for the .data section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, DATA_BEGIN_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 
@@ -5667,7 +6332,7 @@ dwarfout_init (asm_out_file, main_input_filename)
   /* Output a starting label for the .data1 section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA1_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA1_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, DATA1_BEGIN_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 #endif
@@ -5675,7 +6340,7 @@ dwarfout_init (asm_out_file, main_input_filename)
   /* Output a starting label for the .rodata section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, RODATA_BEGIN_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 
@@ -5683,7 +6348,7 @@ dwarfout_init (asm_out_file, main_input_filename)
   /* Output a starting label for the .rodata1 section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA1_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA1_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, RODATA1_BEGIN_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 #endif
@@ -5691,7 +6356,7 @@ dwarfout_init (asm_out_file, main_input_filename)
   /* Output a starting label for the .bss section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, BSS_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, BSS_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, BSS_BEGIN_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 
@@ -5704,7 +6369,7 @@ dwarfout_init (asm_out_file, main_input_filename)
             referenced by the initial entry in the .debug_srcinfo section.  */
     
          fputc ('\n', asm_out_file);
-         ASM_OUTPUT_PUSH_SECTION (asm_out_file, SFNAMES_SECTION);
+         ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SFNAMES_SECTION);
          ASM_OUTPUT_LABEL (asm_out_file, SFNAMES_BEGIN_LABEL);
          {
            register const char *pwd = getpwd ();
@@ -5728,7 +6393,7 @@ dwarfout_init (asm_out_file, main_input_filename)
             TAG_compile_unit DIE.  */
         
           fputc ('\n', asm_out_file);
-          ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION);
+          ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_MACINFO_SECTION);
           ASM_OUTPUT_LABEL (asm_out_file, MACINFO_BEGIN_LABEL);
           ASM_OUTPUT_POP_SECTION (asm_out_file);
        }
@@ -5747,7 +6412,7 @@ dwarfout_init (asm_out_file, main_input_filename)
          /* Generate the initial entry for the .debug_srcinfo section.  */
 
          fputc ('\n', asm_out_file);
-         ASM_OUTPUT_PUSH_SECTION (asm_out_file, SRCINFO_SECTION);
+         ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SRCINFO_SECTION);
          ASM_OUTPUT_LABEL (asm_out_file, SRCINFO_BEGIN_LABEL);
          ASM_OUTPUT_DWARF_ADDR (asm_out_file, LINE_BEGIN_LABEL);
          ASM_OUTPUT_DWARF_ADDR (asm_out_file, SFNAMES_BEGIN_LABEL);
@@ -5764,14 +6429,19 @@ dwarfout_init (asm_out_file, main_input_filename)
       /* Generate the initial entry for the .debug_pubnames section.  */
     
       fputc ('\n', asm_out_file);
-      ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
+      ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_PUBNAMES_SECTION);
       ASM_OUTPUT_DWARF_ADDR (asm_out_file, DEBUG_BEGIN_LABEL);
       ASM_OUTPUT_POP_SECTION (asm_out_file);
     
       /* Generate the initial entry for the .debug_aranges section.  */
     
       fputc ('\n', asm_out_file);
-      ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION);
+      ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_ARANGES_SECTION);
+      ASM_OUTPUT_DWARF_DELTA4 (asm_out_file,
+                              DEBUG_ARANGES_END_LABEL,
+                              DEBUG_ARANGES_BEGIN_LABEL);
+      ASM_OUTPUT_LABEL (asm_out_file, DEBUG_ARANGES_BEGIN_LABEL);
+      ASM_OUTPUT_DWARF_DATA1 (asm_out_file, 1);
       ASM_OUTPUT_DWARF_ADDR (asm_out_file, DEBUG_BEGIN_LABEL);
       ASM_OUTPUT_POP_SECTION (asm_out_file);
     }
@@ -5788,7 +6458,7 @@ dwarfout_init (asm_out_file, main_input_filename)
   fputc ('\n', asm_out_file);
   ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION);
   ASM_OUTPUT_LABEL (asm_out_file, DEBUG_BEGIN_LABEL);
-  output_die (output_compile_unit_die, main_input_filename);
+  output_die (output_compile_unit_die, (PTR) main_input_filename);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 
   fputc ('\n', asm_out_file);
@@ -5796,8 +6466,9 @@ dwarfout_init (asm_out_file, main_input_filename)
 
 /* Output stuff that dwarf requires at the end of every file.  */
 
-void
-dwarfout_finish ()
+static void
+dwarfout_finish (main_input_filename)
+     register const char *main_input_filename ATTRIBUTE_UNUSED;
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
@@ -5843,14 +6514,14 @@ dwarfout_finish ()
   /* Output a terminator label for the .text section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, TEXT_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, TEXT_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, TEXT_END_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 
   /* Output a terminator label for the .data section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, DATA_END_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 
@@ -5858,7 +6529,7 @@ dwarfout_finish ()
   /* Output a terminator label for the .data1 section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA1_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA1_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, DATA1_END_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 #endif
@@ -5866,7 +6537,7 @@ dwarfout_finish ()
   /* Output a terminator label for the .rodata section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, RODATA_END_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 
@@ -5874,7 +6545,7 @@ dwarfout_finish ()
   /* Output a terminator label for the .rodata1 section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA1_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA1_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, RODATA1_END_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 #endif
@@ -5882,7 +6553,7 @@ dwarfout_finish ()
   /* Output a terminator label for the .bss section.  */
 
   fputc ('\n', asm_out_file);
-  ASM_OUTPUT_PUSH_SECTION (asm_out_file, BSS_SECTION);
+  ASM_OUTPUT_PUSH_SECTION (asm_out_file, BSS_SECTION_NAME);
   ASM_OUTPUT_LABEL (asm_out_file, BSS_END_LABEL);
   ASM_OUTPUT_POP_SECTION (asm_out_file);
 
@@ -5904,7 +6575,7 @@ dwarfout_finish ()
          /* Output a terminating entry for the .debug_srcinfo section.  */
 
          fputc ('\n', asm_out_file);
-         ASM_OUTPUT_PUSH_SECTION (asm_out_file, SRCINFO_SECTION);
+         ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SRCINFO_SECTION);
          ASM_OUTPUT_DWARF_DELTA4 (asm_out_file,
                                   LINE_LAST_ENTRY_LABEL, LINE_BEGIN_LABEL);
          ASM_OUTPUT_DWARF_DATA4 (asm_out_file, -1);
@@ -5915,10 +6586,10 @@ dwarfout_finish ()
        {
          /* Output terminating entries for the .debug_macinfo section.  */
        
-         dwarfout_resume_previous_source_file (0);
+         dwarfout_end_source_file (0);
 
          fputc ('\n', asm_out_file);
-         ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION);
+         ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_MACINFO_SECTION);
          ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
          ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
          ASM_OUTPUT_POP_SECTION (asm_out_file);
@@ -5927,7 +6598,7 @@ dwarfout_finish ()
       /* Generate the terminating entry for the .debug_pubnames section.  */
     
       fputc ('\n', asm_out_file);
-      ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
+      ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_PUBNAMES_SECTION);
       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
       ASM_OUTPUT_DWARF_STRING_NEWLINE (asm_out_file, "");
       ASM_OUTPUT_POP_SECTION (asm_out_file);
@@ -5947,7 +6618,7 @@ dwarfout_finish ()
       */
     
       fputc ('\n', asm_out_file);
-      ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION);
+      ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_ARANGES_SECTION);
 
       ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL);
       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, TEXT_END_LABEL, TEXT_BEGIN_LABEL);
@@ -5977,6 +6648,7 @@ dwarfout_finish ()
       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
 
+      ASM_OUTPUT_LABEL (asm_out_file, DEBUG_ARANGES_END_LABEL);
       ASM_OUTPUT_POP_SECTION (asm_out_file);
     }