From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 71786 invoked by alias); 14 Feb 2020 10:31:21 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 71520 invoked by uid 89); 14 Feb 2020 10:31:08 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.0 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=seek, desire, Discover, Nick X-HELO: us-smtp-1.mimecast.com Received: from us-smtp-delivery-1.mimecast.com (HELO us-smtp-1.mimecast.com) (207.211.31.120) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 14 Feb 2020 10:31:03 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1581676262; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=oXwo1h/u+07DqYeumVdlOpSL0Hcpht4zNC1+tdewLrM=; b=Nw8hP4a+giLWqf281E5p0+RsZQAsQgTfnzeLMqPISFalaNI5gSoXG15F6qNmX+Sr5mGfev TQc88OApcXnZTMKbZwSiD23BZkNAYzbdYx/hKD51hJWdRgLhM/O3xqdKet6BwnvArEq/xS aMrQVFSLghgaLyF0Dml1KlOys281lHA= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-361-N57kq8hiMY-KFY53G8m2wg-1; Fri, 14 Feb 2020 05:30:51 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C326DA0CC5 for ; Fri, 14 Feb 2020 10:30:50 +0000 (UTC) Received: from comet.redhat.com (ovpn-117-115.ams2.redhat.com [10.36.117.115]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B5DC419C4F for ; Fri, 14 Feb 2020 10:30:49 +0000 (UTC) From: Nick Clifton To: binutils@sourceware.org Subject: RFC: Supporting multiple relocs per section Date: Fri, 14 Feb 2020 10:31:00 -0000 Message-ID: <877e0pmpew.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2020-02/txt/msg00317.txt.bz2 Hi Guys, Traditionally the BFD library has supported a one-to-one relationship between relocation sections and the sections that they relocate. The ELF portions of the library do support a two-to-one relationship if one of the reloc sections uses REL relocs and the other uses RELA relocs, but that is a bit of a hack. The ELF standard however does not prohibit a many-to-one relationship and I now have a need to support such a feature[1]. Initially I looked at reworking the internals of the BFD library to accommodate a list of reloc sections attached to a normal section but this quickly spiralled out of control and broke far too many things. So I have now come up with an implementation that adds a few new functions to the elf_backend_data structure, and some hooks to call these functions. This encapsulates the new code and helps separate it from the rest of the library. It does however mean that, currently, these extra reloc sections are not processed when linking. For the use case I have in mind however (objcopy/strip) this does not matter. As part of this process I also discovered that the BFD library would unconditionally convert OS-specific and PROC-specific section indices into SHN_ABS indices when writing out symbol tables, so I also added a hook to allow backends to override this behaviour if they so desire. I am hoping to add the code to the upstream sources, but I would like seek out any comments or suggestions that people might have before I do so. So ... any thoughts ? Cheers Nick PS. During testing I also encountered a build failure with the score architecture because that defines target_size=3D64 during configuration but it does not include the 64-bit generic elf functions found in elf64.o. So the patch fixes that as well. [1] This is to support kernel live patch modules used by Fedora and RHEL and possibly other distributions too. bfd/ChangeLog 2020-02-14 Nick Clifton * elf-bfd.h (struct elf_backend_data): Add new fields: init_secondary_reloc_section, slurp_secondary_reloc_section, write_secondary_reloc_section, symbol_section_index. (_bfd_elf_init_secondary_reloc_section): Prototype. (_bfd_elf_slurp_secondary_reloc_section): Prototype. (_bfd_elf_write_secondary_reloc_section): Prototype. (_bfd_elf_symbol_section_index): Prototype. * elf.c ( bfd_section_from_shdr): Invoke the new init_secondary_reloc_section backend function, if defined, when a second reloc section is encountered. (swap_out_syms): Invoke the new symbol_section_index function, if defined, when computing the section index of an OS/PROC specific symbol. (_bfd_elf_init_secondary_reloc_section): New function. (_bfd_elf_slurp_secondary_reloc_section): New function. (_bfd_elf_write_secondary_reloc_section): New function. (_bfd_elf_symbol_section_index): New function. (_bfd_elf_copy_special_section_fields): New function. * elfcode.h (elf_write_relocs): Invoke the new write_secondary_relocs function, if defined, in order to emit secondary relocs. (elf_slurp_reloc_table): Invoke the new slurp_secondary_relocs function, if defined, in order to read in secondary relocs. * elfxx-target.h (elf_backend_copy_special_section_fields): Provide a non-NULL default definition. (elf_backend_init_secondary_reloc_section): Likewise. (elf_backend_slurp_secondary_reloc_section): Likewise. (elf_backend_write_secondary_reloc_section): Likewise. (elf_backend_symbol_section_index): Likewise. (struct elf_backend_data elfNN_bed): Add initialisers for the new fields. * configure.ac (score_elf32_[bl]e_vec): Add elf64.lo * configure: Regenerate. diff --git a/bfd/configure.ac b/bfd/configure.ac index af4d4b8c13..3426ded094 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -619,8 +619,8 @@ do rx_elf32_linux_le_vec) tb=3D"$tb elf32-rx.lo elf32.lo $elf" ;; s390_elf32_vec) tb=3D"$tb elf32-s390.lo elf32.lo $elf" ;; s390_elf64_vec) tb=3D"$tb elf64-s390.lo elf64.lo $elf"; target_size= =3D64 ;; - score_elf32_be_vec) tb=3D"$tb elf32-score.lo elf32-score7.lo elf32.lo= $elf"; want64=3Dtrue; target_size=3D64 ;; - score_elf32_le_vec) tb=3D"$tb elf32-score.lo elf32-score7.lo elf32.lo= $elf"; want64=3Dtrue; target_size=3D64 ;; + score_elf32_be_vec) tb=3D"$tb elf32-score.lo elf32-score7.lo elf32.lo= elf64.lo $elf"; want64=3Dtrue; target_size=3D64 ;; + score_elf32_le_vec) tb=3D"$tb elf32-score.lo elf32-score7.lo elf32.lo= elf64.lo $elf"; want64=3Dtrue; target_size=3D64 ;; sh_coff_vec) tb=3D"$tb coff-sh.lo $coff" ;; sh_coff_le_vec) tb=3D"$tb coff-sh.lo $coff" ;; sh_coff_small_vec) tb=3D"$tb coff-sh.lo $coff" ;; diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index cbbba153f4..a930d8278d 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1503,6 +1503,19 @@ struct elf_backend_data /* Opcode representing no unwind. */ int (*cant_unwind_opcode) (struct bfd_link_info *); =20 + /* Called when a section has extra reloc sections. */ + bfd_boolean (*init_secondary_reloc_section) (bfd *, Elf_Internal_Shdr *,= const char *, unsigned int); + + /* Called when after loading the normal relocs for a section. */ + bfd_boolean (*slurp_secondary_relocs) (bfd *, asection *, asymbol **); + + /* Called after writing the normal relocs for a section. */ + bfd_boolean (*write_secondary_relocs) (bfd *, asection *); + + /* Called to return the value to set in the ST_SHNDX field of an ELF sym= bol + from an iternal symbol which does not map to any known section. */ + unsigned int (*symbol_section_index) (bfd *, elf_symbol_type *); +=20=20 /* This is non-zero if static TLS segments require a special alignment. = */ unsigned static_tls_alignment; =20 @@ -2830,6 +2843,19 @@ extern bfd_vma elf32_r_sym (bfd_vma); =20 extern bfd_boolean is_debuginfo_file (bfd *); =20 + +extern bfd_boolean _bfd_elf_init_secondary_reloc_section + (bfd *, Elf_Internal_Shdr *, const char *, unsigned int); +extern bfd_boolean _bfd_elf_slurp_secondary_reloc_section + (bfd *, asection *, asymbol **); +extern bfd_boolean _bfd_elf_copy_special_section_fields + (const bfd *, bfd *, const Elf_Internal_Shdr *, Elf_Internal_Shdr *); +extern bfd_boolean _bfd_elf_write_secondary_reloc_section + (bfd *, asection *); +extern unsigned int _bfd_elf_symbol_section_index + (bfd *, elf_symbol_type *); + + /* Large common section. */ extern asection _bfd_elf_large_com_section; =20 diff --git a/bfd/elf.c b/bfd/elf.c index c85face630..2c1b6fe67d 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1619,7 +1619,7 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) /* Final attempt. Call the backend copy function with a NULL input section. */ if (bed->elf_backend_copy_special_section_fields !=3D NULL) - bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL, ohead= er); + (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL= , oheader); } } =20 @@ -2468,13 +2468,17 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shin= dex) sections. */ if (*p_hdr !=3D NULL) { - _bfd_error_handler - /* xgettext:c-format */ - (_("%pB: warning: multiple relocation sections for section %pA \ -found - ignoring all but the first"), - abfd, target_sect); + if (bed->init_secondary_reloc_section =3D=3D NULL + || ! bed->init_secondary_reloc_section (abfd, hdr, name, shindex)) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB: warning: secondary relocation section '%s' for section %pA fo= und - ignoring"), + abfd, name, target_sect); + } goto success; } + hdr2 =3D (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2)); if (hdr2 =3D=3D NULL) goto fail; @@ -8199,9 +8203,20 @@ error_return: if (elf_symtab_shndx_list (abfd)) shndx =3D elf_symtab_shndx_list (abfd)->ndx; break; - default: + case SHN_COMMON: + case SHN_ABS: shndx =3D SHN_ABS; break; + default: + if (bed->symbol_section_index) + shndx =3D bed->symbol_section_index (abfd, type_ptr); + else + { + _bfd_error_handler (_("%pB: Unable to handle section index %x in E= LF symbol. Using ABS instead. (%x)"), + abfd, shndx, SHN_COMMON); + shndx =3D SHN_ABS; + } + break; } } else @@ -12289,3 +12304,355 @@ _bfd_elf_maybe_function_sym (const asymbol *sym, = asection *sec, size =3D 1; return size; } + +/* Set to non-zero to enable some debug messages. */ +#define DEBUG_SECONDARY_RELOCS 0 + +/* An internal-to-the-bfd-library only section type + used to indicate a cached secondary reloc section. */ +#define SHT_SECONDARY_RELOC (SHT_LOOS + SHT_RELA) + +/* Create a BFD section to hold a secondary reloc section. */ + +bfd_boolean +_bfd_elf_init_secondary_reloc_section (bfd * abfd, + Elf_Internal_Shdr *hdr, + const char * name, + unsigned int shindex) +{ + /* We only support RELA secondary relocs. */ + if (hdr->sh_type !=3D SHT_RELA) + return FALSE; + +#if DEBUG_SECONDARY_RELOCS + fprintf (stderr, "secondary reloc section %s encountered\n", name); +#endif + hdr->sh_type =3D SHT_SECONDARY_RELOC; + return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); +} + +/* Read in any secondary relocs associated with SEC. */ + +bfd_boolean +_bfd_elf_slurp_secondary_reloc_section (bfd * abfd, + asection * sec, + asymbol ** symbols) +{ + const struct elf_backend_data * const ebd =3D get_elf_backend_data (abfd= ); + asection * relsec; + bfd_boolean result =3D TRUE; + bfd_vma (*r_sym) (bfd_vma); + + BFD_ASSERT (ebd->elf_info_to_howto !=3D NULL); + +#ifdef BFD64 + if (bfd_arch_bits_per_address (abfd) !=3D 32) + r_sym =3D elf64_r_sym; + else +#endif + r_sym =3D elf32_r_sym; +=20=20 + /* Discover if there are any secondary reloc sections + associated with SEC. */ + for (relsec =3D abfd->sections; relsec !=3D NULL; relsec =3D relsec->nex= t) + { + Elf_Internal_Shdr * hdr =3D & elf_section_data (relsec)->this_hdr; + + if (hdr->sh_type =3D=3D SHT_SECONDARY_RELOC + && hdr->sh_info =3D=3D (unsigned) elf_section_data (sec)->this_idx) + { + bfd_byte * native_relocs; + bfd_byte * native_reloc; + arelent * internal_relocs; + arelent * internal_reloc; + unsigned int i; + unsigned int entsize; + unsigned int symcount; + unsigned int reloc_count; + +#if DEBUG_SECONDARY_RELOCS + fprintf (stderr, "read secondary relocs for %s from %s\n", sec->name, r= elsec->name); +#endif + entsize =3D hdr->sh_entsize; + + native_relocs =3D bfd_malloc (hdr->sh_size); + if (native_relocs =3D=3D NULL) + { + result =3D FALSE; + continue; + } + + reloc_count =3D NUM_SHDR_ENTRIES (hdr); + internal_relocs =3D (arelent *) bfd_alloc2 (abfd, reloc_count, sizeof (= arelent)); + if (internal_relocs =3D=3D NULL) + { + free (native_relocs); + result =3D FALSE; + continue; + } + + if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) !=3D 0 + || (bfd_bread (native_relocs, hdr->sh_size, abfd) !=3D hdr->sh_size= )) + { + free (native_relocs); + free (internal_relocs); + result =3D FALSE; + continue; + } + + symcount =3D bfd_get_symcount (abfd); + + for (i =3D 0, internal_reloc =3D internal_relocs, native_reloc =3D nati= ve_relocs; + i < reloc_count; + i++, internal_reloc++, native_reloc +=3D entsize) + { + bfd_boolean res; + Elf_Internal_Rela rela; + + ebd->s->swap_reloca_in (abfd, native_reloc, & rela); + + /* The address of an ELF reloc is section relative for an object + file, and absolute for an executable file or shared library. + The address of a normal BFD reloc is always section relative, + and the address of a dynamic reloc is absolute.. */ + if ((abfd->flags & (EXEC_P | DYNAMIC)) =3D=3D 0) + internal_reloc->address =3D rela.r_offset; + else + internal_reloc->address =3D rela.r_offset - sec->vma; + + if (r_sym (rela.r_info) =3D=3D STN_UNDEF) + { + /* FIXME: This and the error case below mean that we + have a symbol on relocs that is not elf_symbol_type. */ + internal_reloc->sym_ptr_ptr =3D bfd_abs_section_ptr->symbol_ptr_ptr; + } + else if (r_sym (rela.r_info) > symcount) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): relocation %d has invalid symbol index %ld"), + abfd, sec, i, (long) r_sym (rela.r_info)); + bfd_set_error (bfd_error_bad_value); + internal_reloc->sym_ptr_ptr =3D bfd_abs_section_ptr->symbol_ptr_ptr; + result =3D FALSE; + } + else + { + asymbol **ps; + + ps =3D symbols + r_sym (rela.r_info) - 1; + + internal_reloc->sym_ptr_ptr =3D ps; + /* Make sure that this symbol is not removed by strip. */ + (*ps)->flags |=3D BSF_KEEP; + } + + internal_reloc->addend =3D rela.r_addend; + + res =3D ebd->elf_info_to_howto (abfd, internal_reloc, & rela); + if (! res || internal_reloc->howto =3D=3D NULL) + { +#if DEBUG_SECONDARY_RELOCS + fprintf (stderr, "there is no howto associated with reloc %lx\n", rela= .r_info); +#endif + result =3D FALSE; + } + } + + free (native_relocs); + /* Store the internal relocs. */ + elf_section_data (relsec)->sec_info =3D internal_relocs; + } + } + + return result; +} + +/* Set the ELF section header fields of an output secondary reloc section.= */ + +bfd_boolean +_bfd_elf_copy_special_section_fields (const bfd * ibfd ATTRI= BUTE_UNUSED, + bfd * obfd ATTRIBUTE_UNUSED, + const Elf_Internal_Shdr * isection, + Elf_Internal_Shdr * osection) +{ + if (isection->sh_type !=3D SHT_SECONDARY_RELOC) + return TRUE; + + if (isection =3D=3D NULL) + return FALSE; + + asection * isec =3D isection->bfd_section; + if (isec =3D=3D NULL) + return FALSE; + + asection * osec =3D osection->bfd_section; + if (osec =3D=3D NULL) + return FALSE; + + BFD_ASSERT (elf_section_data (osec)->sec_info =3D=3D NULL); + elf_section_data (osec)->sec_info =3D elf_section_data (isec)->sec_info; + osection->sh_type =3D SHT_RELA; + osection->sh_link =3D elf_onesymtab (obfd); + if (osection->sh_link =3D=3D 0) + { + /* There is no symbol table - we are hosed... */ + _bfd_error_handler + /* xgettext:c-format */ + (_("%pB(%pA): link section cannot be set because the output file does not= have a symbol table"), + obfd, osec); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + /* Find the output section that corresponds to the isection's sh_info li= nk. */ + BFD_ASSERT (isection->sh_info > 0 && isection->sh_info < elf_numsections= (ibfd)); + isection =3D elf_elfsections (ibfd)[isection->sh_info]; + + BFD_ASSERT (isection !=3D NULL); + BFD_ASSERT (isection->bfd_section !=3D NULL); + BFD_ASSERT (isection->bfd_section->output_section !=3D NULL); + osection->sh_info =3D elf_section_data (isection->bfd_section->output_se= ction)->this_idx; + +#if DEBUG_SECONDARY_RELOCS + fprintf (stderr, "update header of %s, sh_link =3D %u, sh_info =3D %u\n", + osec->name, osection->sh_link, osection->sh_info); +#endif + + return TRUE; +} + +/* Write out a secondary reloc section. */ + +bfd_boolean +_bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec) +{ + const struct elf_backend_data * const ebd =3D get_elf_backend_data (abfd= ); + bfd_vma addr_offset; + asection * relsec; + bfd_vma (*r_info) (bfd_vma, bfd_vma); + +#ifdef BFD64 + if (bfd_arch_bits_per_address (abfd) !=3D 32) + r_info =3D elf64_r_info; + else +#endif + r_info =3D elf32_r_info; + + if (sec =3D=3D NULL) + return FALSE; + + /* The address of an ELF reloc is section relative for an object + file, and absolute for an executable file or shared library. + The address of a BFD reloc is always section relative. */ + addr_offset =3D 0; + if ((abfd->flags & (EXEC_P | DYNAMIC)) !=3D 0) + addr_offset =3D sec->vma; + + /* Discover if there are any secondary reloc sections + associated with SEC. */ + for (relsec =3D abfd->sections; relsec !=3D NULL; relsec =3D relsec->nex= t) + { + const struct bfd_elf_section_data * const esd =3D elf_section_data (= relsec); + Elf_Internal_Shdr * const hdr =3D (Elf_Internal_Shdr *) & esd->this_= hdr; + + if (hdr->sh_type =3D=3D SHT_RELA + && hdr->sh_info =3D=3D (unsigned) elf_section_data (sec)->this_idx) + { + asymbol * last_sym; + int last_sym_idx; + unsigned int reloc_count; + unsigned int idx; + arelent * src_irel; + bfd_byte * dst_rela; + + BFD_ASSERT (hdr->contents =3D=3D NULL); + + reloc_count =3D hdr->sh_size / hdr->sh_entsize; + BFD_ASSERT (reloc_count > 0); + + hdr->contents =3D bfd_alloc (abfd, hdr->sh_size); + if (hdr->contents =3D=3D NULL) + continue; + +#if DEBUG_SECONDARY_RELOCS + fprintf (stderr, "write %u secondary relocs for %s from %s\n", reloc_co= unt, sec->name, relsec->name); +#endif + last_sym =3D NULL; + last_sym_idx =3D 0; + dst_rela =3D hdr->contents; + src_irel =3D (arelent *) esd->sec_info; + BFD_ASSERT (src_irel !=3D NULL); + + for (idx =3D 0; idx < reloc_count; idx++, dst_rela +=3D hdr->sh_entsize) + { + Elf_Internal_Rela src_rela; + arelent *ptr; + asymbol *sym; + int n; + + ptr =3D src_irel + idx; + sym =3D *ptr->sym_ptr_ptr; + + if (sym =3D=3D last_sym) + n =3D last_sym_idx; + else + { + last_sym =3D sym; + n =3D _bfd_elf_symbol_from_bfd_symbol (abfd, & sym); + if (n < 0) + { +#if DEBUG_SECONDARY_RELOCS + fprintf (stderr, "failed to find symbol %s whilst rewriting relocs= \n", + sym->name); +#endif + /* FIXME: Signal failure somehow. */ + n =3D 0; + } + last_sym_idx =3D n; + } + + if ((*ptr->sym_ptr_ptr)->the_bfd !=3D NULL + && (*ptr->sym_ptr_ptr)->the_bfd->xvec !=3D abfd->xvec + && ! _bfd_elf_validate_reloc (abfd, ptr)) + { +#if DEBUG_SECONDARY_RELOCS + fprintf (stderr, "symbol %s is not in the output bfd\n", + sym->name); +#endif + /* FIXME: Signal failure somehow. */ + n =3D 0; + } + + if (ptr->howto =3D=3D NULL) + { +#if DEBUG_SECONDARY_RELOCS + fprintf (stderr, "reloc for symbol %s does not have a howto associated= with it\n", + sym->name); +#endif + /* FIXME: Signal failure somehow. */ + n =3D 0; + } + + src_rela.r_offset =3D ptr->address + addr_offset; + src_rela.r_info =3D r_info (n, ptr->howto->type); + src_rela.r_addend =3D ptr->addend; + ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela); + } + } + } + + return TRUE; +} + +/* Preserve any OS or PROCESSOR specific section indicies. */ + +unsigned int +_bfd_elf_symbol_section_index (bfd * abfd ATTRIBUTE_UNUSED, + elf_symbol_type * sym) +{ + unsigned int shndx =3D sym->internal_elf_sym.st_shndx; + + /* Preserve special section indicies. */ + return shndx >=3D SHN_LORESERVE ? shndx : SHN_ABS; +} diff --git a/bfd/elfcode.h b/bfd/elfcode.h index e1e89cf78f..27f6b81b1e 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -865,6 +865,7 @@ elf_object_p (bfd *abfd) void elf_write_relocs (bfd *abfd, asection *sec, void *data) { + const struct elf_backend_data * const bed =3D get_elf_backend_data (abfd= ); bfd_boolean *failedp =3D (bfd_boolean *) data; Elf_Internal_Shdr *rela_hdr; bfd_vma addr_offset; @@ -980,6 +981,13 @@ elf_write_relocs (bfd *abfd, asection *sec, void *data) src_rela.r_addend =3D ptr->addend; (*swap_out) (abfd, &src_rela, dst_rela); } + + if (bed->write_secondary_relocs !=3D NULL) + if (! bed->write_secondary_relocs (abfd, sec)) + { + *failedp =3D TRUE; + return; + } } =20 /* Write out the program headers. */ @@ -1281,7 +1289,10 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs= , bfd_boolean dynamic) { /* This symbol is in a section for which we did not create a BFD section. Just use bfd_abs_section, - although it is wrong. FIXME. */ + although it is wrong. FIXME. Note - there is + code in elf.c:swap_out_syms that calls + symbol_section_index() in the elf backend for + cases like this. */ sym->symbol.section =3D bfd_abs_section_ptr; } } @@ -1509,6 +1520,7 @@ elf_slurp_reloc_table (bfd *abfd, asymbol **symbols, bfd_boolean dynamic) { + const struct elf_backend_data * const bed =3D get_elf_backend_data (abfd= ); struct bfd_elf_section_data * const d =3D elf_section_data (asect); Elf_Internal_Shdr *rel_hdr; Elf_Internal_Shdr *rel_hdr2; @@ -1571,6 +1583,10 @@ elf_slurp_reloc_table (bfd *abfd, symbols, dynamic)) return FALSE; =20 + if (bed->slurp_secondary_relocs !=3D NULL + && ! bed->slurp_secondary_relocs (abfd, asect, symbols)) + return FALSE; + asect->relocation =3D relents; return TRUE; } diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index caca83f5c9..8fe21eb671 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -758,7 +758,7 @@ #endif =20 #ifndef elf_backend_copy_special_section_fields -#define elf_backend_copy_special_section_fields NULL +#define elf_backend_copy_special_section_fields _bfd_elf_copy_special_sect= ion_fields #endif =20 #ifndef elf_backend_compact_eh_encoding @@ -766,7 +766,23 @@ #endif =20 #ifndef elf_backend_cant_unwind_opcode -#define elf_backend_cant_unwind_opcode 0 +#define elf_backend_cant_unwind_opcode NULL +#endif + +#ifndef elf_backend_init_secondary_reloc_section +#define elf_backend_init_secondary_reloc_section _bfd_elf_init_secondary_r= eloc_section +#endif + +#ifndef elf_backend_slurp_secondary_reloc_section +#define elf_backend_slurp_secondary_reloc_section _bfd_elf_slurp_secondary= _reloc_section +#endif + +#ifndef elf_backend_write_secondary_reloc_section +#define elf_backend_write_secondary_reloc_section _bfd_elf_write_secondary= _reloc_section +#endif + +#ifndef elf_backend_symbol_section_index +#define elf_backend_symbol_section_index _bfd_elf_symbol_section_index #endif =20 #ifndef elf_match_priority @@ -895,6 +911,10 @@ static struct elf_backend_data elfNN_bed =3D elf_backend_fixup_gnu_properties, elf_backend_compact_eh_encoding, elf_backend_cant_unwind_opcode, + elf_backend_init_secondary_reloc_section, + elf_backend_slurp_secondary_reloc_section, + elf_backend_write_secondary_reloc_section, + elf_backend_symbol_section_index, elf_backend_static_tls_alignment, elf_backend_stack_align, elf_backend_strtab_flags,