aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2008-11-25 13:03:56 +0000
committerNick Clifton <nickc@redhat.com>2008-11-25 13:03:56 +0000
commit83bac4b0108234603a1674d820d0188c9f8c4e68 (patch)
treeaad42da689923236dfd87afb097eb961cd423345 /bfd/elflink.c
parent62443ade10c299bfd81cbb2392bbfcca59bdc4ca (diff)
downloadgdb-83bac4b0108234603a1674d820d0188c9f8c4e68.zip
gdb-83bac4b0108234603a1674d820d0188c9f8c4e68.tar.gz
gdb-83bac4b0108234603a1674d820d0188c9f8c4e68.tar.bz2
* 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.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c125
1 files changed, 125 insertions, 0 deletions
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;
+}