* 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:
parent
5317d6f945
commit
0788224594
|
@ -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
|
||||||
|
|
108
binutils/stabs.c
108
binutils/stabs.c
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue