X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-m68k.c;h=fc3a2af74412ce51c83161a904ebb5ce1ec9267a;hb=44f745a6a20873edb88c82c8b587da6149089e5d;hp=a8b5c6e51be7f33a055a5d14783ad8d71a2922f9;hpb=947216bf8f343c1440e85633b5bf2f2394f87bc4;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index a8b5c6e51b..fc3a2af744 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -1,22 +1,22 @@ /* Motorola 68k series support for 32-bit ELF - Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" @@ -33,89 +33,91 @@ 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 boolean elf_m68k_check_relocs +static bfd_boolean elf_m68k_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection *elf_m68k_gc_mark_hook PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static boolean elf_m68k_gc_sweep_hook +static bfd_boolean elf_m68k_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); -static boolean elf_m68k_adjust_dynamic_symbol +static bfd_boolean elf_m68k_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf_m68k_size_dynamic_sections +static bfd_boolean elf_m68k_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_m68k_relocate_section +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 boolean elf_m68k_finish_dynamic_symbol +static bfd_boolean elf_m68k_finish_dynamic_symbol PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static boolean elf_m68k_finish_dynamic_sections +static bfd_boolean elf_m68k_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf32_m68k_set_private_flags +static bfd_boolean elf32_m68k_set_private_flags PARAMS ((bfd *, flagword)); -static boolean elf32_m68k_merge_private_bfd_data +static bfd_boolean elf32_m68k_merge_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean elf32_m68k_print_private_bfd_data +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), - 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), - HOWTO(R_68K_PC32, 0, 2,32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PC32", false, 0, 0xffffffff,true), - HOWTO(R_68K_PC16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC16", false, 0, 0x0000ffff,true), - HOWTO(R_68K_PC8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC8", false, 0, 0x000000ff,true), - HOWTO(R_68K_GOT32, 0, 2,32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32", false, 0, 0xffffffff,true), - HOWTO(R_68K_GOT16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16", false, 0, 0x0000ffff,true), - HOWTO(R_68K_GOT8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8", false, 0, 0x000000ff,true), - HOWTO(R_68K_GOT32O, 0, 2,32, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32O", false, 0, 0xffffffff,false), - HOWTO(R_68K_GOT16O, 0, 1,16, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16O", false, 0, 0x0000ffff,false), - HOWTO(R_68K_GOT8O, 0, 0, 8, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8O", false, 0, 0x000000ff,false), - HOWTO(R_68K_PLT32, 0, 2,32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32", false, 0, 0xffffffff,true), - HOWTO(R_68K_PLT16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16", false, 0, 0x0000ffff,true), - HOWTO(R_68K_PLT8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8", false, 0, 0x000000ff,true), - HOWTO(R_68K_PLT32O, 0, 2,32, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32O", false, 0, 0xffffffff,false), - HOWTO(R_68K_PLT16O, 0, 1,16, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16O", false, 0, 0x0000ffff,false), - HOWTO(R_68K_PLT8O, 0, 0, 8, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8O", false, 0, 0x000000ff,false), - HOWTO(R_68K_COPY, 0, 0, 0, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_COPY", false, 0, 0xffffffff,false), - HOWTO(R_68K_GLOB_DAT, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_GLOB_DAT", false, 0, 0xffffffff,false), - HOWTO(R_68K_JMP_SLOT, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_JMP_SLOT", false, 0, 0xffffffff,false), - HOWTO(R_68K_RELATIVE, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_RELATIVE", false, 0, 0xffffffff,false), - /* GNU extension to record C++ vtable hierarchy */ + HOWTO(R_68K_NONE, 0, 0, 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), + HOWTO(R_68K_PC32, 0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PC32", FALSE, 0, 0xffffffff,TRUE), + HOWTO(R_68K_PC16, 0, 1,16, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC16", FALSE, 0, 0x0000ffff,TRUE), + HOWTO(R_68K_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC8", FALSE, 0, 0x000000ff,TRUE), + HOWTO(R_68K_GOT32, 0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32", FALSE, 0, 0xffffffff,TRUE), + HOWTO(R_68K_GOT16, 0, 1,16, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16", FALSE, 0, 0x0000ffff,TRUE), + HOWTO(R_68K_GOT8, 0, 0, 8, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8", FALSE, 0, 0x000000ff,TRUE), + HOWTO(R_68K_GOT32O, 0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_GOT32O", FALSE, 0, 0xffffffff,FALSE), + HOWTO(R_68K_GOT16O, 0, 1,16, FALSE,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16O", FALSE, 0, 0x0000ffff,FALSE), + HOWTO(R_68K_GOT8O, 0, 0, 8, FALSE,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8O", FALSE, 0, 0x000000ff,FALSE), + HOWTO(R_68K_PLT32, 0, 2,32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32", FALSE, 0, 0xffffffff,TRUE), + HOWTO(R_68K_PLT16, 0, 1,16, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16", FALSE, 0, 0x0000ffff,TRUE), + HOWTO(R_68K_PLT8, 0, 0, 8, TRUE, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8", FALSE, 0, 0x000000ff,TRUE), + HOWTO(R_68K_PLT32O, 0, 2,32, FALSE,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_PLT32O", FALSE, 0, 0xffffffff,FALSE), + HOWTO(R_68K_PLT16O, 0, 1,16, FALSE,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16O", FALSE, 0, 0x0000ffff,FALSE), + HOWTO(R_68K_PLT8O, 0, 0, 8, FALSE,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8O", FALSE, 0, 0x000000ff,FALSE), + HOWTO(R_68K_COPY, 0, 0, 0, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_COPY", FALSE, 0, 0xffffffff,FALSE), + HOWTO(R_68K_GLOB_DAT, 0, 2,32, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_GLOB_DAT", FALSE, 0, 0xffffffff,FALSE), + HOWTO(R_68K_JMP_SLOT, 0, 2,32, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_JMP_SLOT", FALSE, 0, 0xffffffff,FALSE), + HOWTO(R_68K_RELATIVE, 0, 2,32, FALSE,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_RELATIVE", FALSE, 0, 0xffffffff,FALSE), + /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_68K_GNU_VTINHERIT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ NULL, /* special_function */ "R_68K_GNU_VTINHERIT", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ - false), - /* GNU extension to record C++ vtable member usage */ + FALSE), + /* GNU extension to record C++ vtable member usage. */ HOWTO (R_68K_GNU_VTENTRY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 0, /* bitsize */ - false, /* pc_relative */ + FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ _bfd_elf_rel_vtable_reloc_fn, /* special_function */ "R_68K_GNU_VTENTRY", /* name */ - false, /* partial_inplace */ + FALSE, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ - false), + FALSE), }; static void @@ -179,7 +181,6 @@ reloc_type_lookup (abfd, code) #define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup #define ELF_ARCH bfd_arch_m68k -/* end code generated by elf.el */ /* Functions for the m68k ELF linker. */ @@ -272,25 +273,17 @@ struct elf_m68k_link_hash_entry struct elf_m68k_pcrel_relocs_copied *pcrel_relocs_copied; }; +#define elf_m68k_hash_entry(ent) ((struct elf_m68k_link_hash_entry *) (ent)) + /* m68k ELF linker hash table. */ struct elf_m68k_link_hash_table { struct elf_link_hash_table root; -}; - -/* Declare this now that the above structures are defined. */ - -static boolean elf_m68k_discard_copies - PARAMS ((struct elf_m68k_link_hash_entry *, PTR)); -/* Traverse an m68k ELF linker hash table. */ - -#define elf_m68k_link_hash_traverse(table, func, info) \ - (elf_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ - (info))) + /* Small local sym to section mapping cache. */ + struct sym_sec_cache sym_sec; +}; /* Get the m68k ELF linker hash table from a link_info structure. */ @@ -305,28 +298,22 @@ elf_m68k_link_hash_newfunc (entry, table, string) struct bfd_hash_table *table; const char *string; { - struct elf_m68k_link_hash_entry *ret = - (struct elf_m68k_link_hash_entry *) entry; + struct bfd_hash_entry *ret = entry; /* Allocate the structure if it has not already been allocated by a subclass. */ - if (ret == (struct elf_m68k_link_hash_entry *) NULL) - ret = ((struct elf_m68k_link_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct elf_m68k_link_hash_entry))); - if (ret == (struct elf_m68k_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; + if (ret == NULL) + ret = bfd_hash_allocate (table, + sizeof (struct elf_m68k_link_hash_entry)); + if (ret == NULL) + return ret; /* Call the allocation method of the superclass. */ - ret = ((struct elf_m68k_link_hash_entry *) - _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != (struct elf_m68k_link_hash_entry *) NULL) - { - ret->pcrel_relocs_copied = NULL; - } + ret = _bfd_elf_link_hash_newfunc (ret, table, string); + if (ret != NULL) + elf_m68k_hash_entry (ret)->pcrel_relocs_copied = NULL; - return (struct bfd_hash_entry *) ret; + return ret; } /* Create an m68k ELF linker hash table. */ @@ -349,23 +336,25 @@ elf_m68k_link_hash_table_create (abfd) return NULL; } + ret->sym_sec.abfd = NULL; + return &ret->root.root; } -/* Keep m68k-specific flags in the ELF header */ -static boolean +/* Keep m68k-specific flags in the ELF header. */ +static bfd_boolean elf32_m68k_set_private_flags (abfd, flags) bfd *abfd; flagword flags; { elf_elfheader (abfd)->e_flags = flags; - elf_flags_init (abfd) = true; - return true; + elf_flags_init (abfd) = TRUE; + return TRUE; } /* Merge backend specific data from an object file to the output object file when linking. */ -static boolean +static bfd_boolean elf32_m68k_merge_private_bfd_data (ibfd, obfd) bfd *ibfd; bfd *obfd; @@ -375,22 +364,22 @@ elf32_m68k_merge_private_bfd_data (ibfd, obfd) if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; + return TRUE; in_flags = elf_elfheader (ibfd)->e_flags; out_flags = elf_elfheader (obfd)->e_flags; if (!elf_flags_init (obfd)) { - elf_flags_init (obfd) = true; + elf_flags_init (obfd) = TRUE; elf_elfheader (obfd)->e_flags = in_flags; } - return true; + return TRUE; } -/* Display the flags field */ -static boolean +/* Display the flags field. */ +static bfd_boolean elf32_m68k_print_private_bfd_data (abfd, ptr) bfd *abfd; PTR ptr; @@ -415,13 +404,13 @@ elf32_m68k_print_private_bfd_data (abfd, ptr) fputc ('\n', file); - return true; + return TRUE; } /* Look through the relocs for a section during the first phase, and allocate space in the global offset table or procedure linkage table. */ -static boolean +static bfd_boolean elf_m68k_check_relocs (abfd, info, sec, relocs) bfd *abfd; struct bfd_link_info *info; @@ -439,7 +428,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) asection *sreloc; if (info->relocateable) - return true; + return TRUE; dynobj = elf_hash_table (info)->dynobj; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; @@ -482,7 +471,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) /* Create the .got section. */ elf_hash_table (info)->dynobj = dynobj = abfd; if (!_bfd_elf_create_got_section (dynobj, info)) - return false; + return FALSE; } if (sgot == NULL) @@ -507,7 +496,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) | SEC_LINKER_CREATED | SEC_READONLY)) || !bfd_set_section_alignment (dynobj, srelgot, 2)) - return false; + return FALSE; } } @@ -516,10 +505,11 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) if (h->got.refcount == 0) { /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { if (!bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; + return FALSE; } /* Allocate space in the .got section. */ @@ -541,7 +531,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) local_got_refcounts = ((bfd_signed_vma *) bfd_zalloc (abfd, size)); if (local_got_refcounts == NULL) - return false; + return FALSE; elf_local_got_refcounts (abfd) = local_got_refcounts; } if (local_got_refcounts[r_symndx] == 0) @@ -589,14 +579,15 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) local symbol. FIXME: does it? How to handle it if it does make sense? */ bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { if (!bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; + return FALSE; } h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; @@ -620,6 +611,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) && (sec->flags & SEC_ALLOC) != 0 && h != NULL && (!info->symbolic + || h->root.type == bfd_link_hash_defweak || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0))) { @@ -660,7 +652,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) elf_elfheader (abfd)->e_shstrndx, elf_section_data (sec)->rel_hdr.sh_name)); if (name == NULL) - return false; + return FALSE; BFD_ASSERT (strncmp (name, ".rela", 5) == 0 && strcmp (bfd_get_section_name (abfd, sec), @@ -679,32 +671,55 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) | SEC_LINKER_CREATED | SEC_READONLY)) || !bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; + return FALSE; } - if (sec->flags & SEC_READONLY) - info->flags |= DF_TEXTREL; } + if (sec->flags & SEC_READONLY + /* Don't set DF_TEXTREL yet for PC relative + relocations, they might be discarded later. */ + && !(ELF32_R_TYPE (rel->r_info) == R_68K_PC8 + || ELF32_R_TYPE (rel->r_info) == R_68K_PC16 + || ELF32_R_TYPE (rel->r_info) == R_68K_PC32)) + info->flags |= DF_TEXTREL; + sreloc->_raw_size += sizeof (Elf32_External_Rela); - /* If we are linking with -Bsymbolic, we count the number of - PC relative relocations we have entered for this symbol, - so that we can discard them again if the symbol is later - defined by a regular object. Note that this function is - only called if we are using an m68kelf linker hash table, - which means that h is really a pointer to an + /* We count the number of PC relative relocations we have + entered for this symbol, so that we can discard them + again if, in the -Bsymbolic case, the symbol is later + defined by a regular object, or, in the normal shared + case, the symbol is forced to be local. Note that this + function is only called if we are using an m68kelf linker + hash table, which means that h is really a pointer to an elf_m68k_link_hash_entry. */ - if ((ELF32_R_TYPE (rel->r_info) == R_68K_PC8 - || ELF32_R_TYPE (rel->r_info) == R_68K_PC16 - || ELF32_R_TYPE (rel->r_info) == R_68K_PC32) - && info->symbolic) + if (ELF32_R_TYPE (rel->r_info) == R_68K_PC8 + || ELF32_R_TYPE (rel->r_info) == R_68K_PC16 + || ELF32_R_TYPE (rel->r_info) == R_68K_PC32) { - struct elf_m68k_link_hash_entry *eh; struct elf_m68k_pcrel_relocs_copied *p; + struct elf_m68k_pcrel_relocs_copied **head; - eh = (struct elf_m68k_link_hash_entry *) h; + if (h != NULL) + { + struct elf_m68k_link_hash_entry *eh + = elf_m68k_hash_entry (h); + head = &eh->pcrel_relocs_copied; + } + else + { + asection *s; + s = (bfd_section_from_r_symndx + (abfd, &elf_m68k_hash_table (info)->sym_sec, + sec, r_symndx)); + if (s == NULL) + return FALSE; + + head = ((struct elf_m68k_pcrel_relocs_copied **) + &elf_section_data (s)->local_dynrel); + } - for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next) + for (p = *head; p != NULL; p = p->next) if (p->section == sreloc) break; @@ -713,9 +728,9 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) p = ((struct elf_m68k_pcrel_relocs_copied *) bfd_alloc (dynobj, (bfd_size_type) sizeof *p)); if (p == NULL) - return false; - p->next = eh->pcrel_relocs_copied; - eh->pcrel_relocs_copied = p; + return FALSE; + p->next = *head; + *head = p; p->section = sreloc; p->count = 0; } @@ -730,14 +745,14 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) Reconstruct it for later use during GC. */ case R_68K_GNU_VTINHERIT: if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) - return false; + return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_68K_GNU_VTENTRY: if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) - return false; + return FALSE; break; default: @@ -745,7 +760,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) } } - return true; + return TRUE; } /* Return the section that should be marked against GC for a given @@ -790,7 +805,7 @@ elf_m68k_gc_mark_hook (sec, info, rel, h, sym) /* Update the got entry reference counts for the section being removed. */ -static boolean +static bfd_boolean elf_m68k_gc_sweep_hook (abfd, info, sec, relocs) bfd *abfd; struct bfd_link_info *info; @@ -813,7 +828,7 @@ elf_m68k_gc_sweep_hook (abfd, info, sec, relocs) dynobj = elf_hash_table (info)->dynobj; if (dynobj == NULL) - return true; + return TRUE; sgot = bfd_get_section_by_name (dynobj, ".got"); srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); @@ -886,7 +901,7 @@ elf_m68k_gc_sweep_hook (abfd, info, sec, relocs) } } - return true; + return TRUE; } /* Adjust a symbol defined by a dynamic object and referenced by a @@ -895,7 +910,7 @@ elf_m68k_gc_sweep_hook (abfd, info, sec, relocs) change the definition to something the rest of the link can understand. */ -static boolean +static bfd_boolean elf_m68k_adjust_dynamic_symbol (info, h) struct bfd_link_info *info; struct elf_link_hash_entry *h; @@ -938,7 +953,7 @@ elf_m68k_adjust_dynamic_symbol (info, h) reloc instead. */ BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); h->plt.offset = (bfd_vma) -1; - return true; + return TRUE; } /* GC may have rendered this entry unused. */ @@ -946,14 +961,15 @@ elf_m68k_adjust_dynamic_symbol (info, h) { h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; h->plt.offset = (bfd_vma) -1; - return true; + return TRUE; } /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; + return FALSE; } s = bfd_get_section_by_name (dynobj, ".plt"); @@ -991,18 +1007,16 @@ 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"); BFD_ASSERT (s != NULL); s->_raw_size += 4; /* We also need to make an entry in the .rela.plt section. */ - s = bfd_get_section_by_name (dynobj, ".rela.plt"); BFD_ASSERT (s != NULL); s->_raw_size += sizeof (Elf32_External_Rela); - return true; + return TRUE; } /* Reinitialize the plt offset now that it is not used as a reference @@ -1018,7 +1032,7 @@ elf_m68k_adjust_dynamic_symbol (info, h) || h->weakdef->root.type == bfd_link_hash_defweak); h->root.u.def.section = h->weakdef->root.u.def.section; h->root.u.def.value = h->weakdef->root.u.def.value; - return true; + return TRUE; } /* This is a reference to a symbol defined by a dynamic object which @@ -1029,7 +1043,7 @@ elf_m68k_adjust_dynamic_symbol (info, h) For such cases we need not do anything here; the relocations will be handled correctly by relocate_section. */ if (info->shared) - return true; + return TRUE; /* We must allocate the symbol in our .dynbss section, which will become part of the .bss section of the executable. There will be @@ -1070,7 +1084,7 @@ elf_m68k_adjust_dynamic_symbol (info, h) if (power_of_two > bfd_get_section_alignment (dynobj, s)) { if (!bfd_set_section_alignment (dynobj, s, power_of_two)) - return false; + return FALSE; } /* Define the symbol as being at this point in the section. */ @@ -1080,20 +1094,31 @@ elf_m68k_adjust_dynamic_symbol (info, h) /* Increment the section size to make room for the symbol. */ s->_raw_size += h->size; - return true; + return TRUE; } +/* This is the condition under which elf_m68k_finish_dynamic_symbol + will be called from elflink.h. If elflink.h doesn't call our + finish_dynamic_symbol routine, we'll need to do something about + initializing any .plt and .got entries in elf_m68k_relocate_section. */ +#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ + ((DYN) \ + && ((SHARED) \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ + && ((H)->dynindx != -1 \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) + /* Set the sizes of the dynamic sections. */ -static boolean +static bfd_boolean elf_m68k_size_dynamic_sections (output_bfd, info) bfd *output_bfd ATTRIBUTE_UNUSED; struct bfd_link_info *info; { bfd *dynobj; asection *s; - boolean plt; - boolean relocs; + bfd_boolean plt; + bfd_boolean relocs; dynobj = elf_hash_table (info)->dynobj; BFD_ASSERT (dynobj != NULL); @@ -1121,24 +1146,26 @@ elf_m68k_size_dynamic_sections (output_bfd, info) s->_raw_size = 0; } - /* If this is a -Bsymbolic shared link, then we need to discard all PC - relative relocs against symbols defined in a regular object. 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 && info->symbolic) - elf_m68k_link_hash_traverse (elf_m68k_hash_table (info), - elf_m68k_discard_copies, - (PTR) NULL); + /* If this is a -Bsymbolic shared link, then we need to discard all + PC relative relocs against symbols defined in a regular object. + For the normal shared case we discard the PC relative relocs + 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) + elf_link_hash_traverse (elf_hash_table (info), + elf_m68k_discard_copies, + (PTR) info); /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate memory for them. */ - plt = false; - relocs = false; + plt = FALSE; + relocs = FALSE; for (s = dynobj->sections; s != NULL; s = s->next) { const char *name; - boolean strip; + bfd_boolean strip; if ((s->flags & SEC_LINKER_CREATED) == 0) continue; @@ -1147,7 +1174,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info) of the dynobj section names depend upon the input files. */ name = bfd_get_section_name (dynobj, s); - strip = false; + strip = FALSE; if (strcmp (name, ".plt") == 0) { @@ -1155,12 +1182,12 @@ elf_m68k_size_dynamic_sections (output_bfd, info) { /* Strip this section if we don't need it; see the comment below. */ - strip = true; + strip = TRUE; } else { /* Remember whether there is a PLT. */ - plt = true; + plt = TRUE; } } else if (strncmp (name, ".rela", 5) == 0) @@ -1176,11 +1203,11 @@ elf_m68k_size_dynamic_sections (output_bfd, info) adjust_dynamic_symbol is called, and it is that function which decides whether anything needs to go into these sections. */ - strip = true; + strip = TRUE; } else { - relocs = true; + relocs = TRUE; /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ @@ -1207,7 +1234,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info) contents to zero. */ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); if (s->contents == NULL && s->_raw_size != 0) - return false; + return FALSE; } if (elf_hash_table (info)->dynamic_sections_created) @@ -1223,7 +1250,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info) if (!info->shared) { if (!add_dynamic_entry (DT_DEBUG, 0)) - return false; + return FALSE; } if (plt) @@ -1232,7 +1259,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info) || !add_dynamic_entry (DT_PLTRELSZ, 0) || !add_dynamic_entry (DT_PLTREL, DT_RELA) || !add_dynamic_entry (DT_JMPREL, 0)) - return false; + return FALSE; } if (relocs) @@ -1240,49 +1267,75 @@ elf_m68k_size_dynamic_sections (output_bfd, info) if (!add_dynamic_entry (DT_RELA, 0) || !add_dynamic_entry (DT_RELASZ, 0) || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - return false; + return FALSE; } if ((info->flags & DF_TEXTREL) != 0) { if (!add_dynamic_entry (DT_TEXTREL, 0)) - return false; + return FALSE; } } #undef add_dynamic_entry - return true; + return TRUE; } -/* This function is called via elf_m68k_link_hash_traverse if we are - creating a shared object with -Bsymbolic. It discards the space - allocated to copy PC relative relocs against symbols which are defined - in regular objects. We allocated space for them in the check_relocs - routine, but we won't fill them in in the relocate_section routine. */ - -static boolean -elf_m68k_discard_copies (h, ignore) - struct elf_m68k_link_hash_entry *h; - PTR ignore ATTRIBUTE_UNUSED; +/* This function is called via elf_link_hash_traverse if we are + creating a shared object. In the -Bsymbolic case it discards the + space allocated to copy PC relative relocs against symbols which + are defined in regular objects. For the normal shared case, it + discards space for pc-relative relocs that have become local due to + symbol visibility changes. We allocated space for them in the + check_relocs routine, but we won't fill them in in the + relocate_section routine. + + We also check whether any of the remaining relocations apply + against a readonly section, and set the DF_TEXTREL flag in this + case. */ + +static bfd_boolean +elf_m68k_discard_copies (h, inf) + struct elf_link_hash_entry *h; + PTR inf; { + struct bfd_link_info *info = (struct bfd_link_info *) inf; struct elf_m68k_pcrel_relocs_copied *s; - if (h->root.root.type == bfd_link_hash_warning) - h = (struct elf_m68k_link_hash_entry *) h->root.root.u.i.link; + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; - /* We only discard relocs for symbols defined in a regular object. */ - if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - return true; + if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 + || (!info->symbolic + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)) + { + if ((info->flags & DF_TEXTREL) == 0) + { + /* Look for relocations against read-only sections. */ + for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied; + s != NULL; + s = s->next) + if ((s->section->flags & SEC_READONLY) != 0) + { + info->flags |= DF_TEXTREL; + break; + } + } - for (s = h->pcrel_relocs_copied; s != NULL; s = s->next) + return TRUE; + } + + for (s = elf_m68k_hash_entry (h)->pcrel_relocs_copied; + s != NULL; + s = s->next) s->section->_raw_size -= s->count * sizeof (Elf32_External_Rela); - return true; + return TRUE; } /* Relocate an M68K ELF section. */ -static boolean +static bfd_boolean elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, local_syms, local_sections) bfd *output_bfd; @@ -1305,7 +1358,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, Elf_Internal_Rela *relend; if (info->relocateable) - return true; + return TRUE; dynobj = elf_hash_table (info)->dynobj; symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; @@ -1327,13 +1380,14 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, Elf_Internal_Sym *sym; asection *sec; bfd_vma relocation; + bfd_boolean unresolved_reloc; bfd_reloc_status_type r; r_type = ELF32_R_TYPE (rel->r_info); if (r_type < 0 || r_type >= (int) R_68K_max) { bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } howto = howto_table + r_type; @@ -1342,6 +1396,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, h = NULL; sym = NULL; sec = NULL; + unresolved_reloc = FALSE; if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; @@ -1354,67 +1409,29 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, 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; + + relocation = 0; if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { sec = h->root.u.def.section; - if (((r_type == R_68K_PLT8 - || r_type == R_68K_PLT16 - || r_type == R_68K_PLT32 - || r_type == R_68K_PLT8O - || r_type == R_68K_PLT16O - || r_type == R_68K_PLT32O) - && h->plt.offset != (bfd_vma) -1 - && elf_hash_table (info)->dynamic_sections_created) - || ((r_type == R_68K_GOT8O - || r_type == R_68K_GOT16O - || r_type == R_68K_GOT32O - || ((r_type == R_68K_GOT8 - || r_type == R_68K_GOT16 - || r_type == R_68K_GOT32) - && strcmp (h->root.root.string, - "_GLOBAL_OFFSET_TABLE_") != 0)) - && elf_hash_table (info)->dynamic_sections_created - && (! info->shared - || (! info->symbolic && h->dynindx != -1) - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - || (info->shared - && ((! info->symbolic && h->dynindx != -1) - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) - && ((input_section->flags & SEC_ALLOC) != 0 - /* DWARF will emit R_68K_32 relocations in its - sections against symbols defined externally - in shared libraries. We can't do anything - with them here. */ - || ((input_section->flags & SEC_DEBUGGING) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) - && (r_type == R_68K_8 - || r_type == R_68K_16 - || r_type == R_68K_32 - || r_type == R_68K_PC8 - || r_type == R_68K_PC16 - || r_type == R_68K_PC32))) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } + if (sec->output_section == NULL) + /* Set a flag that will be cleared later if we find a + relocation value for this symbol. output_section + is typically NULL for symbols satisfied by a shared + library. */ + unresolved_reloc = TRUE; else relocation = (h->root.u.def.value + sec->output_section->vma + sec->output_offset); } else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; + ; else if (info->shared - && (!info->symbolic || info->allow_shlib_undefined) && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) - relocation = 0; + ; else { if (!(info->callbacks->undefined_symbol @@ -1422,8 +1439,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, input_section, rel->r_offset, (!info->shared || info->no_undefined || ELF_ST_VISIBILITY (h->other))))) - return false; - relocation = 0; + return FALSE; } } @@ -1455,13 +1471,18 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, if (h != NULL) { + bfd_boolean dyn; + off = h->got.offset; BFD_ASSERT (off != (bfd_vma) -1); - if (!elf_hash_table (info)->dynamic_sections_created + dyn = elf_hash_table (info)->dynamic_sections_created; + if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) || (info->shared - && (info->symbolic || h->dynindx == -1) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + && (info->symbolic + || h->dynindx == -1 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) != 0) { /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined @@ -1484,6 +1505,8 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, h->got.offset |= 1; } } + else + unresolved_reloc = FALSE; } else { @@ -1566,6 +1589,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, relocation = (splt->output_section->vma + splt->output_offset + h->plt.offset); + unresolved_reloc = FALSE; break; case R_68K_PLT8O: @@ -1582,6 +1606,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, } relocation = h->plt.offset; + unresolved_reloc = FALSE; /* This relocation does not use the addend. */ rel->r_addend = 0; @@ -1591,7 +1616,9 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, case R_68K_PC8: case R_68K_PC16: case R_68K_PC32: - if (h == NULL) + if (h == NULL + || (info->shared + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) break; /* Fall through. */ case R_68K_8: @@ -1609,7 +1636,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, { Elf_Internal_Rela outrel; bfd_byte *loc; - boolean skip, relocate; + bfd_boolean skip, relocate; /* When generating a shared object, these relocations are copied into the output file to be resolved at run @@ -1624,7 +1651,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, elf_elfheader (input_bfd)->e_shstrndx, elf_section_data (input_section)->rel_hdr.sh_name)); if (name == NULL) - return false; + return FALSE; BFD_ASSERT (strncmp (name, ".rela", 5) == 0 && strcmp (bfd_get_section_name (input_bfd, @@ -1635,16 +1662,16 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (sreloc != NULL); } - skip = false; - relocate = false; + skip = FALSE; + relocate = FALSE; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) - skip = true; + skip = TRUE; else if (outrel.r_offset == (bfd_vma) -2) - skip = true, relocate = true; + skip = TRUE, relocate = TRUE; outrel.r_offset += (input_section->output_section->vma + input_section->output_offset); @@ -1665,7 +1692,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, { if (r_type == R_68K_32) { - relocate = true; + relocate = TRUE; outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE); outrel.r_addend = relocation + rel->r_addend; } @@ -1687,7 +1714,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, else if (sec == NULL || sec->owner == NULL) { bfd_set_error (bfd_error_bad_value); - return false; + return FALSE; } else { @@ -1726,50 +1753,69 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, break; } + /* Dynamic relocs are not propagated for SEC_DEBUGGING sections + because such sections are not SEC_ALLOC and thus ld.so will + not process them. */ + if (unresolved_reloc + && !((input_section->flags & SEC_DEBUGGING) != 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, + h->root.root.string); + return FALSE; + } + r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, rel->r_offset, relocation, rel->r_addend); if (r != bfd_reloc_ok) { - switch (r) + const char *name; + + if (h != NULL) + name = h->root.root.string; + else { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; + name = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym->st_name); + if (name == NULL) + return FALSE; + if (*name == '\0') + name = bfd_section_name (input_bfd, sec); + } - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (!(info->callbacks->reloc_overflow - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; + if (r == bfd_reloc_overflow) + { + if (!(info->callbacks->reloc_overflow + (info, name, howto->name, (bfd_vma) 0, + input_bfd, input_section, rel->r_offset))) + return FALSE; + } + else + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): reloc against `%s': error %d"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, name, (int) r); + return FALSE; } } } - return true; + return TRUE; } /* Finish up dynamic symbol handling. We set the contents of various dynamic sections here. */ -static boolean +static bfd_boolean elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) bfd *output_bfd; struct bfd_link_info *info; @@ -1897,7 +1943,9 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) The entry in the global offset table will already have been initialized in the relocate_section function. */ if (info->shared - && (info->symbolic || h->dynindx == -1) + && (info->symbolic + || h->dynindx == -1 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) { rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE); @@ -1948,12 +1996,12 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) sym->st_shndx = SHN_ABS; - return true; + return TRUE; } /* Finish up the dynamic sections. */ -static boolean +static bfd_boolean elf_m68k_finish_dynamic_sections (output_bfd, info) bfd *output_bfd; struct bfd_link_info *info; @@ -2087,7 +2135,7 @@ elf_m68k_finish_dynamic_sections (output_bfd, info) elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - return true; + return TRUE; } /* Given a .data section and a .emreloc in-memory section, store @@ -2097,7 +2145,7 @@ elf_m68k_finish_dynamic_sections (output_bfd, info) after the add_symbols entry point has been called for all the objects, and before the final_link entry point is called. */ -boolean +bfd_boolean bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) bfd *abfd; struct bfd_link_info *info; @@ -2117,12 +2165,12 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) *errmsg = NULL; if (datasec->reloc_count == 0) - return true; + return TRUE; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; /* Get a copy of the native relocations. */ - internal_relocs = (_bfd_elf32_link_read_relocs + internal_relocs = (_bfd_elf_link_read_relocs (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL, info->keep_memory)); if (internal_relocs == NULL) @@ -2202,7 +2250,7 @@ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) if (internal_relocs != NULL && elf_section_data (datasec)->relocs != internal_relocs) free (internal_relocs); - return true; + return TRUE; error_return: if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf) @@ -2210,7 +2258,7 @@ error_return: if (internal_relocs != NULL && elf_section_data (datasec)->relocs != internal_relocs) free (internal_relocs); - return false; + return FALSE; } static enum elf_reloc_type_class