blob: aec793d9c334f29819de842f17dc81c418987036 [file] [log] [blame]
From 3eb0c068ad5a698007341b32c82d9e7ac6cabc49 Mon Sep 17 00:00:00 2001
From: Nagaraju Mekala <nmekala@xilix.com>
Date: Sat, 13 Oct 2018 21:17:01 +0530
Subject: [PATCH] Adding new relocation to support 64bit rodata
Signed-off-by: Mahesh Bodapati <mbodapat@xilinx.com>
Signed-off-by: Nagaraju Mekala <nagaraju.mekala@xilinx.com>
---
bfd/elf64-microblaze.c | 11 +++++++++--
gas/config/tc-microblaze.c | 49 ++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 54 insertions(+), 6 deletions(-)
diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
index 40f10aa..4d9b906 100644
--- a/bfd/elf64-microblaze.c
+++ b/bfd/elf64-microblaze.c
@@ -1461,6 +1461,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
case (int) R_MICROBLAZE_64_PCREL :
case (int) R_MICROBLAZE_64:
case (int) R_MICROBLAZE_32:
+ case (int) R_MICROBLAZE_IMML_64:
{
/* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
from removed linkonce sections, or sections discarded by
@@ -1470,6 +1471,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
relocation += addend;
if (r_type == R_MICROBLAZE_32)// || r_type == R_MICROBLAZE_IMML_64)
bfd_put_32 (input_bfd, relocation, contents + offset);
+ else if (r_type == R_MICROBLAZE_IMML_64)
+ bfd_put_64 (input_bfd, relocation, contents + offset);
else
{
if (r_type == R_MICROBLAZE_64_PCREL)
@@ -1547,7 +1550,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
}
else
{
- if (r_type == R_MICROBLAZE_32)
+ if (r_type == R_MICROBLAZE_32 || r_type == R_MICROBLAZE_IMML_64)
{
outrel.r_info = ELF64_R_INFO (0, R_MICROBLAZE_REL);
outrel.r_addend = relocation + addend;
@@ -1573,6 +1576,8 @@ microblaze_elf_relocate_section (bfd *output_bfd,
relocation += addend;
if (r_type == R_MICROBLAZE_32)
bfd_put_32 (input_bfd, relocation, contents + offset);
+ else if (r_type == R_MICROBLAZE_IMML_64)
+ bfd_put_64 (input_bfd, relocation, contents + offset + endian);
else
{
if (r_type == R_MICROBLAZE_64_PCREL)
@@ -2085,7 +2090,8 @@ microblaze_elf_relax_section (bfd *abfd,
microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
irelscan->r_addend);
}
- if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
+ if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32
+ || ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
{
isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
@@ -2591,6 +2597,7 @@ microblaze_elf_check_relocs (bfd * abfd,
case R_MICROBLAZE_64:
case R_MICROBLAZE_64_PCREL:
case R_MICROBLAZE_32:
+ case R_MICROBLAZE_IMML_64:
{
if (h != NULL && !bfd_link_pic (info))
{
diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c
index 46df32e..c6d2e4c 100644
--- a/gas/config/tc-microblaze.c
+++ b/gas/config/tc-microblaze.c
@@ -1119,6 +1119,13 @@ md_assemble (char * str)
as_fatal (_("smi pseudo instruction should not use a label in imm field"));
if(streq (name, "lli") || streq (name, "sli"))
opc = str_microblaze_64;
+ else if ((microblaze_arch_size == 64) && ((streq (name, "lbui")
+ || streq (name, "lhui") || streq (name, "lwi") || streq (name, "sbi")
+ || streq (name, "shi") || streq (name, "swi"))))
+ {
+ opc = str_microblaze_64;
+ subtype = opcode->inst_offset_type;
+ }
else if (reg2 == REG_ROSDP)
opc = str_microblaze_ro_anchor;
else if (reg2 == REG_RWSDP)
@@ -1182,7 +1189,10 @@ md_assemble (char * str)
inst |= (immed << IMM_LOW) & IMM_MASK;
}
}
- else if (streq (name, "lli") || streq (name, "sli"))
+ else if (streq (name, "lli") || streq (name, "sli") || ((microblaze_arch_size == 64)
+ && ((streq (name, "lbui")) || streq (name, "lhui")
+ || streq (name, "lwi") || streq (name, "sbi")
+ || streq (name, "shi") || streq (name, "swi"))))
{
temp = immed & 0xFFFFFF8000;
if (temp != 0 && temp != 0xFFFFFF8000)
@@ -1794,6 +1804,11 @@ md_assemble (char * str)
if (exp.X_md != 0)
subtype = get_imm_otype(exp.X_md);
+ else if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
+ {
+ opc = str_microblaze_64;
+ subtype = opcode->inst_offset_type;
+ }
else
subtype = opcode->inst_offset_type;
@@ -1811,6 +1826,31 @@ md_assemble (char * str)
output = frag_more (isize);
immed = exp.X_add_number;
}
+ if (streq (name, "brealid") || streq (name, "breaid") || streq (name, "breai"))
+ {
+ temp = immed & 0xFFFFFF8000;
+ if (temp != 0 && temp != 0xFFFFFF8000)
+ {
+ /* Needs an immediate inst. */
+ opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imml");
+ if (opcode1 == NULL)
+ {
+ as_bad (_("unknown opcode \"%s\""), "imml");
+ return;
+ }
+ inst1 = opcode1->bit_sequence;
+ inst1 |= ((immed & 0xFFFFFFFFFFFF0000L) >> 16) & IMML_MASK;
+ output[0] = INST_BYTE0 (inst1);
+ output[1] = INST_BYTE1 (inst1);
+ output[2] = INST_BYTE2 (inst1);
+ output[3] = INST_BYTE3 (inst1);
+ output = frag_more (isize);
+ }
+ inst |= (reg1 << RD_LOW) & RD_MASK;
+ inst |= (immed << IMM_LOW) & IMM_MASK;
+ }
+ else
+ {
temp = immed & 0xFFFF8000;
if ((temp != 0) && (temp != 0xFFFF8000))
@@ -1834,6 +1874,7 @@ md_assemble (char * str)
inst |= (reg1 << RD_LOW) & RD_MASK;
inst |= (immed << IMM_LOW) & IMM_MASK;
+ }
break;
case INST_TYPE_R2:
@@ -3085,10 +3126,10 @@ cons_fix_new_microblaze (fragS * frag,
r = BFD_RELOC_32;
break;
case 8:
- /*if (microblaze_arch_size == 64)
- r = BFD_RELOC_32;
- else*/
+ if (microblaze_arch_size == 64)
r = BFD_RELOC_MICROBLAZE_EA64;
+ else
+ r = BFD_RELOC_64;
break;
default:
as_bad (_("unsupported BFD relocation size %u"), size);