aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.h
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1996-01-11 21:06:42 +0000
committerIan Lance Taylor <ian@airs.com>1996-01-11 21:06:42 +0000
commit5b3b9ff61d3a2a6cdd90fcec1a61d38699f3c608 (patch)
tree4a38d859537ed0e9e8ac23a9e6b9989bd9bd9d0d /bfd/elflink.h
parentf9407a89f45c77372d823af6a5aaffe23b2653b2 (diff)
downloadgdb-5b3b9ff61d3a2a6cdd90fcec1a61d38699f3c608.zip
gdb-5b3b9ff61d3a2a6cdd90fcec1a61d38699f3c608.tar.gz
gdb-5b3b9ff61d3a2a6cdd90fcec1a61d38699f3c608.tar.bz2
* elf32-mips.c: Extensive changes for a start at dynamic linking
support, from Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>. * elf-bfd.h (struct elf_backend_data): Add type_change_ok field. (struct elf_backend_data): Remove elf_backend_create_program_headers field. Add elf_backend_additional_program_headers and elf_backend_modify_segment_map fields. * elfxx-target.h (elf_backend_type_change_ok): Define if not defined. (elf_backend_additional_program_headers): Likewise. (elf_backend_modify_segment_map): Likewise. (elf_backend_create_program_headers): Don't define. (elfNN_bed): Change to account for field changes. * elf.c (assign_file_positions_for_segments): Call new modify_segment_map backend function. Don't call old create_program_headers backend function. (get_program_header_size): Call additional_program_headers rather than create_program_headers. * elflink.h (elf_link_add_object_symbols): Initialize type_change_ok from new backend field. (elf_link_output_extsym): Don't warn if _rld_new_interface is defined. (elf_reloc_link_order): Treat a reloc against a defined symbol as a reloc against the appropriate section.
Diffstat (limited to 'bfd/elflink.h')
-rw-r--r--bfd/elflink.h121
1 files changed, 71 insertions, 50 deletions
diff --git a/bfd/elflink.h b/bfd/elflink.h
index 1107c04..fde4006 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -629,7 +629,7 @@ elf_link_add_object_symbols (abfd, info)
definition = true;
size_change_ok = false;
- type_change_ok = false;
+ type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
if (info->hash->creator->flavour == bfd_target_elf_flavour)
{
/* We need to look up the symbol now in order to get some of
@@ -648,15 +648,16 @@ elf_link_add_object_symbols (abfd, info)
/* It's OK to change the type if it used to be a weak
definition. */
- type_change_ok = (h->root.type == bfd_link_hash_defweak
- || h->root.type == bfd_link_hash_undefweak);
+ if (h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_undefweak)
+ type_change_ok = true;
/* It's OK to change the size if it used to be a weak
definition, or if it used to be undefined, or if we will
- be overriding an old definition.
- */
- size_change_ok = (type_change_ok
- || h->root.type == bfd_link_hash_undefined);
+ be overriding an old definition. */
+ if (type_change_ok
+ || h->root.type == bfd_link_hash_undefined)
+ size_change_ok = true;
/* If we are looking at a dynamic object, and this is a
definition, we need to see if it has already been defined
@@ -2401,12 +2402,15 @@ elf_link_output_extsym (h, data)
linker will complain that the symbol is undefined when the
program is run. We don't have to worry about symbols that are
referenced by regular files, because we will already have issued
- warnings for them. */
+ warnings for them. FIXME: _rld_new_interface is apparently
+ supposed to be undefined on Irix 5.3. This should be handled in
+ a better way. */
if (! finfo->info->relocateable
&& ! finfo->info->shared
&& h->root.type == bfd_link_hash_undefined
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
- && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
+ && strcmp (h->root.root.string, "_rld_new_interface") != 0)
{
if (! ((*finfo->info->callbacks->undefined_symbol)
(finfo->info, h->root.root.string, h->root.u.undef.abfd,
@@ -2987,6 +2991,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
reloc_howto_type *howto;
long indx;
bfd_vma offset;
+ bfd_vma addend;
struct elf_link_hash_entry **rel_hash_ptr;
Elf_Internal_Shdr *rel_hdr;
@@ -2997,10 +3002,61 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
return false;
}
+ addend = link_order->u.reloc.p->addend;
+
+ /* Figure out the symbol index. */
+ rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
+ + output_section->reloc_count);
+ if (link_order->type == bfd_section_reloc_link_order)
+ {
+ indx = link_order->u.reloc.p->u.section->target_index;
+ BFD_ASSERT (indx != 0);
+ *rel_hash_ptr = NULL;
+ }
+ else
+ {
+ struct elf_link_hash_entry *h;
+
+ /* Treat a reloc against a defined symbol as though it were
+ actually against the section. */
+ h = elf_link_hash_lookup (elf_hash_table (info),
+ link_order->u.reloc.p->u.name,
+ false, false, true);
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ asection *section;
+
+ section = h->root.u.def.section;
+ indx = section->output_section->target_index;
+ *rel_hash_ptr = NULL;
+ /* It seems that we ought to add the symbol value to the
+ addend here, but in practice it has already been added
+ because it was passed to constructor_callback. */
+ addend += section->output_section->vma + section->output_offset;
+ }
+ else if (h != NULL)
+ {
+ /* Setting the index to -2 tells elf_link_output_extsym that
+ this symbol is used by a reloc. */
+ h->indx = -2;
+ *rel_hash_ptr = h;
+ indx = 0;
+ }
+ else
+ {
+ if (! ((*info->callbacks->unattached_reloc)
+ (info, link_order->u.reloc.p->u.name, (bfd *) NULL,
+ (asection *) NULL, (bfd_vma) 0)))
+ return false;
+ indx = 0;
+ }
+ }
+
/* If this is an inplace reloc, we must write the addend into the
object file. */
- if (howto->partial_inplace
- && link_order->u.reloc.p->addend != 0)
+ if (howto->partial_inplace && addend != 0)
{
bfd_size_type size;
bfd_reloc_status_type rstat;
@@ -3011,8 +3067,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
buf = (bfd_byte *) bfd_zmalloc (size);
if (buf == (bfd_byte *) NULL)
return false;
- rstat = _bfd_relocate_contents (howto, output_bfd,
- link_order->u.reloc.p->addend, buf);
+ rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
switch (rstat)
{
case bfd_reloc_ok:
@@ -3027,8 +3082,8 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
? bfd_section_name (output_bfd,
link_order->u.reloc.p->u.section)
: link_order->u.reloc.p->u.name),
- howto->name, link_order->u.reloc.p->addend,
- (bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
+ howto->name, addend, (bfd *) NULL, (asection *) NULL,
+ (bfd_vma) 0)))
{
free (buf);
return false;
@@ -3042,40 +3097,6 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
return false;
}
- /* Figure out the symbol index. */
- rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
- + output_section->reloc_count);
- if (link_order->type == bfd_section_reloc_link_order)
- {
- indx = link_order->u.reloc.p->u.section->target_index;
- BFD_ASSERT (indx != 0);
- *rel_hash_ptr = NULL;
- }
- else
- {
- struct elf_link_hash_entry *h;
-
- h = elf_link_hash_lookup (elf_hash_table (info),
- link_order->u.reloc.p->u.name,
- false, false, true);
- if (h != NULL)
- {
- /* Setting the index to -2 tells elf_link_output_extsym that
- this symbol is used by a reloc. */
- h->indx = -2;
- *rel_hash_ptr = h;
- indx = 0;
- }
- else
- {
- if (! ((*info->callbacks->unattached_reloc)
- (info, link_order->u.reloc.p->u.name, (bfd *) NULL,
- (asection *) NULL, (bfd_vma) 0)))
- return false;
- indx = 0;
- }
- }
-
/* The address of a reloc is relative to the section in a
relocateable file, and is a virtual address in an executable
file. */
@@ -3103,7 +3124,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
irela.r_offset = offset;
irela.r_info = ELF_R_INFO (indx, howto->type);
- irela.r_addend = link_order->u.reloc.p->addend;
+ irela.r_addend = addend;
erela = ((Elf_External_Rela *) rel_hdr->contents
+ output_section->reloc_count);
elf_swap_reloca_out (output_bfd, &irela, erela);