2009-05-13 Paul Pluzhnikov <ppluzhnikov@google.com>

* objc-lang.c (objc_objfile_data): New variable.
	(find_methods): Skip objfiles without Obj-C methods.
	(_initialize_objc_lang): New function.
This commit is contained in:
Paul Pluzhnikov 2009-05-13 17:36:24 +00:00
parent 3da9440a2c
commit 57a9e6afe1
2 changed files with 110 additions and 68 deletions

View File

@ -1,3 +1,9 @@
2009-05-13 Paul Pluzhnikov <ppluzhnikov@google.com>
* objc-lang.c (objc_objfile_data): New variable.
(find_methods): Skip objfiles without Obj-C methods.
(_initialize_objc_lang): New function.
2009-05-13 Joel Brobecker <brobecker@adacore.com> 2009-05-13 Joel Brobecker <brobecker@adacore.com>
* c-lang.c (print_wchar): Remove unnecessary cast. * c-lang.c (print_wchar): Remove unnecessary cast.

View File

@ -76,6 +76,8 @@ struct objc_method {
CORE_ADDR imp; CORE_ADDR imp;
}; };
static const struct objfile_data *objc_objfile_data;
/* Lookup a structure type named "struct NAME", visible in lexical /* Lookup a structure type named "struct NAME", visible in lexical
block BLOCK. If NOERR is nonzero, return zero if NAME is not block BLOCK. If NOERR is nonzero, return zero if NAME is not
suitably defined. */ suitably defined. */
@ -1154,88 +1156,116 @@ find_methods (struct symtab *symtab, char type,
if (symtab) if (symtab)
block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
ALL_MSYMBOLS (objfile, msymbol) ALL_OBJFILES (objfile)
{ {
QUIT; unsigned int *objc_csym;
if ((MSYMBOL_TYPE (msymbol) != mst_text) /* The objfile_csym variable counts the number of ObjC methods
&& (MSYMBOL_TYPE (msymbol) != mst_file_text)) that this objfile defines. We save that count as a private
/* Not a function or method. */ objfile data. If we have already determined that this objfile
provides no ObjC methods, we can skip it entirely. */
unsigned int objfile_csym = 0;
objc_csym = objfile_data (objfile, objc_objfile_data);
if (objc_csym != NULL && *objc_csym == 0)
/* There are no ObjC symbols in this objfile. Skip it entirely. */
continue; continue;
if (symtab) ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
if ((SYMBOL_VALUE_ADDRESS (msymbol) < BLOCK_START (block)) ||
(SYMBOL_VALUE_ADDRESS (msymbol) >= BLOCK_END (block)))
/* Not in the specified symtab. */
continue;
symname = SYMBOL_NATURAL_NAME (msymbol);
if (symname == NULL)
continue;
if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
/* Not a method name. */
continue;
while ((strlen (symname) + 1) >= tmplen)
{ {
tmplen = (tmplen == 0) ? 1024 : tmplen * 2; QUIT;
tmp = xrealloc (tmp, tmplen);
}
strcpy (tmp, symname);
if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL) if ((MSYMBOL_TYPE (msymbol) != mst_text)
continue; && (MSYMBOL_TYPE (msymbol) != mst_file_text))
/* Not a function or method. */
continue;
if ((type != '\0') && (ntype != type)) if (symtab)
continue; if ((SYMBOL_VALUE_ADDRESS (msymbol) < BLOCK_START (block)) ||
(SYMBOL_VALUE_ADDRESS (msymbol) >= BLOCK_END (block)))
/* Not in the specified symtab. */
continue;
if ((class != NULL) symname = SYMBOL_NATURAL_NAME (msymbol);
&& ((nclass == NULL) || (strcmp (class, nclass) != 0))) if (symname == NULL)
continue; continue;
if ((category != NULL) && if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
((ncategory == NULL) || (strcmp (category, ncategory) != 0))) /* Not a method name. */
continue; continue;
if ((selector != NULL) && while ((strlen (symname) + 1) >= tmplen)
((nselector == NULL) || (strcmp (selector, nselector) != 0))) {
continue; tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
tmp = xrealloc (tmp, tmplen);
}
strcpy (tmp, symname);
sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol)); if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL)
if (sym != NULL) continue;
{
const char *newsymname = SYMBOL_NATURAL_NAME (sym);
if (strcmp (symname, newsymname) == 0) objfile_csym++;
{
/* Found a high-level method sym: swap it into the if ((type != '\0') && (ntype != type))
lower part of sym_arr (below num_debuggable). */ continue;
if (syms != NULL)
{ if ((class != NULL)
syms[csym] = syms[cdebug]; && ((nclass == NULL) || (strcmp (class, nclass) != 0)))
syms[cdebug] = sym; continue;
}
csym++; if ((category != NULL) &&
cdebug++; ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
} continue;
else
{ if ((selector != NULL) &&
warning ( ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
continue;
sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol));
if (sym != NULL)
{
const char *newsymname = SYMBOL_NATURAL_NAME (sym);
if (strcmp (symname, newsymname) == 0)
{
/* Found a high-level method sym: swap it into the
lower part of sym_arr (below num_debuggable). */
if (syms != NULL)
{
syms[csym] = syms[cdebug];
syms[cdebug] = sym;
}
csym++;
cdebug++;
}
else
{
warning (
"debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring", "debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring",
newsymname, symname); newsymname, symname);
if (syms != NULL) if (syms != NULL)
syms[csym] = (struct symbol *) msymbol; syms[csym] = (struct symbol *) msymbol;
csym++; csym++;
} }
} }
else else
{ {
/* Found a non-debuggable method symbol. */ /* Found a non-debuggable method symbol. */
if (syms != NULL) if (syms != NULL)
syms[csym] = (struct symbol *) msymbol; syms[csym] = (struct symbol *) msymbol;
csym++; csym++;
}
} }
if (objc_csym == NULL)
{
objc_csym = xmalloc (sizeof (*objc_csym));
*objc_csym = objfile_csym;
set_objfile_data (objfile, objc_objfile_data, objc_csym);
}
else
/* Count of ObjC methods in this objfile should be constant. */
gdb_assert (*objc_csym == objfile_csym);
} }
if (nsym != NULL) if (nsym != NULL)
@ -1792,3 +1822,9 @@ resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
return 1; return 1;
return 0; return 0;
} }
void
_initialize_objc_lang (void)
{
objc_objfile_data = register_objfile_data ();
}