From 35e89c09636e2ce2f5eafcf62941d15ece79a172 Mon Sep 17 00:00:00 2001
From: Nagaraju Mekala <nmekala@xilix.com>
Date: Wed, 24 Oct 2018 12:34:37 +0530
Subject: [PATCH 19/34] fixing the .bss relocation issue

Conflicts:
	bfd/elf64-microblaze.c

Conflicts:
	bfd/elf64-microblaze.c
---
 bfd/elf64-microblaze.c | 41 +++++++++++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
index 355e9131987..eb7f9138884 100644
--- a/bfd/elf64-microblaze.c
+++ b/bfd/elf64-microblaze.c
@@ -1555,14 +1555,14 @@ microblaze_elf_relocate_section (bfd *output_bfd,
 			  bfd_put_16 (input_bfd, relocation & 0xffff,
 				      contents + offset + endian);
 
-                        unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
-                        if (insn == 0xb2000000 || insn == 0xb2ffffff)
-                          {
-                            insn &= ~0x00ffffff;
-                            insn |= (relocation >> 16) & 0xffffff;
-                            bfd_put_32 (input_bfd, insn,
-                                    contents + offset + endian);
-                          }
+			unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
+			if ((insn & 0xff000000) == 0xb2000000)
+			  {
+        		    insn &= ~0x00ffffff;
+			    insn |= (relocation >> 16) & 0xffffff;
+			    bfd_put_32 (input_bfd, insn,
+			            contents + offset + endian);
+			  }
 			else
 			  {
 			    bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
@@ -1673,7 +1673,7 @@ microblaze_elf_relocate_section (bfd *output_bfd,
 					 contents + offset + endian);
 			  }
 			unsigned long insn = bfd_get_32 (input_bfd, contents + offset +endian);
-                        if (insn == 0xb2000000 || insn == 0xb2ffffff)
+			if ((insn & 0xff000000) == 0xb2000000)
                           {
                             insn &= ~0x00ffffff;
                             insn |= (relocation >> 16) & 0xffffff;
@@ -1791,7 +1791,7 @@ microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
 {
     unsigned long instr = bfd_get_32 (abfd, bfd_addr);
 
-    if (instr == 0xb2000000 || instr == 0xb2ffffff)
+    if ((instr & 0xff000000) == 0xb2000000)
       {
         instr &= ~0x00ffffff;
         instr |= (val & 0xffffff);
@@ -1814,7 +1814,7 @@ microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
     unsigned long instr_lo;
 
     instr_hi = bfd_get_32 (abfd, bfd_addr);
-    if (instr_hi == 0xb2000000 || instr_hi == 0xb2ffffff)
+    if ((instr_hi & 0xff000000) == 0xb2000000)
       {
         instr_hi &= ~0x00ffffff;
         instr_hi |= (val >> 16) & 0xffffff;
@@ -2294,6 +2294,8 @@ microblaze_elf_relax_section (bfd *abfd,
 		  if (isym->st_shndx == shndx
 		      && (ELF64_ST_TYPE (isym->st_info) == STT_SECTION))
 		    {
+		      bfd_vma immediate;
+
 		      if (ocontents == NULL)
 			{
 			  if (elf_section_data (o)->this_hdr.contents != NULL)
@@ -2316,8 +2318,20 @@ microblaze_elf_relax_section (bfd *abfd,
 			      elf_section_data (o)->this_hdr.contents = ocontents;
 			    }
 			}
+              unsigned long instr_hi =  bfd_get_32 (abfd, ocontents
+                                                + irelscan->r_offset);
+              unsigned long instr_lo =  bfd_get_32 (abfd, ocontents
+                                                + irelscan->r_offset
+                                                + INST_WORD_SIZE);
+              if ((instr_hi & 0xff000000) == 0xb2000000)
+                immediate = (instr_hi & 0x00ffffff) << 24;
+	      else
+                immediate = (instr_hi & 0x0000ffff) << 16;
+              immediate |= (instr_lo & 0x0000ffff);
 		      offset = calc_fixup (irelscan->r_addend, 0, sec);
+		      immediate -= offset;
 		      irelscan->r_addend -= offset;
+			  
 		    }
 		}
 	      else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
@@ -2357,7 +2371,10 @@ microblaze_elf_relax_section (bfd *abfd,
           unsigned long instr_lo =  bfd_get_32 (abfd, ocontents
                                                 + irelscan->r_offset
                                                 + INST_WORD_SIZE);
-          immediate = (instr_hi & 0x0000ffff) << 16;
+          if ((instr_hi & 0xff000000) == 0xb2000000)
+            immediate = (instr_hi & 0x00ffffff) << 24;
+	  else
+            immediate = (instr_hi & 0x0000ffff) << 16;
           immediate |= (instr_lo & 0x0000ffff);
 		      target_address = immediate;
 		      offset = calc_fixup (target_address, 0, sec);
-- 
2.37.1 (Apple Git-137.1)

