Exemple #1
0
std::string Demangled(const std::string& name)
{
   std::string demangled;

   demangling_styles style = auto_demangling;
   if (name[0] == '_')
   {
      style = gnu_v3_demangling;
   }

   if (name[0] == '?')
   {
   //   style = msvc_demangling;
   }

#ifdef _MSC_VER
   style = msvc_demangling; // TODO remove
#endif
   cplus_demangle_set_style (style);
   
   char* res = cplus_demangle (name.c_str(), DMGL_ANSI | DMGL_PARAMS);
 
   if (res != 0)
   {
      demangled = res;
   }
   
   free(res);
   
   return demangled;
}
Exemple #2
0
static void
demangle_it (char *mangled_name)
{
    char *result;
    unsigned int skip_first = 0;

    /* _ and $ are sometimes found at the start of function names
       in assembler sources in order to distinguish them from other
       names (eg register names).  So skip them here.  */
    if (mangled_name[0] == '.' || mangled_name[0] == '$')
        ++skip_first;
    if (strip_underscore && mangled_name[skip_first] == '_')
        ++skip_first;

    result = cplus_demangle (mangled_name + skip_first, flags);

    if (result == NULL)
        printf ("%s", mangled_name);
    else
    {
        if (mangled_name[0] == '.')
            putchar ('.');
        printf ("%s", result);
        free (result);
    }
}
Exemple #3
0
const char *
my_demangle(const char *function_name) {
	const char *tmp, *fn_copy;
#ifdef USE_CXA_DEMANGLE
	extern char *__cxa_demangle(const char *, char *, size_t *, int *);
#endif

	debug(DEBUG_FUNCTION, "my_demangle(name=%s)", function_name);

	if (!d)
		d = dict_init(dict_key2hash_string, dict_key_cmp_string);

	tmp = dict_find_entry(d, (void *)function_name);
	if (!tmp) {
		fn_copy = strdup(function_name);
#ifdef HAVE_LIBIBERTY
		tmp = cplus_demangle(function_name, DMGL_ANSI | DMGL_PARAMS);
#elif defined USE_CXA_DEMANGLE
		int status = 0;
		tmp = __cxa_demangle(function_name, NULL, NULL, &status);
#endif
		if (!tmp)
			tmp = fn_copy;
		if (tmp)
			dict_enter(d, (void *)fn_copy, (void *)tmp);
	}
	return tmp;
}
Exemple #4
0
    bool resolve(uint64_t ip, SP_Location &loc)
    {
        uint64_t vma = bfd_get_section_vma(m_abfd, m_text);
        uint64_t size = bfd_get_section_size(m_text);
        uint64_t offset =  ip - vma;

        if (ip < vma || ip > vma + size)
            return false;

        loc.ip = ip;
        loc.module = m_path;

        const char *sym, *file;

        if (!bfd_find_nearest_line(m_abfd, m_text, m_syms, offset, &file, &sym, &loc.line))
            return false;

        loc.symbol = sym;
        loc.file = file ? file : "";

        char *demangled = cplus_demangle(sym, DMGL_AUTO);

        if (demangled) {
            loc.symbol = demangled;
            free(demangled);
        }

        return true;
    }
Exemple #5
0
static char 
*demangleSymbolCString(const char *mangled)
 {
     if(mangled[0]!='_') return NULL;
     if(mangled[1]=='_') mangled++; // allow either __Z or _Z prefix
     if(mangled[1]!='Z') return NULL;
     return cplus_demangle(mangled, 0);
 }
char* sp_rtrace_tracker_query_symbol(sp_rtrace_tracker_t* tracker, const char* name)
{
	char* demangled_name = (char*)cplus_demangle(name, DMGL_ANSI | DMGL_PARAMS);
	if (!tfind(demangled_name ? demangled_name : name, &tracker->symbols, (int (*)(const void *, const void *))_strcmpp)) {
		return NULL;
	}
	return demangled_name ? demangled_name : strdup(name);
}
void BacktraceNames::Demangle()
{
    char *f = cplus_demangle(Symbol, 0);
    if(!f)
        return;
    Symbol = f;
    free(f);
}
Exemple #8
0
char *
demangle(const char *sym)
{
#ifdef HAVE_LIBBFD
    string_var dem = cplus_demangle(sym, DMGL_ANSI|DMGL_PARAMS);
    return (dem == 0 ? g_strdup(sym) : normalise_whitespace(dem));
#else
    return g_strdup(sym);
#endif
}
Exemple #9
0
const char *try_demangle(const char *mangled)
{
	const char *demangled = cplus_demangle(mangled,
		DMGL_GNU_V3 | DMGL_TYPES | DMGL_ANSI | DMGL_PARAMS);
	
	if (demangled != NULL) {
		return demangled;
	} else {
		return mangled;
	}
}
Exemple #10
0
char *
demangle (bfd *abfd, const char *name)
{
  char *res, *alloc;
  const char *pre, *suf;
  size_t pre_len;

  if (abfd != NULL && bfd_get_symbol_leading_char (abfd) == name[0])
    ++name;

  /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
     or the MS PE format.  These formats have a number of leading '.'s
     on at least some symbols, so we remove all dots to avoid
     confusing the demangler.  */
  pre = name;
  while (*name == '.')
    ++name;
  pre_len = name - pre;

  alloc = NULL;
  suf = strchr (name, '@');
  if (suf != NULL)
    {
      alloc = xmalloc (suf - name + 1);
      memcpy (alloc, name, suf - name);
      alloc[suf - name] = '\0';
      name = alloc;
    }

  res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
  if (res != NULL)
    {
      /* Now put back any suffix, or stripped dots.  */
      if (pre_len != 0 || suf != NULL)
	{
	  size_t len;
	  size_t suf_len;
	  char *final;

	  if (alloc != NULL)
	    free (alloc);

	  len = strlen (res);
	  if (suf == NULL)
	    suf = res + len;
	  suf_len = strlen (suf) + 1;
	  final = xmalloc (pre_len + len + suf_len);

	  memcpy (final, pre, pre_len);
	  memcpy (final + pre_len, res, len);
	  memcpy (final + pre_len + len, suf, suf_len);
	  free (res);
	  res = final;
	}
Exemple #11
0
static char 
*demangleSymbolCString(const char *mangled)
{
# if HAVE_CPLUS_DEMANGLE
	 if(mangled[0]!='_') return NULL;
	 if(mangled[1]=='_') mangled++; // allow either __Z or _Z prefix
	 if(mangled[1]!='Z') return NULL;
	 return cplus_demangle(mangled, 0);
# else
	return NULL;
# endif
}
Exemple #12
0
/*
 * Class:     sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:    demangle0
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_demangle0
  (JNIEnv *env, jobject this_object, jstring name) {
  jboolean isCopy;
  const char* ptr = env->GetStringUTFChars(name, &isCopy);
  char  buf[2*SYMBOL_BUF_SIZE + 1];
  jstring res = 0;
  if (cplus_demangle((char*) ptr, buf, sizeof(buf)) != DEMANGLE_ESPACE) {
    res = env->NewStringUTF(buf);
  } else {
    res = name;
  }
  env->ReleaseStringUTFChars(name, ptr);
  return res;
}
Exemple #13
0
static void
demangle_it (char *mangled_name)
{
  char *result;

  /* For command line args, also try to demangle type encodings.  */
  result = cplus_demangle (mangled_name, flags | DMGL_TYPES);
  if (result == NULL)
    {
      printf ("%s\n", mangled_name);
    }
  else
    {
      printf ("%s\n", result);
      free (result);
    }
}
Exemple #14
0
int main(int argc, const char * argv[])
{

    // insert code here...
    atosl("/Users/zhujialai/Downloads/libatosl/ksmobilebrowser",0x1000,0x80000);
    atosl("/Users/zhujialai/Downloads/libatosl/ksmobilebrowser",0x1000,0x80000);
    atosl("/Users/zhujialai/Downloads/libatosl/ksmobilebrowser",0x1000,0x80000);
    std::cout << "Hello, World!\n";
    char* s=cplus_demangle("_ZN7WebCore4Page8goToItemEPNS_11HistoryItemENS_13FrameLoadTypeE", 0);
    symbolFile file;
    file.open("/Users/zhujialai/Downloads/libatosl/ksmobilebrowser");
    s=file.find(0x80000);
    s=file.find(0x80000);
    s=file.find(0x80000);
    file.close();
    return 0;
}
Exemple #15
0
static void
demangle_new_symbols (void)
{
  symbol *sym;

  while ((sym = symbol_pop ()) != NULL)
    {
      demangled *dem;
      const char *p = cplus_demangle (sym->key, DMGL_PARAMS | DMGL_ANSI);

      if (! p)
	continue;

      dem = demangled_hash_lookup (p, true);
      dem->mangled = sym->key;
    }
}
Exemple #16
0
char * P_cplus_demangle( const char * symbol, bool nativeCompiler, 
                                bool includeTypes) 
{
     int opts = 0;
     opts = includeTypes ? DMGL_PARAMS | DMGL_ANSI : 0;
     //opts |= nativeCompiler ? DMGL_AUTO : DMGL_GNU;
     opts |= DMGL_GNU_V3;
     char *demangled = cplus_demangle( const_cast<char *>( symbol ), opts);
     if (demangled == NULL) return NULL;
     //fprintf(stderr, "%s[%d]:  cplus_demangle: %p: %s\n", __FILE__, __LINE__, current_demangling_style, libiberty_demanglers[0].demangling_style_name);

     char *open_paren = strchr(demangled, '(');
     if (open_paren)
       *open_paren = '\0';

     return demangled;
} /* end P_cplus_demangle() */
Exemple #17
0
const char *
my_demangle(const char *function_name) {
#ifdef USE_CXA_DEMANGLE
	extern char *__cxa_demangle(const char *, char *, size_t *, int *);
#endif

	debug(DEBUG_FUNCTION, "my_demangle(name=%s)", function_name);

	if (name_cache == NULL) {
		name_cache = malloc(sizeof(*name_cache));
		if (name_cache != NULL)
			DICT_INIT(name_cache, const char *, const char *,
				  dict_hash_string, dict_eq_string, NULL);
	}

	const char *tmp = NULL;
	if (name_cache != NULL
	    && DICT_FIND_VAL(name_cache, &function_name, &tmp) == 0)
		return tmp;

#ifdef HAVE_LIBIBERTY
	tmp = cplus_demangle(function_name,
					 DMGL_ANSI | DMGL_PARAMS);
#elif defined USE_CXA_DEMANGLE
	int status = 0;
	tmp = __cxa_demangle(function_name, NULL, NULL, &status);
#endif
	if (name_cache == NULL || tmp == NULL) {
	fail:
		if (tmp == NULL)
			return function_name;
		return tmp;
	}

	const char *fn_copy = strdup(function_name);
	if (fn_copy == NULL)
		goto fail;

	if (DICT_INSERT(name_cache, &fn_copy, &tmp) < 0) {
		free((char *)fn_copy);
		goto fail;
	}

	return tmp;
}
Exemple #18
0
bool SP_ModuleBag::resolve(uint64_t ip, SP_Location &loc)
{
    if (d->m_cache.find(ip) != d->m_cache.end()) {
        loc = d->m_cache[ip];
        return true;
    }

#ifdef HAVE_LIBBFD
    if (d->m_main->resolve(ip, loc)) {
        d->m_cache[ip] = loc;
        return true;
    }

    for (auto &map : d->m_maps) {
        if (ip >= map.start && ip <= map.end && map.mod->resolve(ip - map.start, loc)) {
            loc.ip = ip; /* use the loaded address */
            d->m_cache[ip] = loc;
            return true;
        }
    }
#endif
    auto it = d->m_fallback.find(ip);

    if (it != d->m_fallback.end()) {
        loc.ip = ip;
        loc.file = std::string();
        loc.line = 0;
        loc.symbol = it->second;

#ifdef HAVE_LIBIBERTY
        char *demangled = cplus_demangle(it->second.c_str(), DMGL_AUTO);

        if (demangled) {
            loc.symbol = demangled;
            free(demangled);
        }
#endif

        d->m_cache[ip] = loc;
        return true;
    }

    return false;
}
Exemple #19
0
std::string StackTrace::Demangle(const char *mangled) {
  assert(mangled);
  if (!mangled || !*mangled) {
    return "";
  }

  size_t skip_first = 0;
  if (mangled[0] == '.' || mangled[0] == '$') ++skip_first;
  //if (mangled[skip_first] == '_') ++skip_first;

  char *result = cplus_demangle(mangled + skip_first, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
  if (result == nullptr) return mangled;

  std::string ret;
  if (mangled[0] == '.') ret += '.';
  ret += result;
  free (result);
  return ret;
}
Exemple #20
0
        std::string get_symbol(void *ptr)
        {
            if(!ptr)
                return std::string();
            std::ostringstream res;
            res.imbue(std::locale::classic());
            res << ptr<<": ";
            Dl_info info = {0};
            if(dladdr(ptr,&info) == 0) {
                res << "???";
            }
            else {
                if(info.dli_sname) {
                    #if defined(BOOSTER_HAVE_ABI_CXA_DEMANGLE)
                    int status = 0;
                    char *demangled = abi::__cxa_demangle(info.dli_sname,0,0,&status);
                    #elif defined(BOOSTER_HAVE_SOLARIS_DEMANGLE)
                    char demangled[1024];	
                    const int result = cplus_demangle(info.dli_sname, demangled, sizeof(demangled));
                    #else 
                    char *demangled = 0;
                    #endif 
                    if(demangled) {
                        res << demangled;
                        free(demangled);
                    }
                    else {
                        res << info.dli_sname;
                    }
                }
                else {
                    res << "???";
                }

                unsigned offset = (char *)ptr - (char *)info.dli_saddr;
                res << std::hex <<" + 0x" << offset ;

                // We don't print the file name since the function name should be enough.
                // if(info.dli_fname)
                //    res << " in " << info.dli_fname;
            }
           return res.str();
        }
Exemple #21
0
static
BOOL BfdDemangleSymName(LPCTSTR lpName, LPTSTR lpDemangledName, DWORD nSize)
{
	char *res;

	assert(lpName != NULL);

	if((res = cplus_demangle(lpName, DMGL_ANSI /*| DMGL_PARAMS*/)) == NULL)
	{
		lstrcpyn(lpDemangledName, lpName, nSize);
		return FALSE;
	}
	else
	{
		lstrcpyn(lpDemangledName, res, nSize);
		free (res);
		return TRUE;
	}
}
Exemple #22
0
static void
maintenance_demangle(const char *args, int from_tty)
{
  char *demangled;

  if (args == NULL || *args == '\0')
    {
      printf_unfiltered(_("\"maintenance demangle\" takes an argument to demangle.\n"));
    }
  else
    {
      /* APPLE LOCAL: Using language_demangle is wrong here, because this is a
	 simple utility function, and should work in most cases even when the
	 language is not correct... */
#if !(defined(__APPLE__) && defined(__APPLE_CC__))
      demangled = language_demangle(current_language, args,
				    (DMGL_ANSI | DMGL_PARAMS));
#endif /* !(__APPLE__ && __APPLE_CC__) */
      switch (current_language->la_language)
        {
        case language_objc:
          demangled = objc_demangle(args, 0);
          break;
        case language_objcplus:
          demangled = objcplus_demangle(args, (DMGL_ANSI | DMGL_PARAMS));
          break;
        case language_cplus:
        default:
          demangled = cplus_demangle(args, (DMGL_ANSI | DMGL_PARAMS));
          break;
        }

      if (demangled != NULL)
	{
	  printf_unfiltered("%s\n", demangled);
	  xfree(demangled);
	}
      else
	{
	  printf_unfiltered(_("Cannot demangle \"%s\"\n"), args);
	}
    }
}
Exemple #23
0
void StackTraceNoHeap::Demangle(int fd, const char *mangled) {
  assert(mangled);
  if (!mangled || !*mangled) {
    dprintf(fd, "??");
    return ;
  }

  size_t skip_first = 0;
  if (mangled[0] == '.' || mangled[0] == '$') ++skip_first;
  //if (mangled[skip_first] == '_') ++skip_first;

  char *result = cplus_demangle(mangled + skip_first,
                                DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
  if (result == nullptr) {
    dprintf(fd, "%s", mangled);
    return;
  }
  dprintf(fd, "%s%s", mangled[0]=='.' ? "." : "", result);
  return ;
}
Exemple #24
0
int main(int /*argc*/, char **/*argv*/)
{
   char buf[1024];

   while(!feof(stdin))
   {
      fgets(buf, 1024, stdin);
      QByteArray line = buf;
      line = line.trimmed();
      char *res = cplus_demangle(line.data(), DMGL_PARAMS | DMGL_AUTO | DMGL_ANSI );
      if (res)
      {
         printf("%s\n", res);
         free(res);
      }
      else
      {
         printf("%s\n", line.data());
      }
   }
}
Exemple #25
0
char *
demangle (bfd *abfd, const char *name)
{
  char *res;
  const char *p;

  if (abfd != NULL && bfd_get_symbol_leading_char (abfd) == name[0])
    ++name;

  /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
     or the MS PE format.  These formats have a number of leading '.'s
     on at least some symbols, so we remove all dots to avoid
     confusing the demangler.  */
  p = name;
  while (*p == '.')
    ++p;

  res = cplus_demangle (p, DMGL_ANSI | DMGL_PARAMS);
  if (res)
    {
      size_t dots = p - name;

      /* Now put back any stripped dots.  */
      if (dots != 0)
	{
	  size_t len = strlen (res) + 1;
	  char *add_dots = xmalloc (len + dots);

	  memcpy (add_dots, name, dots);
	  memcpy (add_dots + dots, res, len);
	  free (res);
	  res = add_dots;
	}
      return res;
    }

  return xstrdup (name);
}
static struct demangle_component *
mangled_name_to_comp (const char *mangled_name, int options,
		      void **memory, char **demangled_p)
{
  struct demangle_component *ret;
  char *demangled_name;

  /* If it looks like a v3 mangled name, then try to go directly
     to trees.  */
  if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
    {
      ret = cplus_demangle_v3_components (mangled_name, options, memory);
      if (ret)
	{
	  *demangled_p = NULL;
	  return ret;
	}
    }

  /* If it doesn't, or if that failed, then try to demangle the name.  */
  demangled_name = cplus_demangle (mangled_name, options);
  if (demangled_name == NULL)
   return NULL;
  
  /* If we could demangle the name, parse it to build the component tree.  */
  ret = cp_demangled_name_to_comp (demangled_name, NULL);

  if (ret == NULL)
    {
      xfree (demangled_name);
      return NULL;
    }

  *demangled_p = demangled_name;
  return ret;
}
Exemple #27
0
void StackTraceNoHeap::Demangle(FILE *f, const char *mangled) {
  assert(mangled);
  if (!mangled || !*mangled) {
    fprintf(f, "??");
    return ;
  }

#ifndef MAC_OS_X
  size_t skip_first = 0;
  if (mangled[0] == '.' || mangled[0] == '$') ++skip_first;
  //if (mangled[skip_first] == '_') ++skip_first;

  char *result = cplus_demangle(mangled + skip_first, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
  if (result == NULL) {
    fprintf (f, "%s", mangled);
    return;
  }
  fprintf (f, "%s%s", mangled[0]=='.' ? "." : "", result);
  return ;
#else
  fprintf (f, "%s", mangled);
  return ;
#endif
}
Exemple #28
0
static tree
mf_varname_tree (tree decl)
{
  const char *buf_contents;
  tree result;

  gcc_assert (decl);

  pretty_printer buf;

  /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]].  */
  {
    expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (decl));
    const char *sourcefile;
    unsigned sourceline = xloc.line;
    unsigned sourcecolumn = 0;
    sourcecolumn = xloc.column;
    sourcefile = xloc.file;
    if (sourcefile == NULL && current_function_decl != NULL_TREE)
      sourcefile = DECL_SOURCE_FILE (current_function_decl);
    if (sourcefile == NULL)
      sourcefile = "<unknown file>";

    pp_string (&buf, sourcefile);

    if (sourceline != 0)
      {
        pp_colon (&buf);
        pp_decimal_int (&buf, sourceline);

        if (sourcecolumn != 0)
          {
            pp_colon (&buf);
            pp_decimal_int (&buf, sourcecolumn);
          }
      }
  }

  if (current_function_decl != NULL_TREE)
    {
      /* Add (FUNCTION) */
      pp_string (&buf, " (");
      {
        const char *funcname = NULL;
        if (DECL_NAME (current_function_decl))
          funcname = lang_hooks.decl_printable_name (current_function_decl, 1);
        if (funcname == NULL)
          funcname = "anonymous fn";

        pp_string (&buf, funcname);
      }
      pp_string (&buf, ") ");
    }
  else
    pp_space (&buf);

  /* Add <variable-declaration>, possibly demangled.  */
  {
    const char *declname = NULL;

    if (DECL_NAME (decl) != NULL)
      {
	if (strcmp ("GNU C++", lang_hooks.name) == 0)
	  {
	    /* The gcc/cp decl_printable_name hook doesn't do as good a job as
	       the libiberty demangler.  */
	    declname = cplus_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)),
				       DMGL_AUTO | DMGL_VERBOSE);
	  }
	if (declname == NULL)
	  declname = lang_hooks.decl_printable_name (decl, 3);
      }
    if (declname == NULL)
      declname = "<unnamed variable>";

    pp_string (&buf, declname);
  }

  /* Return the lot as a new STRING_CST.  */
  buf_contents = ggc_strdup (pp_formatted_text (&buf));
  result = mf_build_string (buf_contents);
  pp_clear_output_area (&buf);

  return result;
}
char *
mpiPdemangle (const char *mangledSym)
{
  return cplus_demangle (mangledSym, DMGL_ANSI | DMGL_PARAMS);
}
Exemple #30
0
static struct type *
gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
{
  struct type *known_type;
  struct type *rtti_type;
  CORE_ADDR vtbl;
  struct minimal_symbol *minsym;
  char *demangled_name;
  struct type *btype;

  if (full)
    *full = 0;
  if (top)
    *top = -1;
  if (using_enc)
    *using_enc = 0;

  /* Get declared type */
  known_type = value_type (v);
  CHECK_TYPEDEF (known_type);
  /* RTTI works only or class objects */
  if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
    return NULL;

  /* Plan on this changing in the future as i get around to setting
     the vtables properly for G++ compiled stuff.  Also, I'll be using
     the type info functions, which are always right.  Deal with it
     until then.
     JCI - This pretty much useless.  This gets the "true" type 
     correctly when there is single inheritance - but in all such  
     cases that I could find gdb already knows that.  In cases 
     where this points INTO the object (like non-virtual diamond 
     graphs) the demangled name is something like OUTER::INNER 
     and this is not a symbol gdb can resolve, so we fail & return 
     NULL anyway.  Seems like this really isn't going to work till 
     we actually call the RTTI function & parse it. 
*/

  /* If the type has no vptr fieldno, try to get it filled in */
  if (TYPE_VPTR_FIELDNO(known_type) < 0)
    fill_in_vptr_fieldno(known_type);

  /* If we still can't find one, give up */
  if (TYPE_VPTR_FIELDNO(known_type) < 0)
    return NULL;

  /* Make sure our basetype and known type match, otherwise, cast
     so we can get at the vtable properly.
  */
  btype = TYPE_VPTR_BASETYPE (known_type);
  CHECK_TYPEDEF (btype);
  if (btype != known_type )
    {
      v = value_cast (btype, v);
      if (using_enc)
        *using_enc=1;
    }
  /*
    We can't use value_ind here, because it would want to use RTTI, and
    we'd waste a bunch of time figuring out we already know the type.
    Besides, we don't care about the type, just the actual pointer
  */
  if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0)
    return NULL;

  vtbl=value_as_address(value_field(v,TYPE_VPTR_FIELDNO(known_type)));

  /* Try to find a symbol that is the vtable */
  minsym=lookup_minimal_symbol_by_pc(vtbl);
  if (minsym==NULL
      || (demangled_name=DEPRECATED_SYMBOL_NAME (minsym))==NULL
      || !is_vtable_name (demangled_name))
    return NULL;

  /* If we just skip the prefix, we get screwed by namespaces */
  demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI);
  *(strchr(demangled_name,' '))=0;

  /* Lookup the type for the name */
  /* FIXME: chastain/2003-11-26: block=NULL is bogus.  See pr gdb/1465. */
  rtti_type = cp_lookup_rtti_type (demangled_name, NULL);
  if (rtti_type == NULL)
    return NULL;

  if (TYPE_N_BASECLASSES(rtti_type) > 1 &&  full && (*full) != 1)
    {
      if (top)
        *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8;
      if (top && ((*top) >0))
        {
          if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type))
            {
              if (full)
                *full=0;
            }
          else
            {
              if (full)
                *full=1;
            }
        }
    }
  else
    {
      if (full)
        *full=1;
    }

  return rtti_type;
}