Andrew Geissler | 84ad7c5 | 2020-06-27 00:00:16 -0500 | [diff] [blame^] | 1 | From f190b9380c325b48697755328f4193791a758e55 Mon Sep 17 00:00:00 2001 |
| 2 | From: Nagaraju Mekala <nmekala@xilix.com> |
| 3 | Date: Fri, 28 Sep 2018 12:04:55 +0530 |
| 4 | Subject: [PATCH 19/43] -Fixed MB-x relocation issues -Added imml for required |
| 5 | MB-x instructions |
| 6 | |
| 7 | --- |
| 8 | bfd/elf64-microblaze.c | 68 ++++++++++++++--- |
| 9 | 3 files changed, 167 insertions(+), 55 deletions(-) |
| 10 | |
| 11 | diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c |
| 12 | index 56a45f2a05..54a2461037 100644 |
| 13 | --- a/bfd/elf64-microblaze.c |
| 14 | +++ b/bfd/elf64-microblaze.c |
| 15 | @@ -1476,8 +1476,17 @@ microblaze_elf_relocate_section (bfd *output_bfd, |
| 16 | relocation -= (input_section->output_section->vma |
| 17 | + input_section->output_offset |
| 18 | + offset + INST_WORD_SIZE); |
| 19 | - bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, |
| 20 | + unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian); |
| 21 | + if (insn == 0xb2000000 || insn == 0xb2ffffff) |
| 22 | + { |
| 23 | + insn &= ~0x00ffffff; |
| 24 | + insn |= (relocation >> 16) & 0xffffff; |
| 25 | + bfd_put_32 (input_bfd, insn, |
| 26 | contents + offset + endian); |
| 27 | + } |
| 28 | + else |
| 29 | + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, |
| 30 | + contents + offset + endian); |
| 31 | bfd_put_16 (input_bfd, relocation & 0xffff, |
| 32 | contents + offset + endian + INST_WORD_SIZE); |
| 33 | } |
| 34 | @@ -1567,11 +1576,28 @@ microblaze_elf_relocate_section (bfd *output_bfd, |
| 35 | else |
| 36 | { |
| 37 | if (r_type == R_MICROBLAZE_64_PCREL) |
| 38 | - relocation -= (input_section->output_section->vma |
| 39 | - + input_section->output_offset |
| 40 | - + offset + INST_WORD_SIZE); |
| 41 | - bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, |
| 42 | + { |
| 43 | + if (!input_section->output_section->vma && |
| 44 | + !input_section->output_offset && !offset) |
| 45 | + relocation -= (input_section->output_section->vma |
| 46 | + + input_section->output_offset |
| 47 | + + offset); |
| 48 | + else |
| 49 | + relocation -= (input_section->output_section->vma |
| 50 | + + input_section->output_offset |
| 51 | + + offset + INST_WORD_SIZE); |
| 52 | + } |
| 53 | + unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian); |
| 54 | + if (insn == 0xb2000000 || insn == 0xb2ffffff) |
| 55 | + { |
| 56 | + insn &= ~0x00ffffff; |
| 57 | + insn |= (relocation >> 16) & 0xffffff; |
| 58 | + bfd_put_32 (input_bfd, insn, |
| 59 | contents + offset + endian); |
| 60 | + } |
| 61 | + else |
| 62 | + bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff, |
| 63 | + contents + offset + endian); |
| 64 | bfd_put_16 (input_bfd, relocation & 0xffff, |
| 65 | contents + offset + endian + INST_WORD_SIZE); |
| 66 | } |
| 67 | @@ -1690,9 +1716,19 @@ static void |
| 68 | microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val) |
| 69 | { |
| 70 | unsigned long instr = bfd_get_32 (abfd, bfd_addr); |
| 71 | - instr &= ~0x0000ffff; |
| 72 | - instr |= (val & 0x0000ffff); |
| 73 | - bfd_put_32 (abfd, instr, bfd_addr); |
| 74 | + |
| 75 | + if (instr == 0xb2000000 || instr == 0xb2ffffff) |
| 76 | + { |
| 77 | + instr &= ~0x00ffffff; |
| 78 | + instr |= (val & 0xffffff); |
| 79 | + bfd_put_32 (abfd, instr, bfd_addr); |
| 80 | + } |
| 81 | + else |
| 82 | + { |
| 83 | + instr &= ~0x0000ffff; |
| 84 | + instr |= (val & 0x0000ffff); |
| 85 | + bfd_put_32 (abfd, instr, bfd_addr); |
| 86 | + } |
| 87 | } |
| 88 | |
| 89 | /* Read-modify-write into the bfd, an immediate value into appropriate fields of |
| 90 | @@ -1704,10 +1740,18 @@ microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val) |
| 91 | unsigned long instr_lo; |
| 92 | |
| 93 | instr_hi = bfd_get_32 (abfd, bfd_addr); |
| 94 | - instr_hi &= ~0x0000ffff; |
| 95 | - instr_hi |= ((val >> 16) & 0x0000ffff); |
| 96 | - bfd_put_32 (abfd, instr_hi, bfd_addr); |
| 97 | - |
| 98 | + if (instr_hi == 0xb2000000 || instr_hi == 0xb2ffffff) |
| 99 | + { |
| 100 | + instr_hi &= ~0x00ffffff; |
| 101 | + instr_hi |= (val >> 16) & 0xffffff; |
| 102 | + bfd_put_32 (abfd, instr_hi,bfd_addr); |
| 103 | + } |
| 104 | + else |
| 105 | + { |
| 106 | + instr_hi &= ~0x0000ffff; |
| 107 | + instr_hi |= ((val >> 16) & 0x0000ffff); |
| 108 | + bfd_put_32 (abfd, instr_hi, bfd_addr); |
| 109 | + } |
| 110 | instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE); |
| 111 | instr_lo &= ~0x0000ffff; |
| 112 | instr_lo |= (val & 0x0000ffff); |
| 113 | -- |
| 114 | 2.17.1 |
| 115 | |