|
|
3a14e4 |
diff -rup binutils.orig/bfd/elf-bfd.h binutils-2.27/bfd/elf-bfd.h
|
|
|
3a14e4 |
--- binutils.orig/bfd/elf-bfd.h 2020-02-12 14:41:48.890875908 +0000
|
|
|
3a14e4 |
+++ binutils-2.27/bfd/elf-bfd.h 2020-02-12 14:41:58.777803052 +0000
|
|
|
3a14e4 |
@@ -1367,6 +1367,19 @@ struct elf_backend_data
|
|
|
3a14e4 |
/* Opcode representing no unwind. */
|
|
|
3a14e4 |
int (*cant_unwind_opcode) (struct bfd_link_info *);
|
|
|
3a14e4 |
|
|
|
3a14e4 |
+ /* Called when a section has extra reloc sections. */
|
|
|
3a14e4 |
+ bfd_boolean (*init_secondary_reloc_section) (bfd *, Elf_Internal_Shdr *, const char *, unsigned int);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ /* Called when after loading the normal relocs for a section. */
|
|
|
3a14e4 |
+ bfd_boolean (*slurp_secondary_relocs) (bfd *, asection *, asymbol **);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ /* Called after writing the normal relocs for a section. */
|
|
|
3a14e4 |
+ bfd_boolean (*write_secondary_relocs) (bfd *, asection *);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ /* Called to return the value to set in the ST_SHNDX field of an ELF symbol
|
|
|
3a14e4 |
+ from an iternal symbol which does not map to any known section. */
|
|
|
3a14e4 |
+ unsigned int (*symbol_section_index) (bfd *, elf_symbol_type *);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
/* This is non-zero if static TLS segments require a special alignment. */
|
|
|
3a14e4 |
unsigned static_tls_alignment;
|
|
|
3a14e4 |
|
|
|
3a14e4 |
@@ -2535,6 +2548,19 @@ extern bfd_vma elf64_r_sym (bfd_vma);
|
|
|
3a14e4 |
extern bfd_vma elf32_r_info (bfd_vma, bfd_vma);
|
|
|
3a14e4 |
extern bfd_vma elf32_r_sym (bfd_vma);
|
|
|
3a14e4 |
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+extern bfd_boolean _bfd_elf_init_secondary_reloc_section
|
|
|
3a14e4 |
+ (bfd *, Elf_Internal_Shdr *, const char *, unsigned int);
|
|
|
3a14e4 |
+extern bfd_boolean _bfd_elf_slurp_secondary_reloc_section
|
|
|
3a14e4 |
+ (bfd *, asection *, asymbol **);
|
|
|
3a14e4 |
+extern bfd_boolean _bfd_elf_copy_special_section_fields
|
|
|
3a14e4 |
+ (const bfd *, bfd *, const Elf_Internal_Shdr *, Elf_Internal_Shdr *);
|
|
|
3a14e4 |
+extern bfd_boolean _bfd_elf_write_secondary_reloc_section
|
|
|
3a14e4 |
+ (bfd *, asection *);
|
|
|
3a14e4 |
+extern unsigned int _bfd_elf_symbol_section_index
|
|
|
3a14e4 |
+ (bfd *, elf_symbol_type *);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
/* Large common section. */
|
|
|
3a14e4 |
extern asection _bfd_elf_large_com_section;
|
|
|
3a14e4 |
|
|
|
3a14e4 |
diff -rup binutils.orig/bfd/elf.c binutils-2.27/bfd/elf.c
|
|
|
3a14e4 |
--- binutils.orig/bfd/elf.c 2020-02-12 14:41:48.893875886 +0000
|
|
|
3a14e4 |
+++ binutils-2.27/bfd/elf.c 2020-02-12 14:41:58.778803044 +0000
|
|
|
3a14e4 |
@@ -1490,7 +1490,7 @@ _bfd_elf_copy_private_bfd_data (bfd *ibf
|
|
|
3a14e4 |
/* Final attempt. Call the backend copy function
|
|
|
3a14e4 |
with a NULL input section. */
|
|
|
3a14e4 |
if (bed->elf_backend_copy_special_section_fields != NULL)
|
|
|
3a14e4 |
- bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL, oheader);
|
|
|
3a14e4 |
+ (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL, oheader);
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
|
|
|
3a14e4 |
@@ -2329,11 +2329,14 @@ bfd_section_from_shdr (bfd *abfd, unsign
|
|
|
3a14e4 |
sections. */
|
|
|
3a14e4 |
if (*p_hdr != NULL)
|
|
|
3a14e4 |
{
|
|
|
3a14e4 |
- _bfd_error_handler
|
|
|
3a14e4 |
- /* xgettext:c-format */
|
|
|
3a14e4 |
- (_("%B: warning: multiple relocation sections for section %A \
|
|
|
3a14e4 |
-found - ignoring all but the first"),
|
|
|
3a14e4 |
- abfd, target_sect);
|
|
|
3a14e4 |
+ if (bed->init_secondary_reloc_section == NULL
|
|
|
3a14e4 |
+ || ! bed->init_secondary_reloc_section (abfd, hdr, name, shindex))
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ _bfd_error_handler
|
|
|
3a14e4 |
+ /* xgettext:c-format */
|
|
|
3a14e4 |
+ (_("%pB: warning: secondary relocation section '%s' for section %pA found - ignoring"),
|
|
|
3a14e4 |
+ abfd, name, target_sect);
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
goto success;
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2));
|
|
|
3a14e4 |
@@ -7607,9 +7610,20 @@ error_return:
|
|
|
3a14e4 |
if (elf_symtab_shndx_list (abfd))
|
|
|
3a14e4 |
shndx = elf_symtab_shndx_list (abfd)->ndx;
|
|
|
3a14e4 |
break;
|
|
|
3a14e4 |
- default:
|
|
|
3a14e4 |
+ case SHN_COMMON:
|
|
|
3a14e4 |
+ case SHN_ABS:
|
|
|
3a14e4 |
shndx = SHN_ABS;
|
|
|
3a14e4 |
break;
|
|
|
3a14e4 |
+ default:
|
|
|
3a14e4 |
+ if (bed->symbol_section_index)
|
|
|
3a14e4 |
+ shndx = bed->symbol_section_index (abfd, type_ptr);
|
|
|
3a14e4 |
+ else
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ _bfd_error_handler (_("%pB: Unable to handle section index %x in ELF symbol. Using ABS instead. (%x)"),
|
|
|
3a14e4 |
+ abfd, shndx, SHN_COMMON);
|
|
|
3a14e4 |
+ shndx = SHN_ABS;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+ break;
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
else
|
|
|
3a14e4 |
@@ -11056,3 +11070,354 @@ _bfd_elf_maybe_function_sym (const asymb
|
|
|
3a14e4 |
size = 1;
|
|
|
3a14e4 |
return size;
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+/* Set to non-zero to enable some debug messages. */
|
|
|
3a14e4 |
+#define DEBUG_SECONDARY_RELOCS 0
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+/* An internal-to-the-bfd-library only section type
|
|
|
3a14e4 |
+ used to indicate a cached secondary reloc section. */
|
|
|
3a14e4 |
+#define SHT_SECONDARY_RELOC (SHT_LOOS + SHT_RELA)
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+/* Create a BFD section to hold a secondary reloc section. */
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+bfd_boolean
|
|
|
3a14e4 |
+_bfd_elf_init_secondary_reloc_section (bfd * abfd,
|
|
|
3a14e4 |
+ Elf_Internal_Shdr *hdr,
|
|
|
3a14e4 |
+ const char * name,
|
|
|
3a14e4 |
+ unsigned int shindex)
|
|
|
3a14e4 |
+{
|
|
|
3a14e4 |
+ /* We only support RELA secondary relocs. */
|
|
|
3a14e4 |
+ if (hdr->sh_type != SHT_RELA)
|
|
|
3a14e4 |
+ return FALSE;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#if DEBUG_SECONDARY_RELOCS
|
|
|
3a14e4 |
+ fprintf (stderr, "secondary reloc section %s encountered\n", name);
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+ hdr->sh_type = SHT_SECONDARY_RELOC;
|
|
|
3a14e4 |
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
|
|
|
3a14e4 |
+}
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+/* Read in any secondary relocs associated with SEC. */
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+bfd_boolean
|
|
|
3a14e4 |
+_bfd_elf_slurp_secondary_reloc_section (bfd * abfd,
|
|
|
3a14e4 |
+ asection * sec,
|
|
|
3a14e4 |
+ asymbol ** symbols)
|
|
|
3a14e4 |
+{
|
|
|
3a14e4 |
+ const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
|
|
|
3a14e4 |
+ asection * relsec;
|
|
|
3a14e4 |
+ bfd_boolean result = TRUE;
|
|
|
3a14e4 |
+ bfd_vma (*r_sym) (bfd_vma);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#ifdef BFD64
|
|
|
3a14e4 |
+ if (bfd_arch_bits_per_address (abfd) != 32)
|
|
|
3a14e4 |
+ r_sym = elf64_r_sym;
|
|
|
3a14e4 |
+ else
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+ r_sym = elf32_r_sym;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ /* Discover if there are any secondary reloc sections
|
|
|
3a14e4 |
+ associated with SEC. */
|
|
|
3a14e4 |
+ for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ Elf_Internal_Shdr * hdr = & elf_section_data (relsec)->this_hdr;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if (hdr->sh_type == SHT_SECONDARY_RELOC
|
|
|
3a14e4 |
+ && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ bfd_byte * native_relocs;
|
|
|
3a14e4 |
+ bfd_byte * native_reloc;
|
|
|
3a14e4 |
+ arelent * internal_relocs;
|
|
|
3a14e4 |
+ arelent * internal_reloc;
|
|
|
3a14e4 |
+ unsigned int i;
|
|
|
3a14e4 |
+ unsigned int entsize;
|
|
|
3a14e4 |
+ unsigned int symcount;
|
|
|
3a14e4 |
+ unsigned int reloc_count;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#if DEBUG_SECONDARY_RELOCS
|
|
|
3a14e4 |
+ fprintf (stderr, "read secondary relocs for %s from %s\n", sec->name, relsec->name);
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+ entsize = hdr->sh_entsize;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ native_relocs = bfd_malloc (hdr->sh_size);
|
|
|
3a14e4 |
+ if (native_relocs == NULL)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ result = FALSE;
|
|
|
3a14e4 |
+ continue;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ reloc_count = NUM_SHDR_ENTRIES (hdr);
|
|
|
3a14e4 |
+ internal_relocs = (arelent *) bfd_alloc2 (abfd, reloc_count, sizeof (arelent));
|
|
|
3a14e4 |
+ if (internal_relocs == NULL)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ free (native_relocs);
|
|
|
3a14e4 |
+ result = FALSE;
|
|
|
3a14e4 |
+ continue;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
|
|
|
3a14e4 |
+ || (bfd_bread (native_relocs, hdr->sh_size, abfd) != hdr->sh_size))
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ free (native_relocs);
|
|
|
3a14e4 |
+ free (internal_relocs);
|
|
|
3a14e4 |
+ result = FALSE;
|
|
|
3a14e4 |
+ continue;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ symcount = bfd_get_symcount (abfd);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ for (i = 0, internal_reloc = internal_relocs, native_reloc = native_relocs;
|
|
|
3a14e4 |
+ i < reloc_count;
|
|
|
3a14e4 |
+ i++, internal_reloc++, native_reloc += entsize)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ ;
|
|
|
3a14e4 |
+ Elf_Internal_Rela rela;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ ebd->s->swap_reloca_in (abfd, native_reloc, & rela);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ /* The address of an ELF reloc is section relative for an object
|
|
|
3a14e4 |
+ file, and absolute for an executable file or shared library.
|
|
|
3a14e4 |
+ The address of a normal BFD reloc is always section relative,
|
|
|
3a14e4 |
+ and the address of a dynamic reloc is absolute.. */
|
|
|
3a14e4 |
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
|
|
|
3a14e4 |
+ internal_reloc->address = rela.r_offset;
|
|
|
3a14e4 |
+ else
|
|
|
3a14e4 |
+ internal_reloc->address = rela.r_offset - sec->vma;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if (r_sym (rela.r_info) == STN_UNDEF)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ /* FIXME: This and the error case below mean that we
|
|
|
3a14e4 |
+ have a symbol on relocs that is not elf_symbol_type. */
|
|
|
3a14e4 |
+ internal_reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+ else if (r_sym (rela.r_info) > symcount)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ _bfd_error_handler
|
|
|
3a14e4 |
+ /* xgettext:c-format */
|
|
|
3a14e4 |
+ (_("%pB(%pA): relocation %d has invalid symbol index %ld"),
|
|
|
3a14e4 |
+ abfd, sec, i, (long) r_sym (rela.r_info));
|
|
|
3a14e4 |
+ bfd_set_error (bfd_error_bad_value);
|
|
|
3a14e4 |
+ internal_reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
|
|
|
3a14e4 |
+ result = FALSE;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+ else
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ asymbol **ps;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ ps = symbols + r_sym (rela.r_info) - 1;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ internal_reloc->sym_ptr_ptr = ps;
|
|
|
3a14e4 |
+ /* Make sure that this symbol is not removed by strip. */
|
|
|
3a14e4 |
+ (*ps)->flags |= BSF_KEEP;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ internal_reloc->addend = rela.r_addend;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ ebd->elf_info_to_howto (abfd, internal_reloc, & rela);
|
|
|
3a14e4 |
+ if (internal_reloc->howto == NULL)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+#if DEBUG_SECONDARY_RELOCS
|
|
|
3a14e4 |
+ fprintf (stderr, "there is no howto associated with reloc %lx\n", rela.r_info);
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+ result = FALSE;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ free (native_relocs);
|
|
|
3a14e4 |
+ /* Store the internal relocs. */
|
|
|
3a14e4 |
+ elf_section_data (relsec)->sec_info = internal_relocs;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ return result;
|
|
|
3a14e4 |
+}
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+/* Set the ELF section header fields of an output secondary reloc section. */
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+bfd_boolean
|
|
|
3a14e4 |
+_bfd_elf_copy_special_section_fields (const bfd * ibfd ATTRIBUTE_UNUSED,
|
|
|
3a14e4 |
+ bfd * obfd ATTRIBUTE_UNUSED,
|
|
|
3a14e4 |
+ const Elf_Internal_Shdr * isection,
|
|
|
3a14e4 |
+ Elf_Internal_Shdr * osection)
|
|
|
3a14e4 |
+{
|
|
|
3a14e4 |
+ if (isection->sh_type != SHT_SECONDARY_RELOC)
|
|
|
3a14e4 |
+ return TRUE;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if (isection == NULL)
|
|
|
3a14e4 |
+ return FALSE;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ asection * isec = isection->bfd_section;
|
|
|
3a14e4 |
+ if (isec == NULL)
|
|
|
3a14e4 |
+ return FALSE;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ asection * osec = osection->bfd_section;
|
|
|
3a14e4 |
+ if (osec == NULL)
|
|
|
3a14e4 |
+ return FALSE;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ BFD_ASSERT (elf_section_data (osec)->sec_info == NULL);
|
|
|
3a14e4 |
+ elf_section_data (osec)->sec_info = elf_section_data (isec)->sec_info;
|
|
|
3a14e4 |
+ osection->sh_type = SHT_RELA;
|
|
|
3a14e4 |
+ osection->sh_link = elf_onesymtab (obfd);
|
|
|
3a14e4 |
+ if (osection->sh_link == 0)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ /* There is no symbol table - we are hosed... */
|
|
|
3a14e4 |
+ _bfd_error_handler
|
|
|
3a14e4 |
+ /* xgettext:c-format */
|
|
|
3a14e4 |
+ (_("%pB(%pA): link section cannot be set because the output file does not have a symbol table"),
|
|
|
3a14e4 |
+ obfd, osec);
|
|
|
3a14e4 |
+ bfd_set_error (bfd_error_bad_value);
|
|
|
3a14e4 |
+ return FALSE;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ /* Find the output section that corresponds to the isection's sh_info link. */
|
|
|
3a14e4 |
+ BFD_ASSERT (isection->sh_info > 0 && isection->sh_info < elf_numsections (ibfd));
|
|
|
3a14e4 |
+ isection = elf_elfsections (ibfd)[isection->sh_info];
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ BFD_ASSERT (isection != NULL);
|
|
|
3a14e4 |
+ BFD_ASSERT (isection->bfd_section != NULL);
|
|
|
3a14e4 |
+ BFD_ASSERT (isection->bfd_section->output_section != NULL);
|
|
|
3a14e4 |
+ osection->sh_info = elf_section_data (isection->bfd_section->output_section)->this_idx;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#if DEBUG_SECONDARY_RELOCS
|
|
|
3a14e4 |
+ fprintf (stderr, "update header of %s, sh_link = %u, sh_info = %u\n",
|
|
|
3a14e4 |
+ osec->name, osection->sh_link, osection->sh_info);
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ return TRUE;
|
|
|
3a14e4 |
+}
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+/* Write out a secondary reloc section. */
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+bfd_boolean
|
|
|
3a14e4 |
+_bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
|
|
|
3a14e4 |
+{
|
|
|
3a14e4 |
+ const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
|
|
|
3a14e4 |
+ bfd_vma addr_offset;
|
|
|
3a14e4 |
+ asection * relsec;
|
|
|
3a14e4 |
+ bfd_vma (*r_info) (bfd_vma, bfd_vma);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#ifdef BFD64
|
|
|
3a14e4 |
+ if (bfd_arch_bits_per_address (abfd) != 32)
|
|
|
3a14e4 |
+ r_info = elf64_r_info;
|
|
|
3a14e4 |
+ else
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+ r_info = elf32_r_info;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if (sec == NULL)
|
|
|
3a14e4 |
+ return FALSE;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ /* The address of an ELF reloc is section relative for an object
|
|
|
3a14e4 |
+ file, and absolute for an executable file or shared library.
|
|
|
3a14e4 |
+ The address of a BFD reloc is always section relative. */
|
|
|
3a14e4 |
+ addr_offset = 0;
|
|
|
3a14e4 |
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
|
|
|
3a14e4 |
+ addr_offset = sec->vma;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ /* Discover if there are any secondary reloc sections
|
|
|
3a14e4 |
+ associated with SEC. */
|
|
|
3a14e4 |
+ for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ const struct bfd_elf_section_data * const esd = elf_section_data (relsec);
|
|
|
3a14e4 |
+ Elf_Internal_Shdr * const hdr = (Elf_Internal_Shdr *) & esd->this_hdr;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if (hdr->sh_type == SHT_RELA
|
|
|
3a14e4 |
+ && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ asymbol * last_sym;
|
|
|
3a14e4 |
+ int last_sym_idx;
|
|
|
3a14e4 |
+ unsigned int reloc_count;
|
|
|
3a14e4 |
+ unsigned int idx;
|
|
|
3a14e4 |
+ arelent * src_irel;
|
|
|
3a14e4 |
+ bfd_byte * dst_rela;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ BFD_ASSERT (hdr->contents == NULL);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ reloc_count = hdr->sh_size / hdr->sh_entsize;
|
|
|
3a14e4 |
+ BFD_ASSERT (reloc_count > 0);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ hdr->contents = bfd_alloc (abfd, hdr->sh_size);
|
|
|
3a14e4 |
+ if (hdr->contents == NULL)
|
|
|
3a14e4 |
+ continue;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#if DEBUG_SECONDARY_RELOCS
|
|
|
3a14e4 |
+ fprintf (stderr, "write %u secondary relocs for %s from %s\n", reloc_count, sec->name, relsec->name);
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+ last_sym = NULL;
|
|
|
3a14e4 |
+ last_sym_idx = 0;
|
|
|
3a14e4 |
+ dst_rela = hdr->contents;
|
|
|
3a14e4 |
+ src_irel = (arelent *) esd->sec_info;
|
|
|
3a14e4 |
+ BFD_ASSERT (src_irel != NULL);
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ for (idx = 0; idx < reloc_count; idx++, dst_rela += hdr->sh_entsize)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ Elf_Internal_Rela src_rela;
|
|
|
3a14e4 |
+ arelent *ptr;
|
|
|
3a14e4 |
+ asymbol *sym;
|
|
|
3a14e4 |
+ int n;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ ptr = src_irel + idx;
|
|
|
3a14e4 |
+ sym = *ptr->sym_ptr_ptr;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if (sym == last_sym)
|
|
|
3a14e4 |
+ n = last_sym_idx;
|
|
|
3a14e4 |
+ else
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ last_sym = sym;
|
|
|
3a14e4 |
+ n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym);
|
|
|
3a14e4 |
+ if (n < 0)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+#if DEBUG_SECONDARY_RELOCS
|
|
|
3a14e4 |
+ fprintf (stderr, "failed to find symbol %s whilst rewriting relocs\n",
|
|
|
3a14e4 |
+ sym->name);
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+ /* FIXME: Signal failure somehow. */
|
|
|
3a14e4 |
+ n = 0;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+ last_sym_idx = n;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
|
|
|
3a14e4 |
+ && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
|
|
|
3a14e4 |
+ && ! _bfd_elf_validate_reloc (abfd, ptr))
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+#if DEBUG_SECONDARY_RELOCS
|
|
|
3a14e4 |
+ fprintf (stderr, "symbol %s is not in the output bfd\n",
|
|
|
3a14e4 |
+ sym->name);
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+ /* FIXME: Signal failure somehow. */
|
|
|
3a14e4 |
+ n = 0;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if (ptr->howto == NULL)
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+#if DEBUG_SECONDARY_RELOCS
|
|
|
3a14e4 |
+ fprintf (stderr, "reloc for symbol %s does not have a howto associated with it\n",
|
|
|
3a14e4 |
+ sym->name);
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+ /* FIXME: Signal failure somehow. */
|
|
|
3a14e4 |
+ n = 0;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ src_rela.r_offset = ptr->address + addr_offset;
|
|
|
3a14e4 |
+ src_rela.r_info = r_info (n, ptr->howto->type);
|
|
|
3a14e4 |
+ src_rela.r_addend = ptr->addend;
|
|
|
3a14e4 |
+ ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela);
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ return TRUE;
|
|
|
3a14e4 |
+}
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+/* Preserve any OS or PROCESSOR specific section indicies. */
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+unsigned int
|
|
|
3a14e4 |
+_bfd_elf_symbol_section_index (bfd * abfd ATTRIBUTE_UNUSED,
|
|
|
3a14e4 |
+ elf_symbol_type * sym)
|
|
|
3a14e4 |
+{
|
|
|
3a14e4 |
+ unsigned int shndx = sym->internal_elf_sym.st_shndx;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ /* Preserve special section indicies. */
|
|
|
3a14e4 |
+ return shndx >= SHN_LORESERVE ? shndx : SHN_ABS;
|
|
|
3a14e4 |
+}
|
|
|
3a14e4 |
diff -rup binutils.orig/bfd/elfcode.h binutils-2.27/bfd/elfcode.h
|
|
|
3a14e4 |
--- binutils.orig/bfd/elfcode.h 2020-02-12 14:41:48.902875819 +0000
|
|
|
3a14e4 |
+++ binutils-2.27/bfd/elfcode.h 2020-02-12 14:41:58.779803037 +0000
|
|
|
3a14e4 |
@@ -853,6 +853,7 @@ elf_object_p (bfd *abfd)
|
|
|
3a14e4 |
void
|
|
|
3a14e4 |
elf_write_relocs (bfd *abfd, asection *sec, void *data)
|
|
|
3a14e4 |
{
|
|
|
3a14e4 |
+ const struct elf_backend_data * const bed = get_elf_backend_data (abfd);
|
|
|
3a14e4 |
bfd_boolean *failedp = (bfd_boolean *) data;
|
|
|
3a14e4 |
Elf_Internal_Shdr *rela_hdr;
|
|
|
3a14e4 |
bfd_vma addr_offset;
|
|
|
3a14e4 |
@@ -961,6 +962,13 @@ elf_write_relocs (bfd *abfd, asection *s
|
|
|
3a14e4 |
src_rela.r_addend = ptr->addend;
|
|
|
3a14e4 |
(*swap_out) (abfd, &src_rela, dst_rela);
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+ if (bed->write_secondary_relocs != NULL)
|
|
|
3a14e4 |
+ if (! bed->write_secondary_relocs (abfd, sec))
|
|
|
3a14e4 |
+ {
|
|
|
3a14e4 |
+ *failedp = TRUE;
|
|
|
3a14e4 |
+ return;
|
|
|
3a14e4 |
+ }
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
|
|
|
3a14e4 |
/* Write out the program headers. */
|
|
|
3a14e4 |
@@ -1261,7 +1269,10 @@ elf_slurp_symbol_table (bfd *abfd, asymb
|
|
|
3a14e4 |
{
|
|
|
3a14e4 |
/* This symbol is in a section for which we did not
|
|
|
3a14e4 |
create a BFD section. Just use bfd_abs_section,
|
|
|
3a14e4 |
- although it is wrong. FIXME. */
|
|
|
3a14e4 |
+ although it is wrong. FIXME. Note - there is
|
|
|
3a14e4 |
+ code in elf.c:swap_out_syms that calls
|
|
|
3a14e4 |
+ symbol_section_index() in the elf backend for
|
|
|
3a14e4 |
+ cases like this. */
|
|
|
3a14e4 |
sym->symbol.section = bfd_abs_section_ptr;
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
@@ -1488,6 +1499,7 @@ elf_slurp_reloc_table (bfd *abfd,
|
|
|
3a14e4 |
asymbol **symbols,
|
|
|
3a14e4 |
bfd_boolean dynamic)
|
|
|
3a14e4 |
{
|
|
|
3a14e4 |
+ const struct elf_backend_data * const bed = get_elf_backend_data (abfd);
|
|
|
3a14e4 |
struct bfd_elf_section_data * const d = elf_section_data (asect);
|
|
|
3a14e4 |
Elf_Internal_Shdr *rel_hdr;
|
|
|
3a14e4 |
Elf_Internal_Shdr *rel_hdr2;
|
|
|
3a14e4 |
@@ -1551,6 +1563,10 @@ elf_slurp_reloc_table (bfd *abfd,
|
|
|
3a14e4 |
symbols, dynamic))
|
|
|
3a14e4 |
return FALSE;
|
|
|
3a14e4 |
|
|
|
3a14e4 |
+ if (bed->slurp_secondary_relocs != NULL
|
|
|
3a14e4 |
+ && ! bed->slurp_secondary_relocs (abfd, asect, symbols))
|
|
|
3a14e4 |
+ return FALSE;
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
asect->relocation = relents;
|
|
|
3a14e4 |
return TRUE;
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
diff -rup binutils.orig/bfd/elflink.c binutils-2.27/bfd/elflink.c
|
|
|
3a14e4 |
--- binutils.orig/bfd/elflink.c 2020-02-12 14:41:48.896875864 +0000
|
|
|
3a14e4 |
+++ binutils-2.27/bfd/elflink.c 2020-02-12 14:42:44.663464933 +0000
|
|
|
3a14e4 |
@@ -11064,6 +11064,10 @@ elf_final_link_free (bfd *obfd, struct e
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
}
|
|
|
3a14e4 |
|
|
|
3a14e4 |
+#define is_reloc_section(ESDO) \
|
|
|
3a14e4 |
+ ( (ESDO)->this_hdr.sh_type == SHT_REL \
|
|
|
3a14e4 |
+ || (ESDO)->this_hdr.sh_type == SHT_RELA)
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
/* Do the final step of an ELF link. */
|
|
|
3a14e4 |
|
|
|
3a14e4 |
bfd_boolean
|
|
|
3a14e4 |
@@ -11210,8 +11214,7 @@ bfd_elf_final_link (bfd *abfd, struct bf
|
|
|
3a14e4 |
if (sec->flags & SEC_MERGE)
|
|
|
3a14e4 |
merged = TRUE;
|
|
|
3a14e4 |
|
|
|
3a14e4 |
- if (esdo->this_hdr.sh_type == SHT_REL
|
|
|
3a14e4 |
- || esdo->this_hdr.sh_type == SHT_RELA)
|
|
|
3a14e4 |
+ if (is_reloc_section (esdo))
|
|
|
3a14e4 |
/* Some backends use reloc_count in relocation sections
|
|
|
3a14e4 |
to count particular types of relocs. Of course,
|
|
|
3a14e4 |
reloc sections themselves can't have relocations. */
|
|
|
3a14e4 |
diff -rup binutils.orig/bfd/elfxx-target.h binutils-2.27/bfd/elfxx-target.h
|
|
|
3a14e4 |
--- binutils.orig/bfd/elfxx-target.h 2020-02-12 14:41:48.903875812 +0000
|
|
|
3a14e4 |
+++ binutils-2.27/bfd/elfxx-target.h 2020-02-12 14:41:58.780803030 +0000
|
|
|
3a14e4 |
@@ -690,7 +690,7 @@
|
|
|
3a14e4 |
#endif
|
|
|
3a14e4 |
|
|
|
3a14e4 |
#ifndef elf_backend_copy_special_section_fields
|
|
|
3a14e4 |
-#define elf_backend_copy_special_section_fields NULL
|
|
|
3a14e4 |
+#define elf_backend_copy_special_section_fields _bfd_elf_copy_special_section_fields
|
|
|
3a14e4 |
#endif
|
|
|
3a14e4 |
|
|
|
3a14e4 |
#ifndef elf_backend_compact_eh_encoding
|
|
|
3a14e4 |
@@ -698,7 +698,23 @@
|
|
|
3a14e4 |
#endif
|
|
|
3a14e4 |
|
|
|
3a14e4 |
#ifndef elf_backend_cant_unwind_opcode
|
|
|
3a14e4 |
-#define elf_backend_cant_unwind_opcode 0
|
|
|
3a14e4 |
+#define elf_backend_cant_unwind_opcode NULL
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#ifndef elf_backend_init_secondary_reloc_section
|
|
|
3a14e4 |
+#define elf_backend_init_secondary_reloc_section _bfd_elf_init_secondary_reloc_section
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#ifndef elf_backend_slurp_secondary_reloc_section
|
|
|
3a14e4 |
+#define elf_backend_slurp_secondary_reloc_section _bfd_elf_slurp_secondary_reloc_section
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#ifndef elf_backend_write_secondary_reloc_section
|
|
|
3a14e4 |
+#define elf_backend_write_secondary_reloc_section _bfd_elf_write_secondary_reloc_section
|
|
|
3a14e4 |
+#endif
|
|
|
3a14e4 |
+
|
|
|
3a14e4 |
+#ifndef elf_backend_symbol_section_index
|
|
|
3a14e4 |
+#define elf_backend_symbol_section_index _bfd_elf_symbol_section_index
|
|
|
3a14e4 |
#endif
|
|
|
3a14e4 |
|
|
|
3a14e4 |
#ifndef elf_match_priority
|
|
|
3a14e4 |
@@ -817,6 +833,10 @@ static struct elf_backend_data elfNN_bed
|
|
|
3a14e4 |
elf_backend_obj_attrs_handle_unknown,
|
|
|
3a14e4 |
elf_backend_compact_eh_encoding,
|
|
|
3a14e4 |
elf_backend_cant_unwind_opcode,
|
|
|
3a14e4 |
+ elf_backend_init_secondary_reloc_section,
|
|
|
3a14e4 |
+ elf_backend_slurp_secondary_reloc_section,
|
|
|
3a14e4 |
+ elf_backend_write_secondary_reloc_section,
|
|
|
3a14e4 |
+ elf_backend_symbol_section_index,
|
|
|
3a14e4 |
elf_backend_static_tls_alignment,
|
|
|
3a14e4 |
elf_backend_stack_align,
|
|
|
3a14e4 |
elf_backend_strtab_flags,
|
|
|
3a14e4 |
|