/* Support for the generic parts of COFF, for BFD.
- Copyright (C) 1990-2018 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;
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);
+ 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);
if (name == NULL)
- return FALSE;
+ return false;
strcpy (name, strings);
}
}
name = (char *) bfd_alloc (abfd,
(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;
/* xgettext: c-format */
(_("%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);
/* xgettext: c-format */
(_("%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 *
+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;
}
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
/* 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;
+ 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;
symbol->name = "";
if (isym != NULL)
memset (isym, 0, sizeof (*isym));
- return TRUE;
+ return true;
}
else
{
/* 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;
}
}
}
#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 ((unsigned long) auxent->u.auxent.x_sym.x_tagndx.l
- < obj_raw_syment_count (abfd))
+ < 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;
- /* Check for integer overflow and for unreasonable symbol counts. */
- if (size < obj_raw_syment_count (abfd)
- || (bfd_get_file_size (abfd) > 0
- && size > bfd_get_file_size (abfd)))
-
+ if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size))
{
- _bfd_error_handler (_("%pB: corrupt symbol count: %#Lx"),
- abfd, obj_raw_syment_count (abfd));
- return FALSE;
+ bfd_set_error (bfd_error_file_truncated);
+ return false;
}
- syms = bfd_malloc (size);
- if (syms == NULL)
- {
- /* PR 21013: Provide an error message when the alloc fails. */
- _bfd_error_handler (_("%pB: not enough memory to allocate space for %#Lx symbols of size %#Lx"),
- abfd, obj_raw_syment_count (abfd), symesz);
- return FALSE;
- }
-
- if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
- || bfd_bread (syms, size, abfd) != size)
- {
- if (syms != NULL)
- free (syms);
- return FALSE;
- }
+ if (size == 0)
+ 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 TRUE;
+ 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 || strsize > bfd_get_file_size (abfd))
+ filesize = bfd_get_file_size (abfd);
+ if (strsize < STRING_SIZE_SIZE
+ || (filesize != 0 && strsize > filesize))
{
_bfd_error_handler
/* xgettext: c-format */
- (_("%pB: bad string table size %Lu"), abfd, 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;
+ return false;
if (obj_coff_external_syms (abfd) != NULL
&& ! obj_coff_keep_syms (abfd))
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 < obj_raw_syment_count (abfd))
+ 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++)
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,
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);
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)
if (sec_data != NULL && sec_data->saved_bias)
bias = sec_data->saved_bias;
- else
+ 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->saved_bias = true;
sec_data->bias = 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)
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;
}
}
{
*functionname_ptr = NULL;
*line_ptr = 0;
- return TRUE;
+ return true;
}
/* Now wander though the raw linenumbers of the section.
/* 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);
sec_data->line_base = line_base;
}
- return TRUE;
+ return true;
}
-bfd_boolean
+bool
coff_find_nearest_line (bfd *abfd,
asymbol **symbols,
asection *section,
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
+bool
bfd_coff_set_symbol_class (bfd * abfd,
asymbol * symbol,
unsigned int symbol_class)
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,
+ 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++)
{
if (!_bfd_coff_gc_mark_reloc (info, sec, gc_mark_hook, &cookie))
{
- ret = FALSE;
+ ret = false;
break;
}
}
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_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;
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 '%pA' in file '%pB'"),
+ _bfd_error_handler (_("removing unused section '%pA' in file '%pB'"),
o, sub);
#if 0
&& !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
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;
}
}
}
/* ... 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);
+}