/* Generic ECOFF (Extended-COFF) routines.
- Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1990-2022 Free Software Foundation, Inc.
Original version by Per Bothner.
Full support added by Ian Lance Taylor, ian@cygnus.com.
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. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
+#include "ecoff-bfd.h"
#include "aout/ar.h"
-#include "aout/ranlib.h"
#include "aout/stab_gnu.h"
/* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines
#include "libiberty.h"
#define streq(a, b) (strcmp ((a), (b)) == 0)
-#define strneq(a, b, n) (strncmp ((a), (b), (n)) == 0)
\f
/* This stuff is somewhat copied from coffcode.h. */
static asection bfd_debug_section =
-{
- /* name, id, index, next, prev, flags, user_set_vma, */
- "*DEBUG*", 0, 0, NULL, NULL, 0, 0,
- /* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh, */
- 0, 0, 1, 0,
- /* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, */
- 0, 0, 0, 0,
- /* has_gp_reloc, need_finalize_relax, reloc_done, */
- 0, 0, 0,
- /* vma, lma, size, rawsize, */
- 0, 0, 0, 0,
- /* output_offset, output_section, alignment_power, */
- 0, NULL, 0,
- /* relocation, orelocation, reloc_count, filepos, rel_filepos, */
- NULL, NULL, 0, 0, 0,
- /* line_filepos, userdata, contents, lineno, lineno_count, */
- 0, NULL, NULL, NULL, 0,
- /* entsize, kept_section, moving_line_filepos, */
- 0, NULL, 0,
- /* target_index, used_by_bfd, constructor_chain, owner, */
- 0, NULL, NULL, NULL,
- /* symbol, */
- NULL,
- /* symbol_ptr_ptr, */
- NULL,
- /* map_head, map_tail */
- { NULL }, { NULL }
-};
+ BFD_FAKE_SECTION (bfd_debug_section, NULL, "*DEBUG*", 0, 0);
/* Create an ECOFF object. */
-bfd_boolean
+bool
_bfd_ecoff_mkobject (bfd *abfd)
{
- bfd_size_type amt = sizeof (ecoff_data_type);
+ size_t amt = sizeof (ecoff_data_type);
- abfd->tdata.ecoff_obj_data = bfd_zalloc (abfd, amt);
+ abfd->tdata.ecoff_obj_data = (struct ecoff_tdata *) bfd_zalloc (abfd, amt);
if (abfd->tdata.ecoff_obj_data == NULL)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
/* This is a hook called by coff_real_object_p to create any backend
/* Initialize a new section. */
-bfd_boolean
-_bfd_ecoff_new_section_hook (bfd *abfd ATTRIBUTE_UNUSED,
- asection *section)
+bool
+_bfd_ecoff_new_section_hook (bfd *abfd, asection *section)
{
unsigned int i;
static struct
{ _INIT, SEC_ALLOC | SEC_CODE | SEC_LOAD },
{ _FINI, SEC_ALLOC | SEC_CODE | SEC_LOAD },
{ _DATA, SEC_ALLOC | SEC_DATA | SEC_LOAD },
- { _SDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD },
+ { _SDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_SMALL_DATA },
{ _RDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
- { _LIT8, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
- { _LIT4, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
+ { _LIT8, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_SMALL_DATA},
+ { _LIT4, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_SMALL_DATA},
{ _RCONST, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
{ _PDATA, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
{ _BSS, SEC_ALLOC},
- { _SBSS, SEC_ALLOC},
+ { _SBSS, SEC_ALLOC | SEC_SMALL_DATA},
/* An Irix 4 shared libary. */
{ _LIB, SEC_COFF_SHARED_LIBRARY}
};
uncertain about .init on some systems and I don't know how shared
libraries work. */
- return TRUE;
+ return _bfd_generic_new_section_hook (abfd, section);
+}
+
+void
+_bfd_ecoff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section ATTRIBUTE_UNUSED,
+ void *scnhdr ATTRIBUTE_UNUSED)
+{
}
/* Determine the machine architecture and type. This is called from
below. This could be an ECOFF backend routine, with one version
for each target, but there aren't all that many ECOFF targets. */
-bfd_boolean
+bool
_bfd_ecoff_set_arch_mach_hook (bfd *abfd, void * filehdr)
{
- struct internal_filehdr *internal_f = filehdr;
+ struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
enum bfd_architecture arch;
unsigned long mach;
return bfd_default_set_arch_mach (abfd, arch, mach);
}
+bool
+_bfd_ecoff_no_long_sections (bfd *abfd, int enable)
+{
+ (void) abfd;
+ (void) enable;
+ return false;
+}
+
/* Get the magic number to use based on the architecture and machine.
This is the inverse of _bfd_ecoff_set_arch_mach_hook, above. */
}
styp_flags [] =
{
- { _TEXT, STYP_TEXT },
- { _DATA, STYP_DATA },
- { _SDATA, STYP_SDATA },
- { _RDATA, STYP_RDATA },
- { _LITA, STYP_LITA },
- { _LIT8, STYP_LIT8 },
- { _LIT4, STYP_LIT4 },
- { _BSS, STYP_BSS },
- { _SBSS, STYP_SBSS },
- { _INIT, STYP_ECOFF_INIT },
- { _FINI, STYP_ECOFF_FINI },
- { _PDATA, STYP_PDATA },
- { _XDATA, STYP_XDATA },
- { _LIB, STYP_ECOFF_LIB },
- { _GOT, STYP_GOT },
- { _HASH, STYP_HASH },
- { _DYNAMIC, STYP_DYNAMIC },
- { _LIBLIST, STYP_LIBLIST },
- { _RELDYN, STYP_RELDYN },
- { _CONFLIC, STYP_CONFLIC },
- { _DYNSTR, STYP_DYNSTR },
- { _DYNSYM, STYP_DYNSYM },
- { _RCONST, STYP_RCONST }
+ { _TEXT, STYP_TEXT },
+ { _DATA, STYP_DATA },
+ { _SDATA, STYP_SDATA },
+ { _RDATA, STYP_RDATA },
+ { _LITA, STYP_LITA },
+ { _LIT8, STYP_LIT8 },
+ { _LIT4, STYP_LIT4 },
+ { _BSS, STYP_BSS },
+ { _SBSS, STYP_SBSS },
+ { _INIT, STYP_ECOFF_INIT },
+ { _FINI, STYP_ECOFF_FINI },
+ { _PDATA, STYP_PDATA },
+ { _XDATA, STYP_XDATA },
+ { _LIB, STYP_ECOFF_LIB },
+ { _GOT, STYP_GOT },
+ { _HASH, STYP_HASH },
+ { _DYNAMIC, STYP_DYNAMIC },
+ { _LIBLIST, STYP_LIBLIST },
+ { _RELDYN, STYP_RELDYN },
+ { _CONFLIC, STYP_CONFLIC },
+ { _DYNSTR, STYP_DYNSTR },
+ { _DYNSYM, STYP_DYNSYM },
+ { _RCONST, STYP_RCONST }
};
long styp = 0;
/* Get the BFD flags to use for a section. */
-bfd_boolean
+bool
_bfd_ecoff_styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
void * hdr,
const char *name ATTRIBUTE_UNUSED,
asection *section ATTRIBUTE_UNUSED,
flagword * flags_ptr)
{
- struct internal_scnhdr *internal_s = hdr;
+ struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
long styp_flags = internal_s->s_flags;
flagword sec_flags = 0;
|| styp_flags == STYP_PDATA
|| styp_flags == STYP_RCONST)
sec_flags |= SEC_READONLY;
+ if (styp_flags & STYP_SDATA)
+ sec_flags |= SEC_SMALL_DATA;
}
- else if ((styp_flags & STYP_BSS)
- || (styp_flags & STYP_SBSS))
+ else if (styp_flags & STYP_SBSS)
+ sec_flags |= SEC_ALLOC | SEC_SMALL_DATA;
+ else if (styp_flags & STYP_BSS)
sec_flags |= SEC_ALLOC;
else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT)
sec_flags |= SEC_NEVER_LOAD;
else if ((styp_flags & STYP_LITA)
|| (styp_flags & STYP_LIT8)
|| (styp_flags & STYP_LIT4))
- sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
+ sec_flags |= SEC_DATA |SEC_SMALL_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
else if (styp_flags & STYP_ECOFF_LIB)
sec_flags |= SEC_COFF_SHARED_LIBRARY;
else
sec_flags |= SEC_ALLOC | SEC_LOAD;
* flags_ptr = sec_flags;
- return TRUE;
+ return true;
}
\f
/* Read in the symbolic header for an ECOFF object file. */
-static bfd_boolean
+static bool
ecoff_slurp_symbolic_header (bfd *abfd)
{
const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
/* See if we've already read it in. */
if (ecoff_data (abfd)->debug_info.symbolic_header.magic ==
backend->debug_swap.sym_magic)
- return TRUE;
+ return true;
/* See whether there is a symbolic header. */
if (ecoff_data (abfd)->sym_filepos == 0)
{
- bfd_get_symcount (abfd) = 0;
- return TRUE;
+ abfd->symcount = 0;
+ return true;
}
/* At this point bfd_get_symcount (abfd) holds the number of symbols
if (bfd_get_symcount (abfd) != external_hdr_size)
{
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
/* Read the symbolic information header. */
- raw = bfd_malloc (external_hdr_size);
+ if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0)
+ goto error_return;
+ raw = _bfd_malloc_and_read (abfd, external_hdr_size, external_hdr_size);
if (raw == NULL)
goto error_return;
- if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0
- || bfd_bread (raw, external_hdr_size, abfd) != external_hdr_size)
- goto error_return;
internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
(*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr);
}
/* Now we can get the correct number of symbols. */
- bfd_get_symcount (abfd) = (internal_symhdr->isymMax
- + internal_symhdr->iextMax);
+ abfd->symcount = internal_symhdr->isymMax + internal_symhdr->iextMax;
- if (raw != NULL)
- free (raw);
- return TRUE;
+ free (raw);
+ return true;
error_return:
- if (raw != NULL)
- free (raw);
- return FALSE;
+ free (raw);
+ return false;
}
/* Read in and swap the important symbolic information for an ECOFF
object file. This is called by gdb via the read_debug_info entry
point in the backend structure. */
-bfd_boolean
+bool
_bfd_ecoff_slurp_symbolic_info (bfd *abfd,
asection *ignore ATTRIBUTE_UNUSED,
struct ecoff_debug_info *debug)
struct fdr *fdr_ptr;
bfd_size_type raw_end;
bfd_size_type cb_end;
- bfd_size_type amt;
file_ptr pos;
+ size_t amt;
BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info);
/* Check whether we've already gotten it, and whether there's any to
get. */
if (ecoff_data (abfd)->raw_syments != NULL)
- return TRUE;
+ return true;
if (ecoff_data (abfd)->sym_filepos == 0)
{
- bfd_get_symcount (abfd) = 0;
- return TRUE;
+ abfd->symcount = 0;
+ return true;
}
if (! ecoff_slurp_symbolic_header (abfd))
- return FALSE;
+ return false;
internal_symhdr = &debug->symbolic_header;
if (raw_size == 0)
{
ecoff_data (abfd)->sym_filepos = 0;
- return TRUE;
+ return true;
}
- raw = bfd_alloc (abfd, raw_size);
- if (raw == NULL)
- return FALSE;
-
pos = ecoff_data (abfd)->sym_filepos;
pos += backend->debug_swap.external_hdr_size;
- if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bread (raw, raw_size, abfd) != raw_size)
- {
- bfd_release (abfd, raw);
- return FALSE;
- }
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+ return false;
+ raw = _bfd_alloc_and_read (abfd, raw_size, raw_size);
+ if (raw == NULL)
+ return false;
ecoff_data (abfd)->raw_syments = raw;
We need to look at the fdr to deal with a lot of information in
the symbols, so we swap them here. */
- amt = internal_symhdr->ifdMax;
- amt *= sizeof (struct fdr);
- debug->fdr = bfd_alloc (abfd, amt);
+ if (_bfd_mul_overflow ((unsigned long) internal_symhdr->ifdMax,
+ sizeof (struct fdr), &amt))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ return false;
+ }
+ debug->fdr = (FDR *) bfd_alloc (abfd, amt);
if (debug->fdr == NULL)
- return FALSE;
+ return false;
external_fdr_size = backend->debug_swap.external_fdr_size;
fdr_ptr = debug->fdr;
fraw_src = (char *) debug->external_fdr;
+ /* PR 17512: file: 3372-1243-0.004. */
+ if (fraw_src == NULL && internal_symhdr->ifdMax > 0)
+ return false;
fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size;
for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
(*backend->debug_swap.swap_fdr_in) (abfd, (void *) fraw_src, fdr_ptr);
- return TRUE;
+ return true;
}
\f
/* ECOFF symbol table routines. The ECOFF symbol table is described
faster assembler code. This is what we use for the small common
section. */
static asection ecoff_scom_section;
-static asymbol ecoff_scom_symbol;
-static asymbol *ecoff_scom_symbol_ptr;
+static const asymbol ecoff_scom_symbol =
+ GLOBAL_SYM_INIT (SCOMMON, &ecoff_scom_section);
+static asection ecoff_scom_section =
+ BFD_FAKE_SECTION (ecoff_scom_section, &ecoff_scom_symbol,
+ SCOMMON, 0, SEC_IS_COMMON | SEC_SMALL_DATA);
/* Create an empty symbol. */
asymbol *
_bfd_ecoff_make_empty_symbol (bfd *abfd)
{
- ecoff_symbol_type *new;
- bfd_size_type amt = sizeof (ecoff_symbol_type);
+ ecoff_symbol_type *new_symbol;
+ size_t amt = sizeof (ecoff_symbol_type);
- new = bfd_zalloc (abfd, amt);
- if (new == NULL)
+ new_symbol = (ecoff_symbol_type *) bfd_zalloc (abfd, amt);
+ if (new_symbol == NULL)
return NULL;
- new->symbol.section = NULL;
- new->fdr = NULL;
- new->local = FALSE;
- new->native = NULL;
- new->symbol.the_bfd = abfd;
- return &new->symbol;
+ new_symbol->symbol.section = NULL;
+ new_symbol->fdr = NULL;
+ new_symbol->local = false;
+ new_symbol->native = NULL;
+ new_symbol->symbol.the_bfd = abfd;
+ return &new_symbol->symbol;
}
/* Set the BFD flags and section for an ECOFF symbol. */
-static bfd_boolean
+static bool
ecoff_set_symbol_info (bfd *abfd,
SYMR *ecoff_sym,
asymbol *asym,
if (ECOFF_IS_STAB (ecoff_sym))
{
asym->flags = BSF_DEBUGGING;
- return TRUE;
+ return true;
}
break;
default:
asym->flags = BSF_DEBUGGING;
- return TRUE;
+ return true;
}
if (weak)
{
asym->flags = BSF_LOCAL;
/* Normally, a local stProc symbol will have a corresponding
- external symbol. We mark the local symbol as a debugging
- symbol, in order to prevent nm from printing both out.
- Similarly, we mark stLabel and stabs symbols as debugging
- symbols. In both cases, we do want to set the value
- correctly based on the symbol class. */
+ external symbol. We mark the local symbol as a debugging
+ symbol, in order to prevent nm from printing both out.
+ Similarly, we mark stLabel and stabs symbols as debugging
+ symbols. In both cases, we do want to set the value
+ correctly based on the symbol class. */
if (ecoff_sym->st == stProc
|| ecoff_sym->st == stLabel
|| ECOFF_IS_STAB (ecoff_sym))
}
/* Fall through. */
case scSCommon:
- if (ecoff_scom_section.name == NULL)
- {
- /* Initialize the small common section. */
- ecoff_scom_section.name = SCOMMON;
- ecoff_scom_section.flags = SEC_IS_COMMON;
- ecoff_scom_section.output_section = &ecoff_scom_section;
- ecoff_scom_section.symbol = &ecoff_scom_symbol;
- ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr;
- ecoff_scom_symbol.name = SCOMMON;
- ecoff_scom_symbol.flags = BSF_SECTION_SYM;
- ecoff_scom_symbol.section = &ecoff_scom_section;
- ecoff_scom_symbol_ptr = &ecoff_scom_symbol;
- }
asym->section = &ecoff_scom_section;
asym->flags = 0;
break;
break;
}
}
- return TRUE;
+ return true;
}
/* Read an ECOFF symbol table. */
-bfd_boolean
+bool
_bfd_ecoff_slurp_symbol_table (bfd *abfd)
{
const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
= backend->debug_swap.swap_ext_in;
void (* const swap_sym_in) (bfd *, void *, SYMR *)
= backend->debug_swap.swap_sym_in;
- bfd_size_type internal_size;
ecoff_symbol_type *internal;
ecoff_symbol_type *internal_ptr;
char *eraw_src;
char *eraw_end;
FDR *fdr_ptr;
FDR *fdr_end;
+ size_t amt;
/* If we've already read in the symbol table, do nothing. */
if (ecoff_data (abfd)->canonical_symbols != NULL)
- return TRUE;
+ return true;
/* Get the symbolic information. */
if (! _bfd_ecoff_slurp_symbolic_info (abfd, NULL,
&ecoff_data (abfd)->debug_info))
- return FALSE;
+ return false;
if (bfd_get_symcount (abfd) == 0)
- return TRUE;
+ return true;
- internal_size = bfd_get_symcount (abfd);
- internal_size *= sizeof (ecoff_symbol_type);
- internal = bfd_alloc (abfd, internal_size);
+ if (_bfd_mul_overflow (bfd_get_symcount (abfd),
+ sizeof (ecoff_symbol_type), &amt))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ return false;
+ }
+ internal = (ecoff_symbol_type *) bfd_alloc (abfd, amt);
if (internal == NULL)
- return FALSE;
+ return false;
internal_ptr = internal;
eraw_src = (char *) ecoff_data (abfd)->debug_info.external_ext;
EXTR internal_esym;
(*swap_ext_in) (abfd, (void *) eraw_src, &internal_esym);
+
+ /* PR 17512: file: 3372-1000-0.004. */
+ if (internal_esym.asym.iss >= ecoff_data (abfd)->debug_info.symbolic_header.issExtMax
+ || internal_esym.asym.iss < 0)
+ return false;
+
internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext
+ internal_esym.asym.iss);
+
if (!ecoff_set_symbol_info (abfd, &internal_esym.asym,
&internal_ptr->symbol, 1,
internal_esym.weakext))
- return FALSE;
+ return false;
+
/* The alpha uses a negative ifd field for section symbols. */
if (internal_esym.ifd >= 0)
- internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
- + internal_esym.ifd);
+ {
+ /* PR 17512: file: 3372-1983-0.004. */
+ if (internal_esym.ifd >= ecoff_data (abfd)->debug_info.symbolic_header.ifdMax)
+ internal_ptr->fdr = NULL;
+ else
+ internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
+ + internal_esym.ifd);
+ }
else
internal_ptr->fdr = NULL;
- internal_ptr->local = FALSE;
+ internal_ptr->local = false;
internal_ptr->native = (void *) eraw_src;
}
+ internal_sym.iss);
if (!ecoff_set_symbol_info (abfd, &internal_sym,
&internal_ptr->symbol, 0, 0))
- return FALSE;
+ return false;
internal_ptr->fdr = fdr_ptr;
- internal_ptr->local = TRUE;
+ internal_ptr->local = true;
internal_ptr->native = (void *) lraw_src;
}
}
+ /* PR 17512: file: 3372-3080-0.004.
+ A discrepancy between ecoff_data (abfd)->debug_info.symbolic_header.isymMax
+ and ecoff_data (abfd)->debug_info.symbolic_header.ifdMax can mean that
+ we have fewer symbols than we were expecting. Allow for this by updating
+ the symbol count and warning the user. */
+ if (internal_ptr - internal < (ptrdiff_t) bfd_get_symcount (abfd))
+ {
+ abfd->symcount = internal_ptr - internal;
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: warning: isymMax (%ld) is greater than ifdMax (%ld)"),
+ abfd, ecoff_data (abfd)->debug_info.symbolic_header.isymMax,
+ ecoff_data (abfd)->debug_info.symbolic_header.ifdMax);
+ }
+
ecoff_data (abfd)->canonical_symbols = internal;
- return TRUE;
+ return true;
}
/* Return the amount of space needed for the canonical symbols. */
sprintf (string,
"%s %s { ifd = %u, index = %lu }",
which, name, ifd,
- ((long) indx
+ ((unsigned long) indx
+ debug_info->symbolic_header.iextMax));
}
/* Convert the type information to string format. */
static char *
-ecoff_type_to_string (bfd *abfd, FDR *fdr, unsigned int indx)
+ecoff_type_to_string (bfd *abfd, FDR *fdr, unsigned int indx, char *buff)
{
union aux_ext *aux_ptr;
int bigendian;
unsigned int basic_type;
int i;
char buffer1[1024];
- static char buffer2[1024];
char *p1 = buffer1;
- char *p2 = buffer2;
+ char *p2 = buff;
RNDXR rndx;
aux_ptr = ecoff_data (abfd)->debug_info.external_aux + fdr->iauxBase;
break;
default:
- sprintf (p1, _("Unknown basic type %d"), (int) basic_type);
+ sprintf (p1, _("unknown basic type %d"), (int) basic_type);
break;
}
- p1 += strlen (buffer1);
+ p1 += strlen (p1);
/* If this is a bitfield, get the bitsize. */
if (u.ti.fBitfield)
bitsize = AUX_GET_WIDTH (bigendian, &aux_ptr[indx++]);
sprintf (p1, " : %d", bitsize);
- p1 += strlen (buffer1);
}
/* Deal with any qualifiers. */
if (qualifiers[0].type != tqNil)
{
/* Snarf up any array bounds in the correct order. Arrays
- store 5 successive words in the aux. table:
- word 0 RNDXR to type of the bounds (ie, int)
- word 1 Current file descriptor index
- word 2 low bound
- word 3 high bound (or -1 if [])
- word 4 stride size in bits. */
+ store 5 successive words in the aux. table:
+ word 0 RNDXR to type of the bounds (ie, int)
+ word 1 Current file descriptor index
+ word 2 low bound
+ word 3 high bound (or -1 if [])
+ word 4 stride size in bits. */
for (i = 0; i < 7; i++)
{
if (qualifiers[i].type == tqArray)
(long) (qualifiers[j].stride));
else
- sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
+ sprintf (p2, " {%ld bits}", (long) qualifiers[j].stride);
p2 += strlen (p2);
strcpy (p2, "] of ");
}
strcpy (p2, buffer1);
- return buffer2;
+ return buff;
}
/* Return information about ECOFF symbol SYMBOL in RET. */
/* Return whether this is a local label. */
-bfd_boolean
+bool
_bfd_ecoff_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
const char *name)
{
if (ECOFF_IS_STAB (&ecoff_ext.asym))
;
else if (ecoffsymbol (symbol)->local)
- fprintf (file, _("\n End+1 symbol: %-7ld Type: %s"),
- ((long)
- (AUX_GET_ISYM (bigendian,
- &aux_base[ecoff_ext.asym.index])
- + sym_base)),
- ecoff_type_to_string (abfd, fdr, indx + 1));
+ {
+ char buff[1024];
+ /* xgettext:c-format */
+ fprintf (file, _("\n End+1 symbol: %-7ld Type: %s"),
+ ((long)
+ (AUX_GET_ISYM (bigendian,
+ &aux_base[ecoff_ext.asym.index])
+ + sym_base)),
+ ecoff_type_to_string (abfd, fdr, indx + 1, buff));
+ }
else
fprintf (file, _("\n Local symbol: %ld"),
((long) indx
default:
if (! ECOFF_IS_STAB (&ecoff_ext.asym))
- fprintf (file, _("\n Type: %s"),
- ecoff_type_to_string (abfd, fdr, indx));
+ {
+ char buff[1024];
+ fprintf (file, _("\n Type: %s"),
+ ecoff_type_to_string (abfd, fdr, indx, buff));
+ }
break;
}
}
\f
/* Read in the relocs for a section. */
-static bfd_boolean
+static bool
ecoff_slurp_reloc_table (bfd *abfd,
asection *section,
asymbol **symbols)
arelent *internal_relocs;
bfd_size_type external_reloc_size;
bfd_size_type amt;
- char *external_relocs;
+ bfd_byte *external_relocs;
arelent *rptr;
unsigned int i;
if (section->relocation != NULL
|| section->reloc_count == 0
|| (section->flags & SEC_CONSTRUCTOR) != 0)
- return TRUE;
+ return true;
if (! _bfd_ecoff_slurp_symbol_table (abfd))
- return FALSE;
-
- amt = section->reloc_count;
- amt *= sizeof (arelent);
- internal_relocs = bfd_alloc (abfd, amt);
+ return false;
external_reloc_size = backend->external_reloc_size;
amt = external_reloc_size * section->reloc_count;
- external_relocs = bfd_alloc (abfd, amt);
- if (internal_relocs == NULL || external_relocs == NULL)
- return FALSE;
if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0)
- return FALSE;
- if (bfd_bread (external_relocs, amt, abfd) != amt)
- return FALSE;
+ return false;
+ external_relocs = _bfd_malloc_and_read (abfd, amt, amt);
+ if (external_relocs == NULL)
+ return false;
+
+ amt = section->reloc_count;
+ amt *= sizeof (arelent);
+ internal_relocs = (arelent *) bfd_alloc (abfd, amt);
+ if (internal_relocs == NULL)
+ {
+ free (external_relocs);
+ return false;
+ }
for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++)
{
(*backend->swap_reloc_in) (abfd,
external_relocs + i * external_reloc_size,
&intern);
+ rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+ rptr->addend = 0;
if (intern.r_extern)
{
/* r_symndx is an index into the external symbols. */
- BFD_ASSERT (intern.r_symndx >= 0
- && (intern.r_symndx
- < (ecoff_data (abfd)
- ->debug_info.symbolic_header.iextMax)));
- rptr->sym_ptr_ptr = symbols + intern.r_symndx;
- rptr->addend = 0;
- }
- else if (intern.r_symndx == RELOC_SECTION_NONE
- || intern.r_symndx == RELOC_SECTION_ABS)
- {
- rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
- rptr->addend = 0;
+ if (intern.r_symndx >= 0
+ && (intern.r_symndx
+ < (ecoff_data (abfd)->debug_info.symbolic_header.iextMax)))
+ rptr->sym_ptr_ptr = symbols + intern.r_symndx;
}
else
{
case RELOC_SECTION_FINI: sec_name = _FINI; break;
case RELOC_SECTION_LITA: sec_name = _LITA; break;
case RELOC_SECTION_RCONST: sec_name = _RCONST; break;
- default: abort ();
+ default:
+ sec_name = NULL;
+ break;
}
- sec = bfd_get_section_by_name (abfd, sec_name);
- if (sec == NULL)
- abort ();
- rptr->sym_ptr_ptr = sec->symbol_ptr_ptr;
-
- rptr->addend = - bfd_get_section_vma (abfd, sec);
+ if (sec_name != NULL)
+ {
+ sec = bfd_get_section_by_name (abfd, sec_name);
+ if (sec != NULL)
+ {
+ rptr->sym_ptr_ptr = sec->symbol_ptr_ptr;
+ rptr->addend = - bfd_section_vma (sec);
+ }
+ }
}
- rptr->address = intern.r_vaddr - bfd_get_section_vma (abfd, section);
+ rptr->address = intern.r_vaddr - bfd_section_vma (section);
/* Let the backend select the howto field and do any other
required processing. */
(*backend->adjust_reloc_in) (abfd, &intern, rptr);
}
- bfd_release (abfd, external_relocs);
+ free (external_relocs);
section->relocation = internal_relocs;
- return TRUE;
+ return true;
}
/* Get a canonical list of relocs. */
and return the name of the source file and the line nearest to the
wanted location. */
-bfd_boolean
+bool
_bfd_ecoff_find_nearest_line (bfd *abfd,
+ asymbol **symbols ATTRIBUTE_UNUSED,
asection *section,
- asymbol **ignore_symbols ATTRIBUTE_UNUSED,
bfd_vma offset,
const char **filename_ptr,
const char **functionname_ptr,
- unsigned int *retline_ptr)
+ unsigned int *retline_ptr,
+ unsigned int *discriminator_ptr)
{
const struct ecoff_debug_swap * const debug_swap
= &ecoff_backend (abfd)->debug_swap;
/* Make sure we have the FDR's. */
if (! _bfd_ecoff_slurp_symbolic_info (abfd, NULL, debug_info)
|| bfd_get_symcount (abfd) == 0)
- return FALSE;
+ return false;
if (ecoff_data (abfd)->find_line_info == NULL)
{
- bfd_size_type amt = sizeof (struct ecoff_find_line);
+ size_t amt = sizeof (struct ecoff_find_line);
- ecoff_data (abfd)->find_line_info = bfd_zalloc (abfd, amt);
+ ecoff_data (abfd)->find_line_info =
+ (struct ecoff_find_line *) bfd_zalloc (abfd, amt);
if (ecoff_data (abfd)->find_line_info == NULL)
- return FALSE;
+ return false;
}
- line_info = ecoff_data (abfd)->find_line_info;
+ if (discriminator_ptr)
+ *discriminator_ptr = 0;
+ line_info = ecoff_data (abfd)->find_line_info;
return _bfd_ecoff_locate_line (abfd, section, offset, debug_info,
debug_swap, line_info, filename_ptr,
functionname_ptr, retline_ptr);
the symbol table, so this function only handles the other debugging
information. */
-bfd_boolean
+bool
_bfd_ecoff_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
struct ecoff_debug_info *iinfo = &ecoff_data (ibfd)->debug_info;
int i;
asymbol **sym_ptr_ptr;
size_t c;
- bfd_boolean local;
+ bool local;
/* We only want to copy information over if both BFD's use ECOFF
format. */
if (bfd_get_flavour (ibfd) != bfd_target_ecoff_flavour
|| bfd_get_flavour (obfd) != bfd_target_ecoff_flavour)
- return TRUE;
+ return true;
/* Copy the GP value and the register masks. */
ecoff_data (obfd)->gp = ecoff_data (ibfd)->gp;
c = bfd_get_symcount (obfd);
sym_ptr_ptr = bfd_get_outsymbols (obfd);
if (c == 0 || sym_ptr_ptr == NULL)
- return TRUE;
+ return true;
/* See if there are any local symbols. */
- local = FALSE;
+ local = false;
for (; c > 0; c--, sym_ptr_ptr++)
{
if (ecoffsymbol (*sym_ptr_ptr)->local)
{
- local = TRUE;
+ local = true;
break;
}
}
}
}
- return TRUE;
+ return true;
}
\f
/* Set the architecture. The supported architecture is stored in the
backend pointer. We always set the architecture anyhow, since many
callers ignore the return value. */
-bfd_boolean
+bool
_bfd_ecoff_set_arch_mach (bfd *abfd,
enum bfd_architecture arch,
unsigned long machine)
/* Get the size of the section headers. */
int
-_bfd_ecoff_sizeof_headers (bfd *abfd, bfd_boolean reloc ATTRIBUTE_UNUSED)
+_bfd_ecoff_sizeof_headers (bfd *abfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
asection *current;
int c;
ret = (bfd_coff_filhsz (abfd)
+ bfd_coff_aoutsz (abfd)
+ c * bfd_coff_scnhsz (abfd));
- return BFD_ALIGN (ret, 16);
+ return (int) BFD_ALIGN (ret, 16);
}
/* Get the contents of a section. */
-bfd_boolean
+bool
_bfd_ecoff_get_section_contents (bfd *abfd,
asection *section,
void * location,
/* Calculate the file position for each section, and set
reloc_filepos. */
-static bfd_boolean
+static bool
ecoff_compute_section_file_positions (bfd *abfd)
{
file_ptr sofar, file_sofar;
asection *current;
unsigned int i;
file_ptr old_sofar;
- bfd_boolean rdata_in_text;
- bfd_boolean first_data, first_nonalloc;
+ bool rdata_in_text;
+ bool first_data, first_nonalloc;
const bfd_vma round = ecoff_backend (abfd)->round;
bfd_size_type amt;
- sofar = _bfd_ecoff_sizeof_headers (abfd, FALSE);
+ sofar = _bfd_ecoff_sizeof_headers (abfd, NULL);
file_sofar = sofar;
/* Sort the sections by VMA. */
amt = abfd->section_count;
amt *= sizeof (asection *);
- sorted_hdrs = bfd_malloc (amt);
+ sorted_hdrs = (asection **) bfd_malloc (amt);
if (sorted_hdrs == NULL)
- return FALSE;
+ return false;
for (current = abfd->sections, i = 0;
current != NULL;
current = current->next, i++)
&& ! streq (current->name, _PDATA)
&& ! streq (current->name, _RCONST))
{
- rdata_in_text = FALSE;
+ rdata_in_text = false;
break;
}
}
}
ecoff_data (abfd)->rdata_in_text = rdata_in_text;
- first_data = TRUE;
- first_nonalloc = TRUE;
+ first_data = true;
+ first_nonalloc = true;
for (i = 0; i < abfd->section_count; i++)
{
unsigned int alignment_power;
{
sofar = (sofar + round - 1) &~ (round - 1);
file_sofar = (file_sofar + round - 1) &~ (round - 1);
- first_data = FALSE;
+ first_data = false;
}
else if (streq (current->name, _LIB))
{
&& (abfd->flags & D_PAGED) != 0)
{
/* Skip up to the next page for an unallocated section, such
- as the .comment section on the Alpha. This leaves room
- for the .bss section. */
- first_nonalloc = FALSE;
+ as the .comment section on the Alpha. This leaves room
+ for the .bss section. */
+ first_nonalloc = false;
sofar = (sofar + round - 1) &~ (round - 1);
file_sofar = (file_sofar + round - 1) &~ (round - 1);
}
ecoff_data (abfd)->reloc_filepos = file_sofar;
- return TRUE;
+ return true;
}
/* Determine the location of the relocs for all the sections in the
{
if (! ecoff_compute_section_file_positions (abfd))
abort ();
- abfd->output_has_begun = TRUE;
+ abfd->output_has_begun = true;
}
reloc_base = ecoff_data (abfd)->reloc_filepos;
/* Set the contents of a section. */
-bfd_boolean
+bool
_bfd_ecoff_set_section_contents (bfd *abfd,
asection *section,
const void * location,
going to set output_has_begun to TRUE. */
if (! abfd->output_has_begun
&& ! ecoff_compute_section_file_positions (abfd))
- return FALSE;
+ return false;
/* Handle the .lib section specially so that Irix 4 shared libraries
work out. See coff_set_section_contents in coffcode.h. */
}
if (count == 0)
- return TRUE;
+ return true;
pos = section->filepos + offset;
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|| bfd_bwrite (location, count, abfd) != count)
- return FALSE;
+ return false;
- return TRUE;
-}
-
-/* Get the GP value for an ECOFF file. This is a hook used by
- nlmconv. */
-
-bfd_vma
-bfd_ecoff_get_gp_value (bfd *abfd)
-{
- if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
- || bfd_get_format (abfd) != bfd_object)
- {
- bfd_set_error (bfd_error_invalid_operation);
- return 0;
- }
-
- return ecoff_data (abfd)->gp;
+ return true;
}
/* Set the GP value for an ECOFF file. This is a hook used by the
assembler. */
-bfd_boolean
+bool
bfd_ecoff_set_gp_value (bfd *abfd, bfd_vma gp_value)
{
if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
|| bfd_get_format (abfd) != bfd_object)
{
bfd_set_error (bfd_error_invalid_operation);
- return FALSE;
+ return false;
}
ecoff_data (abfd)->gp = gp_value;
- return TRUE;
+ return true;
}
/* Set the register masks for an ECOFF file. This is a hook used by
the assembler. */
-bfd_boolean
+bool
bfd_ecoff_set_regmasks (bfd *abfd,
unsigned long gprmask,
unsigned long fprmask,
|| bfd_get_format (abfd) != bfd_object)
{
bfd_set_error (bfd_error_invalid_operation);
- return FALSE;
+ return false;
}
tdata = ecoff_data (abfd);
tdata->cprmask[i] = cprmask[i];
}
- return TRUE;
+ return true;
}
/* Get ECOFF EXTR information for an external symbol. This function
is passed to bfd_ecoff_debug_externals. */
-static bfd_boolean
+static bool
ecoff_get_extr (asymbol *sym, EXTR *esym)
{
ecoff_symbol_type *ecoff_sym_ptr;
if ((sym->flags & BSF_DEBUGGING) != 0
|| (sym->flags & BSF_LOCAL) != 0
|| (sym->flags & BSF_SECTION_SYM) != 0)
- return FALSE;
+ return false;
esym->jmptbl = 0;
esym->cobol_main = 0;
esym->asym.sc = scAbs;
esym->asym.reserved = 0;
esym->asym.index = indexNil;
- return TRUE;
+ return true;
}
ecoff_sym_ptr = ecoffsymbol (sym);
if (ecoff_sym_ptr->local)
- return FALSE;
+ return false;
input_bfd = bfd_asymbol_bfd (sym);
(*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in))
symbol. */
if ((esym->asym.sc == scUndefined
|| esym->asym.sc == scSUndefined)
- && ! bfd_is_und_section (bfd_get_section (sym)))
+ && ! bfd_is_und_section (bfd_asymbol_section (sym)))
esym->asym.sc = scAbs;
/* Adjust the FDR index for the symbol by that used for the input
esym->ifd = input_debug->ifdmap[esym->ifd];
}
- return TRUE;
+ return true;
}
/* Set the external symbol index. This routine is passed to
/* Write out an ECOFF file. */
-bfd_boolean
+bool
_bfd_ecoff_write_object_contents (bfd *abfd)
{
const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
bfd_size_type reloc_size;
bfd_size_type text_size;
bfd_vma text_start;
- bfd_boolean set_text_start;
+ bool set_text_start;
bfd_size_type data_size;
bfd_vma data_start;
- bfd_boolean set_data_start;
+ bool set_data_start;
bfd_size_type bss_size;
void * buff = NULL;
void * reloc_buff = NULL;
}
if ((abfd->flags & D_PAGED) != 0)
- text_size = _bfd_ecoff_sizeof_headers (abfd, FALSE);
+ text_size = _bfd_ecoff_sizeof_headers (abfd, NULL);
else
text_size = 0;
text_start = 0;
- set_text_start = FALSE;
+ set_text_start = false;
data_size = 0;
data_start = 0;
- set_data_start = FALSE;
+ set_data_start = false;
bss_size = 0;
/* Write section headers to the file. */
strncpy (section.s_name, current->name, sizeof section.s_name);
/* This seems to be correct for Irix 4 shared libraries. */
- vma = bfd_get_section_vma (abfd, current);
+ vma = bfd_section_vma (current);
if (streq (current->name, _LIB))
section.s_vaddr = 0;
else
if (! set_text_start || text_start > vma)
{
text_start = vma;
- set_text_start = TRUE;
+ set_text_start = true;
}
}
else if ((section.s_flags & STYP_RDATA) != 0
if (! set_data_start || data_start > vma)
{
data_start = vma;
- set_data_start = TRUE;
+ set_data_start = true;
}
}
else if ((section.s_flags & STYP_BSS) != 0
if (reloc->howto == NULL)
continue;
- in.r_vaddr = (reloc->address
- + bfd_get_section_vma (abfd, current));
+ in.r_vaddr = reloc->address + bfd_section_vma (current);
in.r_type = reloc->howto->type;
if ((sym->flags & BSF_SECTION_SYM) == 0)
else
{
const char *name;
- unsigned int i;
+ unsigned int j;
static struct
{
const char * name;
{ _RCONST, RELOC_SECTION_RCONST }
};
- name = bfd_get_section_name (abfd, bfd_get_section (sym));
+ name = bfd_section_name (bfd_asymbol_section (sym));
- for (i = 0; i < ARRAY_SIZE (section_symndx); i++)
- if (streq (name, section_symndx[i].name))
+ for (j = 0; j < ARRAY_SIZE (section_symndx); j++)
+ if (streq (name, section_symndx[j].name))
{
- in.r_symndx = section_symndx[i].r_symndx;
+ in.r_symndx = section_symndx[j].r_symndx;
break;
}
- if (i == ARRAY_SIZE (section_symndx))
+ if (j == ARRAY_SIZE (section_symndx))
abort ();
in.r_extern = 0;
}
if (reloc_buff != NULL)
bfd_release (abfd, reloc_buff);
- if (buff != NULL)
- free (buff);
- return TRUE;
+ free (buff);
+ return true;
error_return:
if (reloc_buff != NULL)
bfd_release (abfd, reloc_buff);
- if (buff != NULL)
- free (buff);
- return FALSE;
+ free (buff);
+ return false;
}
\f
/* Archive handling. ECOFF uses what appears to be a unique type of
The Alpha seems to use ________64E[BL]E[BL]_. */
-#define ARMAP_BIG_ENDIAN 'B'
-#define ARMAP_LITTLE_ENDIAN 'L'
-#define ARMAP_MARKER 'E'
-#define ARMAP_START_LENGTH 10
+#define ARMAP_BIG_ENDIAN 'B'
+#define ARMAP_LITTLE_ENDIAN 'L'
+#define ARMAP_MARKER 'E'
+#define ARMAP_START_LENGTH 10
#define ARMAP_HEADER_MARKER_INDEX 10
-#define ARMAP_HEADER_ENDIAN_INDEX 11
-#define ARMAP_OBJECT_MARKER_INDEX 12
-#define ARMAP_OBJECT_ENDIAN_INDEX 13
-#define ARMAP_END_INDEX 14
-#define ARMAP_END "_ "
+#define ARMAP_HEADER_ENDIAN_INDEX 11
+#define ARMAP_OBJECT_MARKER_INDEX 12
+#define ARMAP_OBJECT_ENDIAN_INDEX 13
+#define ARMAP_END_INDEX 14
+#define ARMAP_END "_ "
/* This is a magic number used in the hashing algorithm. */
-#define ARMAP_HASH_MAGIC 0x9dd68ab5
+#define ARMAP_HASH_MAGIC 0x9dd68ab5
/* This returns the hash value to use for a string. It also sets
*REHASH to the rehash adjustment if the first slot is taken. SIZE
/* Read in the armap. */
-bfd_boolean
+bool
_bfd_ecoff_slurp_armap (bfd *abfd)
{
char nextname[17];
unsigned int i;
struct areltdata *mapdata;
- bfd_size_type parsed_size;
+ bfd_size_type parsed_size, stringsize;
char *raw_armap;
struct artdata *ardata;
unsigned int count;
char *raw_ptr;
- struct symdef *symdef_ptr;
+ carsym *symdef_ptr;
char *stringbase;
bfd_size_type amt;
/* Get the name of the first element. */
i = bfd_bread ((void *) nextname, (bfd_size_type) 16, abfd);
if (i == 0)
- return TRUE;
+ return true;
if (i != 16)
- return FALSE;
+ return false;
if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
- return FALSE;
+ return false;
/* Irix 4.0.5F apparently can use either an ECOFF armap or a
standard COFF armap. We could move the ECOFF armap stuff into
bfd_slurp_armap, but that seems inappropriate since no other
target uses this format. Instead, we check directly for a COFF
armap. */
- if (strneq (nextname, "/ ", 16))
+ if (startswith (nextname, "/ "))
return bfd_slurp_armap (abfd);
/* See if the first element is an armap. */
- if (! strneq (nextname, ecoff_backend (abfd)->armap_start, ARMAP_START_LENGTH)
+ if (strncmp (nextname, ecoff_backend (abfd)->armap_start, ARMAP_START_LENGTH) != 0
|| nextname[ARMAP_HEADER_MARKER_INDEX] != ARMAP_MARKER
|| (nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN
&& nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN)
|| nextname[ARMAP_OBJECT_MARKER_INDEX] != ARMAP_MARKER
|| (nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN
&& nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN)
- || ! strneq (nextname + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1))
+ || strncmp (nextname + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1) != 0)
{
- bfd_has_map (abfd) = FALSE;
- return TRUE;
+ abfd->has_armap = false;
+ return true;
}
/* Make sure we have the right byte ordering. */
^ (bfd_big_endian (abfd))))
{
bfd_set_error (bfd_error_wrong_format);
- return FALSE;
+ return false;
}
/* Read in the armap. */
ardata = bfd_ardata (abfd);
mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
if (mapdata == NULL)
- return FALSE;
+ return false;
parsed_size = mapdata->parsed_size;
- bfd_release (abfd, (void *) mapdata);
+ free (mapdata);
- raw_armap = bfd_alloc (abfd, parsed_size);
- if (raw_armap == NULL)
- return FALSE;
-
- if (bfd_bread ((void *) raw_armap, parsed_size, abfd) != parsed_size)
+ if (parsed_size + 1 < 9)
{
- if (bfd_get_error () != bfd_error_system_call)
- bfd_set_error (bfd_error_malformed_archive);
- bfd_release (abfd, (void *) raw_armap);
- return FALSE;
+ bfd_set_error (bfd_error_malformed_archive);
+ return false;
}
+ raw_armap = (char *) _bfd_alloc_and_read (abfd, parsed_size + 1, parsed_size);
+ if (raw_armap == NULL)
+ return false;
+ raw_armap[parsed_size] = 0;
+
ardata->tdata = (void *) raw_armap;
count = H_GET_32 (abfd, raw_armap);
+ if ((parsed_size - 8) / 8 < count)
+ goto error_malformed;
ardata->symdef_count = 0;
ardata->cache = NULL;
/* This code used to overlay the symdefs over the raw archive data,
but that doesn't work on a 64 bit host. */
stringbase = raw_armap + count * 8 + 8;
+ stringsize = parsed_size - (count * 8 + 8);
#ifdef CHECK_ARMAP_HASH
{
++ardata->symdef_count;
amt = ardata->symdef_count;
- amt *= sizeof (struct symdef);
- symdef_ptr = bfd_alloc (abfd, amt);
+ amt *= sizeof (carsym);
+ symdef_ptr = (carsym *) bfd_alloc (abfd, amt);
if (!symdef_ptr)
- return FALSE;
+ goto error_exit;
- ardata->symdefs = (carsym *) symdef_ptr;
+ ardata->symdefs = symdef_ptr;
raw_ptr = raw_armap + 4;
for (i = 0; i < count; i++, raw_ptr += 8)
if (file_offset == 0)
continue;
name_offset = H_GET_32 (abfd, raw_ptr);
- symdef_ptr->s.name = stringbase + name_offset;
+ if (name_offset > stringsize)
+ goto error_malformed;
+ symdef_ptr->name = stringbase + name_offset;
symdef_ptr->file_offset = file_offset;
++symdef_ptr;
}
ardata->first_file_filepos = bfd_tell (abfd);
/* Pad to an even boundary. */
ardata->first_file_filepos += ardata->first_file_filepos % 2;
+ abfd->has_armap = true;
+ return true;
- bfd_has_map (abfd) = TRUE;
-
- return TRUE;
+ error_malformed:
+ bfd_set_error (bfd_error_malformed_archive);
+ error_exit:
+ ardata->symdef_count = 0;
+ ardata->symdefs = NULL;
+ ardata->tdata = NULL;
+ bfd_release (abfd, raw_armap);
+ return false;
}
/* Write out an armap. */
-bfd_boolean
+bool
_bfd_ecoff_write_armap (bfd *abfd,
unsigned int elength,
struct orl *map,
complain that the index is out of date. Actually, the Ultrix
linker just checks the archive name; the GNU linker may check the
date. */
- stat (abfd->filename, &statbuf);
- sprintf (hdr.ar_date, "%ld", (long) (statbuf.st_mtime + 60));
+ stat (bfd_get_filename (abfd), &statbuf);
+ _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
+ (long) (statbuf.st_mtime + 60));
/* The DECstation uses zeroes for the uid, gid and mode of the
armap. */
hdr.ar_mode[1] = '4';
hdr.ar_mode[2] = '4';
- sprintf (hdr.ar_size, "%-10d", (int) mapsize);
+ _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize);
hdr.ar_fmag[0] = '`';
hdr.ar_fmag[1] = '\012';
if (bfd_bwrite ((void *) &hdr, (bfd_size_type) sizeof (struct ar_hdr), abfd)
!= sizeof (struct ar_hdr))
- return FALSE;
+ return false;
H_PUT_32 (abfd, hashsize, temp);
if (bfd_bwrite ((void *) temp, (bfd_size_type) 4, abfd) != 4)
- return FALSE;
+ return false;
- hashtable = bfd_zalloc (abfd, symdefsize);
+ hashtable = (bfd_byte *) bfd_zalloc (abfd, symdefsize);
if (!hashtable)
- return FALSE;
+ return false;
current = abfd->archive_head;
last_elt = current;
for (i = 0; i < orl_count; i++)
{
- unsigned int hash, rehash;
+ unsigned int hash, rehash = 0;
/* Advance firstreal to the file position of this archive
element. */
{
firstreal += arelt_size (current) + sizeof (struct ar_hdr);
firstreal += firstreal % 2;
- current = current->next;
+ current = current->archive_next;
}
while (current != map[i].u.abfd);
}
}
if (bfd_bwrite ((void *) hashtable, symdefsize, abfd) != symdefsize)
- return FALSE;
+ return false;
bfd_release (abfd, hashtable);
/* Now write the strings. */
H_PUT_32 (abfd, stringsize, temp);
if (bfd_bwrite ((void *) temp, (bfd_size_type) 4, abfd) != 4)
- return FALSE;
+ return false;
for (i = 0; i < orl_count; i++)
{
bfd_size_type len;
len = strlen (*map[i].name) + 1;
if (bfd_bwrite ((void *) (*map[i].name), len, abfd) != len)
- return FALSE;
+ return false;
}
/* The spec sez this should be a newline. But in order to be
if (padit)
{
if (bfd_bwrite ("", (bfd_size_type) 1, abfd) != 1)
- return FALSE;
+ return false;
}
- return TRUE;
-}
-
-/* See whether this BFD is an archive. If it is, read in the armap
- and the extended name table. */
-
-const bfd_target *
-_bfd_ecoff_archive_p (bfd *abfd)
-{
- struct artdata *tdata_hold;
- char armag[SARMAG + 1];
- bfd_size_type amt;
-
- if (bfd_bread ((void *) armag, (bfd_size_type) SARMAG, abfd) != SARMAG)
- {
- if (bfd_get_error () != bfd_error_system_call)
- bfd_set_error (bfd_error_wrong_format);
- return NULL;
- }
-
- if (! strneq (armag, ARMAG, SARMAG))
- {
- bfd_set_error (bfd_error_wrong_format);
- return NULL;
- }
-
- tdata_hold = bfd_ardata (abfd);
-
- amt = sizeof (struct artdata);
- bfd_ardata (abfd) = bfd_zalloc (abfd, amt);
- if (bfd_ardata (abfd) == NULL)
- {
- bfd_ardata (abfd) = tdata_hold;
- return NULL;
- }
-
- bfd_ardata (abfd)->first_file_filepos = SARMAG;
- /* Already cleared by bfd_zalloc above.
- bfd_ardata (abfd)->cache = NULL;
- bfd_ardata (abfd)->archive_head = NULL;
- bfd_ardata (abfd)->symdefs = NULL;
- bfd_ardata (abfd)->extended_names = NULL;
- bfd_ardata (abfd)->extended_names_size = 0;
- bfd_ardata (abfd)->tdata = NULL; */
-
- if (! _bfd_ecoff_slurp_armap (abfd)
- || ! _bfd_ecoff_slurp_extended_name_table (abfd))
- {
- bfd_release (abfd, bfd_ardata (abfd));
- bfd_ardata (abfd) = tdata_hold;
- return NULL;
- }
-
- if (bfd_has_map (abfd))
- {
- bfd *first;
-
- /* This archive has a map, so we may presume that the contents
- are object files. Make sure that if the first file in the
- archive can be recognized as an object file, it is for this
- target. If not, assume that this is the wrong format. If
- the first file is not an object file, somebody is doing
- something weird, and we permit it so that ar -t will work. */
-
- first = bfd_openr_next_archived_file (abfd, NULL);
- if (first != NULL)
- {
- first->target_defaulted = FALSE;
- if (bfd_check_format (first, bfd_object)
- && first->xvec != abfd->xvec)
- {
- /* We ought to close `first' here, but we can't, because
- we have no way to remove it from the archive cache.
- It's almost impossible to figure out when we can
- release bfd_ardata. FIXME. */
- bfd_set_error (bfd_error_wrong_object_format);
- bfd_ardata (abfd) = tdata_hold;
- return NULL;
- }
- /* And we ought to close `first' here too. */
- }
- }
-
- return abfd->xvec;
+ return true;
}
\f
/* ECOFF linker code. */
_bfd_ecoff_bfd_link_hash_table_create (bfd *abfd)
{
struct ecoff_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct ecoff_link_hash_table);
+ size_t amt = sizeof (struct ecoff_link_hash_table);
- ret = bfd_malloc (amt);
+ ret = (struct ecoff_link_hash_table *) bfd_malloc (amt);
if (ret == NULL)
return NULL;
if (!_bfd_link_hash_table_init (&ret->root, abfd,
((struct ecoff_link_hash_entry *) \
bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
-/* Traverse an ECOFF link hash table. */
-
-#define ecoff_link_hash_traverse(table, func, info) \
- (bfd_link_hash_traverse \
- (&(table)->root, \
- (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func), \
- (info)))
-
/* Get the ECOFF link hash table from the info structure. This is
just a cast. */
explicitly save any information we may need later on in the link.
We do not want to read the external symbol information again. */
-static bfd_boolean
+static bool
ecoff_link_add_externals (bfd *abfd,
struct bfd_link_info *info,
void * external_ext,
amt = ext_count;
amt *= sizeof (struct bfd_link_hash_entry *);
- sym_hash = bfd_alloc (abfd, amt);
+ sym_hash = (struct bfd_link_hash_entry **) bfd_alloc (abfd, amt);
if (!sym_hash)
- return FALSE;
+ return false;
ecoff_data (abfd)->sym_hashes = (struct ecoff_link_hash_entry **) sym_hash;
ext_ptr = (char *) external_ext;
for (; ext_ptr < ext_end; ext_ptr += external_ext_size, sym_hash++)
{
EXTR esym;
- bfd_boolean skip;
+ bool skip;
bfd_vma value;
asection *section;
const char *name;
(*swap_ext_in) (abfd, (void *) ext_ptr, &esym);
/* Skip debugging symbols. */
- skip = FALSE;
+ skip = false;
switch (esym.asym.st)
{
case stGlobal:
case stStaticProc:
break;
default:
- skip = TRUE;
+ skip = true;
break;
}
}
/* Fall through. */
case scSCommon:
- if (ecoff_scom_section.name == NULL)
- {
- /* Initialize the small common section. */
- ecoff_scom_section.name = SCOMMON;
- ecoff_scom_section.flags = SEC_IS_COMMON;
- ecoff_scom_section.output_section = &ecoff_scom_section;
- ecoff_scom_section.symbol = &ecoff_scom_symbol;
- ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr;
- ecoff_scom_symbol.name = SCOMMON;
- ecoff_scom_symbol.flags = BSF_SECTION_SYM;
- ecoff_scom_symbol.section = &ecoff_scom_section;
- ecoff_scom_symbol_ptr = &ecoff_scom_symbol;
- }
section = &ecoff_scom_section;
break;
case scSUndefined:
if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name,
(flagword) (esym.weakext ? BSF_WEAK : BSF_GLOBAL),
- section, value, NULL, TRUE, TRUE, sym_hash)))
- return FALSE;
+ section, value, NULL, true, true, sym_hash)))
+ return false;
h = (struct ecoff_link_hash_entry *) *sym_hash;
/* If we are building an ECOFF hash table, save the external
symbol information. */
- if (info->hash->creator->flavour == bfd_get_flavour (abfd))
+ if (bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd))
{
if (h->abfd == NULL
|| (! bfd_is_und_section (section)
}
}
- return TRUE;
+ return true;
}
/* Add symbols from an ECOFF object file to the global linker hash
table. */
-static bfd_boolean
+static bool
ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
{
HDRR *symhdr;
void * external_ext = NULL;
bfd_size_type esize;
char *ssext = NULL;
- bfd_boolean result;
+ bool result;
if (! ecoff_slurp_symbolic_header (abfd))
- return FALSE;
+ return false;
/* If there are no symbols, we don't want it. */
if (bfd_get_symcount (abfd) == 0)
- return TRUE;
+ return true;
symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
/* Read in the external symbols and external strings. */
+ if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0)
+ return false;
external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size;
esize = symhdr->iextMax * external_ext_size;
- external_ext = bfd_malloc (esize);
+ external_ext = _bfd_malloc_and_read (abfd, esize, esize);
if (external_ext == NULL && esize != 0)
goto error_return;
- if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0
- || bfd_bread (external_ext, esize, abfd) != esize)
+ if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0)
goto error_return;
-
- ssext = bfd_malloc ((bfd_size_type) symhdr->issExtMax);
+ ssext = (char *) _bfd_malloc_and_read (abfd, symhdr->issExtMax,
+ symhdr->issExtMax);
if (ssext == NULL && symhdr->issExtMax != 0)
goto error_return;
- if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0
- || (bfd_bread (ssext, (bfd_size_type) symhdr->issExtMax, abfd)
- != (bfd_size_type) symhdr->issExtMax))
- goto error_return;
-
result = ecoff_link_add_externals (abfd, info, external_ext, ssext);
- if (ssext != NULL)
- free (ssext);
- if (external_ext != NULL)
- free (external_ext);
+ free (ssext);
+ free (external_ext);
return result;
error_return:
- if (ssext != NULL)
- free (ssext);
- if (external_ext != NULL)
- free (external_ext);
- return FALSE;
+ free (ssext);
+ free (external_ext);
+ return false;
}
/* This is called if we used _bfd_generic_link_add_archive_symbols
because we were not dealing with an ECOFF archive. */
-static bfd_boolean
+static bool
ecoff_link_check_archive_element (bfd *abfd,
struct bfd_link_info *info,
- bfd_boolean *pneeded)
+ struct bfd_link_hash_entry *h,
+ const char *name,
+ bool *pneeded)
{
- const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
- void (* const swap_ext_in) (bfd *, void *, EXTR *)
- = backend->debug_swap.swap_ext_in;
- HDRR *symhdr;
- bfd_size_type external_ext_size;
- void * external_ext = NULL;
- bfd_size_type esize;
- char *ssext = NULL;
- char *ext_ptr;
- char *ext_end;
-
- *pneeded = FALSE;
-
- if (! ecoff_slurp_symbolic_header (abfd))
- goto error_return;
-
- /* If there are no symbols, we don't want it. */
- if (bfd_get_symcount (abfd) == 0)
- goto successful_return;
-
- symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
-
- /* Read in the external symbols and external strings. */
- external_ext_size = backend->debug_swap.external_ext_size;
- esize = symhdr->iextMax * external_ext_size;
- external_ext = bfd_malloc (esize);
- if (external_ext == NULL && esize != 0)
- goto error_return;
+ *pneeded = false;
- if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0
- || bfd_bread (external_ext, esize, abfd) != esize)
- goto error_return;
+ /* Unlike the generic linker, we do not pull in elements because
+ of common symbols. */
+ if (h->type != bfd_link_hash_undefined)
+ return true;
- ssext = bfd_malloc ((bfd_size_type) symhdr->issExtMax);
- if (ssext == NULL && symhdr->issExtMax != 0)
- goto error_return;
+ /* Include this element? */
+ if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
+ return true;
+ *pneeded = true;
- if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0
- || (bfd_bread (ssext, (bfd_size_type) symhdr->issExtMax, abfd)
- != (bfd_size_type) symhdr->issExtMax))
- goto error_return;
-
- /* Look through the external symbols to see if they define some
- symbol that is currently undefined. */
- ext_ptr = (char *) external_ext;
- ext_end = ext_ptr + esize;
- for (; ext_ptr < ext_end; ext_ptr += external_ext_size)
- {
- EXTR esym;
- bfd_boolean def;
- const char *name;
- struct bfd_link_hash_entry *h;
-
- (*swap_ext_in) (abfd, (void *) ext_ptr, &esym);
-
- /* See if this symbol defines something. */
- if (esym.asym.st != stGlobal
- && esym.asym.st != stLabel
- && esym.asym.st != stProc)
- continue;
-
- switch (esym.asym.sc)
- {
- case scText:
- case scData:
- case scBss:
- case scAbs:
- case scSData:
- case scSBss:
- case scRData:
- case scCommon:
- case scSCommon:
- case scInit:
- case scFini:
- case scRConst:
- def = TRUE;
- break;
- default:
- def = FALSE;
- break;
- }
-
- if (! def)
- continue;
-
- name = ssext + esym.asym.iss;
- h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
-
- /* Unlike the generic linker, we do not pull in elements because
- of common symbols. */
- if (h == NULL
- || h->type != bfd_link_hash_undefined)
- continue;
-
- /* Include this element. */
- if (! (*info->callbacks->add_archive_element) (info, abfd, name))
- goto error_return;
- if (! ecoff_link_add_externals (abfd, info, external_ext, ssext))
- goto error_return;
-
- *pneeded = TRUE;
- goto successful_return;
- }
-
- successful_return:
- if (external_ext != NULL)
- free (external_ext);
- if (ssext != NULL)
- free (ssext);
- return TRUE;
- error_return:
- if (external_ext != NULL)
- free (external_ext);
- if (ssext != NULL)
- free (ssext);
- return FALSE;
+ return ecoff_link_add_object_symbols (abfd, info);
}
/* Add the symbols from an archive file to the global hash table.
already have a hash table, so there is no reason to construct
another one. */
-static bfd_boolean
+static bool
ecoff_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
{
const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
{
/* An empty archive is a special case. */
if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
- return TRUE;
+ return true;
bfd_set_error (bfd_error_no_armap);
- return FALSE;
+ return false;
}
/* If we don't have any raw data for this archive, as can happen on
while (*pundef != NULL)
{
struct bfd_link_hash_entry *h;
- unsigned int hash, rehash;
+ unsigned int hash, rehash = 0;
unsigned int file_offset;
const char *name;
bfd *element;
|| ! streq (name, h->root.string))
{
unsigned int srch;
- bfd_boolean found;
+ bool found;
/* That was the wrong symbol. Try rehashing. */
- found = FALSE;
+ found = false;
for (srch = (hash + rehash) & (armap_count - 1);
srch != hash;
srch = (srch + rehash) & (armap_count - 1))
if (name[0] == h->root.string[0]
&& streq (name, h->root.string))
{
- found = TRUE;
+ found = true;
break;
}
}
hash = srch;
}
- element = (*backend->get_elt_at_filepos) (abfd, (file_ptr) file_offset);
+ element = (*backend->get_elt_at_filepos) (abfd,
+ (file_ptr) file_offset,
+ info);
if (element == NULL)
- return FALSE;
+ return false;
if (! bfd_check_format (element, bfd_object))
- return FALSE;
+ return false;
/* Unlike the generic linker, we know that this element provides
a definition for an undefined symbol and we know that we want
to include it. We don't need to check anything. */
- if (! (*info->callbacks->add_archive_element) (info, element, name))
- return FALSE;
+ if (!(*info->callbacks
+ ->add_archive_element) (info, element, name, &element))
+ return false;
if (! ecoff_link_add_object_symbols (element, info))
- return FALSE;
+ return false;
pundef = &(*pundef)->u.undef.next;
}
- return TRUE;
+ return true;
}
/* Given an ECOFF BFD, add symbols to the global hash table as
appropriate. */
-bfd_boolean
+bool
_bfd_ecoff_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
switch (bfd_get_format (abfd))
return ecoff_link_add_archive_symbols (abfd, info);
default:
bfd_set_error (bfd_error_wrong_format);
- return FALSE;
+ return false;
}
}
output BFD. This must read in the symbolic information of the
input BFD. */
-static bfd_boolean
+static bool
ecoff_final_link_debug_accumulate (bfd *output_bfd,
bfd *input_bfd,
struct bfd_link_info *info,
const struct ecoff_debug_swap * const swap =
&ecoff_backend (input_bfd)->debug_swap;
HDRR *symhdr = &debug->symbolic_header;
- bfd_boolean ret;
-
-#define READ(ptr, offset, count, size, type) \
- if (symhdr->count == 0) \
- debug->ptr = NULL; \
- else \
- { \
- bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
- debug->ptr = bfd_malloc (amt); \
- if (debug->ptr == NULL) \
- { \
- ret = FALSE; \
- goto return_something; \
- } \
- if (bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
- || bfd_bread (debug->ptr, amt, input_bfd) != amt) \
- { \
- ret = FALSE; \
- goto return_something; \
- } \
- }
+ bool ret;
+
+#define READ(ptr, offset, count, size, type) \
+ do \
+ { \
+ size_t amt; \
+ debug->ptr = NULL; \
+ if (symhdr->count == 0) \
+ break; \
+ if (_bfd_mul_overflow (size, symhdr->count, &amt)) \
+ { \
+ bfd_set_error (bfd_error_file_too_big); \
+ ret = false; \
+ goto return_something; \
+ } \
+ if (bfd_seek (input_bfd, symhdr->offset, SEEK_SET) != 0) \
+ { \
+ ret = false; \
+ goto return_something; \
+ } \
+ debug->ptr = (type) _bfd_malloc_and_read (input_bfd, amt, amt); \
+ if (debug->ptr == NULL) \
+ { \
+ ret = false; \
+ goto return_something; \
+ } \
+ } while (0)
/* If raw_syments is not NULL, then the data was already by read by
_bfd_ecoff_slurp_symbolic_info. */
return_something:
if (ecoff_data (input_bfd)->raw_syments == NULL)
{
- if (debug->line != NULL)
- free (debug->line);
- if (debug->external_dnr != NULL)
- free (debug->external_dnr);
- if (debug->external_pdr != NULL)
- free (debug->external_pdr);
- if (debug->external_sym != NULL)
- free (debug->external_sym);
- if (debug->external_opt != NULL)
- free (debug->external_opt);
- if (debug->external_aux != NULL)
- free (debug->external_aux);
- if (debug->ss != NULL)
- free (debug->ss);
- if (debug->external_fdr != NULL)
- free (debug->external_fdr);
- if (debug->external_rfd != NULL)
- free (debug->external_rfd);
+ free (debug->line);
+ free (debug->external_dnr);
+ free (debug->external_pdr);
+ free (debug->external_sym);
+ free (debug->external_opt);
+ free (debug->external_aux);
+ free (debug->ss);
+ free (debug->external_fdr);
+ free (debug->external_rfd);
/* Make sure we don't accidentally follow one of these pointers
into freed memory. */
/* Relocate and write an ECOFF section into an ECOFF output file. */
-static bfd_boolean
+static bool
ecoff_indirect_link_order (bfd *output_bfd,
struct bfd_link_info *info,
asection *output_section,
input_section = link_order->u.indirect.section;
input_bfd = input_section->owner;
if (input_section->size == 0)
- return TRUE;
+ return true;
BFD_ASSERT (input_section->output_section == output_section);
BFD_ASSERT (input_section->output_offset == link_order->offset);
external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size;
external_relocs_size = external_reloc_size * input_section->reloc_count;
- external_relocs = bfd_malloc (external_relocs_size);
- if (external_relocs == NULL && external_relocs_size != 0)
+ if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0)
goto error_return;
-
- if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
- || (bfd_bread (external_relocs, external_relocs_size, input_bfd)
- != external_relocs_size))
+ external_relocs = _bfd_malloc_and_read (input_bfd, external_relocs_size,
+ external_relocs_size);
+ if (external_relocs == NULL && external_relocs_size != 0)
goto error_return;
/* Relocate the section contents. */
modified, and we write them out now. We use the reloc_count
field of output_section to keep track of the number of relocs we
have output so far. */
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
{
file_ptr pos = (output_section->rel_filepos
+ output_section->reloc_count * external_reloc_size);
output_section->reloc_count += input_section->reloc_count;
}
- if (contents != NULL)
- free (contents);
- if (external_relocs != NULL)
- free (external_relocs);
- return TRUE;
+ free (contents);
+ free (external_relocs);
+ return true;
error_return:
- if (contents != NULL)
- free (contents);
- if (external_relocs != NULL)
- free (external_relocs);
- return FALSE;
+ free (contents);
+ free (external_relocs);
+ return false;
}
/* Generate a reloc when linking an ECOFF file. This is a reloc
is used to build constructor and destructor tables when linking
with -Ur. */
-static bfd_boolean
+static bool
ecoff_reloc_link_order (bfd *output_bfd,
struct bfd_link_info *info,
asection *output_section,
struct internal_reloc in;
bfd_size_type external_reloc_size;
bfd_byte *rbuf;
- bfd_boolean ok;
+ bool ok;
file_ptr pos;
type = link_order->type;
if (rel.howto == 0)
{
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
if (type == bfd_section_reloc_link_order)
struct bfd_link_hash_entry *h;
/* Treat a reloc against a defined symbol as though it were
- actually against the section. */
+ actually against the section. */
h = bfd_wrapped_link_hash_lookup (output_bfd, info,
link_order->u.reloc.p->u.name,
- FALSE, FALSE, FALSE);
+ false, false, false);
if (h != NULL
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak))
type = bfd_section_reloc_link_order;
section = h->u.def.section->output_section;
/* It seems that we ought to add the symbol value to the
- addend here, but in practice it has already been added
- because it was passed to constructor_callback. */
+ addend here, but in practice it has already been added
+ because it was passed to constructor_callback. */
addend += section->vma + h->u.def.section->output_offset;
}
else
bfd_byte *buf;
size = bfd_get_reloc_size (rel.howto);
- buf = bfd_zmalloc (size);
- if (buf == NULL)
- return FALSE;
+ buf = (bfd_byte *) bfd_zmalloc (size);
+ if (buf == NULL && size != 0)
+ return false;
rstat = _bfd_relocate_contents (rel.howto, output_bfd,
(bfd_vma) addend, buf);
switch (rstat)
case bfd_reloc_outofrange:
abort ();
case bfd_reloc_overflow:
- if (! ((*info->callbacks->reloc_overflow)
- (info, NULL,
- (link_order->type == bfd_section_reloc_link_order
- ? bfd_section_name (output_bfd, section)
- : link_order->u.reloc.p->u.name),
- rel.howto->name, addend, NULL,
- NULL, (bfd_vma) 0)))
- {
- free (buf);
- return FALSE;
- }
+ (*info->callbacks->reloc_overflow)
+ (info, NULL,
+ (link_order->type == bfd_section_reloc_link_order
+ ? bfd_section_name (section)
+ : link_order->u.reloc.p->u.name),
+ rel.howto->name, addend, NULL, NULL, (bfd_vma) 0);
break;
}
ok = bfd_set_section_contents (output_bfd, output_section, (void *) buf,
(file_ptr) link_order->offset, size);
free (buf);
if (! ok)
- return FALSE;
+ return false;
}
rel.addend = 0;
/* Move the information into an internal_reloc structure. */
- in.r_vaddr = (rel.address
- + bfd_get_section_vma (output_bfd, output_section));
+ in.r_vaddr = rel.address + bfd_section_vma (output_section);
in.r_type = rel.howto->type;
if (type == bfd_symbol_reloc_link_order)
h = ((struct ecoff_link_hash_entry *)
bfd_wrapped_link_hash_lookup (output_bfd, info,
link_order->u.reloc.p->u.name,
- FALSE, FALSE, TRUE));
+ false, false, true));
if (h != NULL
&& h->indx != -1)
in.r_symndx = h->indx;
else
{
- if (! ((*info->callbacks->unattached_reloc)
- (info, link_order->u.reloc.p->u.name, NULL,
- NULL, (bfd_vma) 0)))
- return FALSE;
+ (*info->callbacks->unattached_reloc)
+ (info, link_order->u.reloc.p->u.name, NULL, NULL, (bfd_vma) 0);
in.r_symndx = 0;
}
in.r_extern = 1;
{ _RCONST, RELOC_SECTION_RCONST }
};
- name = bfd_get_section_name (output_bfd, section);
+ name = bfd_section_name (section);
for (i = 0; i < ARRAY_SIZE (section_symndx); i++)
if (streq (name, section_symndx[i].name))
/* Get some memory and swap out the reloc. */
external_reloc_size = ecoff_backend (output_bfd)->external_reloc_size;
- rbuf = bfd_malloc (external_reloc_size);
+ rbuf = (bfd_byte *) bfd_malloc (external_reloc_size);
if (rbuf == NULL)
- return FALSE;
+ return false;
(*ecoff_backend (output_bfd)->swap_reloc_out) (output_bfd, &in, (void *) rbuf);
/* Put out information for an external symbol. These come only from
the hash table. */
-static bfd_boolean
-ecoff_link_write_external (struct ecoff_link_hash_entry *h, void * data)
+static bool
+ecoff_link_write_external (struct bfd_hash_entry *bh, void * data)
{
+ struct ecoff_link_hash_entry *h = (struct ecoff_link_hash_entry *) bh;
struct extsym_info *einfo = (struct extsym_info *) data;
bfd *output_bfd = einfo->abfd;
- bfd_boolean strip;
+ bool strip;
if (h->root.type == bfd_link_hash_warning)
{
h = (struct ecoff_link_hash_entry *) h->root.u.i.link;
if (h->root.type == bfd_link_hash_new)
- return TRUE;
+ return true;
}
/* We need to check if this symbol is being stripped. */
if (h->root.type == bfd_link_hash_undefined
|| h->root.type == bfd_link_hash_undefweak)
- strip = FALSE;
+ strip = false;
else if (einfo->info->strip == strip_all
|| (einfo->info->strip == strip_some
&& bfd_hash_lookup (einfo->info->keep_hash,
h->root.root.string,
- FALSE, FALSE) == NULL))
- strip = TRUE;
+ false, false) == NULL))
+ strip = true;
else
- strip = FALSE;
+ strip = false;
if (strip || h->written)
- return TRUE;
+ return true;
if (h->abfd == NULL)
{
};
output_section = h->root.u.def.section->output_section;
- name = bfd_section_name (output_section->owner, output_section);
+ name = bfd_section_name (output_section);
for (i = 0; i < ARRAY_SIZE (section_storage_classes); i++)
if (streq (name, section_storage_classes[i].name))
case bfd_link_hash_indirect:
/* We ignore these symbols, since the indirected symbol is
already in the hash table. */
- return TRUE;
+ return true;
}
/* bfd_ecoff_debug_one_external uses iextMax to keep track of the
processes all the link order information. This may cause it to
close and reopen some input BFDs; I'll see how bad this is. */
-bfd_boolean
+bool
_bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
{
const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
handle = bfd_ecoff_debug_init (abfd, debug, &backend->debug_swap, info);
if (handle == NULL)
- return FALSE;
+ return false;
/* Accumulate the debugging symbols from each input BFD. */
for (input_bfd = info->input_bfds;
input_bfd != NULL;
- input_bfd = input_bfd->link_next)
+ input_bfd = input_bfd->link.next)
{
- bfd_boolean ret;
+ bool ret;
if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour)
{
debug, &backend->debug_swap,
input_bfd, info);
if (! ret)
- return FALSE;
+ return false;
/* Combine the register masks. */
ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask;
/* Write out the external symbols. */
einfo.abfd = abfd;
einfo.info = info;
- ecoff_link_hash_traverse (ecoff_hash_table (info),
- ecoff_link_write_external,
- (void *) &einfo);
+ bfd_hash_traverse (&info->hash->table, ecoff_link_write_external, &einfo);
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
{
/* We need to make a pass over the link_orders to count up the
number of relocations we will need to output, so that we know
if (! bfd_ecoff_write_accumulated_debug (handle, abfd, debug,
&backend->debug_swap, info,
ecoff_data (abfd)->sym_filepos))
- return FALSE;
+ return false;
bfd_ecoff_debug_free (handle, abfd, debug, &backend->debug_swap, info);
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
{
/* Now reset the reloc_count field of the sections in the output
BFD to 0, so that we can use them to keep track of how many
{
struct bfd_link_hash_entry *h;
- h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
+ h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
if (h != NULL
&& h->type == bfd_link_hash_defined)
ecoff_data (abfd)->gp = (h->u.def.value
+ h->u.def.section->output_section->vma
+ h->u.def.section->output_offset);
- else if (info->relocatable)
+ else if (bfd_link_relocatable (info))
{
bfd_vma lo;
== bfd_target_ecoff_flavour))
{
if (! ecoff_indirect_link_order (abfd, info, o, p))
- return FALSE;
+ return false;
}
else if (p->type == bfd_section_reloc_link_order
|| p->type == bfd_symbol_reloc_link_order)
{
if (! ecoff_reloc_link_order (abfd, info, o, p))
- return FALSE;
+ return false;
}
else
{
if (! _bfd_default_link_order (abfd, info, o, p))
- return FALSE;
+ return false;
}
}
}
- bfd_get_symcount (abfd) = symhdr->iextMax + symhdr->isymMax;
+ abfd->symcount = symhdr->iextMax + symhdr->isymMax;
- ecoff_data (abfd)->linker = TRUE;
+ ecoff_data (abfd)->linker = true;
- return TRUE;
+ return true;
}