elf32-cr16.c tidy

Prompted by two occurrences of -Wmisleading-indentation warnings.

	* elf32-cr16.c: Formatting.
	(cr16_elf_final_link_relocate): Sign extend rather than clumsy
	"add or subtract" of offset value.  Simplify range checks.  Move
	common code out of "if" branches.  Don't refetch insn fields
	needlessly.
This commit is contained in:
Alan Modra 2020-10-16 09:27:10 +10:30
parent fba8689ad3
commit db75b8f70c
2 changed files with 361 additions and 368 deletions

View File

@ -1,3 +1,11 @@
2020-10-16 Alan Modra <amodra@gmail.com>
* elf32-cr16.c: Formatting.
(cr16_elf_final_link_relocate): Sign extend rather than clumsy
"add or subtract" of offset value. Simplify range checks. Move
common code out of "if" branches. Don't refetch insn fields
needlessly.
2020-10-16 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (ppc64_elf_relocate_section): Tighten sanity check

View File

@ -937,9 +937,8 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
overflow. */
if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
{
check |= ((bfd_vma) - 1
& ~((bfd_vma) - 1
>> howto->rightshift));
check |= ((bfd_vma) -1
& ~((bfd_vma) -1 >> howto->rightshift));
if (((bfd_vma) check & ~reloc_bits)
!= (-(bfd_vma) 1 & ~reloc_bits))
@ -995,14 +994,11 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
{
Rvalue1 = bfd_get_16 (input_bfd, hit_data);
/* Add or subtract the offset value. */
if (Rvalue1 & 0x8000)
Rvalue -= (~Rvalue1 + 1) & 0xffff;
else
Rvalue1 = (Rvalue1 ^ 0x8000) - 0x8000;
Rvalue += Rvalue1;
/* Check for range. */
if ((long) Rvalue > 0xffff || (long) Rvalue < 0x0)
if (Rvalue > 0xffff)
return bfd_reloc_overflow;
}
@ -1013,16 +1009,13 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
if ((r_type == R_CR16_ABS20) || (r_type == R_CR16_IMM20))
{
Rvalue1 = (bfd_get_16 (input_bfd, hit_data + 2)
| (((bfd_get_16 (input_bfd, hit_data) & 0xf) <<16)));
| (((bfd_get_16 (input_bfd, hit_data) & 0xf) << 16)));
/* Add or subtract the offset value. */
if (Rvalue1 & 0x80000)
Rvalue -= (~Rvalue1 + 1) & 0xfffff;
else
Rvalue1 = (Rvalue1 ^ 0x80000) - 0x80000;
Rvalue += Rvalue1;
/* Check for range. */
if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
if (Rvalue > 0xfffff)
return bfd_reloc_overflow;
bfd_put_16 (input_bfd, ((bfd_get_16 (input_bfd, hit_data) & 0xfff0)
@ -1032,11 +1025,10 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
else if (r_type == R_CR16_GOT_REGREL20)
{
asection *sgot = elf_hash_table (info)->sgot;
bfd_vma off;
if (h != NULL)
{
bfd_vma off;
off = h->got.offset;
BFD_ASSERT (off != (bfd_vma) -1);
@ -1051,24 +1043,19 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
relocation entry to initialize the value. This
is done in the finish_dynamic_symbol routine. */
bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
Rvalue = sgot->output_offset + off;
}
else
{
bfd_vma off;
off = elf_local_got_offsets (input_bfd)[symndx];
bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
Rvalue = sgot->output_offset + off;
bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
}
Rvalue = sgot->output_offset + off;
Rvalue += addend;
/* REVISIT: if ((long) Rvalue > 0xffffff ||
(long) Rvalue < -0x800000). */
if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
if (Rvalue > 0xffffff)
return bfd_reloc_overflow;
@ -1080,15 +1067,14 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
else if (r_type == R_CR16_GOTC_REGREL20)
{
asection *sgot = elf_hash_table (info)->sgot;
bfd_vma off;
if (h != NULL)
{
bfd_vma off;
off = h->got.offset;
BFD_ASSERT (off != (bfd_vma) -1);
Rvalue >>=1; /* For code symbols. */
Rvalue >>= 1; /* For code symbols. */
if (! elf_hash_table (info)->dynamic_sections_created
|| SYMBOL_REFERENCES_LOCAL (info, h))
@ -1101,35 +1087,28 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
relocation entry to initialize the value. This
is done in the finish_dynamic_symbol routine. */
bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
Rvalue = sgot->output_offset + off;
}
else
{
bfd_vma off;
off = elf_local_got_offsets (input_bfd)[symndx];
Rvalue >>= 1;
bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
Rvalue = sgot->output_offset + off;
bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
}
Rvalue = sgot->output_offset + off;
Rvalue += addend;
/* Check if any value in DISP. */
Rvalue1 =((bfd_get_32 (input_bfd, hit_data) >>16)
| (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
Rvalue1 = bfd_get_32 (input_bfd, hit_data);
Rvalue1 = ((Rvalue1 >> 16) | ((Rvalue1 & 0xfff) >> 8 << 16));
/* Add or subtract the offset value. */
if (Rvalue1 & 0x80000)
Rvalue -= (~Rvalue1 + 1) & 0xfffff;
else
Rvalue1 = (Rvalue1 ^ 0x80000) - 0x80000;
Rvalue += Rvalue1;
/* Check for range. */
/* REVISIT: if ((long) Rvalue > 0xffffff
|| (long) Rvalue < -0x800000). */
if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
if (Rvalue > 0xffffff)
return bfd_reloc_overflow;
bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
@ -1140,18 +1119,16 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
{
if (r_type == R_CR16_ABS24)
{
Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
| (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16)
| (((bfd_get_32 (input_bfd, hit_data) & 0xf) <<20)));
Rvalue1 = bfd_get_32 (input_bfd, hit_data);
Rvalue1 = ((Rvalue1 >> 16)
| ((Rvalue1 & 0xfff) >> 8 << 16)
| ((Rvalue1 & 0xf) << 20));
/* Add or subtract the offset value. */
if (Rvalue1 & 0x800000)
Rvalue -= (~Rvalue1 + 1) & 0xffffff;
else
Rvalue1 = (Rvalue1 ^ 0x800000) - 0x800000;
Rvalue += Rvalue1;
/* Check for Range. */
if ((long) Rvalue > 0xffffff || (long) Rvalue < 0x0)
if (Rvalue > 0xffffff)
return bfd_reloc_overflow;
Rvalue = ((((Rvalue >> 20) & 0xf) | (((Rvalue >> 16) & 0xf)<<8)
@ -1166,43 +1143,40 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
}
else if ((r_type == R_CR16_IMM32) || (r_type == R_CR16_IMM32a))
{
Rvalue1 =((((bfd_get_32 (input_bfd, hit_data)) >> 16) &0xffff)
| (((bfd_get_32 (input_bfd, hit_data)) &0xffff)) << 16);
Rvalue1 = bfd_get_32 (input_bfd, hit_data);
Rvalue1 = (((Rvalue1 >> 16) & 0xffff)
| ((Rvalue1 & 0xffff) << 16));
/* Add or subtract the offset value. */
if (Rvalue1 & 0x80000000)
Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
else
Rvalue1 = (Rvalue1 ^ 0x80000000) - 0x80000000;
Rvalue += Rvalue1;
/* Check for range. */
if (Rvalue > 0xffffffff || (long) Rvalue < 0x0)
if (Rvalue > 0xffffffff)
return bfd_reloc_overflow;
Rvalue = (((Rvalue >> 16)& 0xffff) | (Rvalue & 0xffff) << 16);
Rvalue = (((Rvalue >> 16) & 0xffff) | (Rvalue & 0xffff) << 16);
}
else if (r_type == R_CR16_DISP24a)
{
Rvalue = (((Rvalue & 0xfffffe) | (Rvalue >> 23)));
Rvalue = ((Rvalue >> 16) & 0xff) | ((Rvalue & 0xffff) << 16)
| (bfd_get_32 (input_bfd, hit_data));
Rvalue = (((Rvalue >> 16) & 0xff) | ((Rvalue & 0xffff) << 16)
| bfd_get_32 (input_bfd, hit_data));
}
else if ((r_type == R_CR16_REGREL20)
|| (r_type == R_CR16_REGREL20a))
{
Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
| (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
/* Add or subtract the offset value. */
if (Rvalue1 & 0x80000)
Rvalue -= (~Rvalue1 + 1) & 0xfffff;
else
Rvalue1 = bfd_get_32 (input_bfd, hit_data);
Rvalue1 = (((Rvalue1 >> 16) & 0xffff)
| ((Rvalue1 & 0xfff) >> 8 << 16));
Rvalue1 = (Rvalue1 ^ 0x80000) - 0x80000;
Rvalue += Rvalue1;
/* Check for range. */
if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
if (Rvalue > 0xfffff)
return bfd_reloc_overflow;
Rvalue = (((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
Rvalue = (((((Rvalue >> 20) & 0xf) | (((Rvalue >> 16) & 0xf) << 8)
| ((Rvalue & 0xffff) << 16)))
| (bfd_get_32 (input_bfd, hit_data) & 0xf0ff));
@ -1211,13 +1185,10 @@ cr16_elf_final_link_relocate (reloc_howto_type *howto,
{
Rvalue1 = (bfd_get_32 (input_bfd, hit_data));
/* Add or subtract the offset value */
if (Rvalue1 & 0x80000000)
Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
else
Rvalue1 = (Rvalue1 ^ 0x80000000) - 0x80000000;
Rvalue += Rvalue1;
/* Check for Ranga */
/* Check for Range. */
if (Rvalue > 0xffffffff)
return bfd_reloc_overflow;
}
@ -1861,11 +1832,13 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
unsigned int code;
/* Get the opcode. */
code = (unsigned int) bfd_get_32 (abfd, contents + irel->r_offset);
code = (unsigned int) bfd_get_32 (abfd,
contents + irel->r_offset);
/* Verify it's a 'bcond' and fix the opcode. */
if ((code & 0xffff) == 0x0010)
bfd_put_16 (abfd, 0x1800 | ((0xf & (code >> 20)) << 4), contents + irel->r_offset);
bfd_put_16 (abfd, 0x1800 | ((0xf & (code >> 20)) << 4),
contents + irel->r_offset);
else
continue;
@ -1909,7 +1882,7 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
unsigned short code;
/* Get the opcode. */
code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
code = bfd_get_16 (abfd, contents + irel->r_offset);
/* Verify it's a 'bcond' and fix the opcode. */
if ((code & 0xff0f) == 0x1800)
@ -1945,8 +1918,8 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
bfd_vma value1 = 0;
/* Get the existing value from the mcode */
value1 = ((bfd_get_32 (abfd, contents + irel->r_offset + 2) >> 16)
|(((bfd_get_32 (abfd, contents + irel->r_offset + 2) & 0xffff) << 16)));
value1 = bfd_get_32 (abfd, contents + irel->r_offset + 2);
value1 = (value1 >> 16) | ((value1 & 0xffff) << 16);
/* See if the value will fit in 20 bits. */
if ((long) (value + value1) < 0xfffff && (long) (value + value1) > 0)
@ -1954,7 +1927,7 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
unsigned short code;
/* Get the opcode. */
code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
code = bfd_get_16 (abfd, contents + irel->r_offset);
/* Verify it's a 'arithmetic ADDD or MOVD instruction'.
For ADDD and MOVD only, convert to IMM32 -> IMM20. */
@ -1982,9 +1955,16 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
place the 16-20bits (ie 4 bit) in new opcode,
as the 0xffffxxxx, the higher 2 byte values removed. */
if (value1 & 0x80000000)
bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
bfd_put_8 (abfd,
(0x0f | (bfd_get_8 (abfd,
contents + irel->r_offset))),
contents + irel->r_offset);
else
bfd_put_8 (abfd, (((value1 >> 16)&0xf) | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
bfd_put_8 (abfd,
(((value1 >> 16) & 0xf)
| (bfd_get_8 (abfd,
contents + irel->r_offset))),
contents + irel->r_offset);
/* Fix the relocation's type. */
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
@ -2008,7 +1988,7 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
unsigned short code;
/* Get the opcode. */
code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
code = bfd_get_16 (abfd, contents + irel->r_offset);
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
@ -2031,7 +2011,10 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
place the 12-16bits (ie 4 bit) in new opcode,
as the 0xfffffxxx, the higher 2 byte values removed. */
if (value1 & 0x80000000)
bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
bfd_put_8 (abfd,
(0x0f | (bfd_get_8 (abfd,
contents + irel->r_offset))),
contents + irel->r_offset);
else
bfd_put_16 (abfd, value1, contents + irel->r_offset + 2);
@ -2065,7 +2048,8 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
{
value1 |= ((bfd_get_16 (abfd, contents + irel->r_offset + 1) & 0xf000) << 0x4);
value1 |= ((bfd_get_16 (abfd, contents + irel->r_offset + 1)
& 0xf000) << 0x4);
}
/* See if the value will fit in 4 bits. */
@ -2075,7 +2059,7 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
unsigned short code;
/* Get the opcode. */
code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
code = bfd_get_16 (abfd, contents + irel->r_offset);
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
@ -2089,7 +2073,8 @@ elf32_cr16_relax_section (bfd *abfd, asection *sec,
bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
else /* For addd imm20. */
bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
bfd_put_8 (abfd, (code & 0xf0) >> 4, contents + irel->r_offset + 1);
bfd_put_8 (abfd, (code & 0xf0) >> 4,
contents + irel->r_offset + 1);
}
else
{