diff options
author | Ian Lance Taylor <ian@airs.com> | 1996-01-11 21:06:42 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1996-01-11 21:06:42 +0000 |
commit | 5b3b9ff61d3a2a6cdd90fcec1a61d38699f3c608 (patch) | |
tree | 4a38d859537ed0e9e8ac23a9e6b9989bd9bd9d0d /bfd/elflink.h | |
parent | f9407a89f45c77372d823af6a5aaffe23b2653b2 (diff) | |
download | gdb-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.h | 121 |
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); |