aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1996-10-28 22:17:52 +0000
committerIan Lance Taylor <ian@airs.com>1996-10-28 22:17:52 +0000
commit07882245940db77eb343864330f652d3ec6a0d8a (patch)
treecc66d35c8e5e2b5ace2cef2ce3de27a6b6e17fad /binutils
parent5317d6f945f2d58c50b3dbed18c01ce7c25f43d1 (diff)
downloadgdb-07882245940db77eb343864330f652d3ec6a0d8a.zip
gdb-07882245940db77eb343864330f652d3ec6a0d8a.tar.gz
gdb-07882245940db77eb343864330f652d3ec6a0d8a.tar.bz2
* stabs.c (struct stab_handle): Add function_end field.
(start_stab): Initialize function_end. (finish_stab): Pass info->function_end to debug_end_function. (parse_stab): If info->function_end is set, use it as the address which ends a function.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog2
-rw-r--r--binutils/stabs.c108
2 files changed, 95 insertions, 15 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 57d3b36..aac48bc 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,7 @@
Mon Oct 28 16:58:14 1996 Ian Lance Taylor <ian@cygnus.com>
+ * ieee.c (ieee_array_type): Remember the correct size.
+
* ieee.c (ieee_finish_compilation_unit): Permit coalescing ranges
that are up to 0x1000 bytes apart, not just 64.
(ieee_add_bb11_blocks): Don't bother to emit a BB11 that is less
diff --git a/binutils/stabs.c b/binutils/stabs.c
index 59291dd..f931ff2 100644
--- a/binutils/stabs.c
+++ b/binutils/stabs.c
@@ -49,6 +49,8 @@
struct stab_handle
{
+ /* The BFD. */
+ bfd *abfd;
/* True if this is stabs in sections. */
boolean sections;
/* The symbol table. */
@@ -77,6 +79,10 @@ struct stab_handle
struct bincl_file *bincl_stack;
/* Whether we are inside a function or not. */
boolean within_function;
+ /* The address of the end of the function, used if we have seen an
+ N_FUN symbol while in a function. This is -1 if we have not seen
+ an N_FUN (the normal case). */
+ bfd_vma function_end;
/* The depth of block nesting. */
int block_depth;
/* List of pending variable definitions. */
@@ -346,8 +352,9 @@ warn_stab (p, err)
/*ARGSUSED*/
PTR
-start_stab (dhandle, sections, syms, symcount)
+start_stab (dhandle, abfd, sections, syms, symcount)
PTR dhandle;
+ bfd *abfd;
boolean sections;
asymbol **syms;
long symcount;
@@ -356,12 +363,14 @@ start_stab (dhandle, sections, syms, symcount)
ret = (struct stab_handle *) xmalloc (sizeof *ret);
memset (ret, 0, sizeof *ret);
+ ret->abfd = abfd;
ret->sections = sections;
ret->syms = syms;
ret->symcount = symcount;
ret->files = 1;
ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
ret->file_types[0] = NULL;
+ ret->function_end = (bfd_vma) -1;
return (PTR) ret;
}
@@ -379,9 +388,10 @@ finish_stab (dhandle, handle)
if (info->within_function)
{
if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, (bfd_vma) -1))
+ || ! debug_end_function (dhandle, info->function_end))
return false;
info->within_function = false;
+ info->function_end = (bfd_vma) -1;
}
for (st = info->tags; st != NULL; st = st->next)
@@ -505,10 +515,18 @@ parse_stab (dhandle, handle, type, desc, value, string)
/* This always ends a function. */
if (info->within_function)
{
+ bfd_vma endval;
+
+ endval = value;
+ if (*string != '\0'
+ && info->function_end != (bfd_vma) -1
+ && info->function_end < endval)
+ endval = info->function_end;
if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, value))
+ || ! debug_end_function (dhandle, endval))
return false;
info->within_function = false;
+ info->function_end = (bfd_vma) -1;
}
/* An empty string is emitted by gcc at the end of a compilation
@@ -584,10 +602,40 @@ parse_stab (dhandle, handle, type, desc, value, string)
return false;
break;
+ case N_FUN:
+ if (*string == '\0')
+ {
+ if (info->within_function)
+ {
+ /* This always marks the end of a function; we don't
+ need to worry about info->function_end. */
+ if (info->sections)
+ value += info->function_start_offset;
+ if (! stab_emit_pending_vars (dhandle, info)
+ || ! debug_end_function (dhandle, value))
+ return false;
+ info->within_function = false;
+ info->function_end = (bfd_vma) -1;
+ }
+ break;
+ }
+
+ /* A const static symbol in the .text section will have an N_FUN
+ entry. We need to use these to mark the end of the function,
+ in case we are looking at gcc output before it was changed to
+ always emit an empty N_FUN. We can't call debug_end_function
+ here, because it might be a local static symbol. */
+ if (info->within_function
+ && (info->function_end == (bfd_vma) -1
+ || value < info->function_end))
+ info->function_end = value;
+
+ /* Fall through. */
/* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM
symbols, and if it does not start with :S, gdb relocates the
value to the start of the section. gcc always seems to use
:S, so we don't worry about this. */
+ /* Fall through. */
default:
{
const char *colon;
@@ -598,9 +646,16 @@ parse_stab (dhandle, handle, type, desc, value, string)
{
if (info->within_function)
{
+ bfd_vma endval;
+
+ endval = value;
+ if (info->function_end != (bfd_vma) -1
+ && info->function_end < endval)
+ endval = info->function_end;
if (! stab_emit_pending_vars (dhandle, info)
- || ! debug_end_function (dhandle, value))
+ || ! debug_end_function (dhandle, endval))
return false;
+ info->function_end = (bfd_vma) -1;
}
/* For stabs in sections, line numbers and block addresses
are offsets from the start of the function. */
@@ -809,6 +864,7 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
case 'G':
{
+ char leading;
long c;
asymbol **ps;
@@ -818,11 +874,14 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
(debug_type **) NULL);
if (dtype == DEBUG_TYPE_NULL)
return false;
+ leading = bfd_get_symbol_leading_char (info->abfd);
for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
{
const char *n;
n = bfd_asymbol_name (*ps);
+ if (leading != '\0' && *n == leading)
+ ++n;
if (*n == *name && strcmp (n, name) == 0)
break;
}
@@ -2532,6 +2591,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
do
{
debug_type type;
+ boolean stub;
char *argtypes;
enum debug_visibility visibility;
boolean constp, volatilep, staticp;
@@ -2567,6 +2627,11 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
return false;
}
+ stub = false;
+ if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
+ && debug_get_parameter_types (dhandle, type, &varargs) == NULL)
+ stub = true;
+
argtypes = savestring (*pp, p - *pp);
*pp = p + 1;
@@ -2652,6 +2717,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
if (**pp == ':')
{
/* g++ version 1 overloaded methods. */
+ context = DEBUG_TYPE_NULL;
}
else
{
@@ -2673,6 +2739,8 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
staticp = true;
voffset = 0;
context = DEBUG_TYPE_NULL;
+ if (strncmp (argtypes, name, strlen (name)) != 0)
+ stub = true;
break;
default:
@@ -2688,15 +2756,12 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
break;
}
- /* If this is a method type which is not a stub--that is,
- the argument types are fully specified--then the argtypes
- string is actually the physical name of the function.
- Otherwise, the argtypes string is the mangled from of the
- argument types, and the physical name of the function,
- and the argument types, must be deduced from it. */
-
- if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
- && debug_get_parameter_types (dhandle, type, &varargs) != NULL)
+ /* If the type is not a stub, then the argtypes string is
+ the physical name of the function. Otherwise the
+ argtypes string is the mangled form of the argument
+ types, and the full type and the physical name must be
+ extracted from them. */
+ if (! stub)
physname = argtypes;
else
{
@@ -4209,7 +4274,7 @@ stab_demangle_template (minfo, pp)
done = true;
break;
default:
- /* Assume it's a uder defined integral type. */
+ /* Assume it's a user defined integral type. */
integralp = true;
done = true;
break;
@@ -4910,7 +4975,20 @@ stab_demangle_fund_type (minfo, pp, ptype)
case 't':
if (! stab_demangle_template (minfo, pp))
return false;
- abort ();
+ if (ptype != NULL)
+ {
+ debug_type t;
+
+ /* FIXME: I really don't know how a template should be
+ represented in the current type system. Perhaps the
+ template should be demangled into a string, and the type
+ should be represented as a named type. However, I don't
+ know what the base type of the named type should be. */
+ t = debug_make_void_type (minfo->dhandle);
+ t = debug_make_pointer_type (minfo->dhandle, t);
+ t = debug_name_type (minfo->dhandle, "TEMPLATE", t);
+ *ptype = t;
+ }
break;
default: