mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 01:28:46 +00:00
PowerPC64, sanity check r_offset in relocate_section
This hardens the powerpc64 linker code transformations. * elf64-ppc.c (is_8byte_reloc, offset_in_range): New functions. (ppc64_elf_relocate_section): Sanity check r_offset before accessing section contents for various code transformations.
This commit is contained in:
168
bfd/elf64-ppc.c
168
bfd/elf64-ppc.c
@@ -4601,6 +4601,26 @@ is_plt_seq_reloc (enum elf_ppc64_reloc_type r_type)
|
||||
|| r_type == R_PPC64_PLTSEQ_NOTOC);
|
||||
}
|
||||
|
||||
/* Of relocs which might appear paired with TLSGD and TLSLD marker
|
||||
relocs, return true for those that operate on a dword. */
|
||||
|
||||
static bool
|
||||
is_8byte_reloc (enum elf_ppc64_reloc_type r_type)
|
||||
{
|
||||
return (r_type == R_PPC64_PLT_PCREL34
|
||||
|| r_type == R_PPC64_PLT_PCREL34_NOTOC
|
||||
|| r_type == R_PPC64_PLTCALL);
|
||||
}
|
||||
|
||||
/* Like bfd_reloc_offset_in_range but without a howto. Return true
|
||||
iff a field of SIZE bytes at OFFSET is within SEC limits. */
|
||||
|
||||
static bool
|
||||
offset_in_range (asection *sec, bfd_vma offset, size_t size)
|
||||
{
|
||||
return offset <= sec->size && size <= sec->size - offset;
|
||||
}
|
||||
|
||||
/* Look through the relocs for a section during the first phase, and
|
||||
calculate needed space in the global offset table, procedure
|
||||
linkage table, and dynamic reloc sections. */
|
||||
@@ -15222,13 +15242,18 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
|
||||
case R_PPC64_LO_DS_OPT:
|
||||
insn = bfd_get_32 (input_bfd, contents + rel->r_offset - d_offset);
|
||||
if ((insn & (0x3fu << 26)) != 58u << 26)
|
||||
abort ();
|
||||
insn += (14u << 26) - (58u << 26);
|
||||
bfd_put_32 (input_bfd, insn, contents + rel->r_offset - d_offset);
|
||||
r_type = R_PPC64_TOC16_LO;
|
||||
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
|
||||
if (offset_in_range (input_section, rel->r_offset - d_offset, 4))
|
||||
{
|
||||
insn = bfd_get_32 (input_bfd,
|
||||
contents + rel->r_offset - d_offset);
|
||||
if ((insn & (0x3fu << 26)) != 58u << 26)
|
||||
abort ();
|
||||
insn += (14u << 26) - (58u << 26);
|
||||
bfd_put_32 (input_bfd, insn,
|
||||
contents + rel->r_offset - d_offset);
|
||||
r_type = R_PPC64_TOC16_LO;
|
||||
rel->r_info = ELF64_R_INFO (r_symndx, r_type);
|
||||
}
|
||||
break;
|
||||
|
||||
case R_PPC64_TOC16:
|
||||
@@ -15280,7 +15305,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC64_GOT_TPREL16_HI:
|
||||
case R_PPC64_GOT_TPREL16_HA:
|
||||
if ((tls_mask & TLS_TLS) != 0
|
||||
&& (tls_mask & TLS_TPREL) == 0)
|
||||
&& (tls_mask & TLS_TPREL) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset - d_offset, 4))
|
||||
{
|
||||
rel->r_offset -= d_offset;
|
||||
bfd_put_32 (input_bfd, NOP, contents + rel->r_offset);
|
||||
@@ -15292,7 +15318,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC64_GOT_TPREL16_DS:
|
||||
case R_PPC64_GOT_TPREL16_LO_DS:
|
||||
if ((tls_mask & TLS_TLS) != 0
|
||||
&& (tls_mask & TLS_TPREL) == 0)
|
||||
&& (tls_mask & TLS_TPREL) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset - d_offset, 4))
|
||||
{
|
||||
toctprel:
|
||||
insn = bfd_get_32 (input_bfd,
|
||||
@@ -15317,7 +15344,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC64_GOT_TPREL_PCREL34:
|
||||
if ((tls_mask & TLS_TLS) != 0
|
||||
&& (tls_mask & TLS_TPREL) == 0)
|
||||
&& (tls_mask & TLS_TPREL) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
/* pld ra,sym@got@tprel@pcrel -> paddi ra,r13,sym@tprel */
|
||||
pinsn = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
@@ -15336,7 +15364,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC64_TLS:
|
||||
if ((tls_mask & TLS_TLS) != 0
|
||||
&& (tls_mask & TLS_TPREL) == 0)
|
||||
&& (tls_mask & TLS_TPREL) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
|
||||
insn = _bfd_elf_ppc_at_tls_transform (insn, 13);
|
||||
@@ -15387,13 +15416,15 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC64_GOT_TLSGD16_HI:
|
||||
case R_PPC64_GOT_TLSGD16_HA:
|
||||
tls_gd = TLS_GDIE;
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
goto tls_gdld_hi;
|
||||
break;
|
||||
|
||||
case R_PPC64_GOT_TLSLD16_HI:
|
||||
case R_PPC64_GOT_TLSLD16_HA:
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
tls_gdld_hi:
|
||||
if ((tls_mask & tls_gd) != 0)
|
||||
@@ -15412,13 +15443,15 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC64_GOT_TLSGD16:
|
||||
case R_PPC64_GOT_TLSGD16_LO:
|
||||
tls_gd = TLS_GDIE;
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
goto tls_ldgd_opt;
|
||||
break;
|
||||
|
||||
case R_PPC64_GOT_TLSLD16:
|
||||
case R_PPC64_GOT_TLSLD16_LO:
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
unsigned int insn1, insn2;
|
||||
|
||||
@@ -15488,10 +15521,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
}
|
||||
bfd_put_32 (input_bfd, insn1,
|
||||
contents + rel->r_offset - d_offset);
|
||||
if (offset != (bfd_vma) -1)
|
||||
if (offset != (bfd_vma) -1
|
||||
&& offset_in_range (input_section, offset, 4))
|
||||
{
|
||||
bfd_put_32 (input_bfd, insn2, contents + offset);
|
||||
if (offset + 8 <= input_section->size)
|
||||
if (offset_in_range (input_section, offset + 4, 4))
|
||||
{
|
||||
insn2 = bfd_get_32 (input_bfd, contents + offset + 4);
|
||||
if (insn2 == LD_R2_0R1 + STK_TOC (htab))
|
||||
@@ -15509,7 +15543,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
|
||||
case R_PPC64_GOT_TLSGD_PCREL34:
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0)
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
pinsn = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
pinsn <<= 32;
|
||||
@@ -15535,7 +15570,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
|
||||
case R_PPC64_GOT_TLSLD_PCREL34:
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0)
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
pinsn = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
pinsn <<= 32;
|
||||
@@ -15555,7 +15591,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC64_TLSGD:
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_GD) == 0
|
||||
&& rel + 1 < relend)
|
||||
&& rel + 1 < relend
|
||||
&& offset_in_range (input_section, rel->r_offset,
|
||||
is_8byte_reloc (ELF64_R_TYPE (rel[1].r_info))
|
||||
? 8 : 4))
|
||||
{
|
||||
unsigned int insn2;
|
||||
enum elf_ppc64_reloc_type r_type1 = ELF64_R_TYPE (rel[1].r_info);
|
||||
@@ -15571,7 +15610,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
}
|
||||
|
||||
if (ELF64_R_TYPE (rel[1].r_info) == R_PPC64_PLTCALL)
|
||||
if (r_type1 == R_PPC64_PLTCALL)
|
||||
bfd_put_32 (output_bfd, NOP, contents + offset + 4);
|
||||
|
||||
if ((tls_mask & TLS_GDIE) != 0)
|
||||
@@ -15615,7 +15654,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC64_TLSLD:
|
||||
if ((tls_mask & TLS_TLS) != 0 && (tls_mask & TLS_LD) == 0
|
||||
&& rel + 1 < relend)
|
||||
&& rel + 1 < relend
|
||||
&& offset_in_range (input_section, rel->r_offset,
|
||||
is_8byte_reloc (ELF64_R_TYPE (rel[1].r_info))
|
||||
? 8 : 4))
|
||||
{
|
||||
unsigned int insn2;
|
||||
enum elf_ppc64_reloc_type r_type1 = ELF64_R_TYPE (rel[1].r_info);
|
||||
@@ -15631,7 +15673,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
}
|
||||
|
||||
if (ELF64_R_TYPE (rel[1].r_info) == R_PPC64_PLTCALL)
|
||||
if (r_type1 == R_PPC64_PLTCALL)
|
||||
bfd_put_32 (output_bfd, NOP, contents + offset + 4);
|
||||
|
||||
if (r_type1 == R_PPC64_REL24_NOTOC
|
||||
@@ -15663,7 +15705,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
&& rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64)
|
||||
&& rel[1].r_offset == rel->r_offset + 8)
|
||||
{
|
||||
if ((tls_mask & TLS_GD) == 0)
|
||||
if ((tls_mask & TLS_GD) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_NONE);
|
||||
if ((tls_mask & TLS_GDIE) != 0)
|
||||
@@ -15678,7 +15721,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((tls_mask & TLS_LD) == 0)
|
||||
if ((tls_mask & TLS_LD) == 0
|
||||
&& offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
bfd_put_64 (output_bfd, 1, contents + rel->r_offset);
|
||||
r_type = R_PPC64_NONE;
|
||||
@@ -15699,7 +15743,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
relocation = TOCstart + htab->sec_info[input_section->id].toc_off;
|
||||
if (!bfd_link_pic (info)
|
||||
&& !info->traditional_format
|
||||
&& relocation + 0x80008000 <= 0xffffffff)
|
||||
&& relocation + 0x80008000 <= 0xffffffff
|
||||
&& offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
unsigned int insn1, insn2;
|
||||
|
||||
@@ -15721,7 +15766,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
relocation -= (rel->r_offset
|
||||
+ input_section->output_offset
|
||||
+ input_section->output_section->vma);
|
||||
if (relocation + 0x80008000 <= 0xffffffff)
|
||||
if (relocation + 0x80008000 <= 0xffffffff
|
||||
&& offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
unsigned int insn1, insn2;
|
||||
|
||||
@@ -15758,7 +15804,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
&& rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_REL16_LO)
|
||||
&& rel[1].r_offset == rel->r_offset + 4
|
||||
&& rel[1].r_addend == rel->r_addend + 4
|
||||
&& relocation + 0x80008000 <= 0xffffffff)
|
||||
&& relocation + 0x80008000 <= 0xffffffff
|
||||
&& offset_in_range (input_section, rel->r_offset - d_offset, 8))
|
||||
{
|
||||
unsigned int insn1, insn2;
|
||||
offset = rel->r_offset - d_offset;
|
||||
@@ -15793,7 +15840,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
+ input_section->output_offset
|
||||
+ input_section->output_section->vma)
|
||||
&& tocsave_find (htab, NO_INSERT,
|
||||
&local_syms, rel, input_bfd))
|
||||
&local_syms, rel, input_bfd)
|
||||
&& offset_in_range (input_section, rel->r_offset, 4))
|
||||
{
|
||||
insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
if (insn == NOP
|
||||
@@ -15813,6 +15861,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
/* Branch not taken prediction relocations. */
|
||||
case R_PPC64_ADDR14_BRNTAKEN:
|
||||
case R_PPC64_REL14_BRNTAKEN:
|
||||
if (!offset_in_range (input_section, rel->r_offset, 4))
|
||||
break;
|
||||
insn |= bfd_get_32 (input_bfd,
|
||||
contents + rel->r_offset) & ~(0x01 << 21);
|
||||
/* Fall through. */
|
||||
@@ -15873,7 +15923,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
/* All of these stubs may modify r2, so there must be a
|
||||
branch and link followed by a nop. The nop is
|
||||
replaced by an insn to restore r2. */
|
||||
else if (rel->r_offset + 8 <= input_section->size)
|
||||
else if (offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
unsigned long br;
|
||||
|
||||
@@ -16111,7 +16161,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
&& (r_type == R_PPC64_REL24
|
||||
|| r_type == R_PPC64_REL24_NOTOC)
|
||||
&& relocation == 0
|
||||
&& addend == 0)
|
||||
&& addend == 0
|
||||
&& offset_in_range (input_section, rel->r_offset, 4))
|
||||
{
|
||||
bfd_put_32 (input_bfd, NOP, contents + rel->r_offset);
|
||||
goto copy_reloc;
|
||||
@@ -16127,7 +16178,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
&& sec != NULL
|
||||
&& sec->output_section != NULL
|
||||
&& !discarded_section (sec)
|
||||
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
|
||||
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf))
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
|
||||
if ((insn & (0x3fu << 26 | 0x3)) == 58u << 26 /* ld */)
|
||||
@@ -16150,7 +16202,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
&& sec != NULL
|
||||
&& sec->output_section != NULL
|
||||
&& !discarded_section (sec)
|
||||
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
|
||||
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf))
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
|
||||
if (r_type == R_PPC64_GOT16_LO_DS
|
||||
@@ -16181,7 +16234,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
&& sec != NULL
|
||||
&& sec->output_section != NULL
|
||||
&& !discarded_section (sec)
|
||||
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf))))
|
||||
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf))
|
||||
&& offset_in_range (input_section, rel->r_offset, 8)))
|
||||
break;
|
||||
|
||||
offset = rel->r_offset;
|
||||
@@ -16205,7 +16259,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
&& rel + 1 < relend
|
||||
&& rel[1].r_offset == rel->r_offset
|
||||
&& rel[1].r_info == ELF64_R_INFO (0, R_PPC64_PCREL_OPT)
|
||||
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
|
||||
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf))
|
||||
&& offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
offset = rel->r_offset;
|
||||
pinsn = bfd_get_32 (input_bfd, contents + offset);
|
||||
@@ -16220,7 +16275,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
/* zero means next insn. */
|
||||
off2 = 8;
|
||||
off2 += offset;
|
||||
if (off2 + 4 <= input_section->size)
|
||||
if (offset_in_range (input_section, off2, 4))
|
||||
{
|
||||
uint64_t pinsn2;
|
||||
bfd_signed_vma addend_off;
|
||||
@@ -16228,7 +16283,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
pinsn2 <<= 32;
|
||||
if ((pinsn2 & (63ULL << 58)) == 1ULL << 58)
|
||||
{
|
||||
if (off2 + 8 > input_section->size)
|
||||
if (!offset_in_range (input_section, off2, 8))
|
||||
break;
|
||||
pinsn2 |= bfd_get_32 (input_bfd,
|
||||
contents + off2 + 4);
|
||||
@@ -16659,7 +16714,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC64_TPREL16_HIGHESTA:
|
||||
if (h != NULL
|
||||
&& h->elf.root.type == bfd_link_hash_undefweak
|
||||
&& h->elf.dynindx == -1)
|
||||
&& h->elf.dynindx == -1
|
||||
&& offset_in_range (input_section, rel->r_offset - d_offset, 4))
|
||||
{
|
||||
/* Make this relocation against an undefined weak symbol
|
||||
resolve to zero. This is really just a tweak, since
|
||||
@@ -17041,7 +17097,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
htab->notoc_plt = 1;
|
||||
/* Fall through. */
|
||||
case R_PPC64_PLTCALL:
|
||||
if (unresolved_reloc)
|
||||
if (unresolved_reloc
|
||||
&& offset_in_range (input_section, rel->r_offset,
|
||||
r_type == R_PPC64_PLTCALL ? 8 : 4))
|
||||
{
|
||||
/* No plt entry. Make this into a direct call. */
|
||||
bfd_byte *p = contents + rel->r_offset;
|
||||
@@ -17069,7 +17127,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
htab->notoc_plt = 1;
|
||||
/* Fall through. */
|
||||
case R_PPC64_PLT_PCREL34:
|
||||
if (unresolved_reloc)
|
||||
if (unresolved_reloc
|
||||
&& offset_in_range (input_section, rel->r_offset, 8))
|
||||
{
|
||||
bfd_byte *p = contents + rel->r_offset;
|
||||
bfd_put_32 (input_bfd, PNOP >> 32, p);
|
||||
@@ -17097,9 +17156,12 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
{
|
||||
bfd_byte *p;
|
||||
nop_it:
|
||||
p = contents + (rel->r_offset & ~3);
|
||||
bfd_put_32 (input_bfd, NOP, p);
|
||||
goto copy_reloc;
|
||||
if (offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
p = contents + (rel->r_offset & ~3);
|
||||
bfd_put_32 (input_bfd, NOP, p);
|
||||
goto copy_reloc;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -17120,7 +17182,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC64_TOC16_LO:
|
||||
case R_PPC64_TOC16_LO_DS:
|
||||
if (htab->do_toc_opt && relocation + addend + 0x8000 < 0x10000
|
||||
&& !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn)
|
||||
&& !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
bfd_byte *p = contents + (rel->r_offset & ~3);
|
||||
insn = bfd_get_32 (input_bfd, p);
|
||||
@@ -17140,7 +17203,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
|
||||
case R_PPC64_TPREL16_HA:
|
||||
if (htab->do_tls_opt && relocation + addend + 0x8000 < 0x10000)
|
||||
if (htab->do_tls_opt
|
||||
&& relocation + addend + 0x8000 < 0x10000
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
bfd_byte *p = contents + (rel->r_offset & ~3);
|
||||
bfd_put_32 (input_bfd, NOP, p);
|
||||
@@ -17150,7 +17215,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC64_TPREL16_LO:
|
||||
case R_PPC64_TPREL16_LO_DS:
|
||||
if (htab->do_tls_opt && relocation + addend + 0x8000 < 0x10000)
|
||||
if (htab->do_tls_opt
|
||||
&& relocation + addend + 0x8000 < 0x10000
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
bfd_byte *p = contents + (rel->r_offset & ~3);
|
||||
insn = bfd_get_32 (input_bfd, p);
|
||||
@@ -17234,6 +17301,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC64_TPREL16_LO_DS:
|
||||
case R_PPC64_DTPREL16_DS:
|
||||
case R_PPC64_DTPREL16_LO_DS:
|
||||
if (!offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
break;
|
||||
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
|
||||
mask = 3;
|
||||
/* If this reloc is against an lq, lxv, or stxv insn, then
|
||||
@@ -17287,7 +17356,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
have different reloc types. */
|
||||
if (howto->complain_on_overflow != complain_overflow_dont
|
||||
&& howto->dst_mask == 0xffff
|
||||
&& (input_section->flags & SEC_CODE) != 0)
|
||||
&& (input_section->flags & SEC_CODE) != 0
|
||||
&& offset_in_range (input_section, rel->r_offset & ~3, 4))
|
||||
{
|
||||
enum complain_overflow complain = complain_overflow_signed;
|
||||
|
||||
@@ -17329,7 +17399,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC64_PLT_PCREL34_NOTOC:
|
||||
case R_PPC64_D28:
|
||||
case R_PPC64_PCREL28:
|
||||
if (rel->r_offset + 8 > input_section->size)
|
||||
if (!offset_in_range (input_section, rel->r_offset, 8))
|
||||
r = bfd_reloc_outofrange;
|
||||
else
|
||||
{
|
||||
@@ -17358,7 +17428,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
|
||||
case R_PPC64_REL16DX_HA:
|
||||
if (rel->r_offset + 4 > input_section->size)
|
||||
if (!offset_in_range (input_section, rel->r_offset, 4))
|
||||
r = bfd_reloc_outofrange;
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user