/* POWER/PowerPC XCOFF linker support.
- Copyright (C) 1995-2018 Free Software Foundation, Inc.
+ Copyright (C) 1995-2020 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@cygnus.com>, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#include "libcoff.h"
#include "libxcoff.h"
#include "libiberty.h"
+#include "xcofflink.h"
/* This file holds the XCOFF linker code. */
{
if (coff_section_data (abfd, sec) == NULL)
{
- bfd_size_type amt = sizeof (struct coff_section_tdata);
+ size_t amt = sizeof (struct coff_section_tdata);
sec->used_by_bfd = bfd_zalloc (abfd, amt);
if (sec->used_by_bfd == NULL)
if (! bfd_malloc_and_get_section (abfd, sec, &contents))
{
- if (contents != NULL)
- free (contents);
+ free (contents);
return FALSE;
}
coff_section_data (abfd, sec)->contents = contents;
_bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
{
struct xcoff_link_hash_table *ret;
- bfd_size_type amt = sizeof (* ret);
+ size_t amt = sizeof (* ret);
ret = bfd_zmalloc (amt);
if (ret == NULL)
if (*pp == NULL)
{
struct xcoff_import_file *n;
- bfd_size_type amt = sizeof (* n);
+ size_t amt = sizeof (*n);
n = bfd_alloc (info->output_bfd, amt);
if (n == NULL)
if (abfd->my_archive == NULL || bfd_is_thin_archive (abfd->my_archive))
{
- if (!bfd_xcoff_split_import_path (abfd, abfd->filename,
+ if (!bfd_xcoff_split_import_path (abfd, bfd_get_filename (abfd),
&n->path, &n->file))
return FALSE;
n->member = "";
if (!archive_info->impfile)
{
if (!bfd_xcoff_split_import_path (archive_info->archive,
- archive_info->archive->filename,
+ bfd_get_filename (archive_info
+ ->archive),
&archive_info->imppath,
&archive_info->impfile))
return FALSE;
{
bfd_byte *linenos;
- amt = linesz * o->lineno_count;
- linenos = bfd_malloc (amt);
+ if (bfd_seek (abfd, o->line_filepos, SEEK_SET) != 0)
+ goto error_return;
+ if (_bfd_mul_overflow (linesz, o->lineno_count, &amt))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ goto error_return;
+ }
+ linenos = _bfd_malloc_and_read (abfd, amt, amt);
if (linenos == NULL)
goto error_return;
reloc_info[o->target_index].linenos = linenos;
- if (bfd_seek (abfd, o->line_filepos, SEEK_SET) != 0
- || bfd_bread (linenos, amt, abfd) != amt)
- goto error_return;
}
}
if (EXTERN_SYM_P (sym.n_sclass))
{
- bfd_boolean copy;
+ bfd_boolean copy, ok;
flagword flags;
BFD_ASSERT (section != NULL);
BFD_ASSERT (last_real->next == first_csect);
last_real->next = NULL;
flags = (sym.n_sclass == C_EXT ? BSF_GLOBAL : BSF_WEAK);
- if (! (_bfd_generic_link_add_one_symbol
- (info, abfd, name, flags, section, value,
- NULL, copy, TRUE,
- (struct bfd_link_hash_entry **) sym_hash)))
- goto error_return;
+ ok = (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, flags, section, value, NULL, copy, TRUE,
+ (struct bfd_link_hash_entry **) sym_hash));
last_real->next = first_csect;
+ if (!ok)
+ goto error_return;
if (smtyp == XTY_CM)
{
for (o = abfd->sections; o != first_csect; o = o->next)
{
/* Debugging sections have no csects. */
- if (bfd_get_section_flags (abfd, o) & SEC_DEBUGGING)
+ if (bfd_section_flags (o) & SEC_DEBUGGING)
continue;
/* Reset the section size and the line number count, since the
data is now attached to the csects. Don't reset the size of
the .debug section, since we need to read it below in
bfd_xcoff_size_dynamic_sections. */
- if (strcmp (bfd_get_section_name (abfd, o), ".debug") != 0)
+ if (strcmp (bfd_section_name (o), ".debug") != 0)
o->size = 0;
o->lineno_count = 0;
/* If we are not keeping memory, free the reloc information. */
if (! info->keep_memory
&& coff_section_data (abfd, o) != NULL
- && coff_section_data (abfd, o)->relocs != NULL
&& ! coff_section_data (abfd, o)->keep_relocs)
{
free (coff_section_data (abfd, o)->relocs);
/* Free up the line numbers. FIXME: We could cache these
somewhere for the final link, to avoid reading them again. */
- if (reloc_info[o->target_index].linenos != NULL)
- {
- free (reloc_info[o->target_index].linenos);
- reloc_info[o->target_index].linenos = NULL;
- }
+ free (reloc_info[o->target_index].linenos);
+ reloc_info[o->target_index].linenos = NULL;
}
free (reloc_info);
{
for (o = abfd->sections; o != NULL; o = o->next)
{
- if (reloc_info[o->target_index].csects != NULL)
- free (reloc_info[o->target_index].csects);
- if (reloc_info[o->target_index].linenos != NULL)
- free (reloc_info[o->target_index].linenos);
+ free (reloc_info[o->target_index].csects);
+ free (reloc_info[o->target_index].linenos);
}
free (reloc_info);
}
{
char *fnname;
struct xcoff_link_hash_entry *hfn;
- bfd_size_type amt;
+ size_t amt;
amt = strlen (h->root.root.string) + 2;
fnname = bfd_malloc (amt);
case R_RLA:
/* Absolute relocations against absolute symbols can be
resolved statically. */
- if (h != NULL
- && (h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && bfd_is_abs_section (h->root.u.def.section))
+ if (h != NULL && bfd_is_abs_symbol (&h->root))
return FALSE;
return TRUE;
if (! info->keep_memory
&& coff_section_data (sec->owner, sec) != NULL
- && coff_section_data (sec->owner, sec)->relocs != NULL
&& ! coff_section_data (sec->owner, sec)->keep_relocs)
{
free (coff_section_data (sec->owner, sec)->relocs);
|| o == xcoff_hash_table (info)->loader_section
|| o == xcoff_hash_table (info)->linkage_section
|| o == xcoff_hash_table (info)->descriptor_section
- || (bfd_get_section_flags (sub, o) & SEC_DEBUGGING)
+ || (bfd_section_flags (o) & SEC_DEBUGGING)
|| strcmp (o->name, ".debug") == 0)
o->flags |= SEC_MARK;
else
{
struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg;
struct xcoff_link_size_list *n;
- bfd_size_type amt;
+ size_t amt;
if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
return TRUE;
if (val != (bfd_vma) -1)
{
if (h->root.type == bfd_link_hash_defined
- && (! bfd_is_abs_section (h->root.u.def.section)
+ && (!bfd_is_abs_symbol (&h->root)
|| h->root.u.def.value != val))
(*info->callbacks->multiple_definition) (info, &h->root, output_bfd,
bfd_abs_section_ptr, val);
xcoff_build_ldsym (struct xcoff_loader_info *ldinfo,
struct xcoff_link_hash_entry *h)
{
- bfd_size_type amt;
+ size_t amt;
/* Warn if this symbol is exported but not defined. */
if ((h->flags & XCOFF_EXPORT) != 0
bfd *sub;
struct bfd_strtab_hash *debug_strtab;
bfd_byte *debug_contents = NULL;
- bfd_size_type amt;
+ size_t amt;
if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour)
{
return TRUE;
error_return:
- if (ldinfo.strings != NULL)
- free (ldinfo.strings);
- if (debug_contents != NULL)
- free (debug_contents);
+ free (ldinfo.strings);
+ free (debug_contents);
return FALSE;
}
{
bfd_size_type sz = o->rawsize ? o->rawsize : o->size;
if (!bfd_get_section_contents (input_bfd, o, flinfo->contents, 0, sz))
- return FALSE;
+ goto err_out;
contents = flinfo->contents;
}
(flinfo->section_info[target_index].relocs
+ o->output_section->reloc_count)));
if (internal_relocs == NULL)
- return FALSE;
+ goto err_out;
/* Call processor specific code to relocate the section
contents. */
internal_relocs,
flinfo->internal_syms,
xcoff_data (input_bfd)->csects))
- return FALSE;
+ goto err_out;
offset = o->output_section->vma + o->output_offset - o->vma;
irel = internal_relocs;
{
struct xcoff_toc_rel_hash *n;
struct xcoff_link_section_info *si;
- bfd_size_type amt;
+ size_t amt;
amt = sizeof (* n);
n = bfd_alloc (flinfo->output_bfd, amt);
if (n == NULL)
- return FALSE;
+ goto err_out;
si = flinfo->section_info + target_index;
n->next = si->toc_rel_hashes;
n->h = h;
(input_bfd, is, buf));
if (name == NULL)
- return FALSE;
+ goto err_out;
(*flinfo->info->callbacks->unattached_reloc)
(flinfo->info, name,
if (!xcoff_create_ldrel (output_bfd, flinfo,
o->output_section, input_bfd,
irel, sec, h))
- return FALSE;
+ goto err_out;
}
}
if (! bfd_set_section_contents (output_bfd, o->output_section,
contents, (file_ptr) o->output_offset,
o->size))
- return FALSE;
+ goto err_out;
}
obj_coff_keep_syms (input_bfd) = keep_syms;
}
return TRUE;
+
+ err_out:
+ obj_coff_keep_syms (input_bfd) = keep_syms;
+ return FALSE;
}
#undef N_TMASK
|| h->root.type == bfd_link_hash_defweak)
&& h->smclas == XMC_XO)
{
- BFD_ASSERT (bfd_is_abs_section (h->root.u.def.section));
+ BFD_ASSERT (bfd_is_abs_symbol (&h->root));
isym.n_value = h->root.u.def.value;
isym.n_scnum = N_UNDEF;
- if (h->root.type == bfd_link_hash_undefweak
+ if (h->root.type == bfd_link_hash_defweak
&& C_WEAKEXT == C_AIX_WEAKEXT)
isym.n_sclass = C_WEAKEXT;
else
/* We just output an SD symbol. Now output an LD symbol. */
h->indx += 2;
- if (h->root.type == bfd_link_hash_undefweak
+ if (h->root.type == bfd_link_hash_defweak
&& C_WEAKEXT == C_AIX_WEAKEXT)
isym.n_sclass = C_WEAKEXT;
else
}
/* Free up the buffers used by xcoff_link_input_bfd. */
- if (flinfo.internal_syms != NULL)
- {
- free (flinfo.internal_syms);
- flinfo.internal_syms = NULL;
- }
- if (flinfo.sym_indices != NULL)
- {
- free (flinfo.sym_indices);
- flinfo.sym_indices = NULL;
- }
- if (flinfo.linenos != NULL)
- {
- free (flinfo.linenos);
- flinfo.linenos = NULL;
- }
- if (flinfo.contents != NULL)
- {
- free (flinfo.contents);
- flinfo.contents = NULL;
- }
- if (flinfo.external_relocs != NULL)
- {
- free (flinfo.external_relocs);
- flinfo.external_relocs = NULL;
- }
+ free (flinfo.internal_syms);
+ flinfo.internal_syms = NULL;
+ free (flinfo.sym_indices);
+ flinfo.sym_indices = NULL;
+ free (flinfo.linenos);
+ flinfo.linenos = NULL;
+ free (flinfo.contents);
+ flinfo.contents = NULL;
+ free (flinfo.external_relocs);
+ flinfo.external_relocs = NULL;
/* The value of the last C_FILE symbol is supposed to be -1. Write
it out again. */
input files. */
bfd_hash_traverse (&info->hash->table, xcoff_write_global_symbol, &flinfo);
- if (flinfo.outsyms != NULL)
- {
- free (flinfo.outsyms);
- flinfo.outsyms = NULL;
- }
+ free (flinfo.outsyms);
+ flinfo.outsyms = NULL;
/* Now that we have written out all the global symbols, we know the
symbol indices to use for relocs against them, and we can finally
goto error_return;
}
- if (external_relocs != NULL)
- {
- free (external_relocs);
- external_relocs = NULL;
- }
+ free (external_relocs);
+ external_relocs = NULL;
/* Free up the section information. */
if (flinfo.section_info != NULL)
for (i = 0; i < abfd->section_count; i++)
{
- if (flinfo.section_info[i].relocs != NULL)
- free (flinfo.section_info[i].relocs);
- if (flinfo.section_info[i].rel_hashes != NULL)
- free (flinfo.section_info[i].rel_hashes);
+ free (flinfo.section_info[i].relocs);
+ free (flinfo.section_info[i].rel_hashes);
}
free (flinfo.section_info);
flinfo.section_info = NULL;
goto error_return;
}
- /* Setting bfd_get_symcount to 0 will cause write_object_contents to
+ /* Setting symcount to 0 will cause write_object_contents to
not try to write out the symbols. */
- bfd_get_symcount (abfd) = 0;
+ abfd->symcount = 0;
return TRUE;
for (i = 0; i < abfd->section_count; i++)
{
- if (flinfo.section_info[i].relocs != NULL)
- free (flinfo.section_info[i].relocs);
- if (flinfo.section_info[i].rel_hashes != NULL)
- free (flinfo.section_info[i].rel_hashes);
+ free (flinfo.section_info[i].relocs);
+ free (flinfo.section_info[i].rel_hashes);
}
free (flinfo.section_info);
}
- if (flinfo.internal_syms != NULL)
- free (flinfo.internal_syms);
- if (flinfo.sym_indices != NULL)
- free (flinfo.sym_indices);
- if (flinfo.outsyms != NULL)
- free (flinfo.outsyms);
- if (flinfo.linenos != NULL)
- free (flinfo.linenos);
- if (flinfo.contents != NULL)
- free (flinfo.contents);
- if (flinfo.external_relocs != NULL)
- free (flinfo.external_relocs);
- if (external_relocs != NULL)
- free (external_relocs);
+ free (flinfo.internal_syms);
+ free (flinfo.sym_indices);
+ free (flinfo.outsyms);
+ free (flinfo.linenos);
+ free (flinfo.contents);
+ free (flinfo.external_relocs);
+ free (external_relocs);
return FALSE;
}