/* 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, 2008
Free Software Foundation, Inc.
Written by Cygnus Support.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
/*
SECTION
. {* Stuff only useful for archives. *}
. void *arelt_data;
. struct bfd *my_archive; {* The containing archive BFD. *}
-. struct bfd *next; {* The next BFD in the archive. *}
+. struct bfd *archive_next; {* The next BFD in the archive. *}
. struct bfd *archive_head; {* The first BFD in the archive. *}
. bfd_boolean has_armap;
.
.
*/
-#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"
size_t avail = 1000;
char buf[1000];
+ /* PR 4992: Don't interrupt output being sent to stdout. */
+ fflush (stdout);
+
if (_bfd_error_program_name != NULL)
fprintf (stderr, "%s: ", _bfd_error_program_name);
else
if (CONST_STRNEQ (name, "coff-go32")
|| strcmp (name, "pe-i386") == 0
|| strcmp (name, "pei-i386") == 0
+ || strcmp (name, "pe-x86-64") == 0
+ || strcmp (name, "pei-x86-64") == 0
|| strcmp (name, "pe-arm-wince-little") == 0
|| strcmp (name, "pei-arm-wince-little") == 0)
return 1;
_bfd_set_gp_value (bfd *abfd, bfd_vma v)
{
if (! abfd)
- BFD_FAIL ();
+ abort ();
if (abfd->format != bfd_object)
return;
return TRUE;
}
-void
-bfd_sprintf_vma (bfd *abfd, char *buf, bfd_vma value)
+#ifdef BFD64
+/* Return true iff this target is 32-bit. */
+
+static bfd_boolean
+is32bit (bfd *abfd)
{
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
- get_elf_backend_data (abfd)->elf_backend_sprintf_vma (abfd, buf, value);
- else
- sprintf_vma (buf, value);
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ return bed->s->elfclass == ELFCLASS32;
+ }
+
+ /* For non-ELF, make a guess based on the target name. */
+ return (strstr (bfd_get_target (abfd), "64") == NULL
+ && strcmp (bfd_get_target (abfd), "mmo") != 0);
}
+#endif
+
+/* bfd_sprintf_vma and bfd_fprintf_vma display an address in the
+ target's address size. */
void
-bfd_fprintf_vma (bfd *abfd, void *stream, bfd_vma value)
+bfd_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value)
{
- if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
- get_elf_backend_data (abfd)->elf_backend_fprintf_vma (abfd, stream, value);
- else
- fprintf_vma ((FILE *) stream, value);
+#ifdef BFD64
+ if (is32bit (abfd))
+ {
+ sprintf (buf, "%08lx", (unsigned long) value & 0xffffffff);
+ return;
+ }
+#endif
+ sprintf_vma (buf, value);
+}
+
+void
+bfd_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value)
+{
+#ifdef BFD64
+ if (is32bit (abfd))
+ {
+ fprintf ((FILE *) stream, "%08lx", (unsigned long) value & 0xffffffff);
+ return;
+ }
+#endif
+ fprintf_vma ((FILE *) stream, value);
}
/*
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)
+ {
+ 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;
+}