/* Support for the generic parts of COFF, for BFD.
- Copyright (C) 1990-2016 Free Software Foundation, Inc.
+ Copyright (C) 1990-2021 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
coff_data (abfd). */
#include "sysdep.h"
+#include <limits.h>
#include "bfd.h"
#include "libbfd.h"
#include "coff/internal.h"
/* Take a section header read from a coff file (in HOST byte order),
and make a BFD "section" out of it. This is used by ECOFF. */
-static bfd_boolean
+static bool
make_a_section_from_file (bfd *abfd,
struct internal_scnhdr *hdr,
unsigned int target_index)
{
asection *return_section;
char *name;
- bfd_boolean result = TRUE;
+ bool result = true;
flagword flags;
name = NULL;
const char *strings;
/* Flag that this BFD uses long names, even though the format might
- expect them to be off by default. This won't directly affect the
- format of any output BFD created from this one, but the information
- can be used to decide what to do. */
- bfd_coff_set_long_section_names (abfd, TRUE);
+ expect them to be off by default. This won't directly affect the
+ format of any output BFD created from this one, but the information
+ can be used to decide what to do. */
+ bfd_coff_set_long_section_names (abfd, true);
memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1);
buf[SCNNMLEN - 1] = '\0';
strindex = strtol (buf, &p, 10);
{
strings = _bfd_coff_read_string_table (abfd);
if (strings == NULL)
- return FALSE;
+ return false;
if ((bfd_size_type)(strindex + 2) >= obj_coff_strings_len (abfd))
- return FALSE;
+ return false;
strings += strindex;
name = (char *) bfd_alloc (abfd,
- (bfd_size_type) strlen (strings) + 1 + 1);
+ (bfd_size_type) strlen (strings) + 1 + 1);
if (name == NULL)
- return FALSE;
+ return false;
strcpy (name, strings);
}
}
{
/* Assorted wastage to null-terminate the name, thanks AT&T! */
name = (char *) bfd_alloc (abfd,
- (bfd_size_type) sizeof (hdr->s_name) + 1 + 1);
+ (bfd_size_type) sizeof (hdr->s_name) + 1 + 1);
if (name == NULL)
- return FALSE;
+ return false;
strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
name[sizeof (hdr->s_name)] = 0;
}
return_section = bfd_make_section_anyway (abfd, name);
if (return_section == NULL)
- return FALSE;
+ return false;
return_section->vma = hdr->s_vaddr;
return_section->lma = hdr->s_paddr;
if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section,
& flags))
- result = FALSE;
+ result = false;
return_section->flags = flags;
{
_bfd_error_handler
/* xgettext: c-format */
- (_("%B: unable to initialize compress status for section %s"),
+ (_("%pB: unable to initialize compress status for section %s"),
abfd, name);
- return FALSE;
+ return false;
}
if (return_section->compress_status == COMPRESS_SECTION_DONE)
{
new_name = bfd_alloc (abfd, len + 2);
if (new_name == NULL)
- return FALSE;
+ return false;
new_name[0] = '.';
new_name[1] = 'z';
memcpy (new_name + 2, name + 1, len);
}
}
- break;
+ break;
case decompress:
if (!bfd_init_section_decompress_status (abfd, return_section))
{
_bfd_error_handler
/* xgettext: c-format */
- (_("%B: unable to initialize decompress status for section %s"),
+ (_("%pB: unable to initialize decompress status for section %s"),
abfd, name);
- return FALSE;
+ return false;
}
if (name[1] == 'z')
{
new_name = bfd_alloc (abfd, len);
if (new_name == NULL)
- return FALSE;
+ return false;
new_name[0] = '.';
memcpy (new_name + 1, name + 2, len - 1);
}
break;
}
if (new_name != NULL)
- bfd_rename_section (abfd, return_section, new_name);
+ bfd_rename_section (return_section, new_name);
}
return result;
/* Read in a COFF object and make it into a BFD. This is used by
ECOFF as well. */
-const bfd_target *
+bfd_cleanup
coff_real_object_p (bfd *,
- unsigned,
- struct internal_filehdr *,
- struct internal_aouthdr *);
-const bfd_target *
+ unsigned,
+ struct internal_filehdr *,
+ struct internal_aouthdr *);
+bfd_cleanup
coff_real_object_p (bfd *abfd,
unsigned nscns,
struct internal_filehdr *internal_f,
if ((internal_f->f_flags & F_EXEC) != 0)
abfd->flags |= D_PAGED;
- bfd_get_symcount (abfd) = internal_f->f_nsyms;
+ abfd->symcount = internal_f->f_nsyms;
if (internal_f->f_nsyms)
abfd->flags |= HAS_SYMS;
if (internal_a != (struct internal_aouthdr *) NULL)
- bfd_get_start_address (abfd) = internal_a->entry;
+ abfd->start_address = internal_a->entry;
else
- bfd_get_start_address (abfd) = 0;
+ abfd->start_address = 0;
/* Set up the tdata area. ECOFF uses its own routine, and overrides
abfd->flags. */
scnhsz = bfd_coff_scnhsz (abfd);
readsize = (bfd_size_type) nscns * scnhsz;
- external_sections = (char *) bfd_alloc (abfd, readsize);
+ external_sections = (char *) _bfd_alloc_and_read (abfd, readsize, readsize);
if (!external_sections)
goto fail;
- if (bfd_bread ((void *) external_sections, readsize, abfd) != readsize)
- goto fail;
-
/* Set the arch/mach *before* swapping in sections; section header swapping
may depend on arch/mach info. */
if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f))
}
}
- return abfd->xvec;
+ _bfd_coff_free_symbols (abfd);
+ return _bfd_no_cleanup;
fail:
+ _bfd_coff_free_symbols (abfd);
bfd_release (abfd, tdata);
fail2:
abfd->tdata.any = tdata_save;
abfd->flags = oflags;
- bfd_get_start_address (abfd) = ostart;
- return (const bfd_target *) NULL;
+ abfd->start_address = ostart;
+ return NULL;
}
/* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is
not a COFF file. This is also used by ECOFF. */
-const bfd_target *
+bfd_cleanup
coff_object_p (bfd *abfd)
{
bfd_size_type filhsz;
filhsz = bfd_coff_filhsz (abfd);
aoutsz = bfd_coff_aoutsz (abfd);
- filehdr = bfd_alloc (abfd, filhsz);
+ filehdr = _bfd_alloc_and_read (abfd, filhsz, filhsz);
if (filehdr == NULL)
- return NULL;
- if (bfd_bread (filehdr, filhsz, abfd) != filhsz)
{
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_wrong_format);
- bfd_release (abfd, filehdr);
return NULL;
}
bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f);
{
void * opthdr;
- opthdr = bfd_alloc (abfd, aoutsz);
+ opthdr = _bfd_alloc_and_read (abfd, aoutsz, internal_f.f_opthdr);
if (opthdr == NULL)
return NULL;
- if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd)
- != internal_f.f_opthdr)
- {
- bfd_release (abfd, opthdr);
- return NULL;
- }
/* PR 17512: file: 11056-1136-0.004. */
if (internal_f.f_opthdr < aoutsz)
- memset (((char *) opthdr) + internal_f.f_opthdr, 0, aoutsz - internal_f.f_opthdr);
+ memset (((char *) opthdr) + internal_f.f_opthdr, 0,
+ aoutsz - internal_f.f_opthdr);
bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a);
bfd_release (abfd, opthdr);
struct internal_reloc *
_bfd_coff_read_internal_relocs (bfd *abfd,
asection *sec,
- bfd_boolean cache,
+ bool cache,
bfd_byte *external_relocs,
- bfd_boolean require_internal,
+ bool require_internal,
struct internal_reloc *internal_relocs)
{
bfd_size_type relsz;
for (; erel < erel_end; erel += relsz, irel++)
bfd_coff_swap_reloc_in (abfd, (void *) erel, (void *) irel);
- if (free_external != NULL)
- {
- free (free_external);
- free_external = NULL;
- }
+ free (free_external);
+ free_external = NULL;
if (cache && free_internal != NULL)
{
return internal_relocs;
error_return:
- if (free_external != NULL)
- free (free_external);
- if (free_internal != NULL)
- free (free_internal);
+ free (free_external);
+ free (free_internal);
return NULL;
}
if (limit == 0)
{
/* This may be from the backend linker, in which case the
- lineno_count in the sections is correct. */
+ lineno_count in the sections is correct. */
for (s = abfd->sections; s != NULL; s = s->next)
total += s->lineno_count;
return total;
coff_symbol_type *q = coffsymbol (q_maybe);
/* The AIX 4.1 compiler can sometimes generate line numbers
- attached to debugging symbols. We try to simply ignore
- those here. */
+ attached to debugging symbols. We try to simply ignore
+ those here. */
if (q->lineno != NULL
&& q->symbol.section->owner != NULL)
{
/* This symbol has line numbers. Increment the owning
- section's linenumber count. */
+ section's linenumber count. */
alent *l = q->lineno;
do
syment->n_value = (coff_symbol_ptr->symbol.value
+ coff_symbol_ptr->symbol.section->output_offset);
if (! obj_pe (abfd))
- {
- syment->n_value += (syment->n_sclass == C_STATLAB)
- ? coff_symbol_ptr->symbol.section->output_section->lma
- : coff_symbol_ptr->symbol.section->output_section->vma;
- }
+ {
+ syment->n_value += (syment->n_sclass == C_STATLAB)
+ ? coff_symbol_ptr->symbol.section->output_section->lma
+ : coff_symbol_ptr->symbol.section->output_section->vma;
+ }
}
else
{
chain, and that the last one points to the first external symbol. We
do that here too. */
-bfd_boolean
+bool
coff_renumber_symbols (bfd *bfd_ptr, int *first_undef)
{
unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1);
newsyms = (asymbol **) bfd_alloc (bfd_ptr, amt);
if (!newsyms)
- return FALSE;
+ return false;
bfd_ptr->outsymbols = newsyms;
for (i = 0; i < symbol_count; i++)
if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0
obj_conv_table_size (bfd_ptr) = native_index;
- return TRUE;
+ return true;
}
/* Run thorough the symbol table again, and fix it so that all
if (s->fix_line)
{
/* The value is the offset into the line number entries
- for the symbol's section. On output, the symbol's
- section should be N_DEBUG. */
+ for the symbol's section. On output, the symbol's
+ section should be N_DEBUG. */
s->u.syment.n_value =
(coff_symbol_ptr->symbol.section->output_section->line_filepos
+ s->u.syment.n_value * bfd_coff_linesz (bfd_ptr));
if (bfd_coff_force_symnames_in_strings (abfd))
{
- native->u.syment._n._n_n._n_offset =
+ native->u.syment._n._n_n._n_offset =
(*string_size_p + STRING_SIZE_SIZE);
native->u.syment._n._n_n._n_zeroes = 0;
*string_size_p += 6; /* strlen(".file") + 1 */
}
else
- strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
+ strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
BFD_ASSERT (! (native + 1)->is_sym);
auxent = &(native + 1)->u.auxent;
/* Write a symbol out to a COFF file. */
-static bfd_boolean
+static bool
coff_write_symbol (bfd *abfd,
asymbol *symbol,
combined_entry_type *native,
symesz = bfd_coff_symesz (abfd);
buf = bfd_alloc (abfd, symesz);
if (!buf)
- return FALSE;
+ return false;
bfd_coff_swap_sym_out (abfd, &native->u.syment, buf);
if (bfd_bwrite (buf, symesz, abfd) != symesz)
- return FALSE;
+ return false;
bfd_release (abfd, buf);
if (native->u.syment.n_numaux > 0)
auxesz = bfd_coff_auxesz (abfd);
buf = bfd_alloc (abfd, auxesz);
if (!buf)
- return FALSE;
+ return false;
for (j = 0; j < native->u.syment.n_numaux; j++)
{
BFD_ASSERT (! (native + j + 1)->is_sym);
native->u.syment.n_numaux,
buf);
if (bfd_bwrite (buf, auxesz, abfd) != auxesz)
- return FALSE;
+ return false;
}
bfd_release (abfd, buf);
}
set_index (symbol, *written);
*written += numaux + 1;
- return TRUE;
+ return true;
}
/* Write out a symbol to a COFF file that does not come from a COFF
file originally. This symbol may have been created by the linker,
or we may be linking a non COFF file to a COFF file. */
-bfd_boolean
+bool
coff_write_alien_symbol (bfd *abfd,
asymbol *symbol,
struct internal_syment *isym,
? symbol->section->output_section
: symbol->section;
struct bfd_link_info *link_info = coff_data (abfd)->link_info;
- bfd_boolean ret;
+ bool ret;
if ((!link_info || link_info->strip_discarded)
&& !bfd_is_abs_section (symbol->section)
{
symbol->name = "";
if (isym != NULL)
- memset (isym, 0, sizeof (*isym));
- return TRUE;
+ memset (isym, 0, sizeof (*isym));
+ return true;
}
native = dummy;
- native->is_sym = TRUE;
- native[1].is_sym = FALSE;
+ native->is_sym = true;
+ native[1].is_sym = false;
native->u.syment.n_type = T_NULL;
native->u.syment.n_flags = 0;
native->u.syment.n_numaux = 0;
else if (symbol->flags & BSF_DEBUGGING)
{
/* There isn't much point to writing out a debugging symbol
- unless we are prepared to convert it into COFF debugging
- format. So, we just ignore them. We must clobber the symbol
- name to keep it from being put in the string table. */
+ unless we are prepared to convert it into COFF debugging
+ format. So, we just ignore them. We must clobber the symbol
+ name to keep it from being put in the string table. */
symbol->name = "";
if (isym != NULL)
- memset (isym, 0, sizeof (*isym));
- return TRUE;
+ memset (isym, 0, sizeof (*isym));
+ return true;
}
else
{
native->u.syment.n_value += output_section->vma;
/* Copy the any flags from the file header into the symbol.
- FIXME: Why? */
+ FIXME: Why? */
{
coff_symbol_type *c = coff_symbol_from (symbol);
if (c != (coff_symbol_type *) NULL)
/* Write a native symbol to a COFF file. */
-static bfd_boolean
+static bool
coff_write_native_symbol (bfd *abfd,
coff_symbol_type *symbol,
bfd_vma *written,
&& symbol->symbol.section->output_section == bfd_abs_section_ptr)
{
symbol->symbol.name = "";
- return TRUE;
+ return true;
}
BFD_ASSERT (native->is_sym);
+ symbol->symbol.section->output_offset);
count++;
}
- symbol->done_lineno = TRUE;
+ symbol->done_lineno = true;
if (! bfd_is_const_section (symbol->symbol.section->output_section))
symbol->symbol.section->output_section->moving_line_filepos +=
/* Write out the COFF symbols. */
-bfd_boolean
+bool
coff_write_symbols (bfd *abfd)
{
bfd_size_type string_size;
/* Seek to the right place. */
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
- return FALSE;
+ return false;
/* Output all the symbols we have. */
written = 0;
if (!coff_write_alien_symbol (abfd, symbol, NULL, NULL, &written,
&string_size, &debug_string_section,
&debug_string_size))
- return FALSE;
+ return false;
}
else
{
if (!coff_write_native_symbol (abfd, c_symbol, &written,
&string_size, &debug_string_section,
&debug_string_size))
- return FALSE;
+ return false;
}
}
#endif
if (bfd_bwrite ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd)
!= sizeof (buffer))
- return FALSE;
+ return false;
/* Handle long section names. This code must handle section
names just as they are handled in coff_write_object_contents. */
{
if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd)
!= len + 1)
- return FALSE;
+ return false;
}
}
}
if (bfd_coff_force_symnames_in_strings (abfd))
{
if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
- return FALSE;
+ return false;
}
maxlen = bfd_coff_filnmlen (abfd);
}
{
if (bfd_bwrite ((void *) (q->name), (bfd_size_type) name_length + 1,
abfd) != name_length + 1)
- return FALSE;
+ return false;
}
}
}
else
{
/* We would normally not write anything here, but we'll write
- out 4 so that any stupid coff reader which tries to read the
- string table even when there isn't one won't croak. */
+ out 4 so that any stupid coff reader which tries to read the
+ string table even when there isn't one won't croak. */
unsigned int size = STRING_SIZE_SIZE;
bfd_byte buffer[STRING_SIZE_SIZE];
#endif
if (bfd_bwrite ((void *) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd)
!= STRING_SIZE_SIZE)
- return FALSE;
+ return false;
}
/* Make sure the .debug section was created to be the correct size.
1 << debug_string_section->alignment_power)
== debug_string_section->size)));
- return TRUE;
+ return true;
}
-bfd_boolean
+bool
coff_write_linenumbers (bfd *abfd)
{
asection *s;
linesz = bfd_coff_linesz (abfd);
buff = bfd_alloc (abfd, linesz);
if (!buff)
- return FALSE;
+ return false;
for (s = abfd->sections; s != (asection *) NULL; s = s->next)
{
if (s->lineno_count)
{
asymbol **q = abfd->outsymbols;
if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0)
- return FALSE;
+ return false;
/* Find all the linenumbers in this section. */
while (*q)
{
bfd_coff_swap_lineno_out (abfd, &out, buff);
if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd)
!= linesz)
- return FALSE;
+ return false;
l++;
while (l->line_number)
{
bfd_coff_swap_lineno_out (abfd, &out, buff);
if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd)
!= linesz)
- return FALSE;
+ return false;
l++;
}
}
}
}
bfd_release (abfd, buff);
- return TRUE;
+ return true;
}
alent *
combined_entry_type *table_base,
combined_entry_type *symbol,
unsigned int indaux,
- combined_entry_type *auxent)
+ combined_entry_type *auxent,
+ combined_entry_type *table_end)
{
unsigned int type = symbol->u.syment.n_type;
unsigned int n_sclass = symbol->u.syment.n_sclass;
return;
if (n_sclass == C_FILE)
return;
+ if (n_sclass == C_DWARF)
+ return;
BFD_ASSERT (! auxent->is_sym);
/* Otherwise patch up. */
if ((ISFCN (type) || ISTAG (n_sclass) || n_sclass == C_BLOCK
|| n_sclass == C_FCN)
- && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0)
+ && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0
+ && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l
+ < (long) obj_raw_syment_count (abfd)
+ && table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l
+ < table_end)
{
auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p =
table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
auxent->fix_end = 1;
}
+
/* A negative tagndx is meaningless, but the SCO 3.2v4 cc can
generate one, so we must be careful to ignore it. */
- if (auxent->u.auxent.x_sym.x_tagndx.l > 0)
+ if ((unsigned long) auxent->u.auxent.x_sym.x_tagndx.l
+ < obj_raw_syment_count (abfd)
+ && table_base + auxent->u.auxent.x_sym.x_tagndx.l < table_end)
{
auxent->u.auxent.x_sym.x_tagndx.p =
table_base + auxent->u.auxent.x_sym.x_tagndx.l;
return NULL;
}
- sec_size = sect->size;
- debug_section = (char *) bfd_alloc (abfd, sec_size);
- if (debug_section == NULL)
- return NULL;
-
/* Seek to the beginning of the `.debug' section and read it.
Save the current position first; it is needed by our caller.
Then read debug section and reset the file pointer. */
position = bfd_tell (abfd);
- if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0
- || bfd_bread (debug_section, sec_size, abfd) != sec_size
- || bfd_seek (abfd, position, SEEK_SET) != 0)
+ if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0)
+ return NULL;
+
+ sec_size = sect->size;
+ debug_section = (char *) _bfd_alloc_and_read (abfd, sec_size, sec_size);
+ if (debug_section == NULL)
+ return NULL;
+
+ if (bfd_seek (abfd, position, SEEK_SET) != 0)
return NULL;
* sect_return = sect;
/* Read in the external symbols. */
-bfd_boolean
+bool
_bfd_coff_get_external_symbols (bfd *abfd)
{
- bfd_size_type symesz;
- bfd_size_type size;
+ size_t symesz;
+ size_t size;
void * syms;
if (obj_coff_external_syms (abfd) != NULL)
- return TRUE;
+ return true;
symesz = bfd_coff_symesz (abfd);
-
- size = obj_raw_syment_count (abfd) * symesz;
- if (size == 0)
- return TRUE;
-
- syms = bfd_malloc (size);
- if (syms == NULL)
- return FALSE;
-
- if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
- || bfd_bread (syms, size, abfd) != size)
+ if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size))
{
- if (syms != NULL)
- free (syms);
- return FALSE;
+ bfd_set_error (bfd_error_file_truncated);
+ return false;
}
- obj_coff_external_syms (abfd) = syms;
+ if (size == 0)
+ return true;
- return TRUE;
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
+ return false;
+ syms = _bfd_malloc_and_read (abfd, size, size);
+ obj_coff_external_syms (abfd) = syms;
+ return syms != NULL;
}
/* Read in the external strings. The strings are not loaded until
bfd_size_type strsize;
char *strings;
file_ptr pos;
+ ufile_ptr filesize;
if (obj_coff_strings (abfd) != NULL)
return obj_coff_strings (abfd);
#endif
}
- if (strsize < STRING_SIZE_SIZE)
+ filesize = bfd_get_file_size (abfd);
+ if (strsize < STRING_SIZE_SIZE
+ || (filesize != 0 && strsize > filesize))
{
_bfd_error_handler
/* xgettext: c-format */
- (_("%B: bad string table size %lu"), abfd, (unsigned long) strsize);
+ (_("%pB: bad string table size %" PRIu64), abfd, (uint64_t) strsize);
bfd_set_error (bfd_error_bad_value);
return NULL;
}
/* Free up the external symbols and strings read from a COFF file. */
-bfd_boolean
+bool
_bfd_coff_free_symbols (bfd *abfd)
{
+ if (! bfd_family_coff (abfd))
+ return false;
+
if (obj_coff_external_syms (abfd) != NULL
&& ! obj_coff_keep_syms (abfd))
{
free (obj_coff_external_syms (abfd));
obj_coff_external_syms (abfd) = NULL;
}
+
if (obj_coff_strings (abfd) != NULL
&& ! obj_coff_keep_strings (abfd))
{
obj_coff_strings (abfd) = NULL;
obj_coff_strings_len (abfd) = 0;
}
- return TRUE;
+
+ return true;
}
/* Read a symbol table into freshly bfd_allocated memory, swap it, and
if (! _bfd_coff_get_external_symbols (abfd))
return NULL;
- size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type);
+ size = obj_raw_syment_count (abfd);
+ /* Check for integer overflow. */
+ if (size > (bfd_size_type) -1 / sizeof (combined_entry_type))
+ return NULL;
+ size *= sizeof (combined_entry_type);
internal = (combined_entry_type *) bfd_zalloc (abfd, size);
if (internal == NULL && size != 0)
return NULL;
bfd_coff_swap_sym_in (abfd, (void *) raw_src,
(void *) & internal_ptr->u.syment);
symbol_ptr = internal_ptr;
- internal_ptr->is_sym = TRUE;
+ internal_ptr->is_sym = true;
- /* PR 17512: file: 1353-1166-0.004. */
- if (symbol_ptr->u.syment.n_sclass == C_FILE
- && symbol_ptr->u.syment.n_numaux > 0
- && raw_src + symesz + symbol_ptr->u.syment.n_numaux
- * symesz > raw_end)
+ /* PR 17512: Prevent buffer overrun. */
+ if (symbol_ptr->u.syment.n_numaux > ((raw_end - 1) - raw_src) / symesz)
{
bfd_release (abfd, internal);
return NULL;
i++)
{
internal_ptr++;
- /* PR 17512: Prevent buffer overrun. */
- if (internal_ptr >= internal_end)
- {
- bfd_release (abfd, internal);
- return NULL;
- }
-
raw_src += symesz;
+
bfd_coff_swap_aux_in (abfd, (void *) raw_src,
symbol_ptr->u.syment.n_type,
symbol_ptr->u.syment.n_sclass,
(int) i, symbol_ptr->u.syment.n_numaux,
&(internal_ptr->u.auxent));
- internal_ptr->is_sym = FALSE;
+ internal_ptr->is_sym = false;
coff_pointerize_aux (abfd, internal, symbol_ptr, i,
- internal_ptr);
+ internal_ptr, internal_end);
}
}
- /* Free the raw symbols, but not the strings (if we have them). */
- obj_coff_keep_strings (abfd) = TRUE;
- if (! _bfd_coff_free_symbols (abfd))
- return NULL;
+ /* Free the raw symbols. */
+ if (obj_coff_external_syms (abfd) != NULL
+ && ! obj_coff_keep_syms (abfd))
+ {
+ free (obj_coff_external_syms (abfd));
+ obj_coff_external_syms (abfd) = NULL;
+ }
for (internal_ptr = internal; internal_ptr < internal_end;
internal_ptr++)
else
{
/* Ordinary short filename, put into memory anyway. The
- Microsoft PE tools sometimes store a filename in
- multiple AUX entries. */
+ Microsoft PE tools sometimes store a filename in
+ multiple AUX entries. */
if (internal_ptr->u.syment.n_numaux > 1
&& coff_data (abfd)->pe)
internal_ptr->u.syment._n._n_n._n_offset =
char *newstring;
/* Find the length of this string without walking into memory
- that isn't ours. */
+ that isn't ours. */
for (i = 0; i < 8; ++i)
if (internal_ptr->u.syment._n._n_name[i] == '\0')
break;
else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment))
{
/* Long name already. Point symbol at the string in the
- table. */
+ table. */
if (string_table == NULL)
{
string_table = _bfd_coff_read_string_table (abfd);
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
+#if SIZEOF_LONG == SIZEOF_INT
+ if (asect->reloc_count >= LONG_MAX / sizeof (arelent *))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ return -1;
+ }
+#endif
return (asect->reloc_count + 1) * sizeof (arelent *);
}
asymbol *
coff_make_empty_symbol (bfd *abfd)
{
- bfd_size_type amt = sizeof (coff_symbol_type);
+ size_t amt = sizeof (coff_symbol_type);
coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_zalloc (abfd, amt);
if (new_symbol == NULL)
new_symbol->symbol.section = 0;
new_symbol->native = NULL;
new_symbol->lineno = NULL;
- new_symbol->done_lineno = FALSE;
+ new_symbol->done_lineno = false;
new_symbol->symbol.the_bfd = abfd;
return & new_symbol->symbol;
void * ptr ATTRIBUTE_UNUSED,
unsigned long sz ATTRIBUTE_UNUSED)
{
- bfd_size_type amt = sizeof (coff_symbol_type);
+ size_t amt = sizeof (coff_symbol_type);
coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_alloc (abfd, amt);
if (new_symbol == NULL)
new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt);
if (!new_symbol->native)
return NULL;
- new_symbol->native->is_sym = TRUE;
+ new_symbol->native->is_sym = true;
new_symbol->symbol.section = bfd_abs_section_ptr;
new_symbol->symbol.flags = BSF_DEBUGGING;
new_symbol->lineno = NULL;
- new_symbol->done_lineno = FALSE;
+ new_symbol->done_lineno = false;
new_symbol->symbol.the_bfd = abfd;
return & new_symbol->symbol;
fprintf (file, "File ");
break;
+ case C_DWARF:
+ fprintf (file, "AUX scnlen 0x%lx nreloc %ld",
+ (unsigned long) auxp->u.auxent.x_sect.x_scnlen,
+ auxp->u.auxent.x_sect.x_nreloc);
+ break;
+
case C_STAT:
if (combined->u.syment.n_type == T_NULL)
/* Probably a section symbol ? */
function for the is_local_label_name entry point, but some may
override it. */
-bfd_boolean
+bool
_bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
const char *name)
{
section, calculate and return the name of the source file and the line
nearest to the wanted location. */
-bfd_boolean
+bool
coff_find_nearest_line_with_names (bfd *abfd,
- asymbol **symbols,
- asection *section,
- bfd_vma offset,
- const char **filename_ptr,
- const char **functionname_ptr,
- unsigned int *line_ptr,
- const struct dwarf_debug_section *debug_sections)
+ asymbol **symbols,
+ asection *section,
+ bfd_vma offset,
+ const char **filename_ptr,
+ const char **functionname_ptr,
+ unsigned int *line_ptr,
+ const struct dwarf_debug_section *debug_sections)
{
- bfd_boolean found;
+ bool found;
unsigned int i;
unsigned int line_base;
coff_data_type *cof = coff_data (abfd);
combined_entry_type *pend;
alent *l;
struct coff_section_tdata *sec_data;
- bfd_size_type amt;
+ size_t amt;
/* Before looking through the symbol table, try to use a .stab
section to find the information. */
&found, filename_ptr,
functionname_ptr, line_ptr,
&coff_data(abfd)->line_info))
- return FALSE;
+ return false;
if (found)
- return TRUE;
+ return true;
/* Also try examining DWARF2 debugging information. */
if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
filename_ptr, functionname_ptr,
- line_ptr, NULL, debug_sections, 0,
+ line_ptr, NULL, debug_sections,
&coff_data(abfd)->dwarf2_find_line_info))
- return TRUE;
+ return true;
+
+ sec_data = coff_section_data (abfd, section);
/* If the DWARF lookup failed, but there is DWARF information available
then the problem might be that the file has been rebased. This tool
information. So try again, using a bias against the address sought. */
if (coff_data (abfd)->dwarf2_find_line_info != NULL)
{
- bfd_signed_vma bias;
+ bfd_signed_vma bias = 0;
+
+ /* Create a cache of the result for the next call. */
+ if (sec_data == NULL && section->owner == abfd)
+ {
+ amt = sizeof (struct coff_section_tdata);
+ section->used_by_bfd = bfd_zalloc (abfd, amt);
+ sec_data = (struct coff_section_tdata *) section->used_by_bfd;
+ }
- bias = _bfd_dwarf2_find_symbol_bias (symbols,
- & coff_data (abfd)->dwarf2_find_line_info);
+ if (sec_data != NULL && sec_data->saved_bias)
+ bias = sec_data->saved_bias;
+ else if (symbols)
+ {
+ bias = _bfd_dwarf2_find_symbol_bias (symbols,
+ & coff_data (abfd)->dwarf2_find_line_info);
+
+ if (sec_data)
+ {
+ sec_data->saved_bias = true;
+ sec_data->bias = bias;
+ }
+ }
if (bias
&& _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section,
offset + bias,
filename_ptr, functionname_ptr,
- line_ptr, NULL, debug_sections, 0,
+ line_ptr, NULL, debug_sections,
&coff_data(abfd)->dwarf2_find_line_info))
- return TRUE;
+ return true;
}
*filename_ptr = 0;
/* Don't try and find line numbers in a non coff file. */
if (!bfd_family_coff (abfd))
- return FALSE;
+ return false;
if (cof == NULL)
- return FALSE;
+ return false;
/* Find the first C_FILE symbol. */
p = cof->raw_syments;
if (!p)
- return FALSE;
+ return false;
pend = p + cof->raw_syment_count;
while (p < pend)
bfd_vma maxdiff;
/* Look through the C_FILE symbols to find the best one. */
- sec_vma = bfd_get_section_vma (abfd, section);
+ sec_vma = bfd_section_vma (section);
*filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
maxdiff = (bfd_vma) 0 - (bfd_vma) 1;
while (1)
file_addr += coff_section_from_bfd_index (abfd,
p2->u.syment.n_scnum)->vma;
/* We use <= MAXDIFF here so that if we get a zero length
- file, we actually use the next file entry. */
+ file, we actually use the next file entry. */
if (p2 < pend
&& offset + sec_vma >= file_addr
&& offset + sec_vma - file_addr <= maxdiff)
maxdiff = offset + sec_vma - p2->u.syment.n_value;
}
+ if (p->u.syment.n_value >= cof->raw_syment_count)
+ break;
+
/* Avoid endless loops on erroneous files by ensuring that
we always move forward in the file. */
if (p >= cof->raw_syments + p->u.syment.n_value)
break;
p = cof->raw_syments + p->u.syment.n_value;
- if (p > pend || p->u.syment.n_sclass != C_FILE)
+ if (!p->is_sym || p->u.syment.n_sclass != C_FILE)
break;
}
}
- /* Now wander though the raw linenumbers of the section. */
- /* If we have been called on this section before, and the offset we
- want is further down then we can prime the lookup loop. */
- sec_data = coff_section_data (abfd, section);
+ if (section->lineno_count == 0)
+ {
+ *functionname_ptr = NULL;
+ *line_ptr = 0;
+ return true;
+ }
+
+ /* Now wander though the raw linenumbers of the section.
+ If we have been called on this section before, and the offset
+ we want is further down then we can prime the lookup loop. */
if (sec_data != NULL
&& sec_data->i > 0
&& offset >= sec_data->offset)
coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
if (coff->symbol.value > offset)
break;
+
*functionname_ptr = coff->symbol.name;
last_value = coff->symbol.value;
if (coff->native)
/* In XCOFF a debugging symbol can follow the
function symbol. */
- if (s->u.syment.n_scnum == N_DEBUG)
+ if (((size_t) ((char *) s - (char *) obj_raw_syments (abfd))
+ < obj_raw_syment_count (abfd) * sizeof (*s))
+ && s->u.syment.n_scnum == N_DEBUG)
s = s + 1 + s->u.syment.n_numaux;
/* S should now point to the .bf of the function. */
- if (s->u.syment.n_numaux)
+ if (((size_t) ((char *) s - (char *) obj_raw_syments (abfd))
+ < obj_raw_syment_count (abfd) * sizeof (*s))
+ && s->u.syment.n_numaux)
{
/* The linenumber is stored in the auxent. */
union internal_auxent *a = &((s + 1)->u.auxent);
section->used_by_bfd = bfd_zalloc (abfd, amt);
sec_data = (struct coff_section_tdata *) section->used_by_bfd;
}
+
if (sec_data != NULL)
{
sec_data->offset = offset;
sec_data->line_base = line_base;
}
- return TRUE;
+ return true;
}
-bfd_boolean
+bool
coff_find_nearest_line (bfd *abfd,
asymbol **symbols,
asection *section,
if (discriminator_ptr)
*discriminator_ptr = 0;
return coff_find_nearest_line_with_names (abfd, symbols, section, offset,
- filename_ptr, functionname_ptr,
- line_ptr, dwarf_debug_sections);
+ filename_ptr, functionname_ptr,
+ line_ptr, dwarf_debug_sections);
}
-bfd_boolean
+bool
coff_find_inliner_info (bfd *abfd,
const char **filename_ptr,
const char **functionname_ptr,
unsigned int *line_ptr)
{
- bfd_boolean found;
+ bool found;
found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
functionname_ptr, line_ptr,
/* Change the class of a coff symbol held by BFD. */
-bfd_boolean
-bfd_coff_set_symbol_class (bfd * abfd,
- asymbol * symbol,
- unsigned int symbol_class)
+bool
+bfd_coff_set_symbol_class (bfd * abfd,
+ asymbol * symbol,
+ unsigned int symbol_class)
{
coff_symbol_type * csym;
if (csym == NULL)
{
bfd_set_error (bfd_error_invalid_operation);
- return FALSE;
+ return false;
}
else if (csym->native == NULL)
{
coff_write_alien_symbol(). */
combined_entry_type * native;
- bfd_size_type amt = sizeof (* native);
+ size_t amt = sizeof (* native);
native = (combined_entry_type *) bfd_zalloc (abfd, amt);
if (native == NULL)
- return FALSE;
+ return false;
- native->is_sym = TRUE;
+ native->is_sym = true;
native->u.syment.n_type = T_NULL;
native->u.syment.n_sclass = symbol_class;
else
csym->native->u.syment.n_sclass = symbol_class;
- return TRUE;
+ return true;
}
-bfd_boolean
+bool
_bfd_coff_section_already_linked (bfd *abfd,
asection *sec,
struct bfd_link_info *info)
struct bfd_section_already_linked_hash_entry *already_linked_list;
struct coff_comdat_info *s_comdat;
+ if (sec->output_section == bfd_abs_section_ptr)
+ return false;
+
flags = sec->flags;
if ((flags & SEC_LINK_ONCE) == 0)
- return FALSE;
+ return false;
/* The COFF backend linker doesn't support group sections. */
if ((flags & SEC_GROUP) != 0)
- return FALSE;
+ return false;
- name = bfd_get_section_name (abfd, sec);
+ name = bfd_section_name (sec);
s_comdat = bfd_coff_get_comdat_section (abfd, sec);
if (s_comdat != NULL)
key = s_comdat->name;
else
{
- if (CONST_STRNEQ (name, ".gnu.linkonce.")
+ if (startswith (name, ".gnu.linkonce.")
&& (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
key++;
else
.gnu.linkonce.*.<key>. */
if (((s_comdat != NULL) == (l_comdat != NULL)
&& strcmp (name, l->sec->name) == 0)
- || (l->sec->owner->flags & BFD_PLUGIN) != 0)
+ || (l->sec->owner->flags & BFD_PLUGIN) != 0
+ || (sec->owner->flags & BFD_PLUGIN) != 0)
{
/* The section has already been linked. See if we should
issue a warning. */
/* This is the first section with this name. Record it. */
if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
info->callbacks->einfo (_("%F%P: already_linked_table: %E\n"));
- return FALSE;
+ return false;
}
/* Initialize COOKIE for input bfd ABFD. */
-static bfd_boolean
+static bool
init_reloc_cookie (struct coff_reloc_cookie *cookie,
struct bfd_link_info *info ATTRIBUTE_UNUSED,
bfd *abfd)
cookie->symbols = obj_symbols (abfd);
- return TRUE;
+ return true;
}
/* Free the memory allocated by init_reloc_cookie, if appropriate. */
/* Initialize the relocation information in COOKIE for input section SEC
of input bfd ABFD. */
-static bfd_boolean
+static bool
init_reloc_cookie_rels (struct coff_reloc_cookie *cookie,
struct bfd_link_info *info ATTRIBUTE_UNUSED,
bfd *abfd,
cookie->rels = NULL;
cookie->relend = NULL;
cookie->rel = NULL;
- return TRUE;
+ return true;
}
- cookie->rels = _bfd_coff_read_internal_relocs (abfd, sec, FALSE, NULL, 0, NULL);
+ cookie->rels = _bfd_coff_read_internal_relocs (abfd, sec, false, NULL,
+ 0, NULL);
if (cookie->rels == NULL)
- return FALSE;
+ return false;
cookie->rel = cookie->rels;
cookie->relend = (cookie->rels + sec->reloc_count);
- return TRUE;
+ return true;
}
/* Free the memory allocated by init_reloc_cookie_rels,
/* Initialize the whole of COOKIE for input section SEC. */
-static bfd_boolean
+static bool
init_reloc_cookie_for_section (struct coff_reloc_cookie *cookie,
struct bfd_link_info *info,
asection *sec)
{
if (!init_reloc_cookie (cookie, info, sec->owner))
- return FALSE;
+ return false;
if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec))
{
fini_reloc_cookie (cookie, sec->owner);
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/* Free the memory allocated by init_reloc_cookie_for_section,
if (h != NULL)
{
switch (h->root.type)
- {
- case bfd_link_hash_defined:
- case bfd_link_hash_defweak:
- return h->root.u.def.section;
+ {
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ return h->root.u.def.section;
- case bfd_link_hash_common:
- return h->root.u.c.p->section;
+ case bfd_link_hash_common:
+ return h->root.u.c.p->section;
- case bfd_link_hash_undefined:
case bfd_link_hash_undefweak:
- default:
- break;
- }
+ if (h->symbol_class == C_NT_WEAK && h->numaux == 1)
+ {
+ /* PE weak externals. A weak symbol may include an auxiliary
+ record indicating that if the weak symbol is not resolved,
+ another external symbol is used instead. */
+ struct coff_link_hash_entry *h2 =
+ h->auxbfd->tdata.coff_obj_data->sym_hashes[
+ h->aux->x_sym.x_tagndx.l];
+
+ if (h2 && h2->root.type != bfd_link_hash_undefined)
+ return h2->root.u.def.section;
+ }
+ break;
+
+ case bfd_link_hash_undefined:
+ default:
+ break;
+ }
return NULL;
}
+ obj_convert (sec->owner)[cookie->rel->r_symndx])->native->u.syment);
}
-static bfd_boolean _bfd_coff_gc_mark
+static bool _bfd_coff_gc_mark
(struct bfd_link_info *, asection *, coff_gc_mark_hook_fn);
/* COOKIE->rel describes a relocation against section SEC, which is
a section we've decided to keep. Mark the section that contains
the relocation symbol. */
-static bfd_boolean
+static bool
_bfd_coff_gc_mark_reloc (struct bfd_link_info *info,
asection *sec,
coff_gc_mark_hook_fn gc_mark_hook,
if (bfd_get_flavour (rsec->owner) != bfd_target_coff_flavour)
rsec->gc_mark = 1;
else if (!_bfd_coff_gc_mark (info, rsec, gc_mark_hook))
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/* The mark phase of garbage collection. For a given section, mark
it and any sections in this section's group, and all the sections
which define symbols to which it refers. */
-static bfd_boolean
+static bool
_bfd_coff_gc_mark (struct bfd_link_info *info,
asection *sec,
coff_gc_mark_hook_fn gc_mark_hook)
{
- bfd_boolean ret = TRUE;
+ bool ret = true;
sec->gc_mark = 1;
struct coff_reloc_cookie cookie;
if (!init_reloc_cookie_for_section (&cookie, info, sec))
- ret = FALSE;
+ ret = false;
else
- {
- for (; cookie.rel < cookie.relend; cookie.rel++)
- {
+ {
+ for (; cookie.rel < cookie.relend; cookie.rel++)
+ {
if (!_bfd_coff_gc_mark_reloc (info, sec, gc_mark_hook, &cookie))
{
- ret = FALSE;
+ ret = false;
break;
}
}
- fini_reloc_cookie_for_section (&cookie, sec);
- }
+ fini_reloc_cookie_for_section (&cookie, sec);
+ }
}
return ret;
}
-static bfd_boolean
+static bool
_bfd_coff_gc_mark_extra_sections (struct bfd_link_info *info,
coff_gc_mark_hook_fn mark_hook ATTRIBUTE_UNUSED)
{
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
{
asection *isec;
- bfd_boolean some_kept;
+ bool some_kept;
- if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour)
continue;
/* Ensure all linker created sections are kept, and see whether
any other section is already marked. */
- some_kept = FALSE;
+ some_kept = false;
for (isec = ibfd->sections; isec != NULL; isec = isec->next)
{
if ((isec->flags & SEC_LINKER_CREATED) != 0)
isec->gc_mark = 1;
else if (isec->gc_mark)
- some_kept = TRUE;
+ some_kept = true;
}
/* If no section in this file will be kept, then we can
|| (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
isec->gc_mark = 1;
}
- return TRUE;
+ return true;
}
/* Sweep symbols in swept sections. Called via coff_link_hash_traverse. */
-static bfd_boolean
+static bool
coff_gc_sweep_symbol (struct coff_link_hash_entry *h,
void *data ATTRIBUTE_UNUSED)
{
h->symbol_class = C_HIDDEN;
}
- return TRUE;
+ return true;
}
/* The sweep phase of garbage collection. Remove all garbage sections. */
-typedef bfd_boolean (*gc_sweep_hook_fn)
+typedef bool (*gc_sweep_hook_fn)
(bfd *, struct bfd_link_info *, asection *, const struct internal_reloc *);
-static bfd_boolean
+static bool
coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
{
bfd *sub;
for (o = sub->sections; o != NULL; o = o->next)
{
/* Keep debug and special sections. */
- if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
+ if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
|| (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
o->gc_mark = 1;
- else if (CONST_STRNEQ (o->name, ".idata")
- || CONST_STRNEQ (o->name, ".pdata")
- || CONST_STRNEQ (o->name, ".xdata")
- || CONST_STRNEQ (o->name, ".rsrc"))
+ else if (startswith (o->name, ".idata")
+ || startswith (o->name, ".pdata")
+ || startswith (o->name, ".xdata")
+ || startswith (o->name, ".rsrc"))
o->gc_mark = 1;
if (o->gc_mark)
if (info->print_gc_sections && o->size != 0)
/* xgettext: c-format */
- _bfd_error_handler (_("Removing unused section '%s' in file '%B'"), sub, o->name);
+ _bfd_error_handler (_("removing unused section '%pA' in file '%pB'"),
+ o, sub);
#if 0
/* But we also have to update some of the relocation
&& !bfd_is_abs_section (o->output_section))
{
struct internal_reloc *internal_relocs;
- bfd_boolean r;
+ bool r;
internal_relocs
= _bfd_coff_link_read_relocs (o->owner, o, NULL, NULL,
info->keep_memory);
if (internal_relocs == NULL)
- return FALSE;
+ return false;
r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs);
free (internal_relocs);
if (!r)
- return FALSE;
+ return false;
}
#endif
}
coff_link_hash_traverse (coff_hash_table (info), coff_gc_sweep_symbol,
NULL);
- return TRUE;
+ return true;
}
/* Keep all sections containing symbols undefined on the command-line,
struct coff_link_hash_entry *h;
h = coff_link_hash_lookup (coff_hash_table (info), sym->name,
- FALSE, FALSE, FALSE);
+ false, false, false);
if (h != NULL
&& (h->root.type == bfd_link_hash_defined
/* Do mark and sweep of unused sections. */
-bfd_boolean
+bool
bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
{
bfd *sub;
if (!bed->can_gc_sections
|| !is_coff_hash_table (info->hash))
{
- _bfd_error_handler(_("Warning: gc-sections option ignored"));
- return TRUE;
+ _bfd_error_handler(_("warning: gc-sections option ignored"));
+ return true;
}
#endif
asection *o;
if (bfd_get_flavour (sub) != bfd_target_coff_flavour)
- continue;
+ continue;
for (o = sub->sections; o != NULL; o = o->next)
- {
+ {
if (((o->flags & (SEC_EXCLUDE | SEC_KEEP)) == SEC_KEEP
- || CONST_STRNEQ (o->name, ".vectors")
- || CONST_STRNEQ (o->name, ".ctors")
- || CONST_STRNEQ (o->name, ".dtors"))
+ || startswith (o->name, ".vectors")
+ || startswith (o->name, ".ctors")
+ || startswith (o->name, ".dtors"))
&& !o->gc_mark)
{
if (!_bfd_coff_gc_mark (info, o, _bfd_coff_gc_mark_hook))
- return FALSE;
+ return false;
}
- }
+ }
}
/* Allow the backend to mark additional target specific sections. */
/* ... and mark SEC_EXCLUDE for those that go. */
return coff_gc_sweep (abfd, info);
}
+
+/* Return name used to identify a comdat group. */
+
+const char *
+bfd_coff_group_name (bfd *abfd, const asection *sec)
+{
+ struct coff_comdat_info *ci = bfd_coff_get_comdat_section (abfd, sec);
+ if (ci != NULL)
+ return ci->name;
+ return NULL;
+}
+
+bool
+_bfd_coff_close_and_cleanup (bfd *abfd)
+{
+ struct coff_tdata *tdata = coff_data (abfd);
+
+ if (tdata != NULL)
+ {
+ /* PR 25447:
+ Do not clear the keep_syms and keep_strings flags.
+ These may have been set by pe_ILF_build_a_bfd() indicating
+ that the syms and strings pointers are not to be freed. */
+ if (bfd_get_format (abfd) == bfd_object
+ && bfd_family_coff (abfd)
+ && !_bfd_coff_free_symbols (abfd))
+ return false;
+
+ if (bfd_get_format (abfd) == bfd_object
+ || bfd_get_format (abfd) == bfd_core)
+ _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
+ }
+ return _bfd_generic_close_and_cleanup (abfd);
+}