/* Routines to link ECOFF debugging information.
- Copyright (C) 1993-2019 Free Software Foundation, Inc.
+ Copyright (C) 1993-2021 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.
/* Add bytes to a buffer. Return success. */
-static bfd_boolean
+static bool
ecoff_add_bytes (char **buf, char **bufend, size_t need)
{
size_t have;
}
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. */
- bfd_boolean filep;
+ bool filep;
union
{
struct
/* Add a file entry to a shuffle list. */
-static bfd_boolean
+static bool
add_file_shuffle (struct accumulate *ainfo,
struct shuffle **head,
struct shuffle **tail,
(*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 bfd_boolean
+static bool
add_memory_shuffle (struct accumulate *ainfo,
struct shuffle **head,
struct shuffle **tail,
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 = 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
struct bfd_link_info *info)
{
struct accumulate *ainfo;
- bfd_size_type amt = sizeof (struct accumulate);
+ size_t amt = sizeof (struct accumulate);
ainfo = (struct accumulate *) bfd_malloc (amt);
if (!ainfo)
linker information structure. HANDLE is returned by
bfd_ecoff_debug_init. */
-bfd_boolean
+bool
bfd_ecoff_debug_accumulate (void * handle,
bfd *output_bfd,
struct ecoff_debug_info *output_debug,
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;
lookup = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 20);
if (lookup == NULL)
- return FALSE;
+ return false;
sprintf (lookup, "%s %lx %lx", name, (unsigned long) fdr.csym,
(unsigned long) 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;
- bfd_boolean fgotfilename;
+ bool fgotfilename;
if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
{
/* 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;
prevent us from easily merging different FDR's. */
if (! bfd_link_relocatable (info))
{
- bfd_boolean ffilename;
+ bool 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;
}
}
file_ptr pos = input_symhdr->cbLineOffset + fdr.cbLineOffset;
if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
input_bfd, pos, (unsigned long) fdr.cbLine))
- return FALSE;
+ return false;
fdr.ilineBase = output_symhdr->ilineMax;
fdr.cbLineOffset = output_symhdr->cbLine;
output_symhdr->ilineMax += fdr.cline;
if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
input_bfd, pos,
fdr.caux * sizeof (union aux_ext)))
- return FALSE;
+ return false;
fdr.iauxBase = output_symhdr->iauxMax;
output_symhdr->iauxMax += fdr.caux;
}
file_ptr pos = input_symhdr->cbSsOffset + fdr.issBase;
if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
input_bfd, pos, (unsigned long) fdr.cbSs))
- return FALSE;
+ return false;
fdr.issBase = output_symhdr->issMax;
output_symhdr->issMax += fdr.cbSs;
}
unsigned long size = fdr.cpd * external_pdr_size;
if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
input_bfd, pos, size))
- return FALSE;
+ return false;
}
BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
if (fdr.copt > 0)
unsigned long size = fdr.copt * external_opt_size;
if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
input_bfd, pos, size))
- return FALSE;
+ 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;
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.
{
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. */
-bfd_boolean
+bool
bfd_ecoff_debug_accumulate_other (void * handle,
bfd *output_bfd,
struct ecoff_debug_info *output_debug,
fdr.issBase = output_symhdr->issMax;
fdr.cbSs = 0;
fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
- input_bfd->filename);
+ bfd_get_filename (input_bfd));
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;
+ 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,
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,
++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. */
-bfd_boolean
+bool
bfd_ecoff_debug_externals (bfd *abfd,
struct ecoff_debug_info *debug,
const struct ecoff_debug_swap *swap,
- bfd_boolean relocatable,
- bfd_boolean (*get_extr) (asymbol *, EXTR *),
+ bool relocatable,
+ bool (*get_extr) (asymbol *, EXTR *),
void (*set_index) (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++)
{
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. */
-bfd_boolean
+bool
bfd_ecoff_debug_one_external (bfd *abfd,
struct ecoff_debug_info *debug,
const struct ecoff_debug_swap *swap,
if (! ecoff_add_bytes ((char **) &debug->ssext,
(char **) &debug->ssext_end,
symhdr->issExtMax + namelen + 1))
- return FALSE;
+ return false;
}
if ((size_t) ((char *) debug->external_ext_end
- (char *) debug->external_ext)
if (! ecoff_add_bytes ((char **) &external_ext,
(char **) &external_ext_end,
(symhdr->iextMax + 1) * (size_t) external_ext_size))
- return FALSE;
+ return false;
debug->external_ext = external_ext;
debug->external_ext_end = external_ext_end;
}
strcpy (debug->ssext + symhdr->issExtMax, name);
symhdr->issExtMax += namelen + 1;
- return TRUE;
+ return true;
}
/* Align the ECOFF debugging information. */
going to be placed at. This assumes that the counts are set
correctly. */
-static bfd_boolean
+static bool
ecoff_write_symhdr (bfd *abfd,
struct ecoff_debug_info *debug,
const struct ecoff_debug_swap *swap,
/* 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;
!= swap->external_hdr_size)
goto error_return;
- if (buff != NULL)
- free (buff);
- return TRUE;
+ free (buff);
+ return true;
error_return:
- if (buff != NULL)
- free (buff);
- return FALSE;
+ free (buff);
+ return false;
}
/* Write out the ECOFF debugging information. This function assumes
information to. This function fills in the file offsets in the
symbolic header. */
-bfd_boolean
+bool
bfd_ecoff_write_debug (bfd *abfd,
struct ecoff_debug_info *debug,
const struct ecoff_debug_swap *swap,
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_bwrite (debug->ptr, (bfd_size_type) size * symhdr->count, abfd)\
- != size * symhdr->count) \
- return FALSE;
+ BFD_ASSERT (symhdr->offset == 0 \
+ || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \
+ if (symhdr->count != 0 \
+ && bfd_bwrite (debug->ptr, \
+ (bfd_size_type) size * symhdr->count, \
+ abfd) != size * symhdr->count) \
+ return false;
WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
#undef WRITE
- return TRUE;
+ return true;
}
/* Write out a shuffle list. */
-static bfd_boolean
+static bool
ecoff_write_shuffle (bfd *abfd,
const struct ecoff_debug_swap *swap,
struct shuffle *shuffle,
{
if (bfd_bwrite (l->u.memory, (bfd_size_type) l->size, abfd)
!= l->size)
- return FALSE;
+ return false;
}
else
{
|| 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;
+ return false;
}
total += l->size;
}
i = swap->debug_align - (total & (swap->debug_align - 1));
s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
if (s == NULL && i != 0)
- return FALSE;
+ return false;
if (bfd_bwrite (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. */
-bfd_boolean
+bool
bfd_ecoff_write_accumulated_debug (void * handle,
bfd *abfd,
struct ecoff_debug_info *debug,
/* The external strings and symbol are not converted over to using
shuffles. FIXME: They probably should be. */
amt = debug->symbolic_header.issExtMax;
- if (bfd_bwrite (debug->ssext, amt, abfd) != amt)
+ if (amt != 0 && bfd_bwrite (debug->ssext, amt, abfd) != amt)
goto error_return;
if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
{
== (bfd_vma) bfd_tell (abfd)));
amt = debug->symbolic_header.iextMax * swap->external_ext_size;
- if (bfd_bwrite (debug->external_ext, amt, abfd) != amt)
+ if (amt != 0 && bfd_bwrite (debug->external_ext, amt, abfd) != amt)
goto error_return;
- if (space != NULL)
- free (space);
- return TRUE;
+ free (space);
+ return true;
error_return:
- if (space != NULL)
- free (space);
- return FALSE;
+ free (space);
+ 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 bfd_boolean
+static bool
mk_fdrtab (bfd *abfd,
struct ecoff_debug_info * const debug_info,
const struct ecoff_debug_swap * const debug_swap,
FDR *fdr_ptr;
FDR *fdr_start;
FDR *fdr_end;
- bfd_boolean stabs;
+ bool stabs;
long len;
bfd_size_type amt;
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;
(*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)
qsort (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. */
/* Look up a line given an address, storing the information in
LINE_INFO->cache. */
-static bfd_boolean
+static bool
lookup_line (bfd *abfd,
struct ecoff_debug_info * const debug_info,
const struct ecoff_debug_swap * const debug_swap,
{
struct ecoff_fdrtab_entry *tab;
bfd_vma offset;
- bfd_boolean stabs;
+ bool stabs;
FDR *fdr_ptr;
int i;
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. */
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,
/* 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)
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. */
fdr_ptr = best_fdr;
const char *line_file_name;
bfd_vma low_func_vma;
bfd_vma low_line_vma;
- bfd_boolean past_line;
- bfd_boolean past_fn;
+ bool past_line;
+ bool 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 (len != 0)
{
- if (line_info->find_buffer != NULL)
- free (line_info->find_buffer);
+ free (line_info->find_buffer);
buffer = (char *) bfd_malloc ((bfd_size_type) len);
- if (buffer == NULL)
- return FALSE;
line_info->find_buffer = buffer;
+ if (buffer == NULL)
+ return false;
}
if (function_name != NULL)
}
}
- return TRUE;
+ return true;
}
/* Do the work of find_nearest_line. */
-bfd_boolean
+bool
_bfd_ecoff_locate_line (bfd *abfd,
asection *section,
bfd_vma offset,
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 bfd_boolean
+static bool
ecoff_collect_shuffle (struct shuffle *l, bfd_byte *buff)
{
- unsigned long total;
-
- total = 0;
for (; l != (struct shuffle *) NULL; l = l->next)
{
if (! l->filep)
if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
|| (bfd_bread (buff, (bfd_size_type) l->size, l->u.file.input_bfd)
!= l->size))
- return FALSE;
+ return false;
}
- total += l->size;
buff += l->size;
}
- return TRUE;
+ return true;
}
/* Copy PDR information into a memory buffer. */
-bfd_boolean
+bool
_bfd_ecoff_get_accumulated_pdr (void * handle,
bfd_byte *buff)
{
/* Copy symbol information into a memory buffer. */
-bfd_boolean
+bool
_bfd_ecoff_get_accumulated_sym (void * handle, bfd_byte *buff)
{
struct accumulate *ainfo = (struct accumulate *) handle;
/* Copy the string table into a memory buffer. */
-bfd_boolean
+bool
_bfd_ecoff_get_accumulated_ss (void * handle, bfd_byte *buff)
{
struct accumulate *ainfo = (struct accumulate *) handle;
struct string_hash_entry *sh;
- unsigned long total;
/* The string table is written out from the hash table if this is a
final link. */
BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
*buff++ = '\0';
- total = 1;
BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
for (sh = ainfo->ss_hash;
sh != (struct string_hash_entry *) NULL;
len = strlen (sh->root.string);
memcpy (buff, sh->root.string, len + 1);
- total += len + 1;
buff += len + 1;
}
- return TRUE;
+ return true;
}