mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-15 11:45:27 +08:00
PowerPC, sanity check r_offset in relocate_section
* elf32-ppc.c (offset_in_range): New function. (ppc_elf_vle_split16): Sanity check r_offset before accessing section contents. Return status. (ppc_elf_relocate_section): Sanity check r_offset before accessing section contents. Don't segfault on NULL howto.
This commit is contained in:
181
bfd/elf32-ppc.c
181
bfd/elf32-ppc.c
@ -2856,6 +2856,15 @@ is_plt_seq_reloc (enum elf_ppc_reloc_type r_type)
|
||||
|| r_type == R_PPC_PLTSEQ);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
static void
|
||||
bad_shared_reloc (bfd *abfd, enum elf_ppc_reloc_type r_type)
|
||||
{
|
||||
@ -3884,7 +3893,7 @@ ppc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
static bfd_reloc_status_type
|
||||
ppc_elf_vle_split16 (bfd *input_bfd,
|
||||
asection *input_section,
|
||||
unsigned long offset,
|
||||
@ -3895,6 +3904,8 @@ ppc_elf_vle_split16 (bfd *input_bfd,
|
||||
{
|
||||
unsigned int insn, opcode;
|
||||
|
||||
if (!offset_in_range (input_section, offset, 4))
|
||||
return bfd_reloc_outofrange;
|
||||
insn = bfd_get_32 (input_bfd, loc);
|
||||
opcode = insn & E_OPCODE_MASK;
|
||||
if (opcode == E_OR2I_INSN
|
||||
@ -3951,6 +3962,7 @@ ppc_elf_vle_split16 (bfd *input_bfd,
|
||||
}
|
||||
insn |= value & 0x7ff;
|
||||
bfd_put_32 (input_bfd, insn, loc);
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -7132,7 +7144,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_GOT_TPREL16:
|
||||
case R_PPC_GOT_TPREL16_LO:
|
||||
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))
|
||||
{
|
||||
bfd_vma insn;
|
||||
|
||||
@ -7149,7 +7162,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC_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, 4))
|
||||
{
|
||||
bfd_vma insn;
|
||||
|
||||
@ -7170,13 +7184,15 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_GOT_TLSGD16_HI:
|
||||
case R_PPC_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 - d_offset, 4))
|
||||
goto tls_gdld_hi;
|
||||
break;
|
||||
|
||||
case R_PPC_GOT_TLSLD16_HI:
|
||||
case R_PPC_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 - d_offset, 4))
|
||||
{
|
||||
tls_gdld_hi:
|
||||
if ((tls_mask & tls_gd) != 0)
|
||||
@ -7195,13 +7211,15 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_GOT_TLSGD16:
|
||||
case R_PPC_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 - d_offset, 4))
|
||||
goto tls_ldgd_opt;
|
||||
break;
|
||||
|
||||
case R_PPC_GOT_TLSLD16:
|
||||
case R_PPC_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 - d_offset, 4))
|
||||
{
|
||||
unsigned int insn1, insn2;
|
||||
bfd_vma offset;
|
||||
@ -7229,7 +7247,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
/* IE */
|
||||
insn1 &= (0x1f << 21) | (0x1f << 16);
|
||||
insn1 |= 32u << 26; /* lwz */
|
||||
if (offset != (bfd_vma) -1)
|
||||
if (offset != (bfd_vma) -1
|
||||
&& offset_in_range (input_section, offset, 4))
|
||||
{
|
||||
rel[1].r_info = ELF32_R_INFO (STN_UNDEF, R_PPC_NONE);
|
||||
insn2 = 0x7c631214; /* add 3,3,2 */
|
||||
@ -7262,7 +7281,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
}
|
||||
r_type = R_PPC_TPREL16_HA;
|
||||
rel->r_info = ELF32_R_INFO (r_symndx, r_type);
|
||||
if (offset != (bfd_vma) -1)
|
||||
if (offset != (bfd_vma) -1
|
||||
&& offset_in_range (input_section, offset, 4))
|
||||
{
|
||||
rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO);
|
||||
rel[1].r_offset = offset + d_offset;
|
||||
@ -7284,7 +7304,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC_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, 4))
|
||||
{
|
||||
unsigned int insn2;
|
||||
bfd_vma offset = rel->r_offset;
|
||||
@ -7319,7 +7340,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC_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, 4))
|
||||
{
|
||||
unsigned int insn2;
|
||||
|
||||
@ -7372,6 +7394,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
/* Branch not taken prediction relocations. */
|
||||
case R_PPC_ADDR14_BRNTAKEN:
|
||||
case R_PPC_REL14_BRNTAKEN:
|
||||
if (offset_in_range (input_section, rel->r_offset, 4))
|
||||
{
|
||||
unsigned int insn;
|
||||
|
||||
@ -7392,6 +7415,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
|
||||
case R_PPC_PLT16_HA:
|
||||
if (offset_in_range (input_section, rel->r_offset - d_offset, 4))
|
||||
{
|
||||
unsigned int insn;
|
||||
|
||||
@ -7429,7 +7453,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
variable defined in a shared library to PIC. */
|
||||
unsigned int insn;
|
||||
|
||||
if (r_type == R_PPC_ADDR16_HA)
|
||||
if (r_type == R_PPC_ADDR16_HA
|
||||
&& offset_in_range (input_section, rel->r_offset - d_offset, 4))
|
||||
{
|
||||
insn = bfd_get_32 (input_bfd,
|
||||
contents + rel->r_offset - d_offset);
|
||||
@ -7492,7 +7517,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
input_bfd, input_section, (uint64_t) rel->r_offset,
|
||||
"R_PPC_ADDR16_HA", insn);
|
||||
}
|
||||
else if (r_type == R_PPC_ADDR16_LO)
|
||||
else if (r_type == R_PPC_ADDR16_LO
|
||||
&& offset_in_range (input_section,
|
||||
rel->r_offset - d_offset, 4))
|
||||
{
|
||||
insn = bfd_get_32 (input_bfd,
|
||||
contents + rel->r_offset - d_offset);
|
||||
@ -7616,9 +7643,15 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
switch (r_type)
|
||||
{
|
||||
default:
|
||||
de_fault:
|
||||
if (howto)
|
||||
/* xgettext:c-format */
|
||||
_bfd_error_handler (_("%pB: %s unsupported"),
|
||||
input_bfd, howto->name);
|
||||
else
|
||||
/* xgettext:c-format */
|
||||
_bfd_error_handler (_("%pB: reloc %#x unsupported"),
|
||||
input_bfd, r_type);
|
||||
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
ret = false;
|
||||
@ -7956,7 +7989,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_TPREL16_HA:
|
||||
if (h != NULL
|
||||
&& h->root.type == bfd_link_hash_undefweak
|
||||
&& h->dynindx == -1)
|
||||
&& h->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
|
||||
@ -8224,6 +8258,11 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
/* Fall through. */
|
||||
|
||||
case R_PPC_RELAX:
|
||||
if (bfd_link_pic (info)
|
||||
? offset_in_range (input_section, rel->r_offset - 12,
|
||||
ARRAY_SIZE (shared_stub_entry) * 4)
|
||||
: offset_in_range (input_section, rel->r_offset,
|
||||
ARRAY_SIZE (stub_entry) * 4))
|
||||
{
|
||||
const int *stub;
|
||||
size_t size;
|
||||
@ -8284,6 +8323,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
wrel->r_offset += 4;
|
||||
wrel->r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO);
|
||||
}
|
||||
else
|
||||
goto de_fault;
|
||||
continue;
|
||||
|
||||
/* Indirect .sdata relocation. */
|
||||
@ -8487,51 +8528,63 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC_VLE_LO16A:
|
||||
relocation = relocation + addend;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
contents + rel->r_offset, relocation,
|
||||
split16a_type, htab->params->vle_reloc_fixup);
|
||||
goto copy_reloc;
|
||||
split16a_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
goto report_reloc;
|
||||
|
||||
case R_PPC_VLE_LO16D:
|
||||
relocation = relocation + addend;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
contents + rel->r_offset, relocation,
|
||||
split16d_type, htab->params->vle_reloc_fixup);
|
||||
goto copy_reloc;
|
||||
split16d_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
goto report_reloc;
|
||||
|
||||
case R_PPC_VLE_HI16A:
|
||||
relocation = (relocation + addend) >> 16;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
contents + rel->r_offset, relocation,
|
||||
split16a_type, htab->params->vle_reloc_fixup);
|
||||
goto copy_reloc;
|
||||
split16a_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
goto report_reloc;
|
||||
|
||||
case R_PPC_VLE_HI16D:
|
||||
relocation = (relocation + addend) >> 16;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
contents + rel->r_offset, relocation,
|
||||
split16d_type, htab->params->vle_reloc_fixup);
|
||||
goto copy_reloc;
|
||||
split16d_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
goto report_reloc;
|
||||
|
||||
case R_PPC_VLE_HA16A:
|
||||
relocation = (relocation + addend + 0x8000) >> 16;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
contents + rel->r_offset, relocation,
|
||||
split16a_type, htab->params->vle_reloc_fixup);
|
||||
goto copy_reloc;
|
||||
split16a_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
goto report_reloc;
|
||||
|
||||
case R_PPC_VLE_HA16D:
|
||||
relocation = (relocation + addend + 0x8000) >> 16;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
contents + rel->r_offset, relocation,
|
||||
split16d_type, htab->params->vle_reloc_fixup);
|
||||
goto copy_reloc;
|
||||
split16d_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
goto report_reloc;
|
||||
|
||||
/* Relocate against either _SDA_BASE_, _SDA2_BASE_, or 0. */
|
||||
case R_PPC_EMB_SDA21:
|
||||
case R_PPC_VLE_SDA21:
|
||||
case R_PPC_EMB_RELSDA:
|
||||
case R_PPC_VLE_SDA21_LO:
|
||||
if (!offset_in_range (input_section, rel->r_offset, 4))
|
||||
{
|
||||
r = bfd_reloc_outofrange;
|
||||
goto report_reloc;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *name;
|
||||
int reg;
|
||||
@ -8623,10 +8676,11 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
|
||||
|
||||
r = bfd_reloc_ok;
|
||||
if (r_type == R_PPC_VLE_SDA21
|
||||
&& ((relocation + 0x80000) & 0xffffffff) > 0x100000)
|
||||
goto overflow;
|
||||
goto copy_reloc;
|
||||
r = bfd_reloc_overflow;
|
||||
goto report_reloc;
|
||||
}
|
||||
/* Fill in register field. */
|
||||
insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT);
|
||||
@ -8640,6 +8694,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_VLE_SDAREL_HI16D:
|
||||
case R_PPC_VLE_SDAREL_HA16A:
|
||||
case R_PPC_VLE_SDAREL_HA16D:
|
||||
if (!offset_in_range (input_section, rel->r_offset, 4))
|
||||
r = bfd_reloc_outofrange;
|
||||
else
|
||||
{
|
||||
bfd_vma value;
|
||||
const char *name;
|
||||
@ -8682,19 +8739,22 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
value = relocation + addend - SYM_VAL (sda);
|
||||
|
||||
if (r_type == R_PPC_VLE_SDAREL_LO16A)
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section,
|
||||
rel->r_offset,
|
||||
contents + rel->r_offset, value,
|
||||
split16a_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
else if (r_type == R_PPC_VLE_SDAREL_LO16D)
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section,
|
||||
rel->r_offset,
|
||||
contents + rel->r_offset, value,
|
||||
split16d_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
else if (r_type == R_PPC_VLE_SDAREL_HI16A)
|
||||
{
|
||||
value = value >> 16;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section,
|
||||
rel->r_offset,
|
||||
contents + rel->r_offset, value,
|
||||
split16a_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
@ -8702,7 +8762,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
else if (r_type == R_PPC_VLE_SDAREL_HI16D)
|
||||
{
|
||||
value = value >> 16;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section,
|
||||
rel->r_offset,
|
||||
contents + rel->r_offset, value,
|
||||
split16d_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
@ -8710,7 +8771,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
else if (r_type == R_PPC_VLE_SDAREL_HA16A)
|
||||
{
|
||||
value = (value + 0x8000) >> 16;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section,
|
||||
rel->r_offset,
|
||||
contents + rel->r_offset, value,
|
||||
split16a_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
@ -8718,17 +8780,27 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
else if (r_type == R_PPC_VLE_SDAREL_HA16D)
|
||||
{
|
||||
value = (value + 0x8000) >> 16;
|
||||
ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
|
||||
r = ppc_elf_vle_split16 (input_bfd, input_section,
|
||||
rel->r_offset,
|
||||
contents + rel->r_offset, value,
|
||||
split16d_type,
|
||||
htab->params->vle_reloc_fixup);
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
goto copy_reloc;
|
||||
goto report_reloc;
|
||||
|
||||
case R_PPC_VLE_ADDR20:
|
||||
ppc_elf_vle_split20 (output_bfd, contents + rel->r_offset, relocation);
|
||||
goto copy_reloc;
|
||||
if (!offset_in_range (input_section, rel->r_offset, 4))
|
||||
r = bfd_reloc_outofrange;
|
||||
else
|
||||
{
|
||||
ppc_elf_vle_split20 (output_bfd, contents + rel->r_offset,
|
||||
relocation);
|
||||
r = bfd_reloc_ok;
|
||||
}
|
||||
goto report_reloc;
|
||||
|
||||
/* Relocate against the beginning of the section. */
|
||||
case R_PPC_SECTOFF:
|
||||
@ -8780,7 +8852,10 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
|
||||
case R_PPC_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);
|
||||
@ -8788,7 +8863,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
break;
|
||||
|
||||
case R_PPC_TPREL16_LO:
|
||||
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);
|
||||
unsigned int insn = bfd_get_32 (input_bfd, p);
|
||||
@ -8806,6 +8883,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
|
||||
case R_PPC_PLTCALL:
|
||||
if (unresolved_reloc)
|
||||
{
|
||||
if (offset_in_range (input_section, rel->r_offset, 4))
|
||||
{
|
||||
bfd_byte *p = contents + rel->r_offset;
|
||||
unsigned int insn = bfd_get_32 (input_bfd, p);
|
||||
@ -8815,6 +8894,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
r_type = R_PPC_REL24;
|
||||
howto = ppc_elf_howto_table[r_type];
|
||||
}
|
||||
}
|
||||
else if (htab->plt_type != PLT_NEW)
|
||||
info->callbacks->einfo
|
||||
(_("%X%P: %H: %s relocation unsupported for bss-plt\n"),
|
||||
@ -8826,6 +8906,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_PLT16_HA:
|
||||
case R_PPC_PLT16_LO:
|
||||
if (unresolved_reloc)
|
||||
{
|
||||
if (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);
|
||||
@ -8833,6 +8915,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
r_type = R_PPC_NONE;
|
||||
howto = ppc_elf_howto_table[r_type];
|
||||
}
|
||||
}
|
||||
else if (htab->plt_type != PLT_NEW)
|
||||
info->callbacks->einfo
|
||||
(_("%X%P: %H: %s relocation unsupported for bss-plt\n"),
|
||||
@ -8893,6 +8976,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_GOT_DTPREL16_LO:
|
||||
case R_PPC_GOT_TPREL16:
|
||||
case R_PPC_GOT_TPREL16_LO:
|
||||
if (offset_in_range (input_section, rel->r_offset - d_offset, 4))
|
||||
{
|
||||
/* The 32-bit ABI lacks proper relocations to deal with
|
||||
certain 64-bit instructions. Prevent damage to bits
|
||||
@ -8957,7 +9041,8 @@ ppc_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;
|
||||
|
||||
@ -8984,7 +9069,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
if (r_type == R_PPC_REL16DX_HA)
|
||||
{
|
||||
/* Split field reloc isn't handled by _bfd_final_link_relocate. */
|
||||
if (rel->r_offset + 4 > input_section->size)
|
||||
if (offset_in_range (input_section, rel->r_offset, 4))
|
||||
r = bfd_reloc_outofrange;
|
||||
else
|
||||
{
|
||||
@ -9006,11 +9091,11 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
|
||||
rel->r_offset, relocation, addend);
|
||||
|
||||
report_reloc:
|
||||
if (r != bfd_reloc_ok)
|
||||
{
|
||||
if (r == bfd_reloc_overflow)
|
||||
{
|
||||
overflow:
|
||||
/* On code like "if (foo) foo();" don't report overflow
|
||||
on a branch to zero when foo is undefined. */
|
||||
if (!warned
|
||||
|
Reference in New Issue
Block a user