/* linker.c -- BFD linker routines
- Copyright (C) 1993-2015 Free Software Foundation, Inc.
+ Copyright (C) 1993-2016 Free Software Foundation, Inc.
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
This file is part of BFD, the Binary File Descriptor library.
else if (bfd_is_com_section (section))
{
row = COMMON_ROW;
- if (strcmp (name, "__gnu_lto_slim") == 0)
+ if (!bfd_link_relocatable (info)
+ && strcmp (name, "__gnu_lto_slim") == 0)
(*_bfd_error_handler)
(_("%s: plugin needed to handle lto object"),
bfd_get_filename (abfd));
/* We have found a definition for a symbol which was
previously common. */
BFD_ASSERT (h->type == bfd_link_hash_common);
- if (! ((*info->callbacks->multiple_common)
- (info, h, abfd, bfd_link_hash_defined, 0)))
- return FALSE;
+ (*info->callbacks->multiple_common) (info, h, abfd,
+ bfd_link_hash_defined, 0);
/* Fall through. */
case DEF:
case DEFW:
if (oldtype == bfd_link_hash_defweak)
abort ();
- if (! ((*info->callbacks->constructor)
- (info, c == 'I',
- h->root.string, abfd, section, value)))
- return FALSE;
+ (*info->callbacks->constructor) (info, c == 'I',
+ h->root.string, abfd,
+ section, value);
}
}
}
already had a common definition. Use the maximum of the
two sizes, and use the section required by the larger symbol. */
BFD_ASSERT (h->type == bfd_link_hash_common);
- if (! ((*info->callbacks->multiple_common)
- (info, h, abfd, bfd_link_hash_common, value)))
- return FALSE;
+ (*info->callbacks->multiple_common) (info, h, abfd,
+ bfd_link_hash_common, value);
if (value > h->u.c.size)
{
unsigned int power;
case CREF:
/* We have found a common definition for a symbol which
was already defined. */
- if (! ((*info->callbacks->multiple_common)
- (info, h, abfd, bfd_link_hash_common, value)))
- return FALSE;
+ (*info->callbacks->multiple_common) (info, h, abfd,
+ bfd_link_hash_common, value);
break;
case MIND:
/* Fall through. */
case MDEF:
/* Handle a multiple definition. */
- if (! ((*info->callbacks->multiple_definition)
- (info, h, abfd, section, value)))
- return FALSE;
+ (*info->callbacks->multiple_definition) (info, h,
+ abfd, section, value);
break;
case CIND:
/* Create an indirect symbol from an existing common symbol. */
BFD_ASSERT (h->type == bfd_link_hash_common);
- if (! ((*info->callbacks->multiple_common)
- (info, h, abfd, bfd_link_hash_indirect, 0)))
- return FALSE;
+ (*info->callbacks->multiple_common) (info, h, abfd,
+ bfd_link_hash_indirect, 0);
/* Fall through. */
case IND:
if (inh->type == bfd_link_hash_indirect
case SET:
/* Add an entry to a set. */
- if (! (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR,
- abfd, section, value))
- return FALSE;
+ (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR,
+ abfd, section, value);
break;
case WARNC:
if (h->u.i.warning != NULL
&& (abfd->flags & BFD_PLUGIN) == 0)
{
- if (! (*info->callbacks->warning) (info, h->u.i.warning,
- h->root.string, abfd,
- NULL, 0))
- return FALSE;
+ (*info->callbacks->warning) (info, h->u.i.warning,
+ h->root.string, abfd, NULL, 0);
/* Only issue a warning once. */
h->u.i.warning = NULL;
}
&& (h->u.undef.next != NULL || info->hash->undefs_tail == h))
|| h->non_ir_ref)
{
- if (! (*info->callbacks->warning) (info, string, h->root.string,
- hash_entry_bfd (h), NULL, 0))
- return FALSE;
+ (*info->callbacks->warning) (info, string, h->root.string,
+ hash_entry_bfd (h), NULL, 0);
break;
}
/* Fall through. */
if (h == NULL
|| ! h->written)
{
- if (! ((*info->callbacks->unattached_reloc)
- (info, link_order->u.reloc.p->u.name, NULL, NULL, 0)))
- return FALSE;
+ (*info->callbacks->unattached_reloc)
+ (info, link_order->u.reloc.p->u.name, NULL, NULL, 0);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
case bfd_reloc_outofrange:
abort ();
case bfd_reloc_overflow:
- if (! ((*info->callbacks->reloc_overflow)
- (info, NULL,
- (link_order->type == bfd_section_reloc_link_order
- ? bfd_section_name (abfd, link_order->u.reloc.p->u.section)
- : link_order->u.reloc.p->u.name),
- r->howto->name, link_order->u.reloc.p->addend,
- NULL, NULL, 0)))
- {
- free (buf);
- return FALSE;
- }
+ (*info->callbacks->reloc_overflow)
+ (info, NULL,
+ (link_order->type == bfd_section_reloc_link_order
+ ? bfd_section_name (abfd, link_order->u.reloc.p->u.section)
+ : link_order->u.reloc.p->u.name),
+ r->howto->name, link_order->u.reloc.p->addend,
+ NULL, NULL, 0);
break;
}
loc = link_order->offset * bfd_octets_per_byte (abfd);
/*
FUNCTION
- bfd_link_get_defined_symbol
+ bfd_link_check_relocs
SYNOPSIS
- bfd_boolean bfd_link_get_defined_symbol
- (struct bfd_link_info *info, struct bfd_link_hash_entry *h,
- asection **sec, bfd_vma *value);
+ bfd_boolean bfd_link_check_relocs
+ (bfd *abfd, struct bfd_link_info *info);
DESCRIPTION
- Return TRUE, store symbol section and value in @var{*sec} and
- @var{*value} if symbol @var{h} is defined during a final link.
+ Checks the relocs in ABFD for validity.
+ Does not execute the relocs.
+ Return TRUE if everything is OK, FALSE otherwise.
+ This is the external entry point to this code.
*/
bfd_boolean
-bfd_link_get_defined_symbol (struct bfd_link_info *info,
- struct bfd_link_hash_entry *h,
- asection **sec, bfd_vma *value)
+bfd_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
{
- if (h->type == bfd_link_hash_defined
- || h->type == bfd_link_hash_defweak)
- {
- if (sec)
- *sec = h->u.def.section;
- if (value)
- *value = h->u.def.value;
- return TRUE;
- }
-
- if (h->type == bfd_link_hash_new
- || h->type == bfd_link_hash_undefined
- || h->type == bfd_link_hash_undefweak)
- {
- /* Check yet undefined reference to __start_XXX or __stop_XXX
- symbols. The linker will later define such symbols for output
- sections that have a name representable as a C identifier. */
- const char *sec_name;
- if (strncmp (h->root.string, "__start_", 8) == 0)
- sec_name = h->root.string + 8;
- else if (strncmp (h->root.string, "__stop_", 7) == 0)
- sec_name = h->root.string + 7;
- else
- sec_name = NULL;
-
- if (sec_name != NULL && *sec_name != '\0')
- {
- bfd *i;
-
- for (i = info->input_bfds; i != NULL; i = i->link.next)
- {
- asection *s = bfd_get_section_by_name (i, sec_name);
- if (s != NULL)
- {
- asection *asect;
- bfd_vma size;
-
- if (sec)
- *sec = s;
+ return BFD_SEND (abfd, _bfd_link_check_relocs, (abfd, info));
+}
- if (!value)
- return TRUE;
- if (sec_name == (h->root.string + 8))
- {
- /* Set __start_XXX symbol value. */
- *value = 0;
- return TRUE;
- }
+/*
+FUNCTION
+ _bfd_generic_link_check_relocs
- /* Get the size of the output XXX section for
- __stop_XXX symbol value. */
- size = 0;
- for (asect = s->output_section->map_head.s;
- asect != NULL;
- asect = asect->map_head.s)
- {
- size = align_power (size, asect->alignment_power);
- size += asect->size;
- }
+SYNOPSIS
+ bfd_boolean _bfd_generic_link_check_relocs
+ (bfd *abfd, struct bfd_link_info *info);
- *value = size;
- return TRUE;
- }
- }
- }
- }
+DESCRIPTION
+ Stub function for targets that do not implement reloc checking.
+ Return TRUE.
+ This is an internal function. It should not be called from
+ outside the BFD library.
+*/
- return FALSE;
+bfd_boolean
+_bfd_generic_link_check_relocs (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ return TRUE;
}