/* POWER/PowerPC XCOFF linker support.
- Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1995-2018 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.
struct xcoff_link_size_list *next;
struct xcoff_link_hash_entry *h;
bfd_size_type size;
- }
+ }
*size_list;
/* Information about archives. */
return (struct bfd_hash_entry *) ret;
}
-/* Create a XCOFF link hash table. */
+/* Destroy an XCOFF link hash table. */
+
+static void
+_bfd_xcoff_bfd_link_hash_table_free (bfd *obfd)
+{
+ struct xcoff_link_hash_table *ret;
+
+ ret = (struct xcoff_link_hash_table *) obfd->link.hash;
+ if (ret->archive_info)
+ htab_delete (ret->archive_info);
+ if (ret->debug_strtab)
+ _bfd_stringtab_free (ret->debug_strtab);
+ _bfd_generic_link_hash_table_free (obfd);
+}
+
+/* Create an XCOFF link hash table. */
struct bfd_link_hash_table *
_bfd_xcoff_bfd_link_hash_table_create (bfd *abfd)
struct xcoff_link_hash_table *ret;
bfd_size_type amt = sizeof (* ret);
- ret = bfd_malloc (amt);
+ ret = bfd_zmalloc (amt);
if (ret == NULL)
return NULL;
if (!_bfd_link_hash_table_init (&ret->root, abfd, xcoff_link_hash_newfunc,
}
ret->debug_strtab = _bfd_xcoff_stringtab_init ();
- ret->debug_section = NULL;
- ret->loader_section = NULL;
- ret->ldrel_count = 0;
- memset (&ret->ldhdr, 0, sizeof (struct internal_ldhdr));
- ret->linkage_section = NULL;
- ret->toc_section = NULL;
- ret->descriptor_section = NULL;
- ret->imports = NULL;
- ret->file_align = 0;
- ret->textro = FALSE;
- ret->gc = FALSE;
ret->archive_info = htab_create (37, xcoff_archive_info_hash,
xcoff_archive_info_eq, NULL);
- memset (ret->special_sections, 0, sizeof ret->special_sections);
+ if (!ret->debug_strtab || !ret->archive_info)
+ {
+ _bfd_xcoff_bfd_link_hash_table_free (abfd);
+ return NULL;
+ }
+ ret->root.hash_table_free = _bfd_xcoff_bfd_link_hash_table_free;
/* The linker will always generate a full a.out header. We need to
record that fact now, before the sizeof_headers routine could be
return &ret->root;
}
-
-/* Free a XCOFF link hash table. */
-
-void
-_bfd_xcoff_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
-{
- struct xcoff_link_hash_table *ret = (struct xcoff_link_hash_table *) hash;
-
- _bfd_stringtab_free (ret->debug_strtab);
- bfd_hash_table_free (&ret->root.table);
- free (ret);
-}
\f
/* Read internal relocs for an XCOFF csect. This is a wrapper around
_bfd_coff_read_internal_relocs which tries to take advantage of any
bfd_xcoff_split_import_path (bfd *abfd, const char *filename,
const char **imppath, const char **impfile)
{
- const char *basename;
+ const char *base;
size_t length;
char *path;
- basename = lbasename (filename);
- length = basename - filename;
+ base = lbasename (filename);
+ length = base - filename;
if (length == 0)
/* The filename has no directory component, so use an empty path. */
*imppath = "";
path[length - 1] = 0;
*imppath = path;
}
- *impfile = basename;
+ *impfile = base;
return TRUE;
}
*pp != NULL;
pp = &(*pp)->next, ++c)
{
- if (strcmp ((*pp)->path, imppath) == 0
- && strcmp ((*pp)->file, impfile) == 0
- && strcmp ((*pp)->member, impmember) == 0)
+ if (filename_cmp ((*pp)->path, imppath) == 0
+ && filename_cmp ((*pp)->file, impfile) == 0
+ && filename_cmp ((*pp)->member, impmember) == 0)
break;
}
output file. */
if (info->output_bfd->xvec != abfd->xvec)
{
- (*_bfd_error_handler)
- (_("%s: XCOFF shared object when not producing XCOFF output"),
- bfd_get_filename (abfd));
+ _bfd_error_handler
+ (_("%pB: XCOFF shared object when not producing XCOFF output"),
+ abfd);
bfd_set_error (bfd_error_invalid_operation);
return FALSE;
}
lsec = bfd_get_section_by_name (abfd, ".loader");
if (lsec == NULL)
{
- (*_bfd_error_handler)
- (_("%s: dynamic object with no .loader section"),
- bfd_get_filename (abfd));
+ _bfd_error_handler
+ (_("%pB: dynamic object with no .loader section"),
+ abfd);
bfd_set_error (bfd_error_no_symbols);
return FALSE;
}
return FALSE;
n->next = NULL;
- if (abfd->my_archive == NULL)
+ if (abfd->my_archive == NULL || bfd_is_thin_archive (abfd->my_archive))
{
if (!bfd_xcoff_split_import_path (abfd, abfd->filename,
&n->path, &n->file))
won't work if we're producing an XCOFF output file with no
XCOFF input files. FIXME. */
- if (!info->relocatable
+ if (!bfd_link_relocatable (info)
&& xcoff_hash_table (info)->loader_section == NULL)
{
asection *lsec;
If C_FILE or first time, handle special
Advance esym, sym_hash, csect_hash ptrs. */
- if (sym.n_sclass == C_FILE)
+ if (sym.n_sclass == C_FILE || sym.n_sclass == C_DWARF)
csect = NULL;
if (csect != NULL)
*csect_cache = csect;
- else if (first_csect == NULL || sym.n_sclass == C_FILE)
+ else if (first_csect == NULL
+ || sym.n_sclass == C_FILE || sym.n_sclass == C_DWARF)
*csect_cache = coff_section_from_bfd_index (abfd, sym.n_scnum);
else
*csect_cache = NULL;
enclosing = xcoff_section_data (abfd, csect)->enclosing;
if (enclosing == NULL)
{
- (*_bfd_error_handler)
- (_("%B: `%s' has line numbers but no enclosing section"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%s' has line numbers but no enclosing section"),
abfd, name);
bfd_set_error (bfd_error_bad_value);
goto error_return;
/* Pick up the csect auxiliary information. */
if (sym.n_numaux == 0)
{
- (*_bfd_error_handler)
- (_("%B: class %d symbol `%s' has no aux entries"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: class %d symbol `%s' has no aux entries"),
abfd, sym.n_sclass, name);
bfd_set_error (bfd_error_bad_value);
goto error_return;
switch (smtyp)
{
default:
- (*_bfd_error_handler)
- (_("%B: symbol `%s' has unrecognized csect type %d"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: symbol `%s' has unrecognized csect type %d"),
abfd, name, smtyp);
bfd_set_error (bfd_error_bad_value);
goto error_return;
|| sym.n_scnum != N_UNDEF
|| aux.x_csect.x_scnlen.l != 0)
{
- (*_bfd_error_handler)
- (_("%B: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: bad XTY_ER symbol `%s': class %d scnum %d "
+ "scnlen %" PRId64),
abfd, name, sym.n_sclass, sym.n_scnum,
- aux.x_csect.x_scnlen.l);
+ (int64_t) aux.x_csect.x_scnlen.l);
bfd_set_error (bfd_error_bad_value);
goto error_return;
}
if (sym.n_sclass != C_HIDEXT
|| aux.x_csect.x_scnlen.l != 0)
{
- (*_bfd_error_handler)
- (_("%B: XMC_TC0 symbol `%s' is class %d scnlen %d"),
- abfd, name, sym.n_sclass, aux.x_csect.x_scnlen.l);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: XMC_TC0 symbol `%s' is class %d scnlen %" PRId64),
+ abfd, name, sym.n_sclass, (int64_t) aux.x_csect.x_scnlen.l);
bfd_set_error (bfd_error_bad_value);
goto error_return;
}
|| ((bfd_vma) sym.n_value + aux.x_csect.x_scnlen.l
> enclosing->vma + enclosing->size)))
{
- (*_bfd_error_handler)
- (_("%B: csect `%s' not in enclosing section"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: csect `%s' not in enclosing section"),
abfd, name);
bfd_set_error (bfd_error_bad_value);
goto error_return;
}
if (bad)
{
- (*_bfd_error_handler)
- (_("%B: misplaced XTY_LD `%s'"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: misplaced XTY_LD `%s'"),
abfd, name);
bfd_set_error (bfd_error_bad_value);
goto error_return;
}
- csect = section;
+ csect = section;
value = sym.n_value - csect->vma;
}
break;
|| sym._n._n_n._n_offset == 0)
copy = TRUE;
+ /* Ignore global linkage code when linking statically. */
+ if (info->static_link
+ && (smtyp == XTY_SD || smtyp == XTY_LD)
+ && aux.x_csect.x_smclas == XMC_GL)
+ {
+ section = bfd_und_section_ptr;
+ value = 0;
+ }
+
/* The AIX linker appears to only detect multiple symbol
definitions when there is a reference to the symbol. If
a symbol is defined multiple times, and the only
We also have to handle the case of statically linking a
shared object, which will cause symbol redefinitions,
although this is an easier case to detect. */
-
- if (info->output_bfd->xvec == abfd->xvec)
+ else if (info->output_bfd->xvec == abfd->xvec)
{
if (! bfd_is_und_section (section))
*sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info),
&& ! bfd_is_com_section (section))
{
/* This is a second definition of a defined symbol. */
- if ((abfd->flags & DYNAMIC) != 0
- && ((*sym_hash)->smclas != XMC_GL
- || aux.x_csect.x_smclas == XMC_GL
- || ((*sym_hash)->root.u.def.section->owner->flags
- & DYNAMIC) == 0))
- {
- /* The new symbol is from a shared library, and
- either the existing symbol is not global
- linkage code or this symbol is global linkage
- code. If the existing symbol is global
- linkage code and the new symbol is not, then
- we want to use the new symbol. */
- section = bfd_und_section_ptr;
- value = 0;
- }
- else if (((*sym_hash)->flags & XCOFF_DEF_REGULAR) == 0
- && ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC) != 0)
+ if (((*sym_hash)->flags & XCOFF_DEF_REGULAR) == 0
+ && ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC) != 0)
{
/* The existing symbol is from a shared library.
Replace it. */
sure the XCOFF linker is wholly prepared to
handle them, and that would only be a warning,
not an error. */
- if (! ((*info->callbacks->multiple_definition)
- (info, (*sym_hash)->root.root.string,
- NULL, NULL, (bfd_vma) 0,
- (*sym_hash)->root.u.def.section->owner,
- (*sym_hash)->root.u.def.section,
- (*sym_hash)->root.u.def.value)))
- goto error_return;
+ (*info->callbacks->multiple_definition) (info,
+ &(*sym_hash)->root,
+ NULL, NULL,
+ (bfd_vma) 0);
/* Try not to give this error too many times. */
(*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED;
}
= csect->alignment_power;
}
- if (info->output_bfd->xvec == abfd->xvec)
+ if (info->output_bfd->xvec == abfd->xvec)
{
int flag;
- if (smtyp == XTY_ER || smtyp == XTY_CM)
+ if (smtyp == XTY_ER
+ || smtyp == XTY_CM
+ || section == bfd_und_section_ptr)
flag = XCOFF_REF_REGULAR;
else
flag = XCOFF_DEF_REGULAR;
/* Make sure that we have seen all the relocs. */
for (o = abfd->sections; o != first_csect; o = o->next)
{
+ /* Debugging sections have no csects. */
+ if (bfd_get_section_flags (abfd, 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
{
if (*rel_csect == NULL)
{
- (*_bfd_error_handler)
- (_("%B: reloc %s:%d not in csect"),
- abfd, o->name, i);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: reloc %s:%" PRId64 " not in csect"),
+ abfd, o->name, (int64_t) i);
bfd_set_error (bfd_error_bad_value);
goto error_return;
}
/* We identify all function symbols that are the target
of a relocation, so that we can create glue code for
functions imported from dynamic objects. */
- if (info->output_bfd->xvec == abfd->xvec
+ if (info->output_bfd->xvec == abfd->xvec
&& *rel_csect != bfd_und_section_ptr
&& obj_xcoff_sym_hashes (abfd)[rel->r_symndx] != NULL)
{
static bfd_boolean
xcoff_link_check_dynamic_ar_symbols (bfd *abfd,
struct bfd_link_info *info,
- bfd_boolean *pneeded)
+ bfd_boolean *pneeded,
+ bfd **subsbfd)
{
asection *lsec;
bfd_byte *contents;
&& (((struct xcoff_link_hash_entry *) h)->flags
& XCOFF_DEF_DYNAMIC) == 0)
{
- if (! (*info->callbacks->add_archive_element) (info, abfd, name))
- return FALSE;
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, name, subsbfd))
+ continue;
*pneeded = TRUE;
return TRUE;
}
static bfd_boolean
xcoff_link_check_ar_symbols (bfd *abfd,
struct bfd_link_info *info,
- bfd_boolean *pneeded)
+ bfd_boolean *pneeded,
+ bfd **subsbfd)
{
bfd_size_type symesz;
bfd_byte *esym;
if ((abfd->flags & DYNAMIC) != 0
&& ! info->static_link
&& info->output_bfd->xvec == abfd->xvec)
- return xcoff_link_check_dynamic_ar_symbols (abfd, info, pneeded);
+ return xcoff_link_check_dynamic_ar_symbols (abfd, info, pneeded, subsbfd);
symesz = bfd_coff_symesz (abfd);
esym = (bfd_byte *) obj_coff_external_syms (abfd);
undefined references in shared objects. */
if (h != NULL
&& h->type == bfd_link_hash_undefined
- && (info->output_bfd->xvec != abfd->xvec
+ && (info->output_bfd->xvec != abfd->xvec
|| (((struct xcoff_link_hash_entry *) h)->flags
& XCOFF_DEF_DYNAMIC) == 0))
{
- if (! (*info->callbacks->add_archive_element) (info, abfd, name))
- return FALSE;
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, name, subsbfd))
+ continue;
*pneeded = TRUE;
return TRUE;
}
static bfd_boolean
xcoff_link_check_archive_element (bfd *abfd,
struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
bfd_boolean *pneeded)
{
bfd_boolean keep_syms_p;
+ bfd *oldbfd;
keep_syms_p = (obj_coff_external_syms (abfd) != NULL);
- if (! _bfd_coff_get_external_symbols (abfd))
+ if (!_bfd_coff_get_external_symbols (abfd))
return FALSE;
- if (! xcoff_link_check_ar_symbols (abfd, info, pneeded))
+ oldbfd = abfd;
+ if (!xcoff_link_check_ar_symbols (abfd, info, pneeded, &abfd))
return FALSE;
if (*pneeded)
{
- if (! xcoff_link_add_symbols (abfd, info))
+ /* Potentially, the add_archive_element hook may have set a
+ substitute BFD for us. */
+ if (abfd != oldbfd)
+ {
+ if (!keep_syms_p
+ && !_bfd_coff_free_symbols (oldbfd))
+ return FALSE;
+ keep_syms_p = (obj_coff_external_syms (abfd) != NULL);
+ if (!_bfd_coff_get_external_symbols (abfd))
+ return FALSE;
+ }
+ if (!xcoff_link_add_symbols (abfd, info))
return FALSE;
if (info->keep_memory)
keep_syms_p = TRUE;
if (!keep_syms_p)
{
- if (! _bfd_coff_free_symbols (abfd))
+ if (!_bfd_coff_free_symbols (abfd))
return FALSE;
}
bfd_boolean needed;
if (! xcoff_link_check_archive_element (member, info,
- &needed))
+ NULL, NULL, &needed))
return FALSE;
if (needed)
member->archive_pass = -1;
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 we're marking an undefined symbol, try find some way of
defining it. */
- if (!info->relocatable
+ if (!bfd_link_relocatable (info)
&& (h->flags & XCOFF_IMPORT) == 0
&& (h->flags & XCOFF_DEF_REGULAR) == 0
&& (h->root.type == bfd_link_hash_undefined
/* We handle writing out the contents of the descriptor in
xcoff_write_global_symbol. */
}
+ else if (info->static_link)
+ /* We can't get a symbol value dynamically, so just assume
+ that it's undefined. */
+ h->flags |= XCOFF_WAS_UNDEFINED;
else if ((h->flags & XCOFF_CALLED) != 0)
{
/* This is a function symbol for which we need to create
{
bfd *sub;
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
asection *o;
|| 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)
|| strcmp (o->name, ".debug") == 0)
o->flags |= SEC_MARK;
else
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))
- {
- if (! ((*info->callbacks->multiple_definition)
- (info, h->root.root.string, h->root.u.def.section->owner,
- h->root.u.def.section, h->root.u.def.value,
- output_bfd, bfd_abs_section_ptr, val)))
- return FALSE;
- }
+ (*info->callbacks->multiple_definition) (info, &h->root, output_bfd,
+ bfd_abs_section_ptr, val);
h->root.type = bfd_link_hash_defined;
h->root.u.def.section = bfd_abs_section_ptr;
FALSE));
if (h == NULL)
{
- (*_bfd_error_handler) (_("%s: no such symbol"), name);
+ _bfd_error_handler (_("%s: no such symbol"), name);
bfd_set_error (bfd_error_no_symbols);
return FALSE;
}
if ((h->flags & XCOFF_EXPORT) != 0
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("warning: attempt to export undefined symbol `%s'"),
h->root.root.string);
return TRUE;
{
struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p;
- if (h->root.type == bfd_link_hash_warning)
- h = (struct xcoff_link_hash_entry *) h->root.u.i.link;
-
/* __rtinit, this symbol has special handling. */
if (h->flags & XCOFF_RTINIT)
return TRUE;
"__rtinit", FALSE, FALSE, TRUE);
if (hsym == NULL)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("error: undefined symbol __rtinit"));
return FALSE;
}
}
/* Garbage collect unused sections. */
- if (info->relocatable || !gc)
+ if (bfd_link_relocatable (info) || !gc)
{
gc = FALSE;
xcoff_hash_table (info)->gc = FALSE;
/* We still need to call xcoff_mark, in order to set ldrel_count
correctly. */
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
asection *o;
and figure out the contents of the .debug section. */
debug_strtab = xcoff_hash_table (info)->debug_strtab;
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
asection *subdeb;
bfd_size_type symcount;
bim->size = 0;
bim->buffer = 0;
- abfd->link_next = 0;
+ abfd->link.next = 0;
abfd->format = bfd_object;
abfd->iostream = (void *) bim;
abfd->flags = BFD_IN_MEMORY;
+ abfd->iovec = &_bfd_memory_iovec;
abfd->direction = write_direction;
+ abfd->origin = 0;
abfd->where = 0;
if (! bfd_xcoff_generate_rtinit (abfd, init, fini, rtld))
REFERENCE_BFD is the bfd to use in error messages about the relocation. */
static bfd_boolean
-xcoff_create_ldrel (bfd *output_bfd, struct xcoff_final_link_info *finfo,
+xcoff_create_ldrel (bfd *output_bfd, struct xcoff_final_link_info *flinfo,
asection *output_section, bfd *reference_bfd,
struct internal_reloc *irel, asection *hsec,
struct xcoff_link_hash_entry *h)
ldrel.l_symndx = 2;
else
{
- (*_bfd_error_handler)
- (_("%B: loader reloc in unrecognized section `%s'"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: loader reloc in unrecognized section `%s'"),
reference_bfd, secname);
bfd_set_error (bfd_error_nonrepresentable_section);
return FALSE;
{
if (h->ldindx < 0)
{
- (*_bfd_error_handler)
- (_("%B: `%s' in loader reloc but not loader sym"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%s' in loader reloc but not loader sym"),
reference_bfd, h->root.root.string);
bfd_set_error (bfd_error_bad_value);
return FALSE;
ldrel.l_rtype = (irel->r_size << 8) | irel->r_type;
ldrel.l_rsecnm = output_section->target_index;
- if (xcoff_hash_table (finfo->info)->textro
+ if (xcoff_hash_table (flinfo->info)->textro
&& strcmp (output_section->name, ".text") == 0)
{
- (*_bfd_error_handler)
- (_("%B: loader reloc in read-only section %A"),
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: loader reloc in read-only section %pA"),
reference_bfd, output_section);
bfd_set_error (bfd_error_invalid_operation);
return FALSE;
}
- bfd_xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel);
- finfo->ldrel += bfd_xcoff_ldrelsz (output_bfd);
+ bfd_xcoff_swap_ldrel_out (output_bfd, &ldrel, flinfo->ldrel);
+ flinfo->ldrel += bfd_xcoff_ldrelsz (output_bfd);
return TRUE;
}
handles all the sections and relocations of the input file at once. */
static bfd_boolean
-xcoff_link_input_bfd (struct xcoff_final_link_info *finfo,
+xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
bfd *input_bfd)
{
bfd *output_bfd;
/* We can just skip DYNAMIC files, unless this is a static link. */
if ((input_bfd->flags & DYNAMIC) != 0
- && ! finfo->info->static_link)
+ && ! flinfo->info->static_link)
return TRUE;
/* Move all the symbols to the output file. */
- output_bfd = finfo->output_bfd;
+ output_bfd = flinfo->output_bfd;
strings = NULL;
syment_base = obj_raw_syment_count (output_bfd);
isymesz = bfd_coff_symesz (input_bfd);
#define N_BTSHFT n_btshft
copy = FALSE;
- if (! finfo->info->keep_memory)
+ if (! flinfo->info->keep_memory)
copy = TRUE;
hash = TRUE;
- if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
+ if (flinfo->info->traditional_format)
hash = FALSE;
if (! _bfd_coff_get_external_symbols (input_bfd))
sym_hash = obj_xcoff_sym_hashes (input_bfd);
csectpp = xcoff_data (input_bfd)->csects;
debug_index = xcoff_data (input_bfd)->debug_indices;
- isymp = finfo->internal_syms;
- indexp = finfo->sym_indices;
+ isymp = flinfo->internal_syms;
+ indexp = flinfo->sym_indices;
output_index = syment_base;
while (esym < esym_end)
{
ldsym->l_ifile = 0;
else
{
- BFD_ASSERT (impbfd->xvec == finfo->output_bfd->xvec);
+ BFD_ASSERT (impbfd->xvec == flinfo->output_bfd->xvec);
ldsym->l_ifile = xcoff_data (impbfd)->import_file_id;
}
}
ldsym->l_parm = 0;
BFD_ASSERT (h->ldindx >= 0);
- bfd_xcoff_swap_ldsym_out (finfo->output_bfd, ldsym,
- (finfo->ldsym
+ bfd_xcoff_swap_ldsym_out (flinfo->output_bfd, ldsym,
+ (flinfo->ldsym
+ ((h->ldindx - 3)
- * bfd_xcoff_ldsymsz (finfo->output_bfd))));
+ * bfd_xcoff_ldsymsz (flinfo->output_bfd))));
h->ldsym = NULL;
/* Fill in snentry now that we know the target_index. */
esym = (bfd_byte *) obj_coff_external_syms (input_bfd);
esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz;
sym_hash = obj_xcoff_sym_hashes (input_bfd);
- isymp = finfo->internal_syms;
- indexp = finfo->sym_indices;
+ isymp = flinfo->internal_syms;
+ indexp = flinfo->sym_indices;
csectpp = xcoff_data (input_bfd)->csects;
lineno_counts = xcoff_data (input_bfd)->lineno_counts;
debug_index = xcoff_data (input_bfd)->debug_indices;
- outsym = finfo->outsyms;
+ outsym = flinfo->outsyms;
incls = 0;
oline = NULL;
while (esym < esym_end)
if (name == NULL)
return FALSE;
- indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy);
+ indx = _bfd_stringtab_add (flinfo->strtab, name, hash, copy);
if (indx == (bfd_size_type) -1)
return FALSE;
isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
have to write the symbol out twice. */
if (isym.n_sclass == C_FILE)
{
- if (finfo->last_file_index != -1
- && finfo->last_file.n_value != (bfd_vma) *indexp)
+ if (flinfo->last_file_index != -1
+ && flinfo->last_file.n_value != (bfd_vma) *indexp)
{
/* We must correct the value of the last C_FILE entry. */
- finfo->last_file.n_value = *indexp;
- if ((bfd_size_type) finfo->last_file_index >= syment_base)
+ flinfo->last_file.n_value = *indexp;
+ if ((bfd_size_type) flinfo->last_file_index >= syment_base)
{
/* The last C_FILE symbol is in this input file. */
bfd_coff_swap_sym_out (output_bfd,
- (void *) &finfo->last_file,
- (void *) (finfo->outsyms
- + ((finfo->last_file_index
+ (void *) &flinfo->last_file,
+ (void *) (flinfo->outsyms
+ + ((flinfo->last_file_index
- syment_base)
* osymesz)));
}
file_ptr pos;
bfd_coff_swap_sym_out (output_bfd,
- (void *) &finfo->last_file,
+ (void *) &flinfo->last_file,
(void *) outsym);
pos = obj_sym_filepos (output_bfd);
- pos += finfo->last_file_index * osymesz;
+ pos += flinfo->last_file_index * osymesz;
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
|| (bfd_bwrite (outsym, osymesz, output_bfd)
!= osymesz))
}
}
- finfo->last_file_index = *indexp;
- finfo->last_file = isym;
+ flinfo->last_file_index = *indexp;
+ flinfo->last_file = isym;
}
/* The value of a C_BINCL or C_EINCL symbol is a file offset
if (isym.n_sclass == C_BINCL
|| isym.n_sclass == C_EINCL)
{
- isym.n_value = finfo->line_filepos;
+ isym.n_value = flinfo->line_filepos;
++incls;
}
/* The value of a C_BSTAT symbol is the symbol table
{
long symindx;
- symindx = finfo->sym_indices[indx];
+ symindx = flinfo->sym_indices[indx];
if (symindx < 0)
isym.n_value = 0;
else
if (strings == NULL)
return FALSE;
}
- filename = strings + aux.x_file.x_n.x_offset;
- indx = _bfd_stringtab_add (finfo->strtab, filename,
+ if ((bfd_size_type) aux.x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
+ filename = _("<corrupt>");
+ else
+ filename = strings + aux.x_file.x_n.x_offset;
+ indx = _bfd_stringtab_add (flinfo->strtab, filename,
hash, copy);
if (indx == (bfd_size_type) -1)
return FALSE;
{
long symindx;
- symindx = finfo->sym_indices[indx];
+ symindx = flinfo->sym_indices[indx];
if (symindx < 0)
{
aux.x_csect.x_scnlen.l = 0;
the index of the next symbol we are going
to include. I don't know if this is
entirely right. */
- while (finfo->sym_indices[indx] < 0
+ while (flinfo->sym_indices[indx] < 0
&& indx < obj_raw_syment_count (input_bfd))
++indx;
if (indx >= obj_raw_syment_count (input_bfd))
indx = output_index;
else
- indx = finfo->sym_indices[indx];
+ indx = flinfo->sym_indices[indx];
aux.x_sym.x_fcnary.x_fcn.x_endndx.l = indx;
}
{
long symindx;
- symindx = finfo->sym_indices[indx];
+ symindx = flinfo->sym_indices[indx];
if (symindx < 0)
aux.x_sym.x_tagndx.l = 0;
else
pos = enclosing->line_filepos;
amt = linesz * enc_count;
if (bfd_seek (input_bfd, pos, SEEK_SET) != 0
- || (bfd_bread (finfo->linenos, amt, input_bfd)
+ || (bfd_bread (flinfo->linenos, amt, input_bfd)
!= amt))
return FALSE;
oline = enclosing;
symbol index. */
linoff = (aux.x_sym.x_fcnary.x_fcn.x_lnnoptr
- enclosing->line_filepos);
- linp = finfo->linenos + linoff;
+ linp = flinfo->linenos + linoff;
bfd_coff_swap_lineno_in (input_bfd, linp, &lin);
lin.l_addr.l_symndx = *indexp;
bfd_coff_swap_lineno_out (output_bfd, &lin, linp);
+ o->output_section->lineno_count * linesz);
amt = linesz * *lineno_counts;
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
- || bfd_bwrite (finfo->linenos + linoff,
+ || bfd_bwrite (flinfo->linenos + linoff,
amt, output_bfd) != amt)
return FALSE;
o->output_section->lineno_count += *lineno_counts;
/* Update any C_BINCL or C_EINCL symbols
that refer to a line number in the
range we just output. */
- iisp = finfo->internal_syms;
+ iisp = flinfo->internal_syms;
iispend = iisp + obj_raw_syment_count (input_bfd);
- iindp = finfo->sym_indices;
- oos = finfo->outsyms;
+ iindp = flinfo->sym_indices;
+ oos = flinfo->outsyms;
range_start = enclosing->line_filepos + linoff;
range_end = range_start + *lineno_counts * linesz;
while (iisp < iispend)
symbol will be the first symbol in the next input file. In the
normal case, this will save us from writing out the C_FILE symbol
again. */
- if (finfo->last_file_index != -1
- && (bfd_size_type) finfo->last_file_index >= syment_base)
+ if (flinfo->last_file_index != -1
+ && (bfd_size_type) flinfo->last_file_index >= syment_base)
{
- finfo->last_file.n_value = output_index;
- bfd_coff_swap_sym_out (output_bfd, (void *) &finfo->last_file,
- (void *) (finfo->outsyms
- + ((finfo->last_file_index - syment_base)
- * osymesz)));
+ flinfo->last_file.n_value = output_index;
+ bfd_coff_swap_sym_out (output_bfd, (void *) &flinfo->last_file,
+ (void *) (flinfo->outsyms
+ + ((flinfo->last_file_index - syment_base)
+ * osymesz)));
}
/* Write the modified symbols to the output file. */
- if (outsym > finfo->outsyms)
+ if (outsym > flinfo->outsyms)
{
file_ptr pos = obj_sym_filepos (output_bfd) + syment_base * osymesz;
- bfd_size_type amt = outsym - finfo->outsyms;
+ bfd_size_type amt = outsym - flinfo->outsyms;
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
- || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt)
+ || bfd_bwrite (flinfo->outsyms, amt, output_bfd) != amt)
return FALSE;
BFD_ASSERT ((obj_raw_syment_count (output_bfd)
- + (outsym - finfo->outsyms) / osymesz)
+ + (outsym - flinfo->outsyms) / osymesz)
== output_index);
obj_raw_syment_count (output_bfd) = output_index;
else
{
bfd_size_type sz = o->rawsize ? o->rawsize : o->size;
- if (!bfd_get_section_contents (input_bfd, o, finfo->contents, 0, sz))
+ if (!bfd_get_section_contents (input_bfd, o, flinfo->contents, 0, sz))
return FALSE;
- contents = finfo->contents;
+ contents = flinfo->contents;
}
if ((o->flags & SEC_RELOC) != 0)
/* Read in the relocs. */
target_index = o->output_section->target_index;
internal_relocs = (xcoff_read_internal_relocs
- (input_bfd, o, FALSE, finfo->external_relocs,
+ (input_bfd, o, FALSE, flinfo->external_relocs,
TRUE,
- (finfo->section_info[target_index].relocs
+ (flinfo->section_info[target_index].relocs
+ o->output_section->reloc_count)));
if (internal_relocs == NULL)
return FALSE;
/* Call processor specific code to relocate the section
contents. */
- if (! bfd_coff_relocate_section (output_bfd, finfo->info,
+ if (! bfd_coff_relocate_section (output_bfd, flinfo->info,
input_bfd, o,
contents,
internal_relocs,
- finfo->internal_syms,
+ flinfo->internal_syms,
xcoff_data (input_bfd)->csects))
return FALSE;
offset = o->output_section->vma + o->output_offset - o->vma;
irel = internal_relocs;
irelend = irel + o->reloc_count;
- rel_hash = (finfo->section_info[target_index].rel_hashes
+ rel_hash = (flinfo->section_info[target_index].rel_hashes
+ o->output_section->reloc_count);
for (; irel < irelend; irel++, rel_hash++)
{
else
h = obj_xcoff_sym_hashes (input_bfd)[r_symndx];
- if (r_symndx != -1 && finfo->info->strip != strip_all)
+ if (r_symndx != -1 && flinfo->info->strip != strip_all)
{
if (h != NULL
&& h->smclas != XMC_TD
bfd_size_type amt;
amt = sizeof (* n);
- n = bfd_alloc (finfo->output_bfd, amt);
+ n = bfd_alloc (flinfo->output_bfd, amt);
if (n == NULL)
return FALSE;
- si = finfo->section_info + target_index;
+ si = flinfo->section_info + target_index;
n->next = si->toc_rel_hashes;
n->h = h;
n->rel = irel;
{
long indx;
- indx = finfo->sym_indices[r_symndx];
+ indx = flinfo->sym_indices[r_symndx];
if (indx == -1)
{
/* Relocations against a TC0 TOC anchor are
automatically transformed to be against
the TOC anchor in the output file. */
- is = finfo->internal_syms + r_symndx;
+ is = flinfo->internal_syms + r_symndx;
if (is->n_sclass == C_HIDEXT
&& is->n_numaux > 0)
{
(void *) &aux);
if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_SD
&& aux.x_csect.x_smclas == XMC_TC0)
- indx = finfo->toc_symindx;
+ indx = flinfo->toc_symindx;
}
}
/* This reloc is against a symbol we are
stripping. It would be possible to handle
this case, but I don't think it's worth it. */
- is = finfo->internal_syms + r_symndx;
+ is = flinfo->internal_syms + r_symndx;
- name = (_bfd_coff_internal_syment_name
- (input_bfd, is, buf));
+ if (is->n_sclass != C_DWARF)
+ {
+ name = (_bfd_coff_internal_syment_name
+ (input_bfd, is, buf));
- if (name == NULL)
- return FALSE;
+ if (name == NULL)
+ return FALSE;
- if (! ((*finfo->info->callbacks->unattached_reloc)
- (finfo->info, name, input_bfd, o,
- irel->r_vaddr)))
- return FALSE;
+ (*flinfo->info->callbacks->unattached_reloc)
+ (flinfo->info, name,
+ input_bfd, o, irel->r_vaddr);
+ }
}
}
}
- if (xcoff_need_ldrel_p (finfo->info, irel, h))
+ if ((o->flags & SEC_DEBUGGING) == 0
+ && xcoff_need_ldrel_p (flinfo->info, irel, h))
{
asection *sec;
sec = xcoff_data (input_bfd)->csects[r_symndx];
else
sec = xcoff_symbol_section (h);
- if (!xcoff_create_ldrel (output_bfd, finfo,
+ if (!xcoff_create_ldrel (output_bfd, flinfo,
o->output_section, input_bfd,
irel, sec, h))
return FALSE;
obj_coff_keep_syms (input_bfd) = keep_syms;
- if (! finfo->info->keep_memory)
+ if (! flinfo->info->keep_memory)
{
if (! _bfd_coff_free_symbols (input_bfd))
return FALSE;
symbol. */
static bfd_boolean
-xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *finfo)
+xcoff_find_tc0 (bfd *output_bfd, struct xcoff_final_link_info *flinfo)
{
bfd_vma toc_start, toc_end, start, end, best_address;
asection *sec;
toc_start = ~(bfd_vma) 0;
toc_end = 0;
section_index = -1;
- for (input_bfd = finfo->info->input_bfds;
+ for (input_bfd = flinfo->info->input_bfds;
input_bfd != NULL;
- input_bfd = input_bfd->link_next)
+ input_bfd = input_bfd->link.next)
for (sec = input_bfd->sections; sec != NULL; sec = sec->next)
if ((sec->flags & SEC_MARK) != 0 && xcoff_toc_section_p (sec))
{
{
/* Find the lowest TOC csect that is still within range of TOC_END. */
best_address = toc_end;
- for (input_bfd = finfo->info->input_bfds;
+ for (input_bfd = flinfo->info->input_bfds;
input_bfd != NULL;
- input_bfd = input_bfd->link_next)
+ input_bfd = input_bfd->link.next)
for (sec = input_bfd->sections; sec != NULL; sec = sec->next)
if ((sec->flags & SEC_MARK) != 0 && xcoff_toc_section_p (sec))
{
/* Make sure that the start of the TOC is also within range. */
if (best_address > toc_start + 0x8000)
{
- (*_bfd_error_handler)
- (_("TOC overflow: 0x%lx > 0x10000; try -mminimal-toc "
+ _bfd_error_handler
+ (_("TOC overflow: %#" PRIx64 " > 0x10000; try -mminimal-toc "
"when compiling"),
- (unsigned long) (toc_end - toc_start));
+ (uint64_t) (toc_end - toc_start));
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
}
/* Record the chosen TOC value. */
- finfo->toc_symindx = obj_raw_syment_count (output_bfd);
+ flinfo->toc_symindx = obj_raw_syment_count (output_bfd);
xcoff_data (output_bfd)->toc = best_address;
xcoff_data (output_bfd)->sntoc = section_index;
/* Fill out the TC0 symbol. */
- if (!bfd_xcoff_put_symbol_name (output_bfd, finfo->strtab, &irsym, "TOC"))
+ if (!bfd_xcoff_put_symbol_name (output_bfd, flinfo->info, flinfo->strtab,
+ &irsym, "TOC"))
return FALSE;
irsym.n_value = best_address;
irsym.n_scnum = section_index;
irsym.n_sclass = C_HIDEXT;
irsym.n_type = T_NULL;
irsym.n_numaux = 1;
- bfd_coff_swap_sym_out (output_bfd, &irsym, finfo->outsyms);
+ bfd_coff_swap_sym_out (output_bfd, &irsym, flinfo->outsyms);
/* Fill out the auxillary csect information. */
memset (&iraux, 0, sizeof iraux);
iraux.x_csect.x_smclas = XMC_TC0;
iraux.x_csect.x_scnlen.l = 0;
bfd_coff_swap_aux_out (output_bfd, &iraux, T_NULL, C_HIDEXT, 0, 1,
- finfo->outsyms + bfd_coff_symesz (output_bfd));
+ flinfo->outsyms + bfd_coff_symesz (output_bfd));
/* Write the contents to the file. */
pos = obj_sym_filepos (output_bfd);
pos += obj_raw_syment_count (output_bfd) * bfd_coff_symesz (output_bfd);
size = 2 * bfd_coff_symesz (output_bfd);
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
- || bfd_bwrite (finfo->outsyms, size, output_bfd) != size)
+ || bfd_bwrite (flinfo->outsyms, size, output_bfd) != size)
return FALSE;
obj_raw_syment_count (output_bfd) += 2;
/* Write out a non-XCOFF global symbol. */
static bfd_boolean
-xcoff_write_global_symbol (struct xcoff_link_hash_entry *h, void * inf)
+xcoff_write_global_symbol (struct bfd_hash_entry *bh, void * inf)
{
- struct xcoff_final_link_info *finfo = (struct xcoff_final_link_info *) inf;
+ struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) bh;
+ struct xcoff_final_link_info *flinfo = (struct xcoff_final_link_info *) inf;
bfd *output_bfd;
bfd_byte *outsym;
struct internal_syment isym;
file_ptr pos;
bfd_size_type amt;
- output_bfd = finfo->output_bfd;
- outsym = finfo->outsyms;
+ output_bfd = flinfo->output_bfd;
+ outsym = flinfo->outsyms;
if (h->root.type == bfd_link_hash_warning)
{
}
/* If this symbol was garbage collected, just skip it. */
- if (xcoff_hash_table (finfo->info)->gc
+ if (xcoff_hash_table (flinfo->info)->gc
&& (h->flags & XCOFF_MARK) == 0)
return TRUE;
BFD_ASSERT (h->ldindx >= 0);
bfd_xcoff_swap_ldsym_out (output_bfd, ldsym,
- (finfo->ldsym +
+ (flinfo->ldsym +
(h->ldindx - 3)
- * bfd_xcoff_ldsymsz(finfo->output_bfd)));
+ * bfd_xcoff_ldsymsz(flinfo->output_bfd)));
h->ldsym = NULL;
}
/* If this symbol needs global linkage code, write it out. */
if (h->root.type == bfd_link_hash_defined
&& (h->root.u.def.section
- == xcoff_hash_table (finfo->info)->linkage_section))
+ == xcoff_hash_table (flinfo->info)->linkage_section))
{
bfd_byte *p;
bfd_vma tocoff;
tocoff += h->descriptor->u.toc_offset;
/* The first instruction in the glink code needs to be
- cooked to to hold the correct offset in the toc. The
+ cooked to hold the correct offset in the toc. The
rest are just output raw. */
bfd_put_32 (output_bfd,
bfd_xcoff_glink_code(output_bfd, 0) | (tocoff & 0xffff), p);
tocsec = h->toc_section;
osec = tocsec->output_section;
oindx = osec->target_index;
- irel = finfo->section_info[oindx].relocs + osec->reloc_count;
+ irel = flinfo->section_info[oindx].relocs + osec->reloc_count;
irel->r_vaddr = (osec->vma
+ tocsec->output_offset
+ h->u.toc_offset);
return FALSE;
irel->r_type = R_POS;
- finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
+ flinfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
++osec->reloc_count;
- if (!xcoff_create_ldrel (output_bfd, finfo, osec,
+ if (!xcoff_create_ldrel (output_bfd, flinfo, osec,
output_bfd, irel, NULL, h))
return FALSE;
/* We need to emit a symbol to define a csect which holds
the reloc. */
- if (finfo->info->strip != strip_all)
+ if (flinfo->info->strip != strip_all)
{
- result = bfd_xcoff_put_symbol_name (output_bfd, finfo->strtab,
+ result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->info,
+ flinfo->strtab,
&irsym, h->root.root.string);
if (!result)
return FALSE;
pos = obj_sym_filepos (output_bfd);
pos += (obj_raw_syment_count (output_bfd)
* bfd_coff_symesz (output_bfd));
- amt = outsym - finfo->outsyms;
+ amt = outsym - flinfo->outsyms;
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
- || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt)
+ || bfd_bwrite (flinfo->outsyms, amt, output_bfd) != amt)
return FALSE;
obj_raw_syment_count (output_bfd) +=
- (outsym - finfo->outsyms) / bfd_coff_symesz (output_bfd);
+ (outsym - flinfo->outsyms) / bfd_coff_symesz (output_bfd);
- outsym = finfo->outsyms;
+ outsym = flinfo->outsyms;
}
}
}
if ((h->flags & XCOFF_DESCRIPTOR) != 0
&& h->root.type == bfd_link_hash_defined
&& (h->root.u.def.section
- == xcoff_hash_table (finfo->info)->descriptor_section))
+ == xcoff_hash_table (flinfo->info)->descriptor_section))
{
asection *sec;
asection *osec;
|| hentry->root.type == bfd_link_hash_defweak));
esec = hentry->root.u.def.section;
- irel = finfo->section_info[oindx].relocs + osec->reloc_count;
+ irel = flinfo->section_info[oindx].relocs + osec->reloc_count;
irel->r_vaddr = (osec->vma
+ sec->output_offset
+ h->root.u.def.value);
irel->r_symndx = esec->output_section->target_index;
irel->r_type = R_POS;
irel->r_size = reloc_size;
- finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
+ flinfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
++osec->reloc_count;
- if (!xcoff_create_ldrel (output_bfd, finfo, osec,
+ if (!xcoff_create_ldrel (output_bfd, flinfo, osec,
output_bfd, irel, esec, NULL))
return FALSE;
irel->r_symndx = tsec->output_section->target_index;
irel->r_type = R_POS;
irel->r_size = reloc_size;
- finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
+ flinfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL;
++osec->reloc_count;
- if (!xcoff_create_ldrel (output_bfd, finfo, osec,
+ if (!xcoff_create_ldrel (output_bfd, flinfo, osec,
output_bfd, irel, tsec, NULL))
return FALSE;
}
- if (h->indx >= 0 || finfo->info->strip == strip_all)
+ if (h->indx >= 0 || flinfo->info->strip == strip_all)
{
- BFD_ASSERT (outsym == finfo->outsyms);
+ BFD_ASSERT (outsym == flinfo->outsyms);
return TRUE;
}
if (h->indx != -2
- && (finfo->info->strip == strip_all
- || (finfo->info->strip == strip_some
- && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
+ && (flinfo->info->strip == strip_all
+ || (flinfo->info->strip == strip_some
+ && bfd_hash_lookup (flinfo->info->keep_hash, h->root.root.string,
FALSE, FALSE) == NULL)))
{
- BFD_ASSERT (outsym == finfo->outsyms);
+ BFD_ASSERT (outsym == flinfo->outsyms);
return TRUE;
}
if (h->indx != -2
&& (h->flags & (XCOFF_REF_REGULAR | XCOFF_DEF_REGULAR)) == 0)
{
- BFD_ASSERT (outsym == finfo->outsyms);
+ BFD_ASSERT (outsym == flinfo->outsyms);
return TRUE;
}
h->indx = obj_raw_syment_count (output_bfd);
- result = bfd_xcoff_put_symbol_name (output_bfd, finfo->strtab, &isym,
- h->root.root.string);
+ result = bfd_xcoff_put_symbol_name (output_bfd, flinfo->info, flinfo->strtab,
+ &isym, h->root.root.string);
if (!result)
return FALSE;
|| 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
if ((h->flags & XCOFF_HAS_SIZE) != 0)
{
- for (l = xcoff_hash_table (finfo->info)->size_list;
+ for (l = xcoff_hash_table (flinfo->info)->size_list;
l != NULL;
l = l->next)
{
/* 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
pos = obj_sym_filepos (output_bfd);
pos += obj_raw_syment_count (output_bfd) * bfd_coff_symesz (output_bfd);
- amt = outsym - finfo->outsyms;
+ amt = outsym - flinfo->outsyms;
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
- || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt)
+ || bfd_bwrite (flinfo->outsyms, amt, output_bfd) != amt)
return FALSE;
obj_raw_syment_count (output_bfd) +=
- (outsym - finfo->outsyms) / bfd_coff_symesz (output_bfd);
+ (outsym - flinfo->outsyms) / bfd_coff_symesz (output_bfd);
return TRUE;
}
static bfd_boolean
xcoff_reloc_link_order (bfd *output_bfd,
- struct xcoff_final_link_info *finfo,
+ struct xcoff_final_link_info *flinfo,
asection *output_section,
struct bfd_link_order *link_order)
{
}
h = ((struct xcoff_link_hash_entry *)
- bfd_wrapped_link_hash_lookup (output_bfd, finfo->info,
+ bfd_wrapped_link_hash_lookup (output_bfd, flinfo->info,
link_order->u.reloc.p->u.name,
FALSE, FALSE, TRUE));
if (h == NULL)
{
- if (! ((*finfo->info->callbacks->unattached_reloc)
- (finfo->info, link_order->u.reloc.p->u.name, NULL, NULL, (bfd_vma) 0)))
- return FALSE;
+ (*flinfo->info->callbacks->unattached_reloc)
+ (flinfo->info, link_order->u.reloc.p->u.name, NULL, NULL, (bfd_vma) 0);
return TRUE;
}
size = bfd_get_reloc_size (howto);
buf = bfd_zmalloc (size);
- if (buf == NULL)
+ if (buf == NULL && size != 0)
return FALSE;
rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
case bfd_reloc_outofrange:
abort ();
case bfd_reloc_overflow:
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, NULL, link_order->u.reloc.p->u.name,
- howto->name, addend, NULL, NULL, (bfd_vma) 0)))
- {
- free (buf);
- return FALSE;
- }
+ (*flinfo->info->callbacks->reloc_overflow)
+ (flinfo->info, NULL, link_order->u.reloc.p->u.name,
+ howto->name, addend, NULL, NULL, (bfd_vma) 0);
break;
}
ok = bfd_set_section_contents (output_bfd, output_section, (void *) buf,
/* Store the reloc information in the right place. It will get
swapped and written out at the end of the final_link routine. */
- irel = (finfo->section_info[output_section->target_index].relocs
+ irel = (flinfo->section_info[output_section->target_index].relocs
+ output_section->reloc_count);
- rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes
+ rel_hash_ptr = (flinfo->section_info[output_section->target_index].rel_hashes
+ output_section->reloc_count);
memset (irel, 0, sizeof (struct internal_reloc));
++output_section->reloc_count;
/* Now output the reloc to the .loader section. */
- if (xcoff_hash_table (finfo->info)->loader_section)
+ if (xcoff_hash_table (flinfo->info)->loader_section)
{
- if (!xcoff_create_ldrel (output_bfd, finfo, output_section,
+ if (!xcoff_create_ldrel (output_bfd, flinfo, output_section,
output_bfd, irel, hsec, h))
return FALSE;
}
_bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
{
bfd_size_type symesz;
- struct xcoff_final_link_info finfo;
+ struct xcoff_final_link_info flinfo;
asection *o;
struct bfd_link_order *p;
bfd_size_type max_contents_size;
file_ptr pos;
bfd_size_type amt;
- if (info->shared)
+ if (bfd_link_pic (info))
abfd->flags |= DYNAMIC;
symesz = bfd_coff_symesz (abfd);
- finfo.info = info;
- finfo.output_bfd = abfd;
- finfo.strtab = NULL;
- finfo.section_info = NULL;
- finfo.last_file_index = -1;
- finfo.toc_symindx = -1;
- finfo.internal_syms = NULL;
- finfo.sym_indices = NULL;
- finfo.outsyms = NULL;
- finfo.linenos = NULL;
- finfo.contents = NULL;
- finfo.external_relocs = NULL;
+ flinfo.info = info;
+ flinfo.output_bfd = abfd;
+ flinfo.strtab = NULL;
+ flinfo.section_info = NULL;
+ flinfo.last_file_index = -1;
+ flinfo.toc_symindx = -1;
+ flinfo.internal_syms = NULL;
+ flinfo.sym_indices = NULL;
+ flinfo.outsyms = NULL;
+ flinfo.linenos = NULL;
+ flinfo.contents = NULL;
+ flinfo.external_relocs = NULL;
if (xcoff_hash_table (info)->loader_section)
{
- finfo.ldsym = (xcoff_hash_table (info)->loader_section->contents
+ flinfo.ldsym = (xcoff_hash_table (info)->loader_section->contents
+ bfd_xcoff_ldhdrsz (abfd));
- finfo.ldrel = (xcoff_hash_table (info)->loader_section->contents
+ flinfo.ldrel = (xcoff_hash_table (info)->loader_section->contents
+ bfd_xcoff_ldhdrsz (abfd)
+ (xcoff_hash_table (info)->ldhdr.l_nsyms
* bfd_xcoff_ldsymsz (abfd)));
}
else
{
- finfo.ldsym = NULL;
- finfo.ldrel = NULL;
+ flinfo.ldsym = NULL;
+ flinfo.ldrel = NULL;
}
xcoff_data (abfd)->coff.link_info = info;
- finfo.strtab = _bfd_stringtab_init ();
- if (finfo.strtab == NULL)
+ flinfo.strtab = _bfd_stringtab_init ();
+ if (flinfo.strtab == NULL)
goto error_return;
/* Count the relocation entries required for the output file.
o->reloc_count += sec->reloc_count;
- if (sec->rawsize > max_contents_size)
- max_contents_size = sec->rawsize;
- if (sec->size > max_contents_size)
- max_contents_size = sec->size;
+ if ((sec->flags & SEC_IN_MEMORY) == 0)
+ {
+ if (sec->rawsize > max_contents_size)
+ max_contents_size = sec->rawsize;
+ if (sec->size > max_contents_size)
+ max_contents_size = sec->size;
+ }
if (coff_section_data (sec->owner, sec) != NULL
&& xcoff_section_data (sec->owner, sec) != NULL
&& (xcoff_section_data (sec->owner, sec)->lineno_count
the target_index fields are 1 based. */
amt = abfd->section_count + 1;
amt *= sizeof (struct xcoff_link_section_info);
- finfo.section_info = bfd_malloc (amt);
- if (finfo.section_info == NULL)
+ flinfo.section_info = bfd_malloc (amt);
+ if (flinfo.section_info == NULL)
goto error_return;
for (i = 0; i <= abfd->section_count; i++)
{
- finfo.section_info[i].relocs = NULL;
- finfo.section_info[i].rel_hashes = NULL;
- finfo.section_info[i].toc_rel_hashes = NULL;
+ flinfo.section_info[i].relocs = NULL;
+ flinfo.section_info[i].rel_hashes = NULL;
+ flinfo.section_info[i].toc_rel_hashes = NULL;
}
}
would be slow. */
amt = o->reloc_count;
amt *= sizeof (struct internal_reloc);
- finfo.section_info[o->target_index].relocs = bfd_malloc (amt);
+ flinfo.section_info[o->target_index].relocs = bfd_malloc (amt);
amt = o->reloc_count;
amt *= sizeof (struct xcoff_link_hash_entry *);
- finfo.section_info[o->target_index].rel_hashes = bfd_malloc (amt);
+ flinfo.section_info[o->target_index].rel_hashes = bfd_malloc (amt);
- if (finfo.section_info[o->target_index].relocs == NULL
- || finfo.section_info[o->target_index].rel_hashes == NULL)
+ if (flinfo.section_info[o->target_index].relocs == NULL
+ || flinfo.section_info[o->target_index].rel_hashes == NULL)
goto error_return;
if (o->reloc_count > max_output_reloc_count)
/* We now know the size of the relocs, so we can determine the file
positions of the line numbers. */
line_filepos = rel_filepos;
- finfo.line_filepos = line_filepos;
+ flinfo.line_filepos = line_filepos;
linesz = bfd_coff_linesz (abfd);
for (o = abfd->sections; o != NULL; o = o->next)
{
input BFD's. We want at least 6 symbols, since that is the
number which xcoff_write_global_symbol may need. */
max_sym_count = 6;
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
bfd_size_type sz;
/* Allocate some buffers used while linking. */
amt = max_sym_count * sizeof (struct internal_syment);
- finfo.internal_syms = bfd_malloc (amt);
+ flinfo.internal_syms = bfd_malloc (amt);
amt = max_sym_count * sizeof (long);
- finfo.sym_indices = bfd_malloc (amt);
+ flinfo.sym_indices = bfd_malloc (amt);
amt = (max_sym_count + 1) * symesz;
- finfo.outsyms = bfd_malloc (amt);
+ flinfo.outsyms = bfd_malloc (amt);
amt = max_lineno_count * bfd_coff_linesz (abfd);
- finfo.linenos = bfd_malloc (amt);
+ flinfo.linenos = bfd_malloc (amt);
amt = max_contents_size;
- finfo.contents = bfd_malloc (amt);
+ flinfo.contents = bfd_malloc (amt);
amt = max_reloc_count * relsz;
- finfo.external_relocs = bfd_malloc (amt);
-
- if ((finfo.internal_syms == NULL && max_sym_count > 0)
- || (finfo.sym_indices == NULL && max_sym_count > 0)
- || finfo.outsyms == NULL
- || (finfo.linenos == NULL && max_lineno_count > 0)
- || (finfo.contents == NULL && max_contents_size > 0)
- || (finfo.external_relocs == NULL && max_reloc_count > 0))
+ flinfo.external_relocs = bfd_malloc (amt);
+
+ if ((flinfo.internal_syms == NULL && max_sym_count > 0)
+ || (flinfo.sym_indices == NULL && max_sym_count > 0)
+ || flinfo.outsyms == NULL
+ || (flinfo.linenos == NULL && max_lineno_count > 0)
+ || (flinfo.contents == NULL && max_contents_size > 0)
+ || (flinfo.external_relocs == NULL && max_reloc_count > 0))
goto error_return;
obj_raw_syment_count (abfd) = 0;
/* Find a TOC symbol, if we need one. */
- if (!xcoff_find_tc0 (abfd, &finfo))
+ if (!xcoff_find_tc0 (abfd, &flinfo))
goto error_return;
/* We now know the position of everything in the file, except that
sub = p->u.indirect.section->owner;
if (! sub->output_has_begun)
{
- if (! xcoff_link_input_bfd (&finfo, sub))
+ if (! xcoff_link_input_bfd (&flinfo, sub))
goto error_return;
sub->output_has_begun = TRUE;
}
else if (p->type == bfd_section_reloc_link_order
|| p->type == bfd_symbol_reloc_link_order)
{
- if (! xcoff_reloc_link_order (abfd, &finfo, o, p))
+ if (! xcoff_reloc_link_order (abfd, &flinfo, o, p))
goto error_return;
}
else
}
/* Free up the buffers used by xcoff_link_input_bfd. */
- if (finfo.internal_syms != NULL)
+ if (flinfo.internal_syms != NULL)
{
- free (finfo.internal_syms);
- finfo.internal_syms = NULL;
+ free (flinfo.internal_syms);
+ flinfo.internal_syms = NULL;
}
- if (finfo.sym_indices != NULL)
+ if (flinfo.sym_indices != NULL)
{
- free (finfo.sym_indices);
- finfo.sym_indices = NULL;
+ free (flinfo.sym_indices);
+ flinfo.sym_indices = NULL;
}
- if (finfo.linenos != NULL)
+ if (flinfo.linenos != NULL)
{
- free (finfo.linenos);
- finfo.linenos = NULL;
+ free (flinfo.linenos);
+ flinfo.linenos = NULL;
}
- if (finfo.contents != NULL)
+ if (flinfo.contents != NULL)
{
- free (finfo.contents);
- finfo.contents = NULL;
+ free (flinfo.contents);
+ flinfo.contents = NULL;
}
- if (finfo.external_relocs != NULL)
+ if (flinfo.external_relocs != NULL)
{
- free (finfo.external_relocs);
- finfo.external_relocs = 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. */
- if (finfo.last_file_index != -1)
+ if (flinfo.last_file_index != -1)
{
- finfo.last_file.n_value = -(bfd_vma) 1;
- bfd_coff_swap_sym_out (abfd, (void *) &finfo.last_file,
- (void *) finfo.outsyms);
- pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz;
+ flinfo.last_file.n_value = -(bfd_vma) 1;
+ bfd_coff_swap_sym_out (abfd, (void *) &flinfo.last_file,
+ (void *) flinfo.outsyms);
+ pos = obj_sym_filepos (abfd) + flinfo.last_file_index * symesz;
if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz)
+ || bfd_bwrite (flinfo.outsyms, symesz, abfd) != symesz)
goto error_return;
}
/* Write out all the global symbols which do not come from XCOFF
input files. */
- xcoff_link_hash_traverse (xcoff_hash_table (info),
- xcoff_write_global_symbol,
- (void *) &finfo);
+ bfd_hash_traverse (&info->hash->table, xcoff_write_global_symbol, &flinfo);
- if (finfo.outsyms != NULL)
+ if (flinfo.outsyms != NULL)
{
- free (finfo.outsyms);
- finfo.outsyms = NULL;
+ free (flinfo.outsyms);
+ flinfo.outsyms = NULL;
}
/* Now that we have written out all the global symbols, we know the
if (o->reloc_count == 0)
continue;
- irel = finfo.section_info[o->target_index].relocs;
+ irel = flinfo.section_info[o->target_index].relocs;
irelend = irel + o->reloc_count;
- rel_hash = finfo.section_info[o->target_index].rel_hashes;
- for (; irel < irelend; irel++, rel_hash++, erel += relsz)
+ rel_hash = flinfo.section_info[o->target_index].rel_hashes;
+ for (; irel < irelend; irel++, rel_hash++)
{
if (*rel_hash != NULL)
{
if ((*rel_hash)->indx < 0)
{
- if (! ((*info->callbacks->unattached_reloc)
- (info, (*rel_hash)->root.root.string,
- NULL, o, irel->r_vaddr)))
- goto error_return;
+ (*info->callbacks->unattached_reloc)
+ (info, (*rel_hash)->root.root.string,
+ NULL, o, irel->r_vaddr);
(*rel_hash)->indx = 0;
}
irel->r_symndx = (*rel_hash)->indx;
}
}
- for (toc_rel_hash = finfo.section_info[o->target_index].toc_rel_hashes;
+ for (toc_rel_hash = flinfo.section_info[o->target_index].toc_rel_hashes;
toc_rel_hash != NULL;
toc_rel_hash = toc_rel_hash->next)
{
if (toc_rel_hash->h->u.toc_indx < 0)
{
- if (! ((*info->callbacks->unattached_reloc)
- (info, toc_rel_hash->h->root.root.string,
- NULL, o, toc_rel_hash->rel->r_vaddr)))
- goto error_return;
+ (*info->callbacks->unattached_reloc)
+ (info, toc_rel_hash->h->root.root.string,
+ NULL, o, toc_rel_hash->rel->r_vaddr);
toc_rel_hash->h->u.toc_indx = 0;
}
toc_rel_hash->rel->r_symndx = toc_rel_hash->h->u.toc_indx;
appear in the symbol table, which is not necessarily by
address. So we sort them here. There may be a better way to
do this. */
- qsort ((void *) finfo.section_info[o->target_index].relocs,
+ qsort ((void *) flinfo.section_info[o->target_index].relocs,
o->reloc_count, sizeof (struct internal_reloc),
xcoff_sort_relocs);
- irel = finfo.section_info[o->target_index].relocs;
+ irel = flinfo.section_info[o->target_index].relocs;
irelend = irel + o->reloc_count;
erel = external_relocs;
for (; irel < irelend; irel++, rel_hash++, erel += relsz)
}
/* Free up the section information. */
- if (finfo.section_info != NULL)
+ if (flinfo.section_info != NULL)
{
unsigned int i;
for (i = 0; i < abfd->section_count; i++)
{
- if (finfo.section_info[i].relocs != NULL)
- free (finfo.section_info[i].relocs);
- if (finfo.section_info[i].rel_hashes != NULL)
- free (finfo.section_info[i].rel_hashes);
+ 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 (finfo.section_info);
- finfo.section_info = NULL;
+ free (flinfo.section_info);
+ flinfo.section_info = NULL;
}
/* Write out the loader section contents. */
o = xcoff_hash_table (info)->loader_section;
if (o)
{
- BFD_ASSERT ((bfd_byte *) finfo.ldrel
+ BFD_ASSERT ((bfd_byte *) flinfo.ldrel
== (xcoff_hash_table (info)->loader_section->contents
+ xcoff_hash_table (info)->ldhdr.l_impoff));
if (!bfd_set_section_contents (abfd, o->output_section, o->contents,
if (bfd_seek (abfd, pos, SEEK_SET) != 0)
goto error_return;
H_PUT_32 (abfd,
- _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
+ _bfd_stringtab_size (flinfo.strtab) + STRING_SIZE_SIZE,
strbuf);
amt = STRING_SIZE_SIZE;
if (bfd_bwrite (strbuf, amt, abfd) != amt)
goto error_return;
- if (! _bfd_stringtab_emit (abfd, finfo.strtab))
+ if (! _bfd_stringtab_emit (abfd, flinfo.strtab))
goto error_return;
- _bfd_stringtab_free (finfo.strtab);
+ _bfd_stringtab_free (flinfo.strtab);
/* Write out the debugging string table. */
o = xcoff_hash_table (info)->debug_section;
return TRUE;
error_return:
- if (finfo.strtab != NULL)
- _bfd_stringtab_free (finfo.strtab);
+ if (flinfo.strtab != NULL)
+ _bfd_stringtab_free (flinfo.strtab);
- if (finfo.section_info != NULL)
+ if (flinfo.section_info != NULL)
{
unsigned int i;
for (i = 0; i < abfd->section_count; i++)
{
- if (finfo.section_info[i].relocs != NULL)
- free (finfo.section_info[i].relocs);
- if (finfo.section_info[i].rel_hashes != NULL)
- free (finfo.section_info[i].rel_hashes);
+ 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 (finfo.section_info);
- }
-
- if (finfo.internal_syms != NULL)
- free (finfo.internal_syms);
- if (finfo.sym_indices != NULL)
- free (finfo.sym_indices);
- if (finfo.outsyms != NULL)
- free (finfo.outsyms);
- if (finfo.linenos != NULL)
- free (finfo.linenos);
- if (finfo.contents != NULL)
- free (finfo.contents);
- if (finfo.external_relocs != NULL)
- free (finfo.external_relocs);
+ 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);
return FALSE;