/* */
+/* Program space key for finding name and language of "main". */
+
+static const struct program_space_data *main_progspace_key;
+
+/* Type of the data stored on the program space. */
+
+struct main_info
+{
+ /* Name of "main". */
+
+ char *name_of_main;
+
+ /* Language of "main". */
+
+ enum language language_of_main;
+};
+
/* When non-zero, print debugging messages related to symtab creation. */
unsigned int symtab_create_debug = 0;
void
init_sal (struct symtab_and_line *sal)
{
- sal->pspace = NULL;
- sal->symtab = 0;
- sal->section = 0;
- sal->line = 0;
- sal->pc = 0;
- sal->end = 0;
- sal->explicit_pc = 0;
- sal->explicit_line = 0;
- sal->probe = NULL;
+ memset (sal, 0, sizeof (*sal));
}
\f
find_pc_sect_symtab_via_partial (CORE_ADDR pc, struct obj_section *section)
{
struct objfile *objfile;
- struct minimal_symbol *msymbol;
+ struct bound_minimal_symbol msymbol;
/* If we know that this is not a text address, return failure. This is
necessary because we loop based on texthigh and textlow, which do
not include the data ranges. */
- msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym;
- if (msymbol
- && (MSYMBOL_TYPE (msymbol) == mst_data
- || MSYMBOL_TYPE (msymbol) == mst_bss
- || MSYMBOL_TYPE (msymbol) == mst_abs
- || MSYMBOL_TYPE (msymbol) == mst_file_data
- || MSYMBOL_TYPE (msymbol) == mst_file_bss))
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+ if (msymbol.minsym
+ && (MSYMBOL_TYPE (msymbol.minsym) == mst_data
+ || MSYMBOL_TYPE (msymbol.minsym) == mst_bss
+ || MSYMBOL_TYPE (msymbol.minsym) == mst_abs
+ || MSYMBOL_TYPE (msymbol.minsym) == mst_file_data
+ || MSYMBOL_TYPE (msymbol.minsym) == mst_file_bss))
return NULL;
ALL_OBJFILES (objfile)
point to the actual function code. */
msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->name, objfile);
if (msym)
- ginfo->section = SYMBOL_SECTION (msym);
+ ginfo->section = MSYMBOL_SECTION (msym);
else
{
/* Static, function-local variables do appear in the linker
struct symtab *best_s = NULL;
struct objfile *objfile;
CORE_ADDR distance = 0;
- struct minimal_symbol *msymbol;
+ struct bound_minimal_symbol msymbol;
/* If we know that this is not a text address, return failure. This is
necessary because we loop based on the block's high and low code
addresses, which do not include the data ranges, and because
we call find_pc_sect_psymtab which has a similar restriction based
on the partial_symtab's texthigh and textlow. */
- msymbol = lookup_minimal_symbol_by_pc_section (pc, section).minsym;
- if (msymbol
- && (MSYMBOL_TYPE (msymbol) == mst_data
- || MSYMBOL_TYPE (msymbol) == mst_bss
- || MSYMBOL_TYPE (msymbol) == mst_abs
- || MSYMBOL_TYPE (msymbol) == mst_file_data
- || MSYMBOL_TYPE (msymbol) == mst_file_bss))
+ msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
+ if (msymbol.minsym
+ && (MSYMBOL_TYPE (msymbol.minsym) == mst_data
+ || MSYMBOL_TYPE (msymbol.minsym) == mst_bss
+ || MSYMBOL_TYPE (msymbol.minsym) == mst_abs
+ || MSYMBOL_TYPE (msymbol.minsym) == mst_file_data
+ || MSYMBOL_TYPE (msymbol.minsym) == mst_file_bss))
return NULL;
/* Search all symtabs for the one whose file contains our address, and which
struct symtab_and_line val;
struct blockvector *bv;
struct bound_minimal_symbol msymbol;
- struct minimal_symbol *mfunsym;
struct objfile *objfile;
/* Info on best line seen so far, and where it starts, and its file. */
if (msymbol.minsym != NULL)
if (MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline)
{
- mfunsym
- = lookup_minimal_symbol_text (SYMBOL_LINKAGE_NAME (msymbol.minsym),
+ struct bound_minimal_symbol mfunsym
+ = lookup_minimal_symbol_text (MSYMBOL_LINKAGE_NAME (msymbol.minsym),
NULL);
- if (mfunsym == NULL)
+
+ if (mfunsym.minsym == NULL)
/* I eliminated this warning since it is coming out
* in the following situation:
* gdb shmain // test program with shared libraries
SYMBOL_LINKAGE_NAME (msymbol)); */
;
/* fall through */
- else if (SYMBOL_VALUE_ADDRESS (mfunsym)
- == SYMBOL_VALUE_ADDRESS (msymbol.minsym))
+ else if (BMSYMBOL_VALUE_ADDRESS (mfunsym)
+ == BMSYMBOL_VALUE_ADDRESS (msymbol))
/* Avoid infinite recursion */
/* See above comment about why warning is commented out. */
/* warning ("In stub for %s; unable to find real function/line info",
;
/* fall through */
else
- return find_pc_line (SYMBOL_VALUE_ADDRESS (mfunsym), 0);
+ return find_pc_line (BMSYMBOL_VALUE_ADDRESS (mfunsym), 0);
}
}
objfile = msymbol.objfile;
- pc = SYMBOL_VALUE_ADDRESS (msymbol.minsym);
- section = SYMBOL_OBJ_SECTION (objfile, msymbol.minsym);
- name = SYMBOL_LINKAGE_NAME (msymbol.minsym);
+ pc = BMSYMBOL_VALUE_ADDRESS (msymbol);
+ section = MSYMBOL_OBJ_SECTION (objfile, msymbol.minsym);
+ name = MSYMBOL_LINKAGE_NAME (msymbol.minsym);
}
gdbarch = get_objfile_arch (objfile);
/* Skip "first line" of function (which is actually its prologue). */
pc += gdbarch_deprecated_function_start_offset (gdbarch);
+ if (gdbarch_skip_entrypoint_p (gdbarch))
+ pc = gdbarch_skip_entrypoint (gdbarch, pc);
if (skip)
pc = gdbarch_skip_prologue (gdbarch, pc);
|| MSYMBOL_TYPE (msymbol) == ourtype4)
{
if (!datum.preg_p
- || regexec (&datum.preg, SYMBOL_NATURAL_NAME (msymbol), 0,
+ || regexec (&datum.preg, MSYMBOL_NATURAL_NAME (msymbol), 0,
NULL, 0) == 0)
{
/* Note: An important side-effect of these lookup functions
is to expand the symbol table if msymbol is found, for the
benefit of the next loop on ALL_PRIMARY_SYMTABS. */
if (kind == FUNCTIONS_DOMAIN
- ? find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)) == NULL
+ ? find_pc_symtab (MSYMBOL_VALUE_ADDRESS (objfile,
+ msymbol)) == NULL
: (lookup_symbol_in_objfile_from_linkage_name
- (objfile, SYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
+ (objfile, MSYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
== NULL))
found_misc = 1;
}
|| MSYMBOL_TYPE (msymbol) == ourtype4)
{
if (!datum.preg_p
- || regexec (&datum.preg, SYMBOL_NATURAL_NAME (msymbol), 0,
+ || regexec (&datum.preg, MSYMBOL_NATURAL_NAME (msymbol), 0,
NULL, 0) == 0)
{
/* For functions we can do a quick check of whether the
symbol might be found via find_pc_symtab. */
if (kind != FUNCTIONS_DOMAIN
- || find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)) == NULL)
+ || find_pc_symtab (MSYMBOL_VALUE_ADDRESS (objfile,
+ msymbol)) == NULL)
{
if (lookup_symbol_in_objfile_from_linkage_name
- (objfile, SYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
+ (objfile, MSYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
== NULL)
{
/* match */
char *tmp;
if (gdbarch_addr_bit (gdbarch) <= 32)
- tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol.minsym)
+ tmp = hex_string_custom (BMSYMBOL_VALUE_ADDRESS (msymbol)
& (CORE_ADDR) 0xffffffff,
8);
else
- tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol.minsym),
+ tmp = hex_string_custom (BMSYMBOL_VALUE_ADDRESS (msymbol),
16);
printf_filtered ("%s %s\n",
- tmp, SYMBOL_PRINT_NAME (msymbol.minsym));
+ tmp, MSYMBOL_PRINT_NAME (msymbol.minsym));
}
/* This is the guts of the commands "info functions", "info types", and
}
else
{
- int newlen = (strlen (SYMBOL_LINKAGE_NAME (p->msymbol.minsym)) + 3);
+ int newlen = (strlen (MSYMBOL_LINKAGE_NAME (p->msymbol.minsym)) + 3);
if (newlen > len)
{
len = newlen;
}
strcpy (string, "'");
- strcat (string, SYMBOL_LINKAGE_NAME (p->msymbol.minsym));
+ strcat (string, MSYMBOL_LINKAGE_NAME (p->msymbol.minsym));
strcat (string, "'");
break_command (string, from_tty);
printf_filtered ("<function, no debug info> %s;\n",
- SYMBOL_PRINT_NAME (p->msymbol.minsym));
+ MSYMBOL_PRINT_NAME (p->msymbol.minsym));
}
}
completion_list_add_name \
(SYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word))
+#define MCOMPLETION_LIST_ADD_SYMBOL(symbol, sym_text, len, text, word) \
+ completion_list_add_name \
+ (MSYMBOL_NATURAL_NAME (symbol), (sym_text), (len), (text), (word))
+
/* Test to see if the symbol specified by SYMNAME (which is already
demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
characters. If so, add it to the current completion list. */
const char *method, *category, *selector;
char *tmp2 = NULL;
- method = SYMBOL_NATURAL_NAME (msymbol);
+ method = MSYMBOL_NATURAL_NAME (msymbol);
/* Is it a method? */
if ((method[0] != '-') && (method[0] != '+'))
ALL_MSYMBOLS (objfile, msymbol)
{
QUIT;
- COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text,
- word);
+ MCOMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text,
+ word);
completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text,
word);
}
\f
/* Track MAIN */
-static char *name_of_main;
-enum language language_of_main = language_unknown;
-void
-set_main_name (const char *name)
+/* Return the "main_info" object for the current program space. If
+ the object has not yet been created, create it and fill in some
+ default values. */
+
+static struct main_info *
+get_main_info (void)
+{
+ struct main_info *info = program_space_data (current_program_space,
+ main_progspace_key);
+
+ if (info == NULL)
+ {
+ /* It may seem strange to store the main name in the progspace
+ and also in whatever objfile happens to see a main name in
+ its debug info. The reason for this is mainly historical:
+ gdb returned "main" as the name even if no function named
+ "main" was defined the program; and this approach lets us
+ keep compatibility. */
+ info = XCNEW (struct main_info);
+ info->language_of_main = language_unknown;
+ set_program_space_data (current_program_space, main_progspace_key,
+ info);
+ }
+
+ return info;
+}
+
+/* A cleanup to destroy a struct main_info when a progspace is
+ destroyed. */
+
+static void
+main_info_cleanup (struct program_space *pspace, void *data)
{
- if (name_of_main != NULL)
+ struct main_info *info = data;
+
+ if (info != NULL)
+ xfree (info->name_of_main);
+ xfree (info);
+}
+
+static void
+set_main_name (const char *name, enum language lang)
+{
+ struct main_info *info = get_main_info ();
+
+ if (info->name_of_main != NULL)
{
- xfree (name_of_main);
- name_of_main = NULL;
- language_of_main = language_unknown;
+ xfree (info->name_of_main);
+ info->name_of_main = NULL;
+ info->language_of_main = language_unknown;
}
if (name != NULL)
{
- name_of_main = xstrdup (name);
- language_of_main = language_unknown;
+ info->name_of_main = xstrdup (name);
+ info->language_of_main = lang;
}
}
find_main_name (void)
{
const char *new_main_name;
+ struct objfile *objfile;
+
+ /* First check the objfiles to see whether a debuginfo reader has
+ picked up the appropriate main name. Historically the main name
+ was found in a more or less random way; this approach instead
+ relies on the order of objfile creation -- which still isn't
+ guaranteed to get the correct answer, but is just probably more
+ accurate. */
+ ALL_OBJFILES (objfile)
+ {
+ if (objfile->per_bfd->name_of_main != NULL)
+ {
+ set_main_name (objfile->per_bfd->name_of_main,
+ objfile->per_bfd->language_of_main);
+ return;
+ }
+ }
/* Try to see if the main procedure is in Ada. */
/* FIXME: brobecker/2005-03-07: Another way of doing this would
new_main_name = ada_main_name ();
if (new_main_name != NULL)
{
- set_main_name (new_main_name);
+ set_main_name (new_main_name, language_ada);
+ return;
+ }
+
+ new_main_name = d_main_name ();
+ if (new_main_name != NULL)
+ {
+ set_main_name (new_main_name, language_d);
return;
}
new_main_name = go_main_name ();
if (new_main_name != NULL)
{
- set_main_name (new_main_name);
+ set_main_name (new_main_name, language_go);
return;
}
new_main_name = pascal_main_name ();
if (new_main_name != NULL)
{
- set_main_name (new_main_name);
+ set_main_name (new_main_name, language_pascal);
return;
}
/* The languages above didn't identify the name of the main procedure.
Fallback to "main". */
- set_main_name ("main");
+ set_main_name ("main", language_unknown);
}
char *
main_name (void)
{
- if (name_of_main == NULL)
+ struct main_info *info = get_main_info ();
+
+ if (info->name_of_main == NULL)
+ find_main_name ();
+
+ return info->name_of_main;
+}
+
+/* Return the language of the main function. If it is not known,
+ return language_unknown. */
+
+enum language
+main_language (void)
+{
+ struct main_info *info = get_main_info ();
+
+ if (info->name_of_main == NULL)
find_main_name ();
- return name_of_main;
+ return info->language_of_main;
}
/* Handle ``executable_changed'' events for the symtab module. */
symtab_observer_executable_changed (void)
{
/* NAME_OF_MAIN may no longer be the same, so reset it for now. */
- set_main_name (NULL);
+ set_main_name (NULL, language_unknown);
}
/* Return 1 if the supplied producer string matches the ARM RealView
{
initialize_ordinary_address_classes ();
+ main_progspace_key
+ = register_program_space_data_with_cleanup (NULL, main_info_cleanup);
+
add_info ("variables", variables_info, _("\
All global and static variable names, or those matching REGEXP."));
if (dbx_commands)