/* Routines to link ECOFF debugging information.
- Copyright 1993, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
+ 2004, 2005 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.
-This file is part of BFD, the Binary File Descriptor library.
+ This file is part of BFD, the Binary File Descriptor library.
-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
-(at your option) any later version.
+ 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
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-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. */
+ 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. */
#include "bfd.h"
#include "sysdep.h"
#include "coff/sym.h"
#include "coff/symconst.h"
#include "coff/ecoff.h"
+#include "libcoff.h"
+#include "libecoff.h"
\f
-static boolean ecoff_add_bytes PARAMS ((char **buf, char **bufend,
- size_t need));
+static bfd_boolean ecoff_add_bytes
+ PARAMS ((char **buf, char **bufend, size_t need));
static struct bfd_hash_entry *string_hash_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
const char *));
-static void ecoff_align_debug PARAMS ((bfd *abfd,
- struct ecoff_debug_info *debug,
- const struct ecoff_debug_swap *swap));
-static boolean ecoff_write_symhdr PARAMS ((bfd *, struct ecoff_debug_info *,
- const struct ecoff_debug_swap *,
- file_ptr where));
-static int cmp_fdrtab_entry PARAMS ((const PTR, const PTR));
-static boolean mk_fdrtab PARAMS ((bfd *,
- struct ecoff_debug_info * const,
- const struct ecoff_debug_swap * const,
- struct ecoff_find_line *));
-static long fdrtab_lookup PARAMS ((struct ecoff_find_line *, bfd_vma));
-static boolean lookup_line
+static void ecoff_align_debug
+ PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap));
+static bfd_boolean ecoff_write_symhdr
+ PARAMS ((bfd *, struct ecoff_debug_info *, const struct ecoff_debug_swap *,
+ file_ptr where));
+static int cmp_fdrtab_entry
+ PARAMS ((const PTR, const PTR));
+static bfd_boolean mk_fdrtab
+ PARAMS ((bfd *, struct ecoff_debug_info * const,
+ const struct ecoff_debug_swap * const, struct ecoff_find_line *));
+static long fdrtab_lookup
+ PARAMS ((struct ecoff_find_line *, bfd_vma));
+static bfd_boolean lookup_line
PARAMS ((bfd *, struct ecoff_debug_info * const,
const struct ecoff_debug_swap * const, struct ecoff_find_line *));
\f
struct tir_ext ext[1];
*ext = *ext_copy; /* Make it reasonable to do in-place. */
-
- /* now the fun stuff... */
+
+ /* now the fun stuff... */
if (bigend) {
intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG);
intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG);
#ifdef TEST
if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
- abort();
+ abort ();
#endif
}
TIR intern[1];
*intern = *intern_copy; /* Make it reasonable to do in-place. */
-
- /* now the fun stuff... */
+
+ /* now the fun stuff... */
if (bigend) {
ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_BIG : 0)
| (intern->continued ? TIR_BITS1_CONTINUED_BIG : 0)
#ifdef TEST
if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
- abort();
+ abort ();
#endif
}
struct rndx_ext ext[1];
*ext = *ext_copy; /* Make it reasonable to do in-place. */
-
- /* now the fun stuff... */
+
+ /* now the fun stuff... */
if (bigend) {
intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG)
| ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG)
#ifdef TEST
if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
- abort();
+ abort ();
#endif
}
RNDXR intern[1];
*intern = *intern_copy; /* Make it reasonable to do in-place. */
-
- /* now the fun stuff... */
+
+ /* now the fun stuff... */
if (bigend) {
ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_BIG;
ext->r_bits[1] = (((intern->rfd << RNDX_BITS1_RFD_SH_BIG)
#ifdef TEST
if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
- abort();
+ abort ();
#endif
}
\f
/* Add bytes to a buffer. Return success. */
-static boolean
+static bfd_boolean
ecoff_add_bytes (buf, bufend, need)
char **buf;
char **bufend;
if (want < ALLOC_SIZE)
want = ALLOC_SIZE;
}
- newbuf = (char *) bfd_realloc (*buf, have + want);
+ newbuf = (char *) bfd_realloc (*buf, (bfd_size_type) have + want);
if (newbuf == NULL)
- return false;
+ return FALSE;
*buf = newbuf;
*bufend = *buf + have + want;
- return true;
+ return TRUE;
}
/* We keep a hash table which maps strings to numbers. We use it to
/* The length of the information. */
unsigned long size;
/* Whether this information comes from a file or not. */
- boolean filep;
+ bfd_boolean filep;
union
{
struct
/* Add a file entry to a shuffle list. */
-static boolean add_file_shuffle PARAMS ((struct accumulate *,
- struct shuffle **,
- struct shuffle **, bfd *, file_ptr,
- unsigned long));
+static bfd_boolean add_file_shuffle
+ PARAMS ((struct accumulate *, struct shuffle **, struct shuffle **,
+ bfd *, file_ptr, unsigned long));
-static boolean
+static bfd_boolean
add_file_shuffle (ainfo, head, tail, input_bfd, offset, size)
struct accumulate *ainfo;
struct shuffle **head;
(*tail)->size += size;
if ((*tail)->size > ainfo->largest_file_shuffle)
ainfo->largest_file_shuffle = (*tail)->size;
- return true;
+ return TRUE;
}
n = (struct shuffle *) objalloc_alloc (ainfo->memory,
if (!n)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return FALSE;
}
n->next = NULL;
n->size = size;
- n->filep = true;
+ n->filep = TRUE;
n->u.file.input_bfd = input_bfd;
n->u.file.offset = offset;
if (*head == (struct shuffle *) NULL)
*tail = n;
if (size > ainfo->largest_file_shuffle)
ainfo->largest_file_shuffle = size;
- return true;
+ return TRUE;
}
/* Add a memory entry to a shuffle list. */
-static boolean add_memory_shuffle PARAMS ((struct accumulate *,
- struct shuffle **head,
- struct shuffle **tail,
- bfd_byte *data, unsigned long size));
+static bfd_boolean add_memory_shuffle
+ PARAMS ((struct accumulate *, struct shuffle **head, struct shuffle **tail,
+ bfd_byte *data, unsigned long size));
-static boolean
+static bfd_boolean
add_memory_shuffle (ainfo, head, tail, data, size)
struct accumulate *ainfo;
struct shuffle **head;
unsigned long size;
{
struct shuffle *n;
-
+
n = (struct shuffle *) objalloc_alloc (ainfo->memory,
sizeof (struct shuffle));
if (!n)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return FALSE;
}
n->next = NULL;
n->size = size;
- n->filep = false;
+ n->filep = FALSE;
n->u.memory = (PTR) data;
if (*head == (struct shuffle *) NULL)
*head = n;
if (*tail != (struct shuffle *) NULL)
(*tail)->next = n;
*tail = n;
- return true;
+ return TRUE;
}
/* Initialize the FDR hash table. This returns a handle which is then
passed in to bfd_ecoff_debug_accumulate, et. al. */
-/*ARGSUSED*/
PTR
bfd_ecoff_debug_init (output_bfd, output_debug, output_swap, info)
- bfd *output_bfd;
+ bfd *output_bfd ATTRIBUTE_UNUSED;
struct ecoff_debug_info *output_debug;
- const struct ecoff_debug_swap *output_swap;
+ const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
{
struct accumulate *ainfo;
+ bfd_size_type amt = sizeof (struct accumulate);
- ainfo = (struct accumulate *) bfd_malloc (sizeof (struct accumulate));
+ ainfo = (struct accumulate *) bfd_malloc (amt);
if (!ainfo)
return NULL;
if (! bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
ainfo->largest_file_shuffle = 0;
- if (! info->relocateable)
+ if (! info->relocatable)
{
if (! bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc))
return NULL;
/* Free the accumulated debugging information. */
-/*ARGSUSED*/
void
bfd_ecoff_debug_free (handle, output_bfd, output_debug, output_swap, info)
PTR handle;
- bfd *output_bfd;
- struct ecoff_debug_info *output_debug;
- const struct ecoff_debug_swap *output_swap;
+ bfd *output_bfd ATTRIBUTE_UNUSED;
+ struct ecoff_debug_info *output_debug ATTRIBUTE_UNUSED;
+ const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
{
struct accumulate *ainfo = (struct accumulate *) handle;
-
+
bfd_hash_table_free (&ainfo->fdr_hash.table);
- if (! info->relocateable)
+ if (! info->relocatable)
bfd_hash_table_free (&ainfo->str_hash.table);
objalloc_free (ainfo->memory);
linker information structure. HANDLE is returned by
bfd_ecoff_debug_init. */
-/*ARGSUSED*/
-boolean
+bfd_boolean
bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
input_bfd, input_debug, input_swap,
info)
long newrfdbase = 0;
long oldrfdbase = 0;
bfd_byte *fdr_out;
+ bfd_size_type amt;
/* Use section_adjust to hold the value to add to a symbol in a
particular section. */
}
fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add;
- input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd,
- (input_symhdr->ifdMax
- * sizeof (RFDT)));
+ amt = input_symhdr->ifdMax;
+ amt *= sizeof (RFDT);
+ input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd, amt);
sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size;
rfd_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
if (!input_debug->ifdmap || !rfd_out)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return FALSE;
}
if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz))
- return false;
+ return FALSE;
copied = 0;
struct string_hash_entry *fh;
/* We look up a string formed from the file name and the
- number of symbols. Sometimes an include file will
- conditionally define a typedef or something based on the
- order of include files. Using the number of symbols as a
- hash reduces the chance that we will merge symbol
- information that should not be merged. */
+ number of symbols and aux entries. Sometimes an include
+ file will conditionally define a typedef or something
+ based on the order of include files. Using the number of
+ symbols and aux entries as a hash reduces the chance that
+ we will merge symbol information that should not be
+ merged. */
name = input_debug->ss + fdr.issBase + fdr.rss;
- lookup = (char *) bfd_malloc (strlen (name) + 20);
+ lookup = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 20);
if (lookup == NULL)
- return false;
- sprintf (lookup, "%s %lx", name, fdr.csym);
+ return FALSE;
+ sprintf (lookup, "%s %lx %lx", name, fdr.csym, fdr.caux);
- fh = string_hash_lookup (&ainfo->fdr_hash, lookup, true, true);
+ fh = string_hash_lookup (&ainfo->fdr_hash, lookup, TRUE, TRUE);
free (lookup);
if (fh == (struct string_hash_entry *) NULL)
- return false;
+ return FALSE;
if (fh->val != -1)
{
if (!fdr_out)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return FALSE;
}
if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz))
- return false;
+ return FALSE;
for (fdr_ptr = fdr_start, i = 0;
fdr_ptr < fdr_end;
fdr_ptr += fdr_add, i++)
bfd_byte *sym_out;
bfd_byte *lraw_src;
bfd_byte *lraw_end;
- boolean fgotfilename;
+ bfd_boolean fgotfilename;
if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
{
fdr_adr = fdr.adr;
- /* Adjust the FDR address for any changes that may have been
- made by relaxing. */
- if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
- {
- struct ecoff_value_adjust *adjust;
-
- for (adjust = input_debug->adjust;
- adjust != (struct ecoff_value_adjust *) NULL;
- adjust = adjust->next)
- if (fdr_adr >= adjust->start
- && fdr_adr < adjust->end)
- fdr.adr += adjust->adjust;
- }
-
/* FIXME: It is conceivable that this FDR points to the .init or
.fini section, in which case this will not do the right
thing. */
/* Swap in the local symbols, adjust their values, and swap them
out again. */
- fgotfilename = false;
+ fgotfilename = FALSE;
sz = fdr.csym * external_sym_size;
sym_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
if (!sym_out)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return FALSE;
}
if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out,
sz))
- return false;
+ return FALSE;
lraw_src = ((bfd_byte *) input_debug->external_sym
+ fdr.isymBase * input_swap->external_sym_size);
lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
case stLabel:
case stProc:
case stStaticProc:
- if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
- {
- bfd_vma value;
- struct ecoff_value_adjust *adjust;
-
- value = internal_sym.value;
- for (adjust = input_debug->adjust;
- adjust != (struct ecoff_value_adjust *) NULL;
- adjust = adjust->next)
- if (value >= adjust->start
- && value < adjust->end)
- internal_sym.value += adjust->adjust;
- }
internal_sym.value += section_adjust[internal_sym.sc];
break;
/* If we are doing a final link, we hash all the strings in
the local symbol table together. This reduces the amount
of space required by debugging information. We don't do
- this when performing a relocateable link because it would
+ this when performing a relocatable link because it would
prevent us from easily merging different FDR's. */
- if (! info->relocateable)
+ if (! info->relocatable)
{
- boolean ffilename;
+ bfd_boolean ffilename;
const char *name;
if (! fgotfilename && internal_sym.iss == fdr.rss)
- ffilename = true;
+ ffilename = TRUE;
else
- ffilename = false;
+ ffilename = FALSE;
/* Hash the name into the string table. */
name = input_debug->ss + fdr.issBase + internal_sym.iss;
{
struct string_hash_entry *sh;
- sh = string_hash_lookup (&ainfo->str_hash, name, true, true);
+ sh = string_hash_lookup (&ainfo->str_hash, name, TRUE, TRUE);
if (sh == (struct string_hash_entry *) NULL)
- return false;
+ return FALSE;
if (sh->val == -1)
{
sh->val = output_symhdr->issMax;
if (ffilename)
{
fdr.rss = internal_sym.iss;
- fgotfilename = true;
+ fgotfilename = TRUE;
}
}
stabs are adjusted correctly. */
if (fdr.cbLine > 0)
{
+ file_ptr pos = input_symhdr->cbLineOffset + fdr.cbLineOffset;
if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
- input_bfd,
- input_symhdr->cbLineOffset + fdr.cbLineOffset,
- fdr.cbLine))
- return false;
+ input_bfd, pos, (unsigned long) fdr.cbLine))
+ return FALSE;
fdr.ilineBase = output_symhdr->ilineMax;
fdr.cbLineOffset = output_symhdr->cbLine;
output_symhdr->ilineMax += fdr.cline;
}
if (fdr.caux > 0)
{
+ file_ptr pos = (input_symhdr->cbAuxOffset
+ + fdr.iauxBase * sizeof (union aux_ext));
if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
- input_bfd,
- (input_symhdr->cbAuxOffset
- + fdr.iauxBase * sizeof (union aux_ext)),
+ input_bfd, pos,
fdr.caux * sizeof (union aux_ext)))
- return false;
+ return FALSE;
fdr.iauxBase = output_symhdr->iauxMax;
output_symhdr->iauxMax += fdr.caux;
}
- if (! info->relocateable)
+ if (! info->relocatable)
{
/* When are are hashing strings, we lie about the number of
}
else if (fdr.cbSs > 0)
{
+ file_ptr pos = input_symhdr->cbSsOffset + fdr.issBase;
if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
- input_bfd,
- input_symhdr->cbSsOffset + fdr.issBase,
- fdr.cbSs))
- return false;
+ input_bfd, pos, (unsigned long) fdr.cbSs))
+ return FALSE;
fdr.issBase = output_symhdr->issMax;
output_symhdr->issMax += fdr.cbSs;
}
- if ((output_bfd->xvec->header_byteorder
- == input_bfd->xvec->header_byteorder)
- && input_debug->adjust == (struct ecoff_value_adjust *) NULL)
+ if (output_bfd->xvec->header_byteorder
+ == input_bfd->xvec->header_byteorder)
{
/* The two BFD's have the same endianness, and we don't have
to adjust the PDR addresses, so simply copying the
BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
if (fdr.cpd > 0)
{
+ file_ptr pos = (input_symhdr->cbPdOffset
+ + fdr.ipdFirst * external_pdr_size);
+ unsigned long size = fdr.cpd * external_pdr_size;
if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
- input_bfd,
- (input_symhdr->cbPdOffset
- + fdr.ipdFirst * external_pdr_size),
- fdr.cpd * external_pdr_size))
- return false;
+ input_bfd, pos, size))
+ return FALSE;
}
BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
if (fdr.copt > 0)
{
+ file_ptr pos = (input_symhdr->cbOptOffset
+ + fdr.ioptBase * external_opt_size);
+ unsigned long size = fdr.copt * external_opt_size;
if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
- input_bfd,
- (input_symhdr->cbOptOffset
- + fdr.ioptBase * external_opt_size),
- fdr.copt * external_opt_size))
- return false;
+ input_bfd, pos, size))
+ return FALSE;
}
}
else
if (!out)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return FALSE;
}
if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out,
sz))
- return false;
+ return FALSE;
for (; in < end; in += insz, out += outsz)
{
PDR pdr;
(*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr);
-
- /* If we have been relaxing, we may have to adjust the
- address. */
- if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
- {
- bfd_vma adr;
- struct ecoff_value_adjust *adjust;
-
- adr = fdr_adr + pdr.adr;
- for (adjust = input_debug->adjust;
- adjust != (struct ecoff_value_adjust *) NULL;
- adjust = adjust->next)
- if (adr >= adjust->start
- && adr < adjust->end)
- pdr.adr += adjust->adjust;
- }
-
(*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out);
}
if (!out)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return FALSE;
}
if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out,
sz))
- return false;
+ return FALSE;
for (; in < end; in += insz, out += outsz)
{
OPTR opt;
++output_symhdr->ifdMax;
}
- return true;
+ return TRUE;
}
/* Add a string to the debugging information we are accumulating.
Return the offset from the fdr string base. */
-static long ecoff_add_string PARAMS ((struct accumulate *,
- struct bfd_link_info *,
- struct ecoff_debug_info *,
- FDR *fdr, const char *string));
+static long ecoff_add_string
+ PARAMS ((struct accumulate *, struct bfd_link_info *,
+ struct ecoff_debug_info *, FDR *fdr, const char *string));
static long
ecoff_add_string (ainfo, info, debug, fdr, string)
symhdr = &debug->symbolic_header;
len = strlen (string);
- if (info->relocateable)
+ if (info->relocatable)
{
if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,
len + 1))
{
struct string_hash_entry *sh;
- sh = string_hash_lookup (&ainfo->str_hash, string, true, true);
+ sh = string_hash_lookup (&ainfo->str_hash, string, TRUE, TRUE);
if (sh == (struct string_hash_entry *) NULL)
return -1;
if (sh->val == -1)
/* Add debugging information from a non-ECOFF file. */
-boolean
+bfd_boolean
bfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug,
output_swap, input_bfd, info)
PTR handle;
fdr.issBase = output_symhdr->issMax;
fdr.cbSs = 0;
fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
- bfd_get_filename (input_bfd));
+ input_bfd->filename);
if (fdr.rss == -1)
- return false;
+ return FALSE;
fdr.isymBase = output_symhdr->isymMax;
/* Get the local symbols from the input BFD. */
symsize = bfd_get_symtab_upper_bound (input_bfd);
if (symsize < 0)
- return false;
- symbols = (asymbol **) bfd_alloc (output_bfd, symsize);
+ return FALSE;
+ symbols = (asymbol **) bfd_alloc (output_bfd, (bfd_size_type) symsize);
if (symbols == (asymbol **) NULL)
- return false;
+ return FALSE;
symcount = bfd_canonicalize_symtab (input_bfd, symbols);
if (symcount < 0)
- return false;
+ return FALSE;
sym_end = symbols + symcount;
/* Handle the local symbols. Any external symbols are handled
(*sym_ptr)->name);
if (internal_sym.iss == -1)
- return false;
+ return FALSE;
if (bfd_is_com_section ((*sym_ptr)->section)
|| bfd_is_und_section ((*sym_ptr)->section))
internal_sym.value = (*sym_ptr)->value;
if (!external_sym)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return FALSE;
}
(*swap_sym_out) (output_bfd, &internal_sym, external_sym);
add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
- external_sym, output_swap->external_sym_size);
+ external_sym,
+ (unsigned long) output_swap->external_sym_size);
++fdr.csym;
++output_symhdr->isymMax;
}
if (!external_fdr)
{
bfd_set_error (bfd_error_no_memory);
- return false;
+ return FALSE;
}
(*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
- external_fdr, output_swap->external_fdr_size);
+ external_fdr,
+ (unsigned long) output_swap->external_fdr_size);
++output_symhdr->ifdMax;
- return true;
+ return TRUE;
}
/* Set up ECOFF debugging information for the external symbols.
probably be changed to use a shuffle structure. The assembler uses
this interface, so that must be changed to do something else. */
-boolean
-bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,
+bfd_boolean
+bfd_ecoff_debug_externals (abfd, debug, swap, relocatable, get_extr,
set_index)
bfd *abfd;
struct ecoff_debug_info *debug;
const struct ecoff_debug_swap *swap;
- boolean relocateable;
- boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
+ bfd_boolean relocatable;
+ bfd_boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
void (*set_index) PARAMS ((asymbol *, bfd_size_type));
{
HDRR * const symhdr = &debug->symbolic_header;
sym_ptr_ptr = bfd_get_outsymbols (abfd);
if (sym_ptr_ptr == NULL)
- return true;
+ return TRUE;
for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
{
sym_ptr = *sym_ptr_ptr;
/* Get the external symbol information. */
- if ((*get_extr) (sym_ptr, &esym) == false)
+ if (! (*get_extr) (sym_ptr, &esym))
continue;
/* If we're producing an executable, move common symbols into
bss. */
- if (relocateable == false)
+ if (! relocatable)
{
if (esym.asym.sc == scCommon)
esym.asym.sc = scBss;
if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
sym_ptr->name, &esym))
- return false;
+ return FALSE;
}
- return true;
+ return TRUE;
}
/* Add a single external symbol to the debugging information. */
-boolean
+bfd_boolean
bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym)
bfd *abfd;
struct ecoff_debug_info *debug;
if ((size_t) (debug->ssext_end - debug->ssext)
< symhdr->issExtMax + namelen + 1)
{
- if (ecoff_add_bytes ((char **) &debug->ssext,
- (char **) &debug->ssext_end,
- symhdr->issExtMax + namelen + 1)
- == false)
- return false;
+ if (! ecoff_add_bytes ((char **) &debug->ssext,
+ (char **) &debug->ssext_end,
+ symhdr->issExtMax + namelen + 1))
+ return FALSE;
}
if ((size_t) ((char *) debug->external_ext_end
- (char *) debug->external_ext)
< (symhdr->iextMax + 1) * external_ext_size)
{
- if (ecoff_add_bytes ((char **) &debug->external_ext,
- (char **) &debug->external_ext_end,
- (symhdr->iextMax + 1) * external_ext_size)
- == false)
- return false;
+ if (! ecoff_add_bytes ((char **) &debug->external_ext,
+ (char **) &debug->external_ext_end,
+ (symhdr->iextMax + 1) * (size_t) external_ext_size))
+ return FALSE;
}
esym->asym.iss = symhdr->issExtMax;
strcpy (debug->ssext + symhdr->issExtMax, name);
symhdr->issExtMax += namelen + 1;
- return true;
+ return TRUE;
}
/* Align the ECOFF debugging information. */
-/*ARGSUSED*/
static void
ecoff_align_debug (abfd, debug, swap)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
struct ecoff_debug_info *debug;
const struct ecoff_debug_swap *swap;
{
going to be placed at. This assumes that the counts are set
correctly. */
-static boolean
+static bfd_boolean
ecoff_write_symhdr (abfd, debug, swap, where)
bfd *abfd;
struct ecoff_debug_info *debug;
/* Go to the right location in the file. */
if (bfd_seek (abfd, where, SEEK_SET) != 0)
- return false;
+ return FALSE;
where += swap->external_hdr_size;
SET (cbExtOffset, iextMax, swap->external_ext_size);
#undef SET
- buff = (PTR) bfd_malloc ((size_t) swap->external_hdr_size);
+ buff = (PTR) bfd_malloc (swap->external_hdr_size);
if (buff == NULL && swap->external_hdr_size != 0)
goto error_return;
(*swap->swap_hdr_out) (abfd, symhdr, buff);
- if (bfd_write (buff, 1, swap->external_hdr_size, abfd)
+ if (bfd_bwrite (buff, swap->external_hdr_size, abfd)
!= swap->external_hdr_size)
goto error_return;
if (buff != NULL)
free (buff);
- return true;
+ return TRUE;
error_return:
if (buff != NULL)
free (buff);
- return false;
+ return FALSE;
}
/* Write out the ECOFF debugging information. This function assumes
information to. This function fills in the file offsets in the
symbolic header. */
-boolean
+bfd_boolean
bfd_ecoff_write_debug (abfd, debug, swap, where)
bfd *abfd;
struct ecoff_debug_info *debug;
HDRR * const symhdr = &debug->symbolic_header;
if (! ecoff_write_symhdr (abfd, debug, swap, where))
- return false;
+ return FALSE;
#define WRITE(ptr, count, size, offset) \
BFD_ASSERT (symhdr->offset == 0 \
|| (bfd_vma) bfd_tell (abfd) == symhdr->offset); \
- if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \
+ if (bfd_bwrite ((PTR) debug->ptr, (bfd_size_type) size * symhdr->count, abfd)\
!= size * symhdr->count) \
- return false;
+ return FALSE;
WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
- WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset);
+ WRITE (external_aux, iauxMax, (bfd_size_type) sizeof (union aux_ext),
+ cbAuxOffset);
WRITE (ss, issMax, sizeof (char), cbSsOffset);
WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
#undef WRITE
- return true;
+ return TRUE;
}
/* Write out a shuffle list. */
-static boolean ecoff_write_shuffle PARAMS ((bfd *,
- const struct ecoff_debug_swap *,
- struct shuffle *, PTR space));
+static bfd_boolean ecoff_write_shuffle
+ PARAMS ((bfd *, const struct ecoff_debug_swap *, struct shuffle *,
+ PTR space));
-static boolean
+static bfd_boolean
ecoff_write_shuffle (abfd, swap, shuffle, space)
bfd *abfd;
const struct ecoff_debug_swap *swap;
{
if (! l->filep)
{
- if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size)
- return false;
+ if (bfd_bwrite (l->u.memory, (bfd_size_type) l->size, abfd)
+ != l->size)
+ return FALSE;
}
else
{
if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
- || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size
- || bfd_write (space, 1, l->size, abfd) != l->size)
- return false;
+ || bfd_bread (space, (bfd_size_type) l->size,
+ l->u.file.input_bfd) != l->size
+ || bfd_bwrite (space, (bfd_size_type) l->size, abfd) != l->size)
+ return FALSE;
}
total += l->size;
}
bfd_byte *s;
i = swap->debug_align - (total & (swap->debug_align - 1));
- s = (bfd_byte *) bfd_malloc (i);
+ s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
if (s == NULL && i != 0)
- return false;
+ return FALSE;
- memset ((PTR) s, 0, i);
- if (bfd_write ((PTR) s, 1, i, abfd) != i)
+ if (bfd_bwrite ((PTR) s, (bfd_size_type) i, abfd) != i)
{
free (s);
- return false;
+ return FALSE;
}
free (s);
}
- return true;
+ return TRUE;
}
/* Write out debugging information using accumulated linker
information. */
-boolean
+bfd_boolean
bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where)
PTR handle;
bfd *abfd;
{
struct accumulate *ainfo = (struct accumulate *) handle;
PTR space = NULL;
+ bfd_size_type amt;
if (! ecoff_write_symhdr (abfd, debug, swap, where))
goto error_return;
- space = (PTR) bfd_malloc (ainfo->largest_file_shuffle);
+ amt = ainfo->largest_file_shuffle;
+ space = (PTR) bfd_malloc (amt);
if (space == NULL && ainfo->largest_file_shuffle != 0)
goto error_return;
/* The string table is written out from the hash table if this is a
final link. */
- if (info->relocateable)
+ if (info->relocatable)
{
BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
null = 0;
- if (bfd_write ((PTR) &null, 1, 1, abfd) != 1)
+ if (bfd_bwrite ((PTR) &null, (bfd_size_type) 1, abfd) != 1)
goto error_return;
total = 1;
BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
size_t len;
len = strlen (sh->root.string);
- if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1)
+ amt = len + 1;
+ if (bfd_bwrite ((PTR) sh->root.string, amt, abfd) != amt)
goto error_return;
total += len + 1;
}
bfd_byte *s;
i = swap->debug_align - (total & (swap->debug_align - 1));
- s = (bfd_byte *) bfd_malloc (i);
+ s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
if (s == NULL && i != 0)
goto error_return;
- memset ((PTR) s, 0, i);
- if (bfd_write ((PTR) s, 1, i, abfd) != i)
+
+ if (bfd_bwrite ((PTR) s, (bfd_size_type) i, abfd) != i)
{
free (s);
goto error_return;
/* The external strings and symbol are not converted over to using
shuffles. FIXME: They probably should be. */
- if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd)
- != (bfd_size_type) debug->symbolic_header.issExtMax)
+ amt = debug->symbolic_header.issExtMax;
+ if (bfd_bwrite (debug->ssext, amt, abfd) != amt)
goto error_return;
if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
{
i = (swap->debug_align
- (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
- s = (bfd_byte *) bfd_malloc (i);
+ s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
if (s == NULL && i != 0)
goto error_return;
- memset ((PTR) s, 0, i);
- if (bfd_write ((PTR) s, 1, i, abfd) != i)
+
+ if (bfd_bwrite ((PTR) s, (bfd_size_type) i, abfd) != i)
{
free (s);
goto error_return;
|| (debug->symbolic_header.cbExtOffset
== (bfd_vma) bfd_tell (abfd)));
- if (bfd_write (debug->external_ext, swap->external_ext_size,
- debug->symbolic_header.iextMax, abfd)
- != debug->symbolic_header.iextMax * swap->external_ext_size)
+ amt = debug->symbolic_header.iextMax * swap->external_ext_size;
+ if (bfd_bwrite (debug->external_ext, amt, abfd) != amt)
goto error_return;
if (space != NULL)
free (space);
- return true;
+ return TRUE;
error_return:
if (space != NULL)
free (space);
- return false;
+ return FALSE;
}
\f
/* Handle the find_nearest_line function for both ECOFF and MIPS ELF
table will be sorted by address so we can look it up via binary
search. */
-static boolean
+static bfd_boolean
mk_fdrtab (abfd, debug_info, debug_swap, line_info)
bfd *abfd;
struct ecoff_debug_info * const debug_info;
FDR *fdr_ptr;
FDR *fdr_start;
FDR *fdr_end;
- boolean stabs;
+ bfd_boolean stabs;
long len;
+ bfd_size_type amt;
fdr_start = debug_info->fdr;
fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;
- /* First, let's see how long the table needs to be: */
+ /* First, let's see how long the table needs to be. */
for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
{
- if (fdr_ptr->cpd == 0) /* skip FDRs that have no PDRs */
+ if (fdr_ptr->cpd == 0) /* Skip FDRs that have no PDRs. */
continue;
++len;
}
- /* Now, create and fill in the table: */
-
- line_info->fdrtab = ((struct ecoff_fdrtab_entry*)
- bfd_zalloc (abfd,
- len * sizeof (struct ecoff_fdrtab_entry)));
+ /* Now, create and fill in the table. */
+ amt = (bfd_size_type) len * sizeof (struct ecoff_fdrtab_entry);
+ line_info->fdrtab = (struct ecoff_fdrtab_entry*) bfd_zalloc (abfd, amt);
if (line_info->fdrtab == NULL)
- return false;
+ return FALSE;
line_info->fdrtab_len = len;
tab = line_info->fdrtab;
/* Check whether this file has stabs debugging information. In
a file with stabs debugging information, the second local
symbol is named @stabs. */
- stabs = false;
+ stabs = FALSE;
if (fdr_ptr->csym >= 2)
{
char *sym_ptr;
SYMR sym;
sym_ptr = ((char *) debug_info->external_sym
- + (fdr_ptr->isymBase + 1)*debug_swap->external_sym_size);
+ + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
(*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
STABS_SYMBOL) == 0)
- stabs = true;
+ stabs = TRUE;
}
if (!stabs)
{
- bfd_size_type external_pdr_size;
- char *pdr_ptr;
- PDR pdr;
-
- external_pdr_size = debug_swap->external_pdr_size;
-
- pdr_ptr = ((char *) debug_info->external_pdr
- + fdr_ptr->ipdFirst * external_pdr_size);
- (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
+ /* eraxxon: There are at least two problems with this computation:
+ 1) PDRs do *not* contain offsets but full vma's; and typically the
+ address of the first PDR is the address of the FDR, which will
+ make (most) of the results of the original computation 0!
+ 2) Once in a wacky while, the Compaq compiler generated PDR
+ addresses do not equal the FDR vma, but they (the PDR address)
+ are still vma's and not offsets. Cf. comments in
+ 'lookup_line'. */
/* The address of the first PDR is the offset of that
procedure relative to the beginning of file FDR. */
- tab->base_addr = fdr_ptr->adr - pdr.adr;
+ tab->base_addr = fdr_ptr->adr;
}
else
{
/* XXX I don't know about stabs, so this is a guess
- (davidm@cs.arizona.edu): */
+ (davidm@cs.arizona.edu). */
tab->base_addr = fdr_ptr->adr;
}
tab->fdr = fdr_ptr;
The table is mostly sorted already, but there are cases (e.g.,
static functions in include files), where this does not hold.
Use "odump -PFv" to verify... */
- qsort ((PTR) line_info->fdrtab, len,
+ qsort ((PTR) line_info->fdrtab, (size_t) len,
sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry);
- return true;
+ return TRUE;
}
/* Return index of first FDR that covers to OFFSET. */
else
low = mid + 1;
}
+
+ /* eraxxon: at this point 'offset' is either lower than the lowest entry or
+ higher than the highest entry. In the former case high = low = mid = 0;
+ we want to return -1. In the latter case, low = high and mid = low - 1;
+ we want to return the index of the highest entry. Only in former case
+ will the following 'catch-all' test be true. */
++mid;
- /* last entry is catch-all for all higher addresses: */
+ /* Last entry is catch-all for all higher addresses. */
if (offset < tab[mid].base_addr)
return -1;
find_min:
+ /* eraxxon: There may be multiple FDRs in the table with the
+ same base_addr; make sure that we are at the first one. */
while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr)
--mid;
/* Look up a line given an address, storing the information in
LINE_INFO->cache. */
-static boolean
+static bfd_boolean
lookup_line (abfd, debug_info, debug_swap, line_info)
bfd *abfd;
struct ecoff_debug_info * const debug_info;
{
struct ecoff_fdrtab_entry *tab;
bfd_vma offset;
- boolean stabs;
+ bfd_boolean stabs;
FDR *fdr_ptr;
int i;
-
+
+ /* eraxxon: note that 'offset' is the full vma, not a section offset. */
offset = line_info->cache.start;
-
+
/* Build FDR table (sorted by object file's base-address) if we
don't have it already. */
if (line_info->fdrtab == NULL
&& !mk_fdrtab (abfd, debug_info, debug_swap, line_info))
- return false;
+ return FALSE;
tab = line_info->fdrtab;
- /* find first FDR for address OFFSET */
+ /* Find first FDR for address OFFSET. */
i = fdrtab_lookup (line_info, offset);
if (i < 0)
- return false; /* no FDR, no fun... */
+ return FALSE; /* no FDR, no fun... */
+
+ /* eraxxon: 'fdrtab_lookup' doesn't give what we want, at least for Compaq's
+ C++ compiler 6.2. Consider three FDRs with starting addresses of x, y,
+ and z, respectively, such that x < y < z. Assume further that
+ y < 'offset' < z. It is possible at times that the PDR for 'offset' is
+ associated with FDR x and *not* with FDR y. Erg!!
+
+ From a binary dump of my C++ test case 'moo' using Compaq's coffobjanl
+ (output format has been edited for our purposes):
+
+ FDR [2]: (main.C): First instruction: 0x12000207c <x>
+ PDR [5] for File [2]: LoopTest__Xv <0x1200020a0> (a)
+ PDR [7] for File [2]: foo__Xv <0x120002168>
+ FDR [1]: (-1): First instruction: 0x1200020e8 <y>
+ PDR [3] for File [1]: <0x120001ad0> (b)
+ FDR [6]: (-1): First instruction: 0x1200026f0 <z>
+
+ (a) In the case of PDR5, the vma is such that the first few instructions
+ of the procedure can be found. But since the size of this procedure is
+ 160b, the vma will soon cross into the 'address space' of FDR1 and no
+ debugging info will be found. How repugnant!
+
+ (b) It is also possible for a PDR to have a *lower* vma than its associated
+ FDR; see FDR1 and PDR3. Gross!
+
+ Since the FDRs that are causing so much havok (in this case) 1) do not
+ describe actual files (fdr.rss == -1), and 2) contain only compiler
+ generated routines, I thought a simple fix would be to exclude them from
+ the FDR table in 'mk_fdrtab'. But, besides not knowing for certain
+ whether this would be correct, it creates an additional problem. If we
+ happen to ask for source file info on a compiler generated (procedure)
+ symbol -- which is still in the symbol table -- the result can be
+ information from a real procedure! This is because compiler generated
+ procedures with vma's higher than the last FDR in the fdr table will be
+ associated with a PDR from this FDR, specifically the PDR with the
+ highest vma. This wasn't a problem before, because each procedure had a
+ PDR. (Yes, this problem could be eliminated if we kept the size of the
+ last PDR around, but things are already getting ugly).
+
+ Probably, a better solution would be to have a sorted PDR table. Each
+ PDR would have a pointer to its FDR so file information could still be
+ obtained. A FDR table could still be constructed if necessary -- since
+ it only contains pointers, not much extra memory would be used -- but
+ the PDR table would be searched to locate debugging info.
+
+ There is still at least one remaining issue. Sometimes a FDR can have a
+ bogus name, but contain PDRs that should belong to another FDR with a
+ real name. E.g:
+
+ FDR [3]: 0000000120001b50 (/home/.../Array.H~alt~deccxx_5E5A62AD)
+ PDR [a] for File [3]: 0000000120001b50
+ PDR [b] for File [3]: 0000000120001cf0
+ PDR [c] for File [3]: 0000000120001dc8
+ PDR [d] for File [3]: 0000000120001e40
+ PDR [e] for File [3]: 0000000120001eb8
+ PDR [f] for File [3]: 0000000120001f4c
+ FDR [4]: 0000000120001b50 (/home/.../Array.H)
+
+ Here, FDR4 has the correct name, but should (seemingly) contain PDRa-f.
+ The symbol table for PDR4 does contain symbols for PDRa-f, but so does
+ the symbol table for FDR3. However the former is different; perhaps this
+ can be detected easily. (I'm not sure at this point.) This problem only
+ seems to be associated with files with templates. I am assuming the idea
+ is that there is a 'fake' FDR (with PDRs) for each differently typed set
+ of templates that must be generated. Currently, FDR4 is completely
+ excluded from the FDR table in 'mk_fdrtab' because it contains no PDRs.
+
+ Since I don't have time to prepare a real fix for this right now, be
+ prepared for 'A Horrible Hack' to force the inspection of all non-stabs
+ FDRs. It's coming... */
fdr_ptr = tab[i].fdr;
/* Check whether this file has stabs debugging information. In a
file with stabs debugging information, the second local symbol is
named @stabs. */
- stabs = false;
+ stabs = FALSE;
if (fdr_ptr->csym >= 2)
{
char *sym_ptr;
(*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
STABS_SYMBOL) == 0)
- stabs = true;
+ stabs = TRUE;
}
if (!stabs)
char *pdr_ptr;
char *best_pdr = NULL;
FDR *best_fdr;
- bfd_vma best_dist = ~0;
+ bfd_signed_vma best_dist = -1;
PDR pdr;
unsigned char *line_ptr;
unsigned char *line_end;
malloc.c. I'm not sure why this happens, but it could
be due to optimizations that reorder a function's
position within an object-file.
-
+
Strategy:
-
+
On the first call to this function, we build a table of FDRs
that is sorted by the base-address of the object-file the FDR
is referring to. Notice that each object-file may contain
considerably, which is undesirable. */
external_pdr_size = debug_swap->external_pdr_size;
- /* Make offset relative to object file's start-address: */
- offset -= tab[i].base_addr;
+ /* eraxxon: The Horrible Hack: Because of the problems above, set 'i'
+ to 0 so we look through all FDRs.
+
+ Because FDR's without any symbols are assumed to be non-stabs,
+ searching through all FDRs may cause the following code to try to
+ read stabs FDRs as ECOFF ones. However, I don't think this will
+ harm anything. */
+ i = 0;
+
/* Search FDR list starting at tab[i] for the PDR that best matches
OFFSET. Normally, the FDR list is only one entry long. */
best_fdr = NULL;
do
{
- bfd_vma dist, min_dist = 0;
+ /* eraxxon: 'dist' and 'min_dist' can be negative now
+ because we iterate over every FDR rather than just ones
+ with a base address less than or equal to 'offset'. */
+ bfd_signed_vma dist = -1, min_dist = -1;
char *pdr_hold;
char *pdr_end;
-
+
fdr_ptr = tab[i].fdr;
-
+
pdr_ptr = ((char *) debug_info->external_pdr
+ fdr_ptr->ipdFirst * external_pdr_size);
pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
if (offset >= (pdr.adr - 0x10 * pdr.prof))
{
dist = offset - (pdr.adr - 0x10 * pdr.prof);
- if (!pdr_hold || dist < min_dist)
+
+ /* eraxxon: 'dist' can be negative now. Note that
+ 'min_dist' can be negative if 'pdr_hold' below is NULL. */
+ if (!pdr_hold || (dist >= 0 && dist < min_dist))
{
min_dist = dist;
pdr_hold = pdr_ptr;
}
}
}
-
- if (!best_pdr || min_dist < best_dist)
+
+ if (!best_pdr || (min_dist >= 0 && min_dist < best_dist))
{
- best_dist = min_dist;
+ best_dist = (bfd_vma) min_dist;
best_fdr = fdr_ptr;
best_pdr = pdr_hold;
}
- /* continue looping until base_addr of next entry is different: */
+ /* Continue looping until base_addr of next entry is different. */
}
- while (++i < line_info->fdrtab_len
- && tab[i].base_addr == tab[i - 1].base_addr);
+ /* eraxxon: We want to iterate over all FDRs.
+ See previous comment about 'fdrtab_lookup'. */
+ while (++i < line_info->fdrtab_len);
if (!best_fdr || !best_pdr)
- return false; /* shouldn't happen... */
+ return FALSE; /* Shouldn't happen... */
- /* phew, finally we got something that we can hold onto: */
+ /* Phew, finally we got something that we can hold onto. */
fdr_ptr = best_fdr;
pdr_ptr = best_pdr;
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
number entries. */
line_end = debug_info->line + fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
- /* Make offset relative to procedure entry: */
+ /* Make offset relative to procedure entry. */
offset -= pdr.adr - 0x10 * pdr.prof;
lineno = pdr.lnLow;
line_ptr = debug_info->line + fdr_ptr->cbLineOffset + pdr.cbLineOffset;
const char *line_file_name;
bfd_vma low_func_vma;
bfd_vma low_line_vma;
- boolean past_line;
- boolean past_fn;
+ bfd_boolean past_line;
+ bfd_boolean past_fn;
char *sym_ptr, *sym_ptr_end;
size_t len, funclen;
char *buffer = NULL;
line_file_name = NULL;
low_func_vma = 0;
low_line_vma = 0;
- past_line = false;
- past_fn = false;
+ past_line = FALSE;
+ past_fn = FALSE;
external_sym_size = debug_swap->external_sym_size;
case N_FUN:
if (sym.value > offset)
- past_fn = true;
+ past_fn = TRUE;
else if (sym.value >= low_func_vma)
{
low_func_vma = sym.value;
else if (sym.st == stLabel && sym.index != indexNil)
{
if (sym.value > offset)
- past_line = true;
+ past_line = TRUE;
else if (sym.value >= low_line_vma)
{
low_line_vma = sym.value;
{
if (line_info->find_buffer != NULL)
free (line_info->find_buffer);
- buffer = (char *) bfd_malloc (len);
+ buffer = (char *) bfd_malloc ((bfd_size_type) len);
if (buffer == NULL)
- return false;
+ return FALSE;
line_info->find_buffer = buffer;
}
}
}
- return true;
+ return TRUE;
}
/* Do the work of find_nearest_line. */
-boolean
+bfd_boolean
_bfd_ecoff_locate_line (abfd, section, offset, debug_info, debug_swap,
line_info, filename_ptr, functionname_ptr, retline_ptr)
bfd *abfd;
if (! lookup_line (abfd, debug_info, debug_swap, line_info))
{
line_info->cache.sect = NULL;
- return false;
+ return FALSE;
}
}
*functionname_ptr = line_info->cache.functionname;
*retline_ptr = line_info->cache.line_num;
- return true;
+ return TRUE;
}
\f
/* These routines copy symbolic information into a memory buffer.
/* Collect a shuffle into a memory buffer. */
-static boolean ecoff_collect_shuffle PARAMS ((struct shuffle *, bfd_byte *));
+static bfd_boolean ecoff_collect_shuffle
+ PARAMS ((struct shuffle *, bfd_byte *));
-static boolean
+static bfd_boolean
ecoff_collect_shuffle (l, buff)
struct shuffle *l;
bfd_byte *buff;
else
{
if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
- || bfd_read (buff, 1, l->size, l->u.file.input_bfd) != l->size)
- return false;
+ || (bfd_bread (buff, (bfd_size_type) l->size, l->u.file.input_bfd)
+ != l->size))
+ return FALSE;
}
total += l->size;
buff += l->size;
}
- return true;
+ return TRUE;
}
/* Copy PDR information into a memory buffer. */
-boolean
+bfd_boolean
_bfd_ecoff_get_accumulated_pdr (handle, buff)
PTR handle;
bfd_byte *buff;
/* Copy symbol information into a memory buffer. */
-boolean
+bfd_boolean
_bfd_ecoff_get_accumulated_sym (handle, buff)
PTR handle;
bfd_byte *buff;
/* Copy the string table into a memory buffer. */
-boolean
+bfd_boolean
_bfd_ecoff_get_accumulated_ss (handle, buff)
PTR handle;
bfd_byte *buff;
buff += len + 1;
}
- return true;
+ return TRUE;
}