X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-m68k.c;h=f807e03741acfbd194c701ca4dc2fa7e3da7740a;hb=e3cfc1c76d89f904659b106d78b352884797967b;hp=91ae2df17364b256ee2b80d3ef6dc15ccb7252de;hpb=3a4ae681237c26ac55603f3a92c92fd748108cd2;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 91ae2df173..f807e03741 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -1,7 +1,5 @@ /* Motorola 68k series support for 32-bit ELF - Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 - Free Software Foundation, Inc. + Copyright (C) 1993-2015 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -28,43 +26,12 @@ #include "elf/m68k.h" #include "opcode/m68k.h" -static reloc_howto_type *reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void rtype_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static struct bfd_hash_entry *elf_m68k_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *elf_m68k_link_hash_table_create - PARAMS ((bfd *)); -static bfd_boolean elf_m68k_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_boolean elf_m68k_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static bfd_boolean elf_m68k_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean elf_m68k_discard_copies - PARAMS ((struct elf_link_hash_entry *, PTR)); -static bfd_boolean elf_m68k_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static bfd_boolean elf_m68k_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static bfd_boolean elf_m68k_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -static bfd_boolean elf32_m68k_set_private_flags - PARAMS ((bfd *, flagword)); -static bfd_boolean elf32_m68k_merge_private_bfd_data - PARAMS ((bfd *, bfd *)); -static bfd_boolean elf32_m68k_print_private_bfd_data - PARAMS ((bfd *, PTR)); -static enum elf_reloc_type_class elf32_m68k_reloc_type_class - PARAMS ((const Elf_Internal_Rela *)); - -static reloc_howto_type howto_table[] = { - HOWTO(R_68K_NONE, 0, 0, 0, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_NONE", FALSE, 0, 0x00000000,FALSE), +static bfd_boolean +elf_m68k_discard_copies (struct elf_link_hash_entry *, void *); + +static reloc_howto_type howto_table[] = +{ + HOWTO(R_68K_NONE, 0, 3, 0, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_NONE", FALSE, 0, 0x00000000,FALSE), HOWTO(R_68K_32, 0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_32", FALSE, 0, 0xffffffff,FALSE), HOWTO(R_68K_16, 0, 1,16, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_16", FALSE, 0, 0x0000ffff,FALSE), HOWTO(R_68K_8, 0, 0, 8, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_8", FALSE, 0, 0x000000ff,FALSE), @@ -441,9 +408,8 @@ static const struct }; static reloc_howto_type * -reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { unsigned int i; for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++) @@ -974,6 +940,23 @@ elf_m68k_link_hash_newfunc (struct bfd_hash_entry *entry, return ret; } +/* Destroy an m68k ELF linker hash table. */ + +static void +elf_m68k_link_hash_table_free (bfd *obfd) +{ + struct elf_m68k_link_hash_table *htab; + + htab = (struct elf_m68k_link_hash_table *) obfd->link.hash; + + if (htab->multi_got_.bfd2got != NULL) + { + htab_delete (htab->multi_got_.bfd2got); + htab->multi_got_.bfd2got = NULL; + } + _bfd_elf_link_hash_table_free (obfd); +} + /* Create an m68k ELF linker hash table. */ static struct bfd_link_hash_table * @@ -982,7 +965,7 @@ elf_m68k_link_hash_table_create (bfd *abfd) struct elf_m68k_link_hash_table *ret; bfd_size_type amt = sizeof (struct elf_m68k_link_hash_table); - ret = (struct elf_m68k_link_hash_table *) bfd_malloc (amt); + ret = (struct elf_m68k_link_hash_table *) bfd_zmalloc (amt); if (ret == (struct elf_m68k_link_hash_table *) NULL) return NULL; @@ -994,34 +977,13 @@ elf_m68k_link_hash_table_create (bfd *abfd) free (ret); return NULL; } + ret->root.root.hash_table_free = elf_m68k_link_hash_table_free; - ret->sym_cache.abfd = NULL; - ret->plt_info = NULL; - ret->local_gp_p = FALSE; - ret->use_neg_got_offsets_p = FALSE; - ret->allow_multigot_p = FALSE; - ret->multi_got_.bfd2got = NULL; ret->multi_got_.global_symndx = 1; return &ret->root.root; } -/* Destruct local data. */ - -static void -elf_m68k_link_hash_table_free (struct bfd_link_hash_table *_htab) -{ - struct elf_m68k_link_hash_table *htab; - - htab = (struct elf_m68k_link_hash_table *) _htab; - - if (htab->multi_got_.bfd2got != NULL) - { - htab_delete (htab->multi_got_.bfd2got); - htab->multi_got_.bfd2got = NULL; - } -} - /* Set the right machine number. */ static bfd_boolean @@ -1145,9 +1107,7 @@ elf_m68k_final_write_processing (bfd *abfd, /* Keep m68k-specific flags in the ELF header. */ static bfd_boolean -elf32_m68k_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; +elf32_m68k_set_private_flags (bfd *abfd, flagword flags) { elf_elfheader (abfd)->e_flags = flags; elf_flags_init (abfd) = TRUE; @@ -1157,9 +1117,7 @@ elf32_m68k_set_private_flags (abfd, flags) /* Merge backend specific data from an object file to the output object file when linking. */ static bfd_boolean -elf32_m68k_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; +elf32_m68k_merge_private_bfd_data (bfd *ibfd, bfd *obfd) { flagword out_flags; flagword in_flags; @@ -2274,7 +2232,7 @@ elf_m68k_partition_multi_got_2 (struct elf_m68k_partition_multi_got_arg *arg) arg->n_slots += arg->current_got->n_slots[R_32]; - if (!arg->info->shared) + if (!bfd_link_pic (arg->info)) /* If we are generating a shared object, we need to output a R_68K_RELATIVE reloc so that the dynamic linker can adjust this GOT entry. Overwise we @@ -2468,7 +2426,7 @@ elf_m68k_partition_multi_got (struct bfd_link_info *info) { asection *s; - s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".got"); + s = bfd_get_linker_section (elf_hash_table (info)->dynobj, ".got"); if (s != NULL) s->size = arg_.offset; else @@ -2477,7 +2435,7 @@ elf_m68k_partition_multi_got (struct bfd_link_info *info) BFD_ASSERT (arg_.slots_relas_diff <= arg_.n_slots); arg_.n_slots -= arg_.slots_relas_diff; - s = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".rela.got"); + s = bfd_get_linker_section (elf_hash_table (info)->dynobj, ".rela.got"); if (s != NULL) s->size = arg_.n_slots * sizeof (Elf32_External_Rela); else @@ -2581,11 +2539,10 @@ elf_m68k_copy_indirect_symbol (struct bfd_link_info *info, table. */ static bfd_boolean -elf_m68k_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +elf_m68k_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { bfd *dynobj; Elf_Internal_Shdr *symtab_hdr; @@ -2597,7 +2554,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) asection *sreloc; struct elf_m68k_got *got; - if (info->relocatable) + if (bfd_link_relocatable (info)) return TRUE; dynobj = elf_hash_table (info)->dynobj; @@ -2626,6 +2583,10 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; + + /* PR15323, ref flags aren't set for references in the same + object. */ + h->root.non_ir_ref = 1; } switch (ELF32_R_TYPE (rel->r_info)) @@ -2659,7 +2620,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) case R_68K_TLS_DTPREL32: if (ELF32_R_TYPE (rel->r_info) == R_68K_TLS_TPREL32 - && info->shared) + && bfd_link_pic (info)) /* Do the special chorus for libraries with static TLS. */ info->flags |= DF_STATIC_TLS; @@ -2675,24 +2636,22 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) if (sgot == NULL) { - sgot = bfd_get_section_by_name (dynobj, ".got"); + sgot = bfd_get_linker_section (dynobj, ".got"); BFD_ASSERT (sgot != NULL); } if (srelgot == NULL - && (h != NULL || info->shared)) + && (h != NULL || bfd_link_pic (info))) { - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); + srelgot = bfd_get_linker_section (dynobj, ".rela.got"); if (srelgot == NULL) { - srelgot = bfd_make_section_with_flags (dynobj, - ".rela.got", - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY)); + flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS + | SEC_IN_MEMORY | SEC_LINKER_CREATED + | SEC_READONLY); + srelgot = bfd_make_section_anyway_with_flags (dynobj, + ".rela.got", + flags); if (srelgot == NULL || !bfd_set_section_alignment (dynobj, srelgot, 2)) return FALSE; @@ -2796,10 +2755,10 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) will be set later (it is never cleared). We account for that possibility below by storing information in the pcrel_relocs_copied field of the hash table entry. */ - if (!(info->shared + if (!(bfd_link_pic (info) && (sec->flags & SEC_ALLOC) != 0 && h != NULL - && (!info->symbolic + && (!SYMBOLIC_BIND (info, h) || h->root.type == bfd_link_hash_defweak || !h->def_regular))) { @@ -2827,14 +2786,14 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) turns out to be a function defined by a dynamic object. */ h->plt.refcount++; - if (!info->shared) + if (bfd_link_executable (info)) /* This symbol needs a non-GOT reference. */ h->non_got_ref = 1; } /* If we are creating a shared library, we need to copy the reloc into the shared library. */ - if (info->shared) + if (bfd_link_pic (info)) { /* When creating a shared object, we must copy these reloc types into the output file. We create a reloc @@ -2979,7 +2938,7 @@ elf_m68k_gc_sweep_hook (bfd *abfd, bfd *dynobj; struct elf_m68k_got *got; - if (info->relocatable) + if (bfd_link_relocatable (info)) return TRUE; dynobj = elf_hash_table (info)->dynobj; @@ -3130,9 +3089,8 @@ elf_m68k_always_size_sections (bfd *output_bfd, struct bfd_link_info *info) understand. */ static bfd_boolean -elf_m68k_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; +elf_m68k_adjust_dynamic_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) { struct elf_m68k_link_hash_table *htab; bfd *dynobj; @@ -3182,7 +3140,7 @@ elf_m68k_adjust_dynamic_symbol (info, h) return FALSE; } - s = bfd_get_section_by_name (dynobj, ".plt"); + s = bfd_get_linker_section (dynobj, ".plt"); BFD_ASSERT (s != NULL); /* If this is the first .plt entry, make room for the special @@ -3195,7 +3153,7 @@ elf_m68k_adjust_dynamic_symbol (info, h) location in the .plt. This is required to make function pointers compare as equal between the normal executable and the shared library. */ - if (!info->shared + if (!bfd_link_pic (info) && !h->def_regular) { h->root.u.def.section = s; @@ -3209,12 +3167,12 @@ elf_m68k_adjust_dynamic_symbol (info, h) /* We also need to make an entry in the .got.plt section, which will be placed in the .got section by the linker script. */ - s = bfd_get_section_by_name (dynobj, ".got.plt"); + s = bfd_get_linker_section (dynobj, ".got.plt"); BFD_ASSERT (s != NULL); s->size += 4; /* We also need to make an entry in the .rela.plt section. */ - s = bfd_get_section_by_name (dynobj, ".rela.plt"); + s = bfd_get_linker_section (dynobj, ".rela.plt"); BFD_ASSERT (s != NULL); s->size += sizeof (Elf32_External_Rela); @@ -3244,7 +3202,7 @@ elf_m68k_adjust_dynamic_symbol (info, h) only references to the symbol are via the global offset table. For such cases we need not do anything here; the relocations will be handled correctly by relocate_section. */ - if (info->shared) + if (bfd_link_pic (info)) return TRUE; /* If there are no references to this symbol that do not use the @@ -3262,7 +3220,7 @@ elf_m68k_adjust_dynamic_symbol (info, h) both the dynamic object and the regular object will refer to the same memory location for the variable. */ - s = bfd_get_section_by_name (dynobj, ".dynbss"); + s = bfd_get_linker_section (dynobj, ".dynbss"); BFD_ASSERT (s != NULL); /* We must generate a R_68K_COPY reloc to tell the dynamic linker to @@ -3273,21 +3231,20 @@ elf_m68k_adjust_dynamic_symbol (info, h) { asection *srel; - srel = bfd_get_section_by_name (dynobj, ".rela.bss"); + srel = bfd_get_linker_section (dynobj, ".rela.bss"); BFD_ASSERT (srel != NULL); srel->size += sizeof (Elf32_External_Rela); h->needs_copy = 1; } - return _bfd_elf_adjust_dynamic_copy (h, s); + return _bfd_elf_adjust_dynamic_copy (info, h, s); } /* Set the sizes of the dynamic sections. */ static bfd_boolean -elf_m68k_size_dynamic_sections (output_bfd, info) - bfd *output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; +elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info) { bfd *dynobj; asection *s; @@ -3300,9 +3257,9 @@ elf_m68k_size_dynamic_sections (output_bfd, info) if (elf_hash_table (info)->dynamic_sections_created) { /* Set the contents of the .interp section to the interpreter. */ - if (info->executable) + if (bfd_link_executable (info)) { - s = bfd_get_section_by_name (dynobj, ".interp"); + s = bfd_get_linker_section (dynobj, ".interp"); BFD_ASSERT (s != NULL); s->size = sizeof ELF_DYNAMIC_INTERPRETER; s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; @@ -3315,7 +3272,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info) not actually use these entries. Reset the size of .rela.got, which will cause it to get stripped from the output file below. */ - s = bfd_get_section_by_name (dynobj, ".rela.got"); + s = bfd_get_linker_section (dynobj, ".rela.got"); if (s != NULL) s->size = 0; } @@ -3326,10 +3283,10 @@ elf_m68k_size_dynamic_sections (output_bfd, info) against symbols that have become local due to visibility changes. We allocated space for them in the check_relocs routine, but we will not fill them in in the relocate_section routine. */ - if (info->shared) + if (bfd_link_pic (info)) elf_link_hash_traverse (elf_hash_table (info), elf_m68k_discard_copies, - (PTR) info); + info); /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate @@ -3409,7 +3366,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info) #define add_dynamic_entry(TAG, VAL) \ _bfd_elf_add_dynamic_entry (info, TAG, VAL) - if (!info->shared) + if (bfd_link_executable (info)) { if (!add_dynamic_entry (DT_DEBUG, 0)) return FALSE; @@ -3457,9 +3414,8 @@ elf_m68k_size_dynamic_sections (output_bfd, info) case. */ static bfd_boolean -elf_m68k_discard_copies (h, inf) - struct elf_link_hash_entry *h; - PTR inf; +elf_m68k_discard_copies (struct elf_link_hash_entry *h, + void * inf) { struct bfd_link_info *info = (struct bfd_link_info *) inf; struct elf_m68k_pcrel_relocs_copied *s; @@ -3479,6 +3435,18 @@ elf_m68k_discard_copies (h, inf) } } + /* Make sure undefined weak symbols are output as a dynamic symbol + in PIEs. */ + if (h->non_got_ref + && h->root.type == bfd_link_hash_undefweak + && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + && h->dynindx == -1 + && !h->forced_local) + { + if (! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } + return TRUE; } @@ -3632,16 +3600,14 @@ elf_m68k_init_got_entry_local_shared (struct bfd_link_info *info, /* Relocate an M68K ELF section. */ static bfd_boolean -elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +elf_m68k_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { bfd *dynobj; Elf_Internal_Shdr *symtab_hdr; @@ -3702,19 +3668,19 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, } else { - bfd_boolean warned; + bfd_boolean warned, ignored; RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, r_symndx, symtab_hdr, sym_hashes, h, sec, relocation, - unresolved_reloc, warned); + unresolved_reloc, warned, ignored); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, - rel, relend, howto, contents); + rel, 1, relend, howto, 0, contents); - if (info->relocatable) + if (bfd_link_relocatable (info)) continue; switch (r_type) @@ -3734,7 +3700,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, if (sgot == NULL) { - sgot = bfd_get_section_by_name (dynobj, ".got"); + sgot = bfd_get_linker_section (dynobj, ".got"); if (sgot != NULL) sgot_output_offset = sgot->output_offset; @@ -3809,7 +3775,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, if (sgot == NULL) { - sgot = bfd_get_section_by_name (dynobj, ".got"); + sgot = bfd_get_linker_section (dynobj, ".got"); BFD_ASSERT (sgot != NULL); } @@ -3844,8 +3810,10 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, bfd_boolean dyn; dyn = elf_hash_table (info)->dynamic_sections_created; - if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) - || (info->shared + if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, + bfd_link_pic (info), + h) + || (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h)) || (ELF_ST_VISIBILITY (h->other) && h->root.type == bfd_link_hash_undefweak)) @@ -3875,12 +3843,12 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, else unresolved_reloc = FALSE; } - else if (info->shared) /* && h == NULL */ + else if (bfd_link_pic (info)) /* && h == NULL */ /* Process local symbol during dynamic link. */ { if (srela == NULL) { - srela = bfd_get_section_by_name (dynobj, ".rela.got"); + srela = bfd_get_linker_section (dynobj, ".rela.got"); BFD_ASSERT (srela != NULL); } @@ -3894,7 +3862,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, *off_ptr |= 1; } - else /* h == NULL && !info->shared */ + else /* h == NULL && !bfd_link_pic (info) */ { elf_m68k_init_got_entry_static (info, output_bfd, @@ -3948,7 +3916,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, case R_68K_TLS_LE32: case R_68K_TLS_LE16: case R_68K_TLS_LE8: - if (info->shared && !info->pie) + if (bfd_link_dll (info)) { (*_bfd_error_handler) (_("%B(%A+0x%lx): R_68K_TLS_LE32 relocation not permitted " @@ -3984,7 +3952,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, if (splt == NULL) { - splt = bfd_get_section_by_name (dynobj, ".plt"); + splt = bfd_get_linker_section (dynobj, ".plt"); BFD_ASSERT (splt != NULL); } @@ -4003,7 +3971,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, if (splt == NULL) { - splt = bfd_get_section_by_name (dynobj, ".plt"); + splt = bfd_get_linker_section (dynobj, ".plt"); BFD_ASSERT (splt != NULL); } @@ -4021,7 +3989,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, case R_68K_PC8: case R_68K_PC16: case R_68K_PC32: - if (info->shared + if (bfd_link_pic (info) && r_symndx != STN_UNDEF && (input_section->flags & SEC_ALLOC) != 0 && (h == NULL @@ -4060,8 +4028,8 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, && (r_type == R_68K_PC8 || r_type == R_68K_PC16 || r_type == R_68K_PC32 - || !info->shared - || !info->symbolic + || !bfd_link_pic (info) + || !SYMBOLIC_BIND (info, h) || !h->def_regular)) { outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); @@ -4257,11 +4225,10 @@ elf_m68k_install_pc32 (asection *sec, bfd_vma offset, bfd_vma value) dynamic sections here. */ static bfd_boolean -elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +elf_m68k_finish_dynamic_symbol (bfd *output_bfd, + struct bfd_link_info *info, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { bfd *dynobj; @@ -4284,9 +4251,9 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) BFD_ASSERT (h->dynindx != -1); plt_info = elf_m68k_hash_table (info)->plt_info; - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - srela = bfd_get_section_by_name (dynobj, ".rela.plt"); + splt = bfd_get_linker_section (dynobj, ".plt"); + sgot = bfd_get_linker_section (dynobj, ".got.plt"); + srela = bfd_get_linker_section (dynobj, ".rela.plt"); BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL); /* Get the index in the procedure linkage table which @@ -4351,8 +4318,8 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) /* This symbol has an entry in the global offset table. Set it up. */ - sgot = bfd_get_section_by_name (dynobj, ".got"); - srela = bfd_get_section_by_name (dynobj, ".rela.got"); + sgot = bfd_get_linker_section (dynobj, ".got"); + srela = bfd_get_linker_section (dynobj, ".rela.got"); BFD_ASSERT (sgot != NULL && srela != NULL); got_entry = elf_m68k_hash_entry (h)->glist; @@ -4370,7 +4337,7 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) the symbol was forced to be local because of a version file. The entry in the global offset table already have been initialized in the relocate_section function. */ - if (info->shared + if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h)) { bfd_vma relocation; @@ -4475,8 +4442,7 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) && (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak)); - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rela.bss"); + s = bfd_get_linker_section (dynobj, ".rela.bss"); BFD_ASSERT (s != NULL); rela.r_offset = (h->root.u.def.value @@ -4488,20 +4454,13 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); } - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || h == elf_hash_table (info)->hgot) - sym->st_shndx = SHN_ABS; - return TRUE; } /* Finish up the dynamic sections. */ static bfd_boolean -elf_m68k_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; +elf_m68k_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) { bfd *dynobj; asection *sgot; @@ -4509,16 +4468,16 @@ elf_m68k_finish_dynamic_sections (output_bfd, info) dynobj = elf_hash_table (info)->dynobj; - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); + sgot = bfd_get_linker_section (dynobj, ".got.plt"); BFD_ASSERT (sgot != NULL); - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); + sdyn = bfd_get_linker_section (dynobj, ".dynamic"); if (elf_hash_table (info)->dynamic_sections_created) { asection *splt; Elf32_External_Dyn *dyncon, *dynconend; - splt = bfd_get_section_by_name (dynobj, ".plt"); + splt = bfd_get_linker_section (dynobj, ".plt"); BFD_ASSERT (splt != NULL && sdyn != NULL); dyncon = (Elf32_External_Dyn *) sdyn->contents; @@ -4634,7 +4593,7 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) bfd_byte *p; bfd_size_type amt; - BFD_ASSERT (! info->relocatable); + BFD_ASSERT (! bfd_link_relocatable (info)); *errmsg = NULL; @@ -4645,7 +4604,7 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) /* Get a copy of the native relocations. */ internal_relocs = (_bfd_elf_link_read_relocs - (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL, + (abfd, datasec, NULL, (Elf_Internal_Rela *) NULL, info->keep_memory)); if (internal_relocs == NULL) goto error_return; @@ -4783,8 +4742,9 @@ bfd_elf_m68k_set_target_options (struct bfd_link_info *info, int got_handling) } static enum elf_reloc_type_class -elf32_m68k_reloc_type_class (rela) - const Elf_Internal_Rela *rela; +elf32_m68k_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, + const asection *rel_sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela *rela) { switch ((int) ELF32_R_TYPE (rela->r_info)) { @@ -4809,7 +4769,91 @@ elf_m68k_plt_sym_val (bfd_vma i, const asection *plt, return plt->vma + (i + 1) * elf_m68k_get_plt_info (plt->owner)->size; } -#define TARGET_BIG_SYM bfd_elf32_m68k_vec +/* Support for core dump NOTE sections. */ + +static bfd_boolean +elf_m68k_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) +{ + int offset; + size_t size; + + switch (note->descsz) + { + default: + return FALSE; + + case 154: /* Linux/m68k */ + /* pr_cursig */ + elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12); + + /* pr_pid */ + elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 22); + + /* pr_reg */ + offset = 70; + size = 80; + + break; + } + + /* Make a ".reg/999" section. */ + return _bfd_elfcore_make_pseudosection (abfd, ".reg", + size, note->descpos + offset); +} + +static bfd_boolean +elf_m68k_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) +{ + switch (note->descsz) + { + default: + return FALSE; + + case 124: /* Linux/m68k elf_prpsinfo. */ + elf_tdata (abfd)->core->pid + = bfd_get_32 (abfd, note->descdata + 12); + elf_tdata (abfd)->core->program + = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); + elf_tdata (abfd)->core->command + = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); + } + + /* Note that for some reason, a spurious space is tacked + onto the end of the args in some (at least one anyway) + implementations, so strip it off if it exists. */ + { + char *command = elf_tdata (abfd)->core->command; + int n = strlen (command); + + if (n > 0 && command[n - 1] == ' ') + command[n - 1] = '\0'; + } + + return TRUE; +} + +/* Hook called by the linker routine which adds symbols from an object + file. */ + +static bfd_boolean +elf_m68k_add_symbol_hook (bfd *abfd, + struct bfd_link_info *info, + Elf_Internal_Sym *sym, + const char **namep ATTRIBUTE_UNUSED, + flagword *flagsp ATTRIBUTE_UNUSED, + asection **secp ATTRIBUTE_UNUSED, + bfd_vma *valp ATTRIBUTE_UNUSED) +{ + if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC + || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE) + && (abfd->flags & DYNAMIC) == 0 + && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour) + elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any; + + return TRUE; +} + +#define TARGET_BIG_SYM m68k_elf32_vec #define TARGET_BIG_NAME "elf32-m68k" #define ELF_MACHINE_CODE EM_68K #define ELF_MAXPAGESIZE 0x2000 @@ -4817,9 +4861,6 @@ elf_m68k_plt_sym_val (bfd_vma i, const asection *plt, _bfd_elf_create_dynamic_sections #define bfd_elf32_bfd_link_hash_table_create \ elf_m68k_link_hash_table_create -/* ??? Should it be this macro or bfd_elfNN_bfd_link_hash_table_create? */ -#define bfd_elf32_bfd_link_hash_table_free \ - elf_m68k_link_hash_table_free #define bfd_elf32_bfd_final_link bfd_elf_final_link #define elf_backend_check_relocs elf_m68k_check_relocs @@ -4848,6 +4889,9 @@ elf_m68k_plt_sym_val (bfd_vma i, const asection *plt, #define elf_backend_reloc_type_class elf32_m68k_reloc_type_class #define elf_backend_plt_sym_val elf_m68k_plt_sym_val #define elf_backend_object_p elf32_m68k_object_p +#define elf_backend_grok_prstatus elf_m68k_grok_prstatus +#define elf_backend_grok_psinfo elf_m68k_grok_psinfo +#define elf_backend_add_symbol_hook elf_m68k_add_symbol_hook #define elf_backend_can_gc_sections 1 #define elf_backend_can_refcount 1