/* Generic BFD library interface and support routines.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004
+ 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Written by Cygnus Support.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/*
SECTION
. {* Pointer to linked list of sections. *}
. struct bfd_section *sections;
.
-. {* The place where we add to the section list. *}
-. struct bfd_section **section_tail;
+. {* The last section on the section list. *}
+. struct bfd_section *section_last;
.
. {* The number of sections. *}
. unsigned int section_count;
. {* Pointer to structure which contains architecture information. *}
. const struct bfd_arch_info *arch_info;
.
+. {* Flag set if symbols from this BFD should not be exported. *}
+. bfd_boolean no_export;
+.
. {* Stuff only useful for archives. *}
. void *arelt_data;
. struct bfd *my_archive; {* The containing archive BFD. *}
static const char *_bfd_error_program_name;
-/* This is the default routine to handle BFD error messages. */
+/* This is the default routine to handle BFD error messages.
+ Like fprintf (stderr, ...), but also handles some extra format specifiers.
+
+ %A section name from section. For group components, print group name too.
+ %B file name from bfd. For archive components, prints archive too.
+ */
void
-_bfd_default_error_handler (const char *s, ...)
+_bfd_default_error_handler (const char *fmt, ...)
{
- va_list p;
+ va_list ap;
+ char *bufp;
+ const char *new_fmt, *p;
+ size_t avail = 1000;
+ char buf[1000];
if (_bfd_error_program_name != NULL)
fprintf (stderr, "%s: ", _bfd_error_program_name);
else
fprintf (stderr, "BFD: ");
- va_start (p, s);
- vfprintf (stderr, s, p);
- va_end (p);
+ va_start (ap, fmt);
+ new_fmt = fmt;
+ bufp = buf;
+
+ /* Reserve enough space for the existing format string. */
+ avail -= strlen (fmt) + 1;
+ if (avail > 1000)
+ abort ();
+
+ p = fmt;
+ while (1)
+ {
+ char *q;
+ size_t len, extra, trim;
+
+ p = strchr (p, '%');
+ if (p == NULL || p[1] == '\0')
+ {
+ if (new_fmt == buf)
+ {
+ len = strlen (fmt);
+ memcpy (bufp, fmt, len + 1);
+ }
+ break;
+ }
+
+ if (p[1] == 'A' || p[1] == 'B')
+ {
+ len = p - fmt;
+ memcpy (bufp, fmt, len);
+ bufp += len;
+ fmt = p + 2;
+ new_fmt = buf;
+
+ /* If we run out of space, tough, you lose your ridiculously
+ long file or section name. It's not safe to try to alloc
+ memory here; We might be printing an out of memory message. */
+ if (avail == 0)
+ {
+ *bufp++ = '*';
+ *bufp++ = '*';
+ *bufp = '\0';
+ }
+ else
+ {
+ if (p[1] == 'B')
+ {
+ bfd *abfd = va_arg (ap, bfd *);
+ if (abfd->my_archive)
+ snprintf (bufp, avail, "%s(%s)",
+ abfd->my_archive->filename, abfd->filename);
+ else
+ snprintf (bufp, avail, "%s", abfd->filename);
+ }
+ else
+ {
+ asection *sec = va_arg (ap, asection *);
+ bfd *abfd = sec->owner;
+ const char *group = NULL;
+ struct coff_comdat_info *ci;
+
+ if (abfd != NULL
+ && bfd_get_flavour (abfd) == bfd_target_elf_flavour
+ && elf_next_in_group (sec) != NULL
+ && (sec->flags & SEC_GROUP) == 0)
+ group = elf_group_name (sec);
+ else if (abfd != NULL
+ && bfd_get_flavour (abfd) == bfd_target_coff_flavour
+ && (ci = bfd_coff_get_comdat_section (sec->owner,
+ sec)) != NULL)
+ group = ci->name;
+ if (group != NULL)
+ snprintf (bufp, avail, "%s[%s]", sec->name, group);
+ else
+ snprintf (bufp, avail, "%s", sec->name);
+ }
+ len = strlen (bufp);
+ avail = avail - len + 2;
+
+ /* We need to replace any '%' we printed by "%%".
+ First count how many. */
+ q = bufp;
+ bufp += len;
+ extra = 0;
+ while ((q = strchr (q, '%')) != NULL)
+ {
+ ++q;
+ ++extra;
+ }
+
+ /* If there isn't room, trim off the end of the string. */
+ q = bufp;
+ bufp += extra;
+ if (extra > avail)
+ {
+ trim = extra - avail;
+ bufp -= trim;
+ do
+ {
+ if (*--q == '%')
+ --extra;
+ }
+ while (--trim != 0);
+ *q = '\0';
+ avail = extra;
+ }
+ avail -= extra;
+
+ /* Now double all '%' chars, shuffling the string as we go. */
+ while (extra != 0)
+ {
+ while ((q[extra] = *q) != '%')
+ --q;
+ q[--extra] = '%';
+ --q;
+ }
+ }
+ }
+ p = p + 2;
+ }
+
+ vfprintf (stderr, new_fmt, ap);
+ va_end (ap);
- fprintf (stderr, "\n");
+ putc ('\n', stderr);
}
/* This is a function pointer to the routine which should handle BFD
{
return _bfd_error_handler;
}
-
-/*
-FUNCTION
- bfd_archive_filename
-
-SYNOPSIS
- const char *bfd_archive_filename (bfd *);
-
-DESCRIPTION
- For a BFD that is a component of an archive, returns a string
- with both the archive name and file name. For other BFDs, just
- returns the file name.
-*/
-
-const char *
-bfd_archive_filename (bfd *abfd)
-{
- if (abfd == NULL)
- return NULL;
-
- if (abfd->my_archive)
- {
- static size_t curr = 0;
- static char *buf;
- size_t needed;
-
- needed = (strlen (bfd_get_filename (abfd->my_archive))
- + strlen (bfd_get_filename (abfd)) + 3);
- if (needed > curr)
- {
- if (curr)
- free (buf);
- curr = needed + (needed >> 1);
- buf = bfd_malloc (curr);
- /* If we can't malloc, fail safe by returning just the file
- name. This function is only used when building error
- messages. */
- if (!buf)
- {
- curr = 0;
- return bfd_get_filename (abfd);
- }
- }
- sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
- bfd_get_filename (abfd));
- return buf;
- }
- else
- return bfd_get_filename (abfd);
-}
\f
/*
SECTION
- Symbols
+ Miscellaneous
+
+SUBSECTION
+ Miscellaneous functions
*/
/*
. BFD_SEND (abfd, _bfd_find_nearest_line, \
. (abfd, sec, syms, off, file, func, line))
.
+.#define bfd_find_line(abfd, syms, sym, file, line) \
+. BFD_SEND (abfd, _bfd_find_line, \
+. (abfd, syms, sym, file, line))
+.
+.#define bfd_find_inliner_info(abfd, file, func, line) \
+. BFD_SEND (abfd, _bfd_find_inliner_info, \
+. (abfd, file, func, line))
+.
.#define bfd_debug_info_start(abfd) \
. BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
.
.#define bfd_link_add_symbols(abfd, info) \
. BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
.
-.#define bfd_link_just_syms(sec, info) \
+.#define bfd_link_just_syms(abfd, sec, info) \
. BFD_SEND (abfd, _bfd_link_just_syms, (sec, info))
.
.#define bfd_final_link(abfd, info) \
.#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
. BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
.
-.#define bfd_get_synthetic_symtab(abfd, dynsyms, ret) \
-. BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, dynsyms, ret))
+.#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \
+. BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \
+. dyncount, dynsyms, ret))
.
.#define bfd_get_dynamic_reloc_upper_bound(abfd) \
. BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
. flagword flags;
. const struct bfd_arch_info *arch_info;
. struct bfd_section *sections;
-. struct bfd_section **section_tail;
+. struct bfd_section *section_last;
. unsigned int section_count;
. struct bfd_hash_table section_htab;
.};
preserve->arch_info = abfd->arch_info;
preserve->flags = abfd->flags;
preserve->sections = abfd->sections;
- preserve->section_tail = abfd->section_tail;
+ preserve->section_last = abfd->section_last;
preserve->section_count = abfd->section_count;
preserve->section_htab = abfd->section_htab;
abfd->arch_info = &bfd_default_arch_struct;
abfd->flags &= BFD_IN_MEMORY;
abfd->sections = NULL;
- abfd->section_tail = &abfd->sections;
+ abfd->section_last = NULL;
abfd->section_count = 0;
return TRUE;
abfd->flags = preserve->flags;
abfd->section_htab = preserve->section_htab;
abfd->sections = preserve->sections;
- abfd->section_tail = preserve->section_tail;
+ abfd->section_last = preserve->section_last;
abfd->section_count = preserve->section_count;
/* bfd_release frees all memory more recently bfd_alloc'd than
/*
FUNCTION
- bfd_get_section_ident
+ bfd_hide_symbol
SYNOPSIS
- char *bfd_get_section_ident (asection *sec);
+ void bfd_hide_symbol (bfd *,
+ struct bfd_link_info *,
+ struct bfd_link_hash_entry *,
+ bfd_boolean);
DESCRIPTION
- This function returns "section name[group name]" in a malloced
- buffer if @var{sec} is a member of an ELF section group and
- returns NULL otherwise. The caller should free the non-NULL
- return after use.
+ This function hides a symbol so that it won't be exported.
*/
-char *
-bfd_get_section_ident (asection *sec)
+void
+bfd_hide_symbol (bfd *abfd,
+ struct bfd_link_info *link_info,
+ struct bfd_link_hash_entry *h,
+ bfd_boolean force_local)
{
- char *buf;
- bfd_size_type nlen;
- bfd_size_type glen;
-
- if (sec->owner == NULL
- || bfd_get_flavour (sec->owner) != bfd_target_elf_flavour
- || elf_next_in_group (sec) == NULL
- || (sec->flags & SEC_GROUP) != 0)
- return NULL;
-
- nlen = strlen (sec->name);
- glen = strlen (elf_group_name (sec));
- buf = bfd_malloc (nlen + glen + 2 + 1);
- if (buf != NULL)
- {
- strcpy (buf, sec->name);
- buf [nlen] = '[';
- strcpy (&buf [nlen + 1], elf_group_name (sec));
- buf [nlen + 1 + glen] = ']';
- buf [nlen + 1 + glen + 1] = '\0';
- }
-
- return buf;
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ (get_elf_backend_data (abfd)->elf_backend_hide_symbol)
+ (link_info, (struct elf_link_hash_entry *) h, force_local);
}