summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/sdbout.c
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2007-05-19 01:19:51 +0000
committerkan <kan@FreeBSD.org>2007-05-19 01:19:51 +0000
commit1f9ea4d0a40cca64d60cf4dab152349da7b9dddf (patch)
tree0cb530c9c38af219e6dda2994c078b6b2b9ad853 /contrib/gcc/sdbout.c
parent4895159b2b4f648051c1f139faa7b6dc50c2bfcb (diff)
downloadFreeBSD-src-1f9ea4d0a40cca64d60cf4dab152349da7b9dddf.zip
FreeBSD-src-1f9ea4d0a40cca64d60cf4dab152349da7b9dddf.tar.gz
GCC 4.2.0 release.
Diffstat (limited to 'contrib/gcc/sdbout.c')
-rw-r--r--contrib/gcc/sdbout.c230
1 files changed, 119 insertions, 111 deletions
diff --git a/contrib/gcc/sdbout.c b/contrib/gcc/sdbout.c
index 3d62047..1868a81 100644
--- a/contrib/gcc/sdbout.c
+++ b/contrib/gcc/sdbout.c
@@ -1,6 +1,6 @@
/* Output sdb-format symbol table information from GNU compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
@@ -16,8 +16,8 @@ for more details.
You should have received a copy of the GNU General Public License
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. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
/* mike@tredysvr.Tredydev.Unisys.COM says:
I modified the struct.c example and have a nm of a .o resulting from the
@@ -48,17 +48,25 @@ AT&T C compiler. From the example below I would conclude the following:
#include "debug.h"
#include "tree.h"
#include "ggc.h"
+#include "varray.h"
static GTY(()) tree anonymous_types;
-/* Counter for sdbout_source_line. */
-
-static GTY(()) int sdbout_source_line_counter;
-
/* Counter to generate unique "names" for nameless struct members. */
static GTY(()) int unnamed_struct_number;
+/* Declarations whose debug info was deferred till end of compilation. */
+
+static GTY(()) varray_type deferred_global_decls;
+
+/* The C front end may call sdbout_symbol before sdbout_init runs.
+ We save all such decls in this list and output them when we get
+ to sdbout_init. */
+
+static GTY(()) tree preinit_symbols;
+static GTY(()) bool sdbout_initialized;
+
#ifdef SDB_DEBUGGING_INFO
#include "rtl.h"
@@ -76,7 +84,7 @@ static GTY(()) int unnamed_struct_number;
/* 1 if PARM is passed to this function in memory. */
#define PARM_PASSED_IN_MEMORY(PARM) \
- (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM)
+ (MEM_P (DECL_INCOMING_RTL (PARM)))
/* A C expression for the integer offset value of an automatic variable
(C_AUTO) having address X (an RTX). */
@@ -244,11 +252,6 @@ do { fprintf (asm_out_file, "\t.tag\t"); \
SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
#endif
-#ifndef SDB_GENERATE_FAKE
-#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
- sprintf ((BUFFER), ".%dfake", (NUMBER));
-#endif
-
/* Return the sdb tag identifier string for TYPE
if TYPE has already been defined; otherwise return a null pointer. */
@@ -280,11 +283,6 @@ do { fprintf (asm_out_file, "\t.tag\t"); \
#ifdef MIPS_DEBUGGING_INFO
-#ifndef PUT_SDB_SRC_FILE
-#define PUT_SDB_SRC_FILE(FILENAME) \
-output_file_directive (asm_out_file, (FILENAME))
-#endif
-
/* ECOFF linkers have an optimization that does the same kind of thing as
N_BINCL/E_INCL in stabs: eliminate duplicate debug information in the
executable. To achieve this, GCC must output a .file for each file
@@ -307,34 +305,39 @@ static struct sdb_file *current_file;
/* The debug hooks structure. */
const struct gcc_debug_hooks sdb_debug_hooks =
{
- sdbout_init, /* init */
- sdbout_finish, /* finish */
- debug_nothing_int_charstar, /* define */
- debug_nothing_int_charstar, /* undef */
- sdbout_start_source_file, /* start_source_file */
- sdbout_end_source_file, /* end_source_file */
- sdbout_begin_block, /* begin_block */
- sdbout_end_block, /* end_block */
- debug_true_tree, /* ignore_block */
- sdbout_source_line, /* source_line */
+ sdbout_init, /* init */
+ sdbout_finish, /* finish */
+ debug_nothing_int_charstar, /* define */
+ debug_nothing_int_charstar, /* undef */
+ sdbout_start_source_file, /* start_source_file */
+ sdbout_end_source_file, /* end_source_file */
+ sdbout_begin_block, /* begin_block */
+ sdbout_end_block, /* end_block */
+ debug_true_tree, /* ignore_block */
+ sdbout_source_line, /* source_line */
#ifdef MIPS_DEBUGGING_INFO
/* Defer on MIPS systems so that parameter descriptions follow
function entry. */
- debug_nothing_int_charstar, /* begin_prologue */
- sdbout_end_prologue, /* end_prologue */
+ debug_nothing_int_charstar, /* begin_prologue */
+ sdbout_end_prologue, /* end_prologue */
#else
- sdbout_begin_prologue, /* begin_prologue */
- debug_nothing_int_charstar, /* end_prologue */
+ sdbout_begin_prologue, /* begin_prologue */
+ debug_nothing_int_charstar, /* end_prologue */
#endif
- sdbout_end_epilogue, /* end_epilogue */
- sdbout_begin_function, /* begin_function */
- sdbout_end_function, /* end_function */
- debug_nothing_tree, /* function_decl */
- sdbout_global_decl, /* global_decl */
- debug_nothing_tree, /* deferred_inline_function */
- debug_nothing_tree, /* outlining_inline_function */
- sdbout_label, /* label */
- debug_nothing_int /* handle_pch */
+ sdbout_end_epilogue, /* end_epilogue */
+ sdbout_begin_function, /* begin_function */
+ sdbout_end_function, /* end_function */
+ debug_nothing_tree, /* function_decl */
+ sdbout_global_decl, /* global_decl */
+ sdbout_symbol, /* type_decl */
+ debug_nothing_tree_tree, /* imported_module_or_decl */
+ debug_nothing_tree, /* deferred_inline_function */
+ debug_nothing_tree, /* outlining_inline_function */
+ sdbout_label, /* label */
+ debug_nothing_int, /* handle_pch */
+ debug_nothing_rtx, /* var_location */
+ debug_nothing_void, /* switch_text_section */
+ 0 /* start_end_main_source_file */
};
/* Return a unique string to name an anonymous type. */
@@ -344,7 +347,7 @@ gen_fake_label (void)
{
char label[10];
char *labelstr;
- SDB_GENERATE_FAKE (label, unnamed_struct_number);
+ sprintf (label, ".%dfake", unnamed_struct_number);
unnamed_struct_number++;
labelstr = xstrdup (label);
return labelstr;
@@ -523,15 +526,15 @@ plain_type_1 (tree type, int level)
}
if (size == INT_TYPE_SIZE)
- return (TREE_UNSIGNED (type) ? T_UINT : T_INT);
+ return (TYPE_UNSIGNED (type) ? T_UINT : T_INT);
if (size == CHAR_TYPE_SIZE)
- return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
+ return (TYPE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
if (size == SHORT_TYPE_SIZE)
- return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT);
+ return (TYPE_UNSIGNED (type) ? T_USHORT : T_SHORT);
if (size == LONG_TYPE_SIZE)
- return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
+ return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
if (size == LONG_LONG_TYPE_SIZE) /* better than nothing */
- return (TREE_UNSIGNED (type) ? T_ULONG : T_LONG);
+ return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
return 0;
}
@@ -691,6 +694,14 @@ sdbout_symbol (tree decl, int local)
int regno = -1;
const char *name;
+ /* If we are called before sdbout_init is run, just save the symbol
+ for later. */
+ if (!sdbout_initialized)
+ {
+ preinit_symbols = tree_cons (0, decl, preinit_symbols);
+ return;
+ }
+
sdbout_one_type (type);
switch (TREE_CODE (decl))
@@ -709,7 +720,7 @@ sdbout_symbol (tree decl, int local)
a DECL_INITIAL value of 0. */
if (! DECL_INITIAL (decl))
return;
- if (GET_CODE (DECL_RTL (decl)) != MEM
+ if (!MEM_P (DECL_RTL (decl))
|| GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
return;
PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
@@ -723,6 +734,11 @@ sdbout_symbol (tree decl, int local)
return;
if (DECL_IGNORED_P (decl))
return;
+ /* Don't output intrinsic types. GAS chokes on SDB .def
+ statements that contain identifiers with embedded spaces
+ (eg "unsigned long"). */
+ if (DECL_IS_BUILTIN (decl))
+ return;
/* Output typedef name. */
if (template_name_p (DECL_NAME (decl)))
@@ -735,7 +751,7 @@ sdbout_symbol (tree decl, int local)
case PARM_DECL:
/* Parm decls go in their own separate chains
and are output by sdbout_reg_parms and sdbout_parms. */
- abort ();
+ gcc_unreachable ();
case VAR_DECL:
/* Don't mention a variable that is external.
@@ -767,7 +783,7 @@ sdbout_symbol (tree decl, int local)
If DECL was from an inline function, then its rtl
is not identically the rtl that was used in this
particular compilation. */
- if (GET_CODE (value) == REG)
+ if (REG_P (value))
{
regno = REGNO (value);
if (regno >= FIRST_PSEUDO_REGISTER)
@@ -777,7 +793,7 @@ sdbout_symbol (tree decl, int local)
{
while (GET_CODE (value) == SUBREG)
value = SUBREG_REG (value);
- if (GET_CODE (value) == REG)
+ if (REG_P (value))
{
if (REGNO (value) >= FIRST_PSEUDO_REGISTER)
return;
@@ -788,7 +804,7 @@ sdbout_symbol (tree decl, int local)
/* Don't output anything if an auto variable
gets RTL that is static.
GAS version 2.2 can't handle such output. */
- else if (GET_CODE (value) == MEM && CONSTANT_P (XEXP (value, 0))
+ else if (MEM_P (value) && CONSTANT_P (XEXP (value, 0))
&& ! TREE_STATIC (decl))
return;
@@ -807,7 +823,7 @@ sdbout_symbol (tree decl, int local)
/* Defer SDB information for top-level initialized variables! */
if (! local
- && GET_CODE (value) == MEM
+ && MEM_P (value)
&& DECL_INITIAL (decl))
return;
@@ -822,7 +838,7 @@ sdbout_symbol (tree decl, int local)
else
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- if (GET_CODE (value) == MEM
+ if (MEM_P (value)
&& GET_CODE (XEXP (value, 0)) == SYMBOL_REF)
{
PUT_SDB_DEF (name);
@@ -843,9 +859,9 @@ sdbout_symbol (tree decl, int local)
PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno));
PUT_SDB_SCL (C_REG);
}
- else if (GET_CODE (value) == MEM
- && (GET_CODE (XEXP (value, 0)) == MEM
- || (GET_CODE (XEXP (value, 0)) == REG
+ else if (MEM_P (value)
+ && (MEM_P (XEXP (value, 0))
+ || (REG_P (XEXP (value, 0))
&& REGNO (XEXP (value, 0)) != HARD_FRAME_POINTER_REGNUM
&& REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM)))
/* If the value is indirect by memory or by a register
@@ -855,7 +871,7 @@ sdbout_symbol (tree decl, int local)
so all we can do is output the variable as a pointer. */
{
PUT_SDB_DEF (name);
- if (GET_CODE (XEXP (value, 0)) == REG)
+ if (REG_P (XEXP (value, 0)))
{
PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0))));
PUT_SDB_SCL (C_REG);
@@ -878,14 +894,14 @@ sdbout_symbol (tree decl, int local)
type = make_node (POINTER_TYPE);
TREE_TYPE (type) = TREE_TYPE (decl);
}
- else if (GET_CODE (value) == MEM
+ else if (MEM_P (value)
&& ((GET_CODE (XEXP (value, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
+ && REG_P (XEXP (XEXP (value, 0), 0))
&& GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT)
/* This is for variables which are at offset zero from
the frame pointer. This happens on the Alpha.
Non-frame pointer registers are excluded above. */
- || (GET_CODE (XEXP (value, 0)) == REG)))
+ || (REG_P (XEXP (value, 0)))))
{
/* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
or (MEM (REG...)). We want the value of that CONST_INT
@@ -919,10 +935,9 @@ sdbout_toplevel_data (tree decl)
if (DECL_IGNORED_P (decl))
return;
- if (! (TREE_CODE (decl) == VAR_DECL
- && GET_CODE (DECL_RTL (decl)) == MEM
- && DECL_INITIAL (decl)))
- abort ();
+ gcc_assert (TREE_CODE (decl) == VAR_DECL);
+ gcc_assert (MEM_P (DECL_RTL (decl)));
+ gcc_assert (DECL_INITIAL (decl));
PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
@@ -1035,7 +1050,7 @@ sdbout_one_type (tree type)
&& DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
; /* Don't change section amid function. */
else
- text_section ();
+ switch_to_section (text_section);
switch (TREE_CODE (type))
{
@@ -1086,7 +1101,6 @@ sdbout_one_type (tree type)
int size = int_size_in_bytes (type);
int member_scl = 0;
tree tem;
- int i, n_baseclasses = 0;
/* Record the type tag, but not in its permanent place just yet. */
sdbout_record_type_name (type);
@@ -1126,17 +1140,17 @@ sdbout_one_type (tree type)
/* This is only relevant to aggregate types. TYPE_BINFO is used
for other purposes in an ENUMERAL_TYPE, so we must exclude that
case. */
- if (TREE_CODE (type) != ENUMERAL_TYPE)
+ if (TREE_CODE (type) != ENUMERAL_TYPE && TYPE_BINFO (type))
{
- if (TYPE_BINFO (type)
- && TYPE_BINFO_BASETYPES (type))
- n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
- for (i = 0; i < n_baseclasses; i++)
+ int i;
+ tree binfo, child;
+
+ for (binfo = TYPE_BINFO (type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, child); i++)
{
- tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)),
- i);
tree child_type = BINFO_TYPE (child);
tree child_type_name;
+
if (TYPE_NAME (child_type) == 0)
continue;
if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
@@ -1163,7 +1177,7 @@ sdbout_one_type (tree type)
if (TREE_CODE (type) == ENUMERAL_TYPE)
{
- for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
+ for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
if (host_integerp (TREE_VALUE (tem), 0))
{
PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
@@ -1268,7 +1282,7 @@ sdbout_parms (tree parms)
else
current_sym_value = 0;
- if (GET_CODE (DECL_RTL (parms)) == REG
+ if (REG_P (DECL_RTL (parms))
&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
type = DECL_ARG_TYPE (parms);
else
@@ -1287,7 +1301,7 @@ sdbout_parms (tree parms)
(GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
- GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
- if (GET_CODE (DECL_RTL (parms)) == MEM
+ if (MEM_P (DECL_RTL (parms))
&& GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
&& (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1))
== CONST_INT)
@@ -1307,7 +1321,7 @@ sdbout_parms (tree parms)
PUT_SDB_TYPE (plain_type (type));
PUT_SDB_ENDEF;
}
- else if (GET_CODE (DECL_RTL (parms)) == REG)
+ else if (REG_P (DECL_RTL (parms)))
{
rtx best_rtl;
/* Parm passed in registers and lives in registers or nowhere. */
@@ -1329,7 +1343,7 @@ sdbout_parms (tree parms)
PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
PUT_SDB_ENDEF;
}
- else if (GET_CODE (DECL_RTL (parms)) == MEM
+ else if (MEM_P (DECL_RTL (parms))
&& XEXP (DECL_RTL (parms), 0) != const0_rtx)
{
/* Parm was passed in registers but lives on the stack. */
@@ -1338,8 +1352,8 @@ sdbout_parms (tree parms)
in which case we want the value of that CONST_INT,
or (MEM (REG ...)) or (MEM (MEM ...)),
in which case we use a value of zero. */
- if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG
- || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM)
+ if (REG_P (XEXP (DECL_RTL (parms), 0))
+ || MEM_P (XEXP (DECL_RTL (parms), 0)))
current_sym_value = 0;
else
current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
@@ -1376,7 +1390,7 @@ sdbout_reg_parms (tree parms)
/* Report parms that live in registers during the function
but were passed in memory. */
- if (GET_CODE (DECL_RTL (parms)) == REG
+ if (REG_P (DECL_RTL (parms))
&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
&& PARM_PASSED_IN_MEMORY (parms))
{
@@ -1389,7 +1403,7 @@ sdbout_reg_parms (tree parms)
PUT_SDB_ENDEF;
}
/* Report parms that live in memory but not where they were passed. */
- else if (GET_CODE (DECL_RTL (parms)) == MEM
+ else if (MEM_P (DECL_RTL (parms))
&& GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
&& GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
&& PARM_PASSED_IN_MEMORY (parms)
@@ -1436,10 +1450,12 @@ sdbout_global_decl (tree decl)
sdbout_finish (). */
if (!DECL_INITIAL (decl) || !TREE_PUBLIC (decl))
sdbout_symbol (decl, 0);
+ else
+ VARRAY_PUSH_TREE (deferred_global_decls, decl);
/* Output COFF information for non-global file-scope initialized
variables. */
- if (DECL_INITIAL (decl) && GET_CODE (DECL_RTL (decl)) == MEM)
+ if (DECL_INITIAL (decl) && MEM_P (DECL_RTL (decl)))
sdbout_toplevel_data (decl);
}
}
@@ -1450,29 +1466,10 @@ sdbout_global_decl (tree decl)
static void
sdbout_finish (const char *main_filename ATTRIBUTE_UNUSED)
{
- tree decl = (*lang_hooks.decls.getdecls) ();
- unsigned int len = list_length (decl);
- tree *vec = xmalloc (sizeof (tree) * len);
- unsigned int i;
-
- /* Process the decls in reverse order--earliest first. Put them
- into VEC from back to front, then take out from front. */
+ size_t i;
- for (i = 0; i < len; i++, decl = TREE_CHAIN (decl))
- vec[len - i - 1] = decl;
-
- for (i = 0; i < len; i++)
- {
- decl = vec[i];
- if (TREE_CODE (decl) == VAR_DECL
- && ! DECL_EXTERNAL (decl)
- && DECL_INITIAL (decl)
- && TREE_PUBLIC (decl)
- && DECL_RTL_SET_P (decl))
- sdbout_symbol (decl, 0);
- }
-
- free (vec);
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_global_decls); i++)
+ sdbout_symbol (VARRAY_TREE (deferred_global_decls, i), 0);
}
/* Describe the beginning of an internal block within a function.
@@ -1541,9 +1538,8 @@ sdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED)
/* COFF relative line numbers must be positive. */
if ((int) line > sdb_begin_function_line)
{
-#ifdef ASM_OUTPUT_SOURCE_LINE
- sdbout_source_line_counter += 1;
- ASM_OUTPUT_SOURCE_LINE (asm_out_file, line, sdbout_source_line_counter);
+#ifdef SDB_OUTPUT_SOURCE_LINE
+ SDB_OUTPUT_SOURCE_LINE (asm_out_file, line);
#else
fprintf (asm_out_file, "\t.ln\t%d\n",
((sdb_begin_function_line > -1)
@@ -1646,7 +1642,7 @@ sdbout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
n->next = current_file;
n->name = filename;
current_file = n;
- PUT_SDB_SRC_FILE (filename);
+ output_file_directive (asm_out_file, filename);
#endif
}
@@ -1661,7 +1657,7 @@ sdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
next = current_file->next;
free (current_file);
current_file = next;
- PUT_SDB_SRC_FILE (current_file->name);
+ output_file_directive (asm_out_file, current_file->name);
#endif
}
@@ -1670,11 +1666,23 @@ sdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
static void
sdbout_init (const char *input_file_name ATTRIBUTE_UNUSED)
{
+ tree t;
+
#ifdef MIPS_DEBUGGING_INFO
current_file = xmalloc (sizeof *current_file);
current_file->next = NULL;
current_file->name = input_file_name;
#endif
+
+ VARRAY_TREE_INIT (deferred_global_decls, 12, "deferred_global_decls");
+
+ /* Emit debug information which was queued by sdbout_symbol before
+ we got here. */
+ sdbout_initialized = true;
+
+ for (t = nreverse (preinit_symbols); t; t = TREE_CHAIN (t))
+ sdbout_symbol (TREE_VALUE (t), 0);
+ preinit_symbols = 0;
}
#else /* SDB_DEBUGGING_INFO */
OpenPOWER on IntegriCloud