daily update
[deliverable/binutils-gdb.git] / bfd / bfd.c
index 79ae8a98a7c37719b6878f5d4243a3776306c521..e4c733c86fdd5f655076852d9778aec3009c1f65 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1,6 +1,6 @@
 /* Generic BFD library interface and support routines.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -202,11 +202,12 @@ CODE_FRAGMENT
 .
 */
 
-#include "bfd.h"
-#include "bfdver.h"
 #include "sysdep.h"
 #include <stdarg.h>
+#include "bfd.h"
+#include "bfdver.h"
 #include "libiberty.h"
+#include "demangle.h"
 #include "safe-ctype.h"
 #include "bfdlink.h"
 #include "libbfd.h"
@@ -1388,6 +1389,15 @@ bfd_fprintf_vma (bfd *abfd, void *stream, bfd_vma value)
 {
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
     get_elf_backend_data (abfd)->elf_backend_fprintf_vma (abfd, stream, value);
+#ifdef BFD64
+  /* fprintf_vma() on a 64-bit enabled host will always print a 64-bit
+     value, but really we want to display the address in the target's
+     address size.  Since we do not have a field in the bfd structure
+     to tell us this, we take a guess, based on the target's name.  */
+  else if (strstr (bfd_get_target (abfd), "64") == NULL
+          && strcmp (bfd_get_target (abfd), "mmo") != 0)
+    fprintf ((FILE *) stream, "%08lx", (unsigned long) (value & 0xffffffff));
+#endif
   else
     fprintf_vma ((FILE *) stream, value);
 }
@@ -1693,3 +1703,85 @@ bfd_emul_set_commonpagesize (const char *emul, bfd_vma size)
                          offsetof (struct elf_backend_data,
                                    commonpagesize), target);
 }
+
+/*
+FUNCTION
+       bfd_demangle
+
+SYNOPSIS
+       char *bfd_demangle (bfd *, const char *, int);
+
+DESCRIPTION
+       Wrapper around cplus_demangle.  Strips leading underscores and
+       other such chars that would otherwise confuse the demangler.
+       If passed a g++ v3 ABI mangled name, returns a buffer allocated
+       with malloc holding the demangled name.  Returns NULL otherwise
+       and on memory alloc failure.
+*/
+
+char *
+bfd_demangle (bfd *abfd, const char *name, int options)
+{
+  char *res, *alloc;
+  const char *pre, *suf;
+  size_t pre_len;
+
+  if (abfd != NULL
+      && *name != '\0'
+      && bfd_get_symbol_leading_char (abfd) == *name)
+    ++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 == '$')
+    ++name;
+  pre_len = name - pre;
+
+  /* Strip off @plt and suchlike too.  */
+  alloc = NULL;
+  suf = strchr (name, '@');
+  if (suf != NULL)
+    {
+      alloc = bfd_malloc (suf - name + 1);
+      if (alloc == NULL)
+       return NULL;
+      memcpy (alloc, name, suf - name);
+      alloc[suf - name] = '\0';
+      name = alloc;
+    }
+
+  res = cplus_demangle (name, options);
+
+  if (alloc != NULL)
+    free (alloc);
+
+  if (res == NULL)
+    return NULL;
+
+  /* Put back any prefix or suffix.  */
+  if (pre_len != 0 || suf != NULL)
+    {
+      size_t len;
+      size_t suf_len;
+      char *final;
+
+      len = strlen (res);
+      if (suf == NULL)
+       suf = res + len;
+      suf_len = strlen (suf) + 1;
+      final = bfd_malloc (pre_len + len + suf_len);
+      if (final == NULL)
+       return NULL;
+
+      memcpy (final, pre, pre_len);
+      memcpy (final + pre_len, res, len);
+      memcpy (final + pre_len + len, suf, suf_len);
+      free (res);
+      res = final;
+    }
+
+  return res;
+}
This page took 0.02857 seconds and 4 git commands to generate.