const struct elf_backend_data *bed = get_elf_backend_data (abfd);
struct elf_outext_info eoinfo;
bool merged;
- size_t relativecount = 0;
+ size_t relativecount;
+ size_t relr_entsize;
asection *reldyn = 0;
bfd_size_type amt;
asection *attr_section = NULL;
o->reloc_count = 0;
}
+ relativecount = 0;
if (dynamic && info->combreloc && dynobj != NULL)
relativecount = elf_link_sort_relocs (abfd, info, &reldyn);
+ relr_entsize = 0;
+ if (htab->srelrdyn != NULL
+ && htab->srelrdyn->output_section != NULL
+ && htab->srelrdyn->size != 0)
+ {
+ asection *s = htab->srelrdyn->output_section;
+ relr_entsize = elf_section_data (s)->this_hdr.sh_entsize;
+ if (relr_entsize == 0)
+ {
+ relr_entsize = bed->s->arch_size / 8;
+ elf_section_data (s)->this_hdr.sh_entsize = relr_entsize;
+ }
+ }
+
/* If we are linking against a dynamic object, or generating a
shared library, finish up the dynamic linking information. */
if (dynamic)
default:
continue;
case DT_NULL:
- if (relativecount > 0 && dyncon + bed->s->sizeof_dyn < dynconend)
+ if (relativecount != 0)
{
switch (elf_section_data (reldyn)->this_hdr.sh_type)
{
case SHT_REL: dyn.d_tag = DT_RELCOUNT; break;
case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break;
- default: continue;
}
- dyn.d_un.d_val = relativecount;
+ if (dyn.d_tag != DT_NULL
+ && dynconend - dyncon >= bed->s->sizeof_dyn)
+ {
+ dyn.d_un.d_val = relativecount;
+ relativecount = 0;
+ break;
+ }
relativecount = 0;
- break;
+ }
+ if (relr_entsize != 0)
+ {
+ if (dynconend - dyncon >= 3 * bed->s->sizeof_dyn)
+ {
+ asection *s = htab->srelrdyn;
+ dyn.d_tag = DT_RELR;
+ dyn.d_un.d_ptr
+ = s->output_section->vma + s->output_offset;
+ bed->s->swap_dyn_out (dynobj, &dyn, dyncon);
+ dyncon += bed->s->sizeof_dyn;
+
+ dyn.d_tag = DT_RELRSZ;
+ dyn.d_un.d_val = s->size;
+ bed->s->swap_dyn_out (dynobj, &dyn, dyncon);
+ dyncon += bed->s->sizeof_dyn;
+
+ dyn.d_tag = DT_RELRENT;
+ dyn.d_un.d_val = relr_entsize;
+ relr_entsize = 0;
+ break;
+ }
+ relr_entsize = 0;
}
continue;
asection *sdyn;
bfd_byte *dyncon, *dynconend;
bfd_size_type sizeof_dyn;
- bfd_size_type dt_relr_bitmap_count;
bed = get_elf_backend_data (output_bfd);
htab = elf_x86_hash_table (info, bed->target_id);
if (sdyn == NULL || htab->elf.sgot == NULL)
abort ();
- dt_relr_bitmap_count = htab->dt_relr_bitmap.count;
-
sizeof_dyn = bed->s->sizeof_dyn;
dyncon = sdyn->contents;
dynconend = sdyn->contents + sdyn->size;
break;
continue;
- case DT_NULL:
- if (dt_relr_bitmap_count != 0)
- {
- /* Convert 3 spare dynamic tags to DT_RELR, DT_RELRSZ and
- DT_RELRENT for compact relative relocation. */
- s = htab->elf.srelrdyn;
- dyn.d_tag = DT_RELR;
- dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
- (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
- dyncon += sizeof_dyn;
- dyn.d_tag = DT_RELRSZ;
- dyn.d_un.d_val = s->size;
- (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
- dyncon += sizeof_dyn;
- dyn.d_tag = DT_RELRENT;
- dyn.d_un.d_val = ABI_64_P (output_bfd) ? 8 : 4;
- elf_section_data (s->output_section)->this_hdr.sh_entsize
- = dyn.d_un.d_val;
- dt_relr_bitmap_count = 0;
- }
- break;
-
case DT_PLTGOT:
s = htab->elf.sgotplt;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;