/* Symbol table lookup for the GNU debugger, GDB.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GDB.
#include "source.h"
#include "filenames.h" /* for FILENAME_CMP */
#include "objc-lang.h"
+#include "ada-lang.h"
#include "hashtab.h"
#include "gdb_stat.h"
#include <ctype.h>
#include "cp-abi.h"
+#include "observer.h"
/* Prototypes for local functions */
static void sources_info (char *, int);
-static void output_source_filename (char *, int *);
+static void output_source_filename (const char *, int *);
static int find_line_common (struct linetable *, int, int *);
struct symtab **symtab);
#endif
-/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
-/* Signals the presence of objects compiled by HP compilers */
-int hp_som_som_object_present = 0;
+/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c.
+ Signals the presence of objects compiled by HP compilers. */
+int deprecated_hp_som_som_object_present = 0;
static void fixup_section (struct general_symbol_info *, struct objfile *);
if (full_path != NULL)
{
- const char *fp = symtab_to_filename (s);
- if (FILENAME_CMP (full_path, fp) == 0)
- {
- return s;
- }
+ const char *fp = symtab_to_fullname (s);
+ if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
+ {
+ return s;
+ }
}
if (real_path != NULL)
{
- char *rp = gdb_realpath (symtab_to_filename (s));
- make_cleanup (xfree, rp);
- if (FILENAME_CMP (real_path, rp) == 0)
- {
- return s;
- }
+ char *fullname = symtab_to_fullname (s);
+ if (fullname != NULL)
+ {
+ char *rp = gdb_realpath (fullname);
+ make_cleanup (xfree, rp);
+ if (FILENAME_CMP (real_path, rp) == 0)
+ {
+ return s;
+ }
+ }
}
}
return (NULL);
if (ps->readin)
- error ("Internal: readin %s pst for `%s' found when no symtab found.",
+ error (_("Internal: readin %s pst for `%s' found when no symtab found."),
ps->filename, name);
s = PSYMTAB_TO_SYMTAB (ps);
this symtab and use its absolute path. */
if (full_path != NULL)
{
- if (pst->fullname == NULL)
- source_full_path_of (pst->filename, &pst->fullname);
+ psymtab_to_fullname (pst);
if (pst->fullname != NULL
&& FILENAME_CMP (full_path, pst->fullname) == 0)
{
if (real_path != NULL)
{
char *rp = NULL;
- if (pst->fullname == NULL)
- source_full_path_of (pst->filename, &pst->fullname);
+ psymtab_to_fullname (pst);
if (pst->fullname != NULL)
{
rp = gdb_realpath (pst->fullname);
is_full_physname_constructor = is_constructor_name (physname);
is_constructor =
- is_full_physname_constructor || (newname && STREQ (field_name, newname));
+ is_full_physname_constructor || (newname && strcmp (field_name, newname) == 0);
if (!is_destructor)
is_destructor = (strncmp (physname, "__dt", 4) == 0);
Choosing a much larger table size wastes memory, and saves only about
1% in symbol reading. */
- objfile->demangled_names_hash = htab_create_alloc_ex
+ objfile->demangled_names_hash = htab_create_alloc
(256, htab_hash_string, (int (*) (const void *, const void *)) streq,
- NULL, objfile->md, xmcalloc, xmfree);
+ NULL, xcalloc, xfree);
}
/* Try to determine the demangled name for a symbol, based on the
/* Set both the mangled and demangled (if any) names for GSYMBOL based
on LINKAGE_NAME and LEN. The hash table corresponding to OBJFILE
- is used, and the memory comes from that objfile's symbol_obstack.
+ is used, and the memory comes from that objfile's objfile_obstack.
LINKAGE_NAME is copied, so the pointer can be discarded after
calling this function. */
/* If there is a demangled name, place it right after the mangled name.
Otherwise, just place a second zero byte after the end of the mangled
name. */
- *slot = obstack_alloc (&objfile->symbol_obstack,
+ *slot = obstack_alloc (&objfile->objfile_obstack,
lookup_len + demangled_len + 2);
memcpy (*slot, lookup_name, lookup_len + 1);
if (demangled_name != NULL)
char *
symbol_natural_name (const struct general_symbol_info *gsymbol)
{
- if ((gsymbol->language == language_cplus
- || gsymbol->language == language_java
- || gsymbol->language == language_objc)
- && (gsymbol->language_specific.cplus_specific.demangled_name != NULL))
- {
- return gsymbol->language_specific.cplus_specific.demangled_name;
- }
- else
+ switch (gsymbol->language)
{
- return gsymbol->name;
+ case language_cplus:
+ case language_java:
+ case language_objc:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ break;
+ case language_ada:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ else
+ return ada_decode_symbol (gsymbol);
+ break;
+ default:
+ break;
}
+ return gsymbol->name;
}
/* Return the demangled name for a symbol based on the language for
char *
symbol_demangled_name (struct general_symbol_info *gsymbol)
{
- if (gsymbol->language == language_cplus
- || gsymbol->language == language_java
- || gsymbol->language == language_objc)
- return gsymbol->language_specific.cplus_specific.demangled_name;
+ switch (gsymbol->language)
+ {
+ case language_cplus:
+ case language_java:
+ case language_objc:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ break;
+ case language_ada:
+ if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+ else
+ return ada_decode_symbol (gsymbol);
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
- else
- return NULL;
+/* Return the search name of a symbol---generally the demangled or
+ linkage name of the symbol, depending on how it will be searched for.
+ If there is no distinct demangled name, then returns the same value
+ (same pointer) as SYMBOL_LINKAGE_NAME. */
+char *
+symbol_search_name (const struct general_symbol_info *gsymbol)
+{
+ if (gsymbol->language == language_ada)
+ return gsymbol->name;
+ else
+ return symbol_natural_name (gsymbol);
}
/* Initialize the structure fields to zero values. */
\f
-/* Find which partial symtab on contains PC and SECTION. Return 0 if none. */
-
+/* Find which partial symtab contains PC and SECTION. Return 0 if
+ none. We return the psymtab that contains a symbol whose address
+ exactly matches PC, or, if we cannot find an exact match, the
+ psymtab that contains a symbol whose address is closest to PC. */
struct partial_symtab *
find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
{
if (pc >= pst->textlow && pc < pst->texthigh)
{
struct partial_symtab *tpst;
+ struct partial_symtab *best_pst = pst;
+ struct partial_symbol *best_psym = NULL;
/* An objfile that has its functions reordered might have
many partial symbol tables containing the PC, but
if (msymbol == NULL)
return (pst);
+ /* The code range of partial symtabs sometimes overlap, so, in
+ the loop below, we need to check all partial symtabs and
+ find the one that fits better for the given PC address. We
+ select the partial symtab that contains a symbol whose
+ address is closest to the PC address. By closest we mean
+ that find_pc_sect_symbol returns the symbol with address
+ that is closest and still less than the given PC. */
for (tpst = pst; tpst != NULL; tpst = tpst->next)
{
if (pc >= tpst->textlow && pc < tpst->texthigh)
&& SYMBOL_VALUE_ADDRESS (p)
== SYMBOL_VALUE_ADDRESS (msymbol))
return (tpst);
+ if (p != NULL)
+ {
+ /* We found a symbol in this partial symtab which
+ matches (or is closest to) PC, check whether it
+ is closer than our current BEST_PSYM. Since
+ this symbol address is necessarily lower or
+ equal to PC, the symbol closer to PC is the
+ symbol which address is the highest. */
+ /* This way we return the psymtab which contains
+ such best match symbol. This can help in cases
+ where the symbol information/debuginfo is not
+ complete, like for instance on IRIX6 with gcc,
+ where no debug info is emitted for
+ statics. (See also the nodebug.exp
+ testcase.) */
+ if (best_psym == NULL
+ || SYMBOL_VALUE_ADDRESS (p)
+ > SYMBOL_VALUE_ADDRESS (best_psym))
+ {
+ best_psym = p;
+ best_pst = tpst;
+ }
+ }
+
}
}
- return (pst);
+ return (best_pst);
}
}
return (NULL);
ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
ginfo->section = SYMBOL_SECTION (msym);
}
+ else if (objfile)
+ {
+ /* Static, function-local variables do appear in the linker
+ (minimal) symbols, but are frequently given names that won't
+ be found via lookup_minimal_symbol(). E.g., it has been
+ observed in frv-uclinux (ELF) executables that a static,
+ function-local variable named "foo" might appear in the
+ linker symbols as "foo.6" or "foo.3". Thus, there is no
+ point in attempting to extend the lookup-by-name mechanism to
+ handle this case due to the fact that there can be multiple
+ names.
+
+ So, instead, search the section table when lookup by name has
+ failed. The ``addr'' and ``endaddr'' fields may have already
+ been relocated. If so, the relocation offset (i.e. the
+ ANOFFSET value) needs to be subtracted from these values when
+ performing the comparison. We unconditionally subtract it,
+ because, when no relocation has been performed, the ANOFFSET
+ value will simply be zero.
+
+ The address of the symbol whose section we're fixing up HAS
+ NOT BEEN adjusted (relocated) yet. It can't have been since
+ the section isn't yet known and knowing the section is
+ necessary in order to add the correct relocation value. In
+ other words, we wouldn't even be in this function (attempting
+ to compute the section) if it were already known.
+
+ Note that it is possible to search the minimal symbols
+ (subtracting the relocation value if necessary) to find the
+ matching minimal symbol, but this is overkill and much less
+ efficient. It is not necessary to find the matching minimal
+ symbol, only its section.
+
+ Note that this technique (of doing a section table search)
+ can fail when unrelocated section addresses overlap. For
+ this reason, we still attempt a lookup by name prior to doing
+ a search of the section table. */
+
+ CORE_ADDR addr;
+ struct obj_section *s;
+
+ addr = ginfo->value.address;
+
+ ALL_OBJFILE_OSECTIONS (objfile, s)
+ {
+ int idx = s->the_bfd_section->index;
+ CORE_ADDR offset = ANOFFSET (objfile->section_offsets, idx);
+
+ if (s->addr - offset <= addr && addr < s->endaddr - offset)
+ {
+ ginfo->bfd_section = s->the_bfd_section;
+ ginfo->section = idx;
+ return;
+ }
+ }
+ }
}
struct symbol *
modified_name = name;
- /* If we are using C++ language, demangle the name before doing a lookup, so
+ /* If we are using C++ or Java, demangle the name before doing a lookup, so
we can always binary search. */
if (current_language->la_language == language_cplus)
{
needtofreename = 1;
}
}
+ else if (current_language->la_language == language_java)
+ {
+ demangled_name = cplus_demangle (name,
+ DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
+ if (demangled_name)
+ {
+ mangled_name = name;
+ modified_name = demangled_name;
+ needtofreename = 1;
+ }
+ }
if (case_sensitivity == case_sensitive_off)
{
STATIC_BLOCK : GLOBAL_BLOCK);
sym = lookup_block_symbol (block, name, linkage_name, domain);
if (!sym)
- error ("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>).",
+ error (_("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>)."),
block_index == GLOBAL_BLOCK ? "global" : "static",
name, ps->filename, name, name);
}
{
center = bottom + (top - bottom) / 2;
if (!(center < top))
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
if (!do_linear_search
&& (SYMBOL_LANGUAGE (*center) == language_java))
{
do_linear_search = 1;
}
- if (strcmp_iw_ordered (SYMBOL_NATURAL_NAME (*center), name) >= 0)
+ if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), name) >= 0)
{
top = center;
}
}
}
if (!(top == bottom))
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
while (top <= real_top
&& (linkage_name != NULL
? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0
- : SYMBOL_MATCHES_NATURAL_NAME (*top,name)))
+ : SYMBOL_MATCHES_SEARCH_NAME (*top,name)))
{
if (SYMBOL_DOMAIN (*top) == domain)
{
{
if (linkage_name != NULL
? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0
- : SYMBOL_MATCHES_NATURAL_NAME (*psym, name))
+ : SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
{
return (*psym);
}
}
/* Look up a type named NAME in the struct_domain. The type returned
- must not be opaque -- i.e., must have at least one field defined
+ must not be opaque -- i.e., must have at least one field
+ defined. */
- This code was modelled on lookup_symbol -- the parts not relevant to looking
- up types were just left out. In particular it's assumed here that types
- are available in struct_domain and only at file-static or global blocks. */
+struct type *
+lookup_transparent_type (const char *name)
+{
+ return current_language->la_lookup_transparent_type (name);
+}
+/* The standard implementation of lookup_transparent_type. This code
+ was modeled on lookup_symbol -- the parts not relevant to looking
+ up types were just left out. In particular it's assumed here that
+ types are available in struct_domain and only at file-static or
+ global blocks. */
struct type *
-lookup_transparent_type (const char *name)
+basic_lookup_transparent_type (const char *name)
{
struct symbol *sym;
struct symtab *s = NULL;
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
- error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+ error (_("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
%s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>).",
+(if a template, try specifying an instantiation: %s<type>)."),
name, ps->filename, name, name);
}
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
if (!sym)
- error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+ error (_("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
%s may be an inlined function, or may be a template function\n\
-(if a template, try specifying an instantiation: %s<type>).",
+(if a template, try specifying an instantiation: %s<type>)."),
name, ps->filename, name, name);
}
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
/* Might want to error() here (in case symtab is corrupt and
will cause a core dump), but maybe we can successfully
continue, so let's not. */
- warning ("\
-(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n",
+ warning (_("\
+(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n"),
paddr_nz (pc));
s = PSYMTAB_TO_SYMTAB (ps);
}
struct linetable *l;
int ind;
- if (!STREQ (symtab->filename, s->filename))
+ if (strcmp (symtab->filename, s->filename) != 0)
continue;
l = LINETABLE (s);
ind = find_line_common (l, line, &exact);
!section_is_mapped (section))
pc = overlay_unmapped_address (pc, section);
- pc += FUNCTION_START_OFFSET;
+ pc += DEPRECATED_FUNCTION_START_OFFSET;
pc = SKIP_PROLOGUE (pc);
/* For overlays, map pc back into its mapped VMA range */
}
sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
-#ifdef PROLOGUE_FIRSTLINE_OVERLAP
- /* Convex: no need to suppress code on first line, if any */
- sal.pc = pc;
-#else
/* Check if SKIP_PROLOGUE left us in mid-line, and the next
line is still part of the same function. */
if (sal.pc != pc
sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
}
sal.pc = pc;
-#endif
return sal;
}
else if (p[1] == '[')
{
if (p[2] == ']')
- error ("mismatched quoting on brackets, try 'operator\\[\\]'");
+ error (_("mismatched quoting on brackets, try 'operator\\[\\]'"));
else if (p[2] == '\\' && p[3] == ']')
{
*end = p + 4; /* 'operator\[\]' */
return p;
}
else
- error ("nothing is allowed between '[' and ']'");
+ error (_("nothing is allowed between '[' and ']'"));
}
else
{
return p;
case '(':
if (p[1] != ')')
- error ("`operator ()' must be specified without whitespace in `()'");
+ error (_("`operator ()' must be specified without whitespace in `()'"));
*end = p + 2;
return p;
case '?':
if (p[1] != ':')
- error ("`operator ?:' must be specified without whitespace in `?:'");
+ error (_("`operator ?:' must be specified without whitespace in `?:'"));
*end = p + 2;
return p;
case '[':
if (p[1] != ']')
- error ("`operator []' must be specified without whitespace in `[]'");
+ error (_("`operator []' must be specified without whitespace in `[]'"));
*end = p + 2;
return p;
default:
- error ("`operator %s' not supported", p);
+ error (_("`operator %s' not supported"), p);
break;
}
NAME is the name to print and *FIRST is nonzero if this is the first
name printed. Set *FIRST to zero. */
static void
-output_source_filename (char *name, int *first)
+output_source_filename (const char *name, int *first)
{
/* Since a single source file can result in several partial symbol
tables, we need to avoid printing it more than once. Note: if
if (!have_full_symbols () && !have_partial_symbols ())
{
- error ("No symbol table is loaded. Use the \"file\" command.");
+ error (_("No symbol table is loaded. Use the \"file\" command."));
}
printf_filtered ("Source files for which symbols have been read in:\n\n");
first = 1;
ALL_SYMTABS (objfile, s)
{
- output_source_filename (s->filename, &first);
+ const char *fullname = symtab_to_fullname (s);
+ output_source_filename (fullname ? fullname : s->filename, &first);
}
printf_filtered ("\n\n");
{
if (!ps->readin)
{
- output_source_filename (ps->filename, &first);
+ const char *fullname = psymtab_to_fullname (ps);
+ output_source_filename (fullname ? fullname : ps->filename, &first);
}
}
printf_filtered ("\n");
struct cleanup *old_chain = NULL;
if (kind < VARIABLES_DOMAIN)
- error ("must search on specific domain");
+ error (_("must search on specific domain"));
ourtype = types[(int) (kind - VARIABLES_DOMAIN)];
ourtype2 = types2[(int) (kind - VARIABLES_DOMAIN)];
}
if (0 != (val = re_comp (regexp)))
- error ("Invalid regexp (%s): %s", val, regexp);
+ error (_("Invalid regexp (%s): %s"), val, regexp);
}
/* Search through the partial symtabs *first* for all symbols
char *tmp;
if (TARGET_ADDR_BIT <= 32)
- tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
- & (CORE_ADDR) 0xffffffff,
- "08l");
+ tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
+ & (CORE_ADDR) 0xffffffff,
+ 8);
else
- tmp = local_hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
- "016l");
+ tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol),
+ 16);
printf_filtered ("%s %s\n",
tmp, SYMBOL_PRINT_NAME (msymbol));
}
return func_addr <= pc && pc < sal.end;
}
+/* Given PC at the function's start address, attempt to find the
+ prologue end using SAL information. Return zero if the skip fails.
+
+ A non-optimized prologue traditionally has one SAL for the function
+ and a second for the function body. A single line function has
+ them both pointing at the same line.
+
+ An optimized prologue is similar but the prologue may contain
+ instructions (SALs) from the instruction body. Need to skip those
+ while not getting into the function body.
+
+ The functions end point and an increasing SAL line are used as
+ indicators of the prologue's endpoint.
+
+ This code is based on the function refine_prologue_limit (versions
+ found in both ia64 and ppc). */
+
+CORE_ADDR
+skip_prologue_using_sal (CORE_ADDR func_addr)
+{
+ struct symtab_and_line prologue_sal;
+ CORE_ADDR start_pc;
+ CORE_ADDR end_pc;
+
+ /* Get an initial range for the function. */
+ find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
+ start_pc += DEPRECATED_FUNCTION_START_OFFSET;
+
+ prologue_sal = find_pc_line (start_pc, 0);
+ if (prologue_sal.line != 0)
+ {
+ while (prologue_sal.end < end_pc)
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (prologue_sal.end, 0);
+ if (sal.line == 0)
+ break;
+ /* Assume that a consecutive SAL for the same (or larger)
+ line mark the prologue -> body transition. */
+ if (sal.line >= prologue_sal.line)
+ break;
+ /* The case in which compiler's optimizer/scheduler has
+ moved instructions into the prologue. We look ahead in
+ the function looking for address ranges whose
+ corresponding line number is less the first one that we
+ found for the function. This is more conservative then
+ refine_prologue_limit which scans a large number of SALs
+ looking for any in the prologue */
+ prologue_sal = sal;
+ }
+ }
+ return prologue_sal.end;
+}
\f
struct symtabs_and_lines
decode_line_spec (char *string, int funfirstline)
struct symtab_and_line cursal;
if (string == 0)
- error ("Empty line specification.");
+ error (_("Empty line specification."));
/* We use whatever is set as the current source line. We do not try
and get a default or it will recursively call us! */
sals = decode_line_1 (&string, funfirstline,
cursal.symtab, cursal.line,
- (char ***) NULL);
+ (char ***) NULL, NULL);
if (*string)
- error ("Junk at end of line specification: %s", string);
+ error (_("Junk at end of line specification: %s"), string);
return sals;
}
}
}
+/* Deduce the name of the main procedure, and set NAME_OF_MAIN
+ accordingly. */
+
+static void
+find_main_name (void)
+{
+ char *new_main_name;
+
+ /* Try to see if the main procedure is in Ada. */
+ /* FIXME: brobecker/2005-03-07: Another way of doing this would
+ be to add a new method in the language vector, and call this
+ method for each language until one of them returns a non-empty
+ name. This would allow us to remove this hard-coded call to
+ an Ada function. It is not clear that this is a better approach
+ at this point, because all methods need to be written in a way
+ such that false positives never be returned. For instance, it is
+ important that a method does not return a wrong name for the main
+ procedure if the main procedure is actually written in a different
+ language. It is easy to guaranty this with Ada, since we use a
+ special symbol generated only when the main in Ada to find the name
+ of the main procedure. It is difficult however to see how this can
+ be guarantied for languages such as C, for instance. This suggests
+ that order of call for these methods becomes important, which means
+ a more complicated approach. */
+ new_main_name = ada_main_name ();
+ if (new_main_name != NULL)
+ {
+ set_main_name (new_main_name);
+ return;
+ }
+
+ /* The languages above didn't identify the name of the main procedure.
+ Fallback to "main". */
+ set_main_name ("main");
+}
+
char *
main_name (void)
{
- if (name_of_main != NULL)
- return name_of_main;
- else
- return "main";
+ if (name_of_main == NULL)
+ find_main_name ();
+
+ return name_of_main;
}
+/* Handle ``executable_changed'' events for the symtab module. */
+
+static void
+symtab_observer_executable_changed (void *unused)
+{
+ /* NAME_OF_MAIN may no longer be the same, so reset it for now. */
+ set_main_name (NULL);
+}
void
_initialize_symtab (void)
{
- add_info ("variables", variables_info,
- "All global and static variable names, or those matching REGEXP.");
+ add_info ("variables", variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
if (dbx_commands)
- add_com ("whereis", class_info, variables_info,
- "All global and static variable names, or those matching REGEXP.");
+ add_com ("whereis", class_info, variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
add_info ("functions", functions_info,
- "All function names, or those matching REGEXP.");
+ _("All function names, or those matching REGEXP."));
/* FIXME: This command has at least the following problems:
I also think "ptype" or "whatis" is more likely to be useful (but if
there is much disagreement "info types" can be fixed). */
add_info ("types", types_info,
- "All type names, or those matching REGEXP.");
+ _("All type names, or those matching REGEXP."));
add_info ("sources", sources_info,
- "Source files in the program.");
+ _("Source files in the program."));
add_com ("rbreak", class_breakpoint, rbreak_command,
- "Set a breakpoint for all functions matching REGEXP.");
+ _("Set a breakpoint for all functions matching REGEXP."));
if (xdb_commands)
{
- add_com ("lf", class_info, sources_info, "Source files in the program");
- add_com ("lg", class_info, variables_info,
- "All global and static variable names, or those matching REGEXP.");
+ add_com ("lf", class_info, sources_info,
+ _("Source files in the program"));
+ add_com ("lg", class_info, variables_info, _("\
+All global and static variable names, or those matching REGEXP."));
}
/* Initialize the one built-in type that isn't language dependent... */
builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0,
"<unknown type>", (struct objfile *) NULL);
+
+ observer_attach_executable_changed (symtab_observer_executable_changed);
}