diff options
author | Nick Clifton <nickc@redhat.com> | 2008-11-25 13:03:56 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2008-11-25 13:03:56 +0000 |
commit | 83bac4b0108234603a1674d820d0188c9f8c4e68 (patch) | |
tree | aad42da689923236dfd87afb097eb961cd423345 /bfd/elflink.c | |
parent | 62443ade10c299bfd81cbb2392bbfcca59bdc4ca (diff) | |
download | gdb-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.c | 125 |
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; +} |