* 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.
This commit is contained in:
Ian Lance Taylor 1996-10-28 22:17:52 +00:00
parent 5317d6f945
commit 0788224594
2 changed files with 95 additions and 15 deletions

View File

@ -1,5 +1,7 @@
Mon Oct 28 16:58:14 1996 Ian Lance Taylor <ian@cygnus.com> 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 * ieee.c (ieee_finish_compilation_unit): Permit coalescing ranges
that are up to 0x1000 bytes apart, not just 64. that are up to 0x1000 bytes apart, not just 64.
(ieee_add_bb11_blocks): Don't bother to emit a BB11 that is less (ieee_add_bb11_blocks): Don't bother to emit a BB11 that is less

View File

@ -49,6 +49,8 @@
struct stab_handle struct stab_handle
{ {
/* The BFD. */
bfd *abfd;
/* True if this is stabs in sections. */ /* True if this is stabs in sections. */
boolean sections; boolean sections;
/* The symbol table. */ /* The symbol table. */
@ -77,6 +79,10 @@ struct stab_handle
struct bincl_file *bincl_stack; struct bincl_file *bincl_stack;
/* Whether we are inside a function or not. */ /* Whether we are inside a function or not. */
boolean within_function; 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. */ /* The depth of block nesting. */
int block_depth; int block_depth;
/* List of pending variable definitions. */ /* List of pending variable definitions. */
@ -346,8 +352,9 @@ warn_stab (p, err)
/*ARGSUSED*/ /*ARGSUSED*/
PTR PTR
start_stab (dhandle, sections, syms, symcount) start_stab (dhandle, abfd, sections, syms, symcount)
PTR dhandle; PTR dhandle;
bfd *abfd;
boolean sections; boolean sections;
asymbol **syms; asymbol **syms;
long symcount; long symcount;
@ -356,12 +363,14 @@ start_stab (dhandle, sections, syms, symcount)
ret = (struct stab_handle *) xmalloc (sizeof *ret); ret = (struct stab_handle *) xmalloc (sizeof *ret);
memset (ret, 0, sizeof *ret); memset (ret, 0, sizeof *ret);
ret->abfd = abfd;
ret->sections = sections; ret->sections = sections;
ret->syms = syms; ret->syms = syms;
ret->symcount = symcount; ret->symcount = symcount;
ret->files = 1; ret->files = 1;
ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types); ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types);
ret->file_types[0] = NULL; ret->file_types[0] = NULL;
ret->function_end = (bfd_vma) -1;
return (PTR) ret; return (PTR) ret;
} }
@ -379,9 +388,10 @@ finish_stab (dhandle, handle)
if (info->within_function) if (info->within_function)
{ {
if (! stab_emit_pending_vars (dhandle, info) if (! stab_emit_pending_vars (dhandle, info)
|| ! debug_end_function (dhandle, (bfd_vma) -1)) || ! debug_end_function (dhandle, info->function_end))
return false; return false;
info->within_function = false; info->within_function = false;
info->function_end = (bfd_vma) -1;
} }
for (st = info->tags; st != NULL; st = st->next) 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. */ /* This always ends a function. */
if (info->within_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) if (! stab_emit_pending_vars (dhandle, info)
|| ! debug_end_function (dhandle, value)) || ! debug_end_function (dhandle, endval))
return false; return false;
info->within_function = false; info->within_function = false;
info->function_end = (bfd_vma) -1;
} }
/* An empty string is emitted by gcc at the end of a compilation /* 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; return false;
break; 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 /* 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 symbols, and if it does not start with :S, gdb relocates the
value to the start of the section. gcc always seems to use value to the start of the section. gcc always seems to use
:S, so we don't worry about this. */ :S, so we don't worry about this. */
/* Fall through. */
default: default:
{ {
const char *colon; const char *colon;
@ -598,9 +646,16 @@ parse_stab (dhandle, handle, type, desc, value, string)
{ {
if (info->within_function) 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) if (! stab_emit_pending_vars (dhandle, info)
|| ! debug_end_function (dhandle, value)) || ! debug_end_function (dhandle, endval))
return false; return false;
info->function_end = (bfd_vma) -1;
} }
/* For stabs in sections, line numbers and block addresses /* For stabs in sections, line numbers and block addresses
are offsets from the start of the function. */ are offsets from the start of the function. */
@ -809,6 +864,7 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
case 'G': case 'G':
{ {
char leading;
long c; long c;
asymbol **ps; asymbol **ps;
@ -818,11 +874,14 @@ parse_stab_string (dhandle, info, stabtype, desc, value, string)
(debug_type **) NULL); (debug_type **) NULL);
if (dtype == DEBUG_TYPE_NULL) if (dtype == DEBUG_TYPE_NULL)
return false; return false;
leading = bfd_get_symbol_leading_char (info->abfd);
for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps) for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps)
{ {
const char *n; const char *n;
n = bfd_asymbol_name (*ps); n = bfd_asymbol_name (*ps);
if (leading != '\0' && *n == leading)
++n;
if (*n == *name && strcmp (n, name) == 0) if (*n == *name && strcmp (n, name) == 0)
break; break;
} }
@ -2532,6 +2591,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
do do
{ {
debug_type type; debug_type type;
boolean stub;
char *argtypes; char *argtypes;
enum debug_visibility visibility; enum debug_visibility visibility;
boolean constp, volatilep, staticp; boolean constp, volatilep, staticp;
@ -2567,6 +2627,11 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
return false; 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); argtypes = savestring (*pp, p - *pp);
*pp = p + 1; *pp = p + 1;
@ -2652,6 +2717,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
if (**pp == ':') if (**pp == ':')
{ {
/* g++ version 1 overloaded methods. */ /* g++ version 1 overloaded methods. */
context = DEBUG_TYPE_NULL;
} }
else else
{ {
@ -2673,6 +2739,8 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
staticp = true; staticp = true;
voffset = 0; voffset = 0;
context = DEBUG_TYPE_NULL; context = DEBUG_TYPE_NULL;
if (strncmp (argtypes, name, strlen (name)) != 0)
stub = true;
break; break;
default: default:
@ -2688,15 +2756,12 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp)
break; break;
} }
/* If this is a method type which is not a stub--that is, /* If the type is not a stub, then the argtypes string is
the argument types are fully specified--then the argtypes the physical name of the function. Otherwise the
string is actually the physical name of the function. argtypes string is the mangled form of the argument
Otherwise, the argtypes string is the mangled from of the types, and the full type and the physical name must be
argument types, and the physical name of the function, extracted from them. */
and the argument types, must be deduced from it. */ if (! stub)
if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD
&& debug_get_parameter_types (dhandle, type, &varargs) != NULL)
physname = argtypes; physname = argtypes;
else else
{ {
@ -4209,7 +4274,7 @@ stab_demangle_template (minfo, pp)
done = true; done = true;
break; break;
default: default:
/* Assume it's a uder defined integral type. */ /* Assume it's a user defined integral type. */
integralp = true; integralp = true;
done = true; done = true;
break; break;
@ -4910,7 +4975,20 @@ stab_demangle_fund_type (minfo, pp, ptype)
case 't': case 't':
if (! stab_demangle_template (minfo, pp)) if (! stab_demangle_template (minfo, pp))
return false; 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; break;
default: default: