diff options
-rw-r--r-- | bfd/ChangeLog | 48 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 4 | ||||
-rw-r--r-- | bfd/elf-m10300.c | 46 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 66 | ||||
-rw-r--r-- | bfd/elf32-bfin.c | 4 | ||||
-rw-r--r-- | bfd/elf32-cris.c | 61 | ||||
-rw-r--r-- | bfd/elf32-hppa.c | 37 | ||||
-rw-r--r-- | bfd/elf32-i370.c | 49 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 39 | ||||
-rw-r--r-- | bfd/elf32-m32r.c | 55 | ||||
-rw-r--r-- | bfd/elf32-m68k.c | 30 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 52 | ||||
-rw-r--r-- | bfd/elf32-s390.c | 40 | ||||
-rw-r--r-- | bfd/elf32-sh.c | 68 | ||||
-rw-r--r-- | bfd/elf32-v850.c | 4 | ||||
-rw-r--r-- | bfd/elf32-vax.c | 48 | ||||
-rw-r--r-- | bfd/elf64-alpha.c | 37 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 38 | ||||
-rw-r--r-- | bfd/elf64-s390.c | 41 | ||||
-rw-r--r-- | bfd/elf64-sh64.c | 48 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 39 | ||||
-rw-r--r-- | bfd/elflink.c | 125 | ||||
-rw-r--r-- | bfd/elfxx-sparc.c | 37 |
23 files changed, 289 insertions, 727 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 45448f8..8f01ddf 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,51 @@ +2008-11-25 Nick Clifton <nickc@redhat.com> + + * elflink.c (is_reloc_section): New function. Returns true if the + given name matches the name of the reloc-containing section + associated with the given section. + (get_dynamic_reloc_section_name): New function. Computes the name + of the section that contains the dynamic relocs associated with + the given section. + (_bfd_elf_get_dynamic_reloc_section): New function. Returns a + pointer to the section containing the dynamic relocs associated + with the given section. + (_bfd_elf_make_dynamic_reloc_section): New function. Creates a + section to contain the dynamic relocs associated with a given + section. + * elf-bfd.h: Prototype the new functions. + * elf-m10300.c (mn10300_elf_check_relocs): Use new functions. + (mn10300_elf_final_link_relocs): Likewise. + * elf32-arm.c (reloc_section_p): Delete - replaced by new + functions. + (elf32_arm_final_link_relocate): Use new functions. + (elf32_arm_check_relocs): Likewise. + * elf32-cris.c (cris_elf_relocate_section): Likewise. + (elf_cris_check_relocs): Likewise. + * elf32-hppa.c (elf32_hppa_check_relocs): Likewise. + * elf32-i370.c (i370_elf_check_relocs): Likewise. + (i370_elf_relocate_section): Likewise. + * elf32-i386.c (elf_i386_check_relocs): Likewise. + * elf32-m32r.c (m32r_elf_relocate_section): Likewise. + (m32r_elf_check_relocs): Likewise. + * elf32-m68k.c (elf_m68k_check_relocs): Likewise. + * elf32_ppc.c (ppc_elf_check_relocs): Likewise. + (ppc_elf_relocate_section): Likewise. + * elf32-s390.c (elf_s390_check_relocs): Likewise. + * elf32-sh.c (sh_elf_relocate_section): Likewise. + (sh_elf_check_relocs): Likewise. + * elf32-vax.c (elf_vax_check_relocs): Likewise. + (elf_vax_relocate_section): Likewise. + * elf64-alpha.c (elf64_alpha_check_relocs): Likewise. + * elf64-ppc.c (ppc64_elf_check_relocs): Likewise. + * elf64-s390.c (elf_s390_check_relocs): Likewise. + * elf64-sh64.c (sh_elf64_relocate_section): Likewise. + * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise. + * elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise. + * elf32-bfin.c (bfin_check_relocs): Remove redundant local + variable 'sreloc'. + (bfin_relocate_section): Likewise. + * elf32-v850.c (v850_elf_check_relocs): Likewise. + 2008-11-23 Hans-Peter Nilsson <hp@axis.com> Implement TLS for CRIS. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 0fd1ed2..5418e7f 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1764,6 +1764,10 @@ extern long _bfd_elf_get_reloc_upper_bound (bfd *, sec_ptr); extern long _bfd_elf_canonicalize_reloc (bfd *, sec_ptr, arelent **, asymbol **); +extern asection * _bfd_elf_get_dynamic_reloc_section + (bfd *, asection *, bfd_boolean); +extern asection * _bfd_elf_make_dynamic_reloc_section + (asection *, bfd *, unsigned int, bfd *, bfd_boolean); extern long _bfd_elf_get_dynamic_reloc_upper_bound (bfd *); extern long _bfd_elf_canonicalize_dynamic_reloc diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index 37c4f3b..d41906c 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -917,32 +917,10 @@ mn10300_elf_check_relocs (bfd *abfd, section in dynobj and make room for this reloc. */ if (sreloc == NULL) { - const char * name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - goto fail; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && streq (bfd_get_section_name (abfd, sec), name + 5)); - - sreloc = bfd_get_section_by_name (dynobj, name); + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, name, flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - goto fail; - } + goto fail; } sreloc->size += sizeof (Elf32_External_Rela); @@ -1108,22 +1086,10 @@ mn10300_elf_final_link_relocate (reloc_howto_type *howto, time. */ if (sreloc == NULL) { - const char * name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && streq (bfd_get_section_name (input_bfd, - input_section), - name + 5)); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); } skip = FALSE; diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 9008a4b..5b78dc3 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2466,19 +2466,6 @@ stub_hash_newfunc (struct bfd_hash_entry *entry, return entry; } -/* Return true if NAME is the name of the relocation section associated - with S. */ - -static bfd_boolean -reloc_section_p (struct elf32_arm_link_hash_table *htab, - const char *name, asection *s) -{ - if (htab->use_rel) - return CONST_STRNEQ (name, ".rel") && strcmp (s->name, name + 4) == 0; - else - return CONST_STRNEQ (name, ".rela") && strcmp (s->name, name + 5) == 0; -} - /* Create .got, .gotplt, and .rel(a).got sections in DYNOBJ, and set up shortcuts to them in our hash table. */ @@ -5960,19 +5947,11 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, if (sreloc == NULL) { - const char * name; + sreloc = _bfd_elf_get_dynamic_reloc_section (input_bfd, input_section, + ! globals->use_rel); - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) + if (sreloc == NULL) return bfd_reloc_notsupported; - - BFD_ASSERT (reloc_section_p (globals, name, input_section)); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); } skip = FALSE; @@ -9278,40 +9257,23 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, /* When creating a shared object, we must copy these reloc types into the output file. We create a reloc section in dynobj and make room for this reloc. */ - if (sreloc == NULL) + if (sreloc == NULL) { - const char * name; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, ! htab->use_rel); - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) + if (sreloc == NULL) return FALSE; - BFD_ASSERT (reloc_section_p (htab, name, sec)); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) + /* BPABI objects never have dynamic relocations mapped. */ + if (! htab->symbian_p) { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0 - /* BPABI objects never have dynamic - relocations mapped. */ - && !htab->symbian_p) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; - } + flagword flags; - elf_section_data (sec)->sreloc = sreloc; + flags = bfd_get_section_flags (dynobj, sreloc); + flags &= ~(SEC_LOAD | SEC_ALLOC); + bfd_set_section_flags (dynobj, sreloc, flags); + } } /* If this is a global symbol, we count the number of diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c index a5c2400..c7d1124 100644 --- a/bfd/elf32-bfin.c +++ b/bfd/elf32-bfin.c @@ -1150,7 +1150,6 @@ bfin_check_relocs (bfd * abfd, const Elf_Internal_Rela *rel_end; asection *sgot; asection *srelgot; - asection *sreloc; if (info->relocatable) return TRUE; @@ -1161,7 +1160,6 @@ bfin_check_relocs (bfd * abfd, sgot = NULL; srelgot = NULL; - sreloc = NULL; rel_end = relocs + sec->reloc_count; for (rel = relocs; rel < rel_end; rel++) @@ -1363,7 +1361,6 @@ bfin_relocate_section (bfd * output_bfd, struct elf_link_hash_entry **sym_hashes; bfd_vma *local_got_offsets; asection *sgot; - asection *sreloc; Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; int i = 0; @@ -1374,7 +1371,6 @@ bfin_relocate_section (bfd * output_bfd, local_got_offsets = elf_local_got_offsets (input_bfd); sgot = NULL; - sreloc = NULL; rel = relocs; relend = relocs + input_section->reloc_count; diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index ec3e522..72916f2 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -1,5 +1,5 @@ /* CRIS-specific support for 32-bit ELF. - Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Contributed by Axis Communications AB. Written by Hans-Peter Nilsson, based on elf32-fr30.c @@ -1500,33 +1500,13 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section, if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - - /* That section should have been created in - cris_elf_check_relocs, but that function will not be - called for objects which fail in + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + /* The section should have been created in cris_elf_check_relocs, + but that function will not be called for objects which fail in cris_elf_merge_private_bfd_data. */ if (sreloc == NULL) { - (*_bfd_error_handler) - (_("%B: Internal inconsistency; no relocation section %s"), - input_bfd, - name); - bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -3507,37 +3487,16 @@ cris_elf_check_relocs (abfd, info, sec, relocs) } } - /* We create a reloc section in dynobj and make room for this - reloc. */ + /* We may need to create a reloc section in the dynobj and made room + for this reloc. */ if (sreloc == NULL) { - const char *name; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) + if (sreloc == NULL) return FALSE; - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section_with_flags (dynobj, name, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY)); - if (sreloc == NULL - || !bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; - } if (sec->flags & SEC_READONLY) info->flags |= DF_TEXTREL; } diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 7707060..077f3ef 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1505,44 +1505,17 @@ elf32_hppa_check_relocs (bfd *abfd, this reloc. */ if (sreloc == NULL) { - char *name; - bfd *dynobj; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - { - (*_bfd_error_handler) - (_("Could not find relocation section for %s"), - sec->name); - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - if (htab->etab.dynobj == NULL) htab->etab.dynobj = abfd; - dynobj = htab->etab.dynobj; - sreloc = bfd_get_section_by_name (dynobj, name); + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->etab.dynobj, 2, abfd, /*rela?*/ TRUE); + if (sreloc == NULL) { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || !bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; + bfd_set_error (bfd_error_bad_value); + return FALSE; } - - elf_section_data (sec)->sreloc = sreloc; } /* If this is a global symbol, we count the number of diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c index 9c5cfbd..c419edd 100644 --- a/bfd/elf32-i370.c +++ b/bfd/elf32-i370.c @@ -1,6 +1,6 @@ /* i370-specific support for 32-bit ELF Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. Hacked by Linas Vepstas for i370 linas@linas.org @@ -852,33 +852,11 @@ i370_elf_check_relocs (bfd *abfd, #endif if (sreloc == NULL) { - const char *name; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; - } + return FALSE; } sreloc->size += sizeof (Elf32_External_Rela); @@ -1064,7 +1042,6 @@ i370_elf_relocate_section (bfd *output_bfd, { Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); - bfd *dynobj = elf_hash_table (info)->dynobj; Elf_Internal_Rela *rel = relocs; Elf_Internal_Rela *relend = relocs + input_section->reloc_count; asection *sreloc = NULL; @@ -1232,22 +1209,10 @@ i370_elf_relocate_section (bfd *output_bfd, if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); } skip = 0; diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 9e96e21..7d14fef 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1462,45 +1462,14 @@ elf_i386_check_relocs (bfd *abfd, this reloc. */ if (sreloc == NULL) { - const char *name; - bfd *dynobj; - unsigned int strndx = elf_elfheader (abfd)->e_shstrndx; - unsigned int shnam = elf_section_data (sec)->rel_hdr.sh_name; - - name = bfd_elf_string_from_elf_section (abfd, strndx, shnam); - if (name == NULL) - return FALSE; - - if (! CONST_STRNEQ (name, ".rel") - || strcmp (bfd_get_section_name (abfd, sec), - name + 4) != 0) - { - (*_bfd_error_handler) - (_("%B: bad relocation section name `%s\'"), - abfd, name); - } - if (htab->elf.dynobj == NULL) htab->elf.dynobj = abfd; - dynobj = htab->elf.dynobj; - sreloc = bfd_get_section_by_name (dynobj, name); + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ FALSE); + if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + return FALSE; } /* If this is a global symbol, we count the number of diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index 032a17d..96db6cb 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -1,6 +1,6 @@ /* M32R-specific support for 32-bit ELF. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007 Free Software Foundation, Inc. + 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -2911,22 +2911,10 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, time. */ if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) + return FALSE; } skip = FALSE; @@ -3950,36 +3938,11 @@ m32r_elf_check_relocs (bfd *abfd, section in dynobj and make room for the reloc. */ if (sreloc == NULL) { - const char *name; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + if (sreloc == NULL) + return FALSE; } /* If this is a global symbol, we count the number of diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 0b6fff3..adf401a 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -2368,35 +2368,11 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) section in dynobj and make room for this reloc. */ if (sreloc == NULL) { - const char *name; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); if (sreloc == NULL) - { - sreloc = bfd_make_section_with_flags (dynobj, - name, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY)); - if (sreloc == NULL - || !bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + return FALSE; } if (sec->flags & SEC_READONLY diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 55348ae..432605b 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -3768,38 +3768,14 @@ ppc_elf_check_relocs (bfd *abfd, #endif if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - if (htab->elf.dynobj == NULL) htab->elf.dynobj = abfd; - sreloc = bfd_get_section_by_name (htab->elf.dynobj, name); + + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ TRUE); + if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED - | SEC_ALLOC | SEC_LOAD); - sreloc = bfd_make_section_with_flags (htab->elf.dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (htab->elf.dynobj, - sreloc, 2)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + return FALSE; } /* If this is a global symbol, we count the number of @@ -6836,22 +6812,10 @@ ppc_elf_relocate_section (bfd *output_bfd, time. */ if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (htab->elf.dynobj, name); - BFD_ASSERT (sreloc != NULL); } skip = 0; diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 7d63372..7aadadc 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -1279,46 +1279,14 @@ elf_s390_check_relocs (abfd, info, sec, relocs) this reloc. */ if (sreloc == NULL) { - const char *name; - bfd *dynobj; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - if (! CONST_STRNEQ (name, ".rela") - || strcmp (bfd_get_section_name (abfd, sec), - name + 5) != 0) - { - (*_bfd_error_handler) - (_("%B: bad relocation section name `%s\'"), - abfd, name); - } - if (htab->elf.dynobj == NULL) htab->elf.dynobj = abfd; - dynobj = htab->elf.dynobj; - sreloc = bfd_get_section_by_name (dynobj, name); + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ TRUE); + if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + return FALSE; } /* If this is a global symbol, we count the number of diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 26c69bc..89cef67 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -3626,22 +3626,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); } skip = FALSE; @@ -4352,22 +4340,10 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); } if (h == NULL || h->dynindx == -1) @@ -5223,37 +5199,11 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, section in dynobj and make room for this reloc. */ if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->root.dynobj, 2, abfd, /*rela?*/ TRUE); - sreloc = bfd_get_section_by_name (htab->root.dynobj, name); if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (htab->root.dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (htab->root.dynobj, - sreloc, 2)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + return FALSE; } /* If this is a global symbol, we count the number of diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index 422e34b..8f9eda4 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -1,6 +1,6 @@ /* V850-specific support for 32-bit ELF Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007 Free Software Foundation, Inc. + 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -52,7 +52,6 @@ v850_elf_check_relocs (bfd *abfd, struct elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; - asection *sreloc; enum v850_reloc_type r_type; int other = 0; const char *common = NULL; @@ -68,7 +67,6 @@ v850_elf_check_relocs (bfd *abfd, dynobj = elf_hash_table (info)->dynobj; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; sym_hashes = elf_sym_hashes (abfd); - sreloc = NULL; rel_end = relocs + sec->reloc_count; for (rel = relocs; rel < rel_end; rel++) diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index 77f8b41..7f47819 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -1,6 +1,6 @@ /* VAX series support for 32-bit ELF Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Contributed by Matt Thomas <matt@3am-software.com>. This file is part of BFD, the Binary File Descriptor library. @@ -738,34 +738,12 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, section in dynobj and make room for this reloc. */ if (sreloc == NULL) { - const char *name; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) + if (sreloc == NULL) return FALSE; - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section_with_flags (dynobj, - name, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY)); - if (sreloc == NULL - || !bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; - } if (sec->flags & SEC_READONLY) info->flags |= DF_TEXTREL; } @@ -1622,22 +1600,10 @@ elf_vax_relocate_section (bfd *output_bfd, time. */ if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); } skip = FALSE; diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 308b4e9..c22b4fd 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -1748,7 +1748,6 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, { bfd *dynobj; asection *sreloc; - const char *rel_sec_name; Elf_Internal_Shdr *symtab_hdr; struct alpha_elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel, *relend; @@ -1773,7 +1772,6 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, elf_hash_table (info)->dynobj = dynobj = abfd; sreloc = NULL; - rel_sec_name = NULL; symtab_hdr = &elf_symtab_hdr (abfd); sym_hashes = alpha_elf_sym_hashes (abfd); @@ -1923,41 +1921,16 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, if (need & NEED_DYNREL) { - if (rel_sec_name == NULL) - { - rel_sec_name = (bfd_elf_string_from_elf_section - (abfd, elf_elfheader(abfd)->e_shstrndx, - elf_section_data(sec)->rel_hdr.sh_name)); - if (rel_sec_name == NULL) - return FALSE; - - BFD_ASSERT (CONST_STRNEQ (rel_sec_name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - rel_sec_name+5) == 0); - } - /* We need to create the section here now whether we eventually use it or not so that it gets mapped to an output section by - the linker. If not used, we'll kill it in - size_dynamic_sections. */ + the linker. If not used, we'll kill it in size_dynamic_sections. */ if (sreloc == NULL) { - sreloc = bfd_get_section_by_name (dynobj, rel_sec_name); + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 3, abfd, /*rela?*/ TRUE); + if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_LINKER_CREATED | SEC_READONLY); - if (sec->flags & SEC_ALLOC) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - rel_sec_name, - flags); - if (sreloc == NULL - || !bfd_set_section_alignment (dynobj, sreloc, 3)) - return FALSE; - } + return FALSE; } if (h) diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 9138371..c4be65a 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -5028,43 +5028,11 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, this reloc. */ if (sreloc == NULL) { - const char *name; - bfd *dynobj; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - if (! CONST_STRNEQ (name, ".rela") - || strcmp (bfd_get_section_name (abfd, sec), - name + 5) != 0) - { - (*_bfd_error_handler) - (_("%B: bad relocation section name `%s\'"), - abfd, name); - bfd_set_error (bfd_error_bad_value); - } + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE); - dynobj = htab->elf.dynobj; - sreloc = bfd_get_section_by_name (dynobj, name); if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED - | SEC_ALLOC | SEC_LOAD); - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 3)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + return FALSE; } /* If this is a global symbol, we count the number of diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 820e463..5eb44b2 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -1246,46 +1246,11 @@ elf_s390_check_relocs (abfd, info, sec, relocs) this reloc. */ if (sreloc == NULL) { - const char *name; - bfd *dynobj; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - if (! CONST_STRNEQ (name, ".rela") - || strcmp (bfd_get_section_name (abfd, sec), - name + 5) != 0) - { - (*_bfd_error_handler) - (_("%B: bad relocation section name `%s\'"), - abfd, name); - } + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE); - if (htab->elf.dynobj == NULL) - htab->elf.dynobj = abfd; - - dynobj = htab->elf.dynobj; - sreloc = bfd_get_section_by_name (dynobj, name); if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 3)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + return FALSE; } /* If this is a global symbol, we count the number of diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index a390025..e76aeb7 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -1725,22 +1725,10 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) + sreloc = _bfd_elf_get_dynamic_reloc_section + (input_bfd, input_section, /*rela?*/ TRUE); + if (sreloc == NULL) return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); } skip = FALSE; @@ -2711,35 +2699,11 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info, section in dynobj and make room for this reloc. */ if (sreloc == NULL) { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 2, abfd, /*rela?*/ TRUE); - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return FALSE; - } + return FALSE; } sreloc->size += sizeof (Elf64_External_Rela); diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index bc8c652..7eecb22 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1281,47 +1281,14 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, this reloc. */ if (sreloc == NULL) { - const char *name; - bfd *dynobj; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - if (! CONST_STRNEQ (name, ".rela") - || strcmp (bfd_get_section_name (abfd, sec), - name + 5) != 0) - { - (*_bfd_error_handler) - (_("%B: bad relocation section name `%s\'"), - abfd, name); - } - if (htab->elf.dynobj == NULL) htab->elf.dynobj = abfd; - dynobj = htab->elf.dynobj; + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE); - sreloc = bfd_get_section_by_name (dynobj, name); if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, 3)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + return FALSE; } /* If this is a global symbol, we count the number of diff --git a/bfd/elflink.c b/bfd/elflink.c index 55173ff..ce1dff7 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -12269,3 +12269,128 @@ _bfd_elf_default_got_elt_size (bfd *abfd, const struct elf_backend_data *bed = get_elf_backend_data (abfd); return bed->s->arch_size / 8; } + +/* Routines to support the creation of dynamic relocs. */ + +/* Return true if NAME is a name of a relocation + section associated with section S. */ + +static bfd_boolean +is_reloc_section (bfd_boolean rela, const char * name, asection * s) +{ + if (rela) + return CONST_STRNEQ (name, ".rela") + && strcmp (bfd_get_section_name (NULL, s), name + 5) == 0; + + return CONST_STRNEQ (name, ".rel") + && strcmp (bfd_get_section_name (NULL, s), name + 4) == 0; +} + +/* Returns the name of the dynamic reloc section associated with SEC. */ + +static const char * +get_dynamic_reloc_section_name (bfd * abfd, + asection * sec, + bfd_boolean is_rela) +{ + const char * name; + unsigned int strndx = elf_elfheader (abfd)->e_shstrndx; + unsigned int shnam = elf_section_data (sec)->rel_hdr.sh_name; + + name = bfd_elf_string_from_elf_section (abfd, strndx, shnam); + if (name == NULL) + return NULL; + + if (! is_reloc_section (is_rela, name, sec)) + { + static bfd_boolean complained = FALSE; + + if (! complained) + { + (*_bfd_error_handler) + (_("%B: bad relocation section name `%s\'"), abfd, name); + complained = TRUE; + } + name = NULL; + } + + return name; +} + +/* Returns the dynamic reloc section associated with SEC. + If necessary compute the name of the dynamic reloc section based + on SEC's name (looked up in ABFD's string table) and the setting + of IS_RELA. */ + +asection * +_bfd_elf_get_dynamic_reloc_section (bfd * abfd, + asection * sec, + bfd_boolean is_rela) +{ + asection * reloc_sec = elf_section_data (sec)->sreloc; + + if (reloc_sec == NULL) + { + const char * name = get_dynamic_reloc_section_name (abfd, sec, is_rela); + + if (name != NULL) + { + reloc_sec = bfd_get_section_by_name (abfd, name); + + if (reloc_sec != NULL) + elf_section_data (sec)->sreloc = reloc_sec; + } + } + + return reloc_sec; +} + +/* Returns the dynamic reloc section associated with SEC. If the + section does not exist it is created and attached to the DYNOBJ + bfd and stored in the SRELOC field of SEC's elf_section_data + structure. + + ALIGNMENT is the alignment for the newly created section and + IS_RELA defines whether the name should be .rela.<SEC's name> + or .rel.<SEC's name>. The section name is looked up in the + string table associated with ABFD. */ + +asection * +_bfd_elf_make_dynamic_reloc_section (asection * sec, + bfd * dynobj, + unsigned int alignment, + bfd * abfd, + bfd_boolean is_rela) +{ + asection * reloc_sec = elf_section_data (sec)->sreloc; + + if (reloc_sec == NULL) + { + const char * name = get_dynamic_reloc_section_name (abfd, sec, is_rela); + + if (name == NULL) + return NULL; + + reloc_sec = bfd_get_section_by_name (dynobj, name); + + if (reloc_sec == NULL) + { + flagword flags; + + flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_IN_MEMORY | SEC_LINKER_CREATED); + if ((sec->flags & SEC_ALLOC) != 0) + flags |= SEC_ALLOC | SEC_LOAD; + + reloc_sec = bfd_make_section_with_flags (dynobj, name, flags); + if (reloc_sec != NULL) + { + if (! bfd_set_section_alignment (dynobj, reloc_sec, alignment)) + reloc_sec = NULL; + } + } + + elf_section_data (sec)->sreloc = reloc_sec; + } + + return reloc_sec; +} diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 83d26b0..6449f3b 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -1451,42 +1451,15 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, section in dynobj and make room for the reloc. */ if (sreloc == NULL) { - const char *name; - bfd *dynobj; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return FALSE; - - BFD_ASSERT (CONST_STRNEQ (name, ".rela") - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - if (htab->elf.dynobj == NULL) htab->elf.dynobj = abfd; - dynobj = htab->elf.dynobj; - sreloc = bfd_get_section_by_name (dynobj, name); + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->elf.dynobj, htab->word_align_power, + abfd, /*rela?*/ TRUE); + if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_READONLY - | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if ((sec->flags & SEC_ALLOC) != 0) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - name, - flags); - if (sreloc == NULL - || ! bfd_set_section_alignment (dynobj, sreloc, - htab->word_align_power)) - return FALSE; - } - elf_section_data (sec)->sreloc = sreloc; + return FALSE; } /* If this is a global symbol, we count the number of |