Brad Bishop | 26bdd44 | 2019-08-16 17:08:17 -0400 | [diff] [blame] | 1 | From 8b98898add56667d28b7d6242c86603bb2f5946e Mon Sep 17 00:00:00 2001 |
| 2 | From: Nagaraju Mekala <nmekala@xilix.com> |
| 3 | Date: Tue, 9 Oct 2018 10:14:22 +0530 |
| 4 | Subject: [PATCH] - Fixed address computation issues with 64bit address - Fixed |
| 5 | imml dissassamble issue |
| 6 | |
| 7 | Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com> |
| 8 | Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com> |
| 9 | |
| 10 | --- |
| 11 | bfd/bfd-in2.h | 5 ++++ |
| 12 | bfd/elf64-microblaze.c | 14 ++++----- |
| 13 | gas/config/tc-microblaze.c | 74 +++++++++++++++++++++++++++++++++++++++++----- |
| 14 | opcodes/microblaze-dis.c | 2 +- |
| 15 | 4 files changed, 79 insertions(+), 16 deletions(-) |
| 16 | |
| 17 | diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h |
| 18 | index f74aac1..434b41c 100644 |
| 19 | --- a/bfd/bfd-in2.h |
| 20 | +++ b/bfd/bfd-in2.h |
| 21 | @@ -5882,6 +5882,11 @@ done here - only used for relaxing */ |
| 22 | * +done here - only used for relaxing */ |
| 23 | BFD_RELOC_MICROBLAZE_64, |
| 24 | |
| 25 | +/* This is a 64 bit reloc that stores the 32 bit relative |
| 26 | + * +value in two words (with an imml instruction). No relocation is |
| 27 | + * +done here - only used for relaxing */ |
| 28 | + BFD_RELOC_MICROBLAZE_EA64, |
| 29 | + |
| 30 | /* This is a 64 bit reloc that stores the 32 bit pc relative |
| 31 | * +value in two words (with an imm instruction). No relocation is |
| 32 | * +done here - only used for relaxing */ |
| 33 | diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c |
| 34 | index e9b3cf3..40f10aa 100644 |
| 35 | --- a/bfd/elf64-microblaze.c |
| 36 | +++ b/bfd/elf64-microblaze.c |
| 37 | @@ -121,15 +121,15 @@ static reloc_howto_type microblaze_elf_howto_raw[] = |
| 38 | 0, /* Rightshift. */ |
| 39 | 4, /* Size (0 = byte, 1 = short, 2 = long). */ |
| 40 | 64, /* Bitsize. */ |
| 41 | - TRUE, /* PC_relative. */ |
| 42 | + FALSE, /* PC_relative. */ |
| 43 | 0, /* Bitpos. */ |
| 44 | complain_overflow_dont, /* Complain on overflow. */ |
| 45 | bfd_elf_generic_reloc,/* Special Function. */ |
| 46 | "R_MICROBLAZE_IMML_64", /* Name. */ |
| 47 | FALSE, /* Partial Inplace. */ |
| 48 | 0, /* Source Mask. */ |
| 49 | - 0x0000ffff, /* Dest Mask. */ |
| 50 | - TRUE), /* PC relative offset? */ |
| 51 | + 0xffffffffffffff, /* Dest Mask. */ |
| 52 | + FALSE), /* PC relative offset? */ |
| 53 | |
| 54 | /* A 64 bit relocation. Table entry not really used. */ |
| 55 | HOWTO (R_MICROBLAZE_64, /* Type. */ |
| 56 | @@ -585,9 +585,9 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, |
| 57 | case BFD_RELOC_32: |
| 58 | microblaze_reloc = R_MICROBLAZE_32; |
| 59 | break; |
| 60 | - /* RVA is treated the same as 32 */ |
| 61 | + /* RVA is treated the same as 64 */ |
| 62 | case BFD_RELOC_RVA: |
| 63 | - microblaze_reloc = R_MICROBLAZE_32; |
| 64 | + microblaze_reloc = R_MICROBLAZE_IMML_64; |
| 65 | break; |
| 66 | case BFD_RELOC_32_PCREL: |
| 67 | microblaze_reloc = R_MICROBLAZE_32_PCREL; |
| 68 | @@ -619,7 +619,7 @@ microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, |
| 69 | case BFD_RELOC_VTABLE_ENTRY: |
| 70 | microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY; |
| 71 | break; |
| 72 | - case BFD_RELOC_MICROBLAZE_64: |
| 73 | + case BFD_RELOC_MICROBLAZE_EA64: |
| 74 | microblaze_reloc = R_MICROBLAZE_IMML_64; |
| 75 | break; |
| 76 | case BFD_RELOC_MICROBLAZE_64_GOTPC: |
| 77 | @@ -1969,7 +1969,7 @@ microblaze_elf_relax_section (bfd *abfd, |
| 78 | efix = calc_fixup (target_address, 0, sec); |
| 79 | |
| 80 | /* Validate the in-band val. */ |
| 81 | - val = bfd_get_32 (abfd, contents + irel->r_offset); |
| 82 | + val = bfd_get_64 (abfd, contents + irel->r_offset); |
| 83 | if (val != irel->r_addend && ELF64_R_TYPE (irel->r_info) == R_MICROBLAZE_32_NONE) { |
| 84 | fprintf(stderr, "%d: CORRUPT relax reloc %x %lx\n", __LINE__, val, irel->r_addend); |
| 85 | } |
| 86 | diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c |
| 87 | index fa437b6..46df32e 100644 |
| 88 | --- a/gas/config/tc-microblaze.c |
| 89 | +++ b/gas/config/tc-microblaze.c |
| 90 | @@ -402,7 +402,6 @@ pseudo_typeS md_pseudo_table[] = |
| 91 | {"ent", s_func, 0}, /* Treat ent as function entry point. */ |
| 92 | {"end", microblaze_s_func, 1}, /* Treat end as function end point. */ |
| 93 | {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */ |
| 94 | - {"gpdword", s_rva, 8}, /* gpword label => store resolved label address in data section. */ |
| 95 | {"weakext", microblaze_s_weakext, 0}, |
| 96 | {"rodata", microblaze_s_rdata, 0}, |
| 97 | {"sdata2", microblaze_s_rdata, 1}, |
| 98 | @@ -2482,15 +2481,71 @@ md_apply_fix (fixS * fixP, |
| 99 | /* Don't do anything if the symbol is not defined. */ |
| 100 | if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) |
| 101 | { |
| 102 | + if ((fixP->fx_r_type == BFD_RELOC_RVA) && (microblaze_arch_size == 64)) |
| 103 | + { |
| 104 | + if (target_big_endian) |
| 105 | + { |
| 106 | + buf[0] |= ((val >> 56) & 0xff); |
| 107 | + buf[1] |= ((val >> 48) & 0xff); |
| 108 | + buf[2] |= ((val >> 40) & 0xff); |
| 109 | + buf[3] |= ((val >> 32) & 0xff); |
| 110 | + buf[4] |= ((val >> 24) & 0xff); |
| 111 | + buf[5] |= ((val >> 16) & 0xff); |
| 112 | + buf[6] |= ((val >> 8) & 0xff); |
| 113 | + buf[7] |= (val & 0xff); |
| 114 | + } |
| 115 | + else |
| 116 | + { |
| 117 | + buf[7] |= ((val >> 56) & 0xff); |
| 118 | + buf[6] |= ((val >> 48) & 0xff); |
| 119 | + buf[5] |= ((val >> 40) & 0xff); |
| 120 | + buf[4] |= ((val >> 32) & 0xff); |
| 121 | + buf[3] |= ((val >> 24) & 0xff); |
| 122 | + buf[2] |= ((val >> 16) & 0xff); |
| 123 | + buf[1] |= ((val >> 8) & 0xff); |
| 124 | + buf[0] |= (val & 0xff); |
| 125 | + } |
| 126 | + } |
| 127 | + else { |
| 128 | + if (target_big_endian) |
| 129 | + { |
| 130 | + buf[0] |= ((val >> 24) & 0xff); |
| 131 | + buf[1] |= ((val >> 16) & 0xff); |
| 132 | + buf[2] |= ((val >> 8) & 0xff); |
| 133 | + buf[3] |= (val & 0xff); |
| 134 | + } |
| 135 | + else |
| 136 | + { |
| 137 | + buf[3] |= ((val >> 24) & 0xff); |
| 138 | + buf[2] |= ((val >> 16) & 0xff); |
| 139 | + buf[1] |= ((val >> 8) & 0xff); |
| 140 | + buf[0] |= (val & 0xff); |
| 141 | + } |
| 142 | + } |
| 143 | + } |
| 144 | + break; |
| 145 | + |
| 146 | + case BFD_RELOC_MICROBLAZE_EA64: |
| 147 | + /* Don't do anything if the symbol is not defined. */ |
| 148 | + if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) |
| 149 | + { |
| 150 | if (target_big_endian) |
| 151 | { |
| 152 | - buf[0] |= ((val >> 24) & 0xff); |
| 153 | - buf[1] |= ((val >> 16) & 0xff); |
| 154 | - buf[2] |= ((val >> 8) & 0xff); |
| 155 | - buf[3] |= (val & 0xff); |
| 156 | + buf[0] |= ((val >> 56) & 0xff); |
| 157 | + buf[1] |= ((val >> 48) & 0xff); |
| 158 | + buf[2] |= ((val >> 40) & 0xff); |
| 159 | + buf[3] |= ((val >> 32) & 0xff); |
| 160 | + buf[4] |= ((val >> 24) & 0xff); |
| 161 | + buf[5] |= ((val >> 16) & 0xff); |
| 162 | + buf[6] |= ((val >> 8) & 0xff); |
| 163 | + buf[7] |= (val & 0xff); |
| 164 | } |
| 165 | else |
| 166 | { |
| 167 | + buf[7] |= ((val >> 56) & 0xff); |
| 168 | + buf[6] |= ((val >> 48) & 0xff); |
| 169 | + buf[5] |= ((val >> 40) & 0xff); |
| 170 | + buf[4] |= ((val >> 32) & 0xff); |
| 171 | buf[3] |= ((val >> 24) & 0xff); |
| 172 | buf[2] |= ((val >> 16) & 0xff); |
| 173 | buf[1] |= ((val >> 8) & 0xff); |
| 174 | @@ -2611,6 +2666,8 @@ md_apply_fix (fixS * fixP, |
| 175 | fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE; |
| 176 | else if (fixP->fx_r_type == BFD_RELOC_32) |
| 177 | fixP->fx_r_type = BFD_RELOC_MICROBLAZE_32_NONE; |
| 178 | + else if(fixP->fx_r_type == BFD_RELOC_MICROBLAZE_EA64) |
| 179 | + fixP->fx_r_type = BFD_RELOC_MICROBLAZE_EA64; |
| 180 | else |
| 181 | fixP->fx_r_type = BFD_RELOC_NONE; |
| 182 | fixP->fx_addsy = section_symbol (absolute_section); |
| 183 | @@ -2882,6 +2939,7 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp) |
| 184 | case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM: |
| 185 | case BFD_RELOC_MICROBLAZE_64_GOTPC: |
| 186 | case BFD_RELOC_MICROBLAZE_64_GPC: |
| 187 | + case BFD_RELOC_MICROBLAZE_EA64: |
| 188 | case BFD_RELOC_MICROBLAZE_64: |
| 189 | case BFD_RELOC_MICROBLAZE_64_PCREL: |
| 190 | case BFD_RELOC_MICROBLAZE_64_GOT: |
| 191 | @@ -3027,10 +3085,10 @@ cons_fix_new_microblaze (fragS * frag, |
| 192 | r = BFD_RELOC_32; |
| 193 | break; |
| 194 | case 8: |
| 195 | - if (microblaze_arch_size == 64) |
| 196 | + /*if (microblaze_arch_size == 64) |
| 197 | r = BFD_RELOC_32; |
| 198 | - else |
| 199 | - r = BFD_RELOC_64; |
| 200 | + else*/ |
| 201 | + r = BFD_RELOC_MICROBLAZE_EA64; |
| 202 | break; |
| 203 | default: |
| 204 | as_bad (_("unsupported BFD relocation size %u"), size); |
| 205 | diff --git a/opcodes/microblaze-dis.c b/opcodes/microblaze-dis.c |
| 206 | index 20ea6a8..f679a43 100644 |
| 207 | --- a/opcodes/microblaze-dis.c |
| 208 | +++ b/opcodes/microblaze-dis.c |
| 209 | @@ -61,7 +61,7 @@ get_field_imml (long instr) |
| 210 | { |
| 211 | char tmpstr[25]; |
| 212 | |
| 213 | - sprintf (tmpstr, "%d", (short)((instr & IMML_MASK) >> IMM_LOW)); |
| 214 | + sprintf (tmpstr, "%d", (int)((instr & IMML_MASK) >> IMM_LOW)); |
| 215 | return (strdup (tmpstr)); |
| 216 | } |
| 217 | |