From 9fb3bc7ade713f55182aae4c57f8504cc07c366b Mon Sep 17 00:00:00 2001
From: Mahesh Bodapati <mbodapat@xilinx.com>
Date: Mon, 24 Jan 2022 16:04:07 +0530
Subject: [PATCH] [Patch,MicroBlaze] : Invalid data offsets (pointer) after
 relaxation. Proposed patch from community member (dednev@rambler.ru) against
 2021.1 [CR-1115232]

---
 bfd/elf32-microblaze.c | 18 ++++++++++++++++++
 bfd/elf64-microblaze.c | 17 +++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
index 713f5e8e50..37a1873570 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
@@ -2131,6 +2131,9 @@ microblaze_elf_relax_section (bfd *abfd,
                 {
                   unsigned int val;
 
+	  	  if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+		    continue;
+
                   isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
 
                   /* hax: We only do the following fixup for debug location lists.  */
@@ -2172,6 +2175,9 @@ microblaze_elf_relax_section (bfd *abfd,
               }
               if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
                 {
+		  if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+		    continue;
+
 	          isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
 
                   /* Look at the reloc only if the value has been resolved.  */
@@ -2204,6 +2210,9 @@ microblaze_elf_relax_section (bfd *abfd,
 		    }
 		  else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
 		    {
+		      if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+		        continue;
+
 		      isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
 
 		      /* Look at the reloc only if the value has been resolved.  */
@@ -2241,6 +2250,9 @@ microblaze_elf_relax_section (bfd *abfd,
 		       || (ELF32_R_TYPE (irelscan->r_info)
 				   == (int) R_MICROBLAZE_TEXTREL_32_LO))
 		{
+		  if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+		    continue;
+
 		  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
 
 		  /* Look at the reloc only if the value has been resolved.  */
@@ -2287,6 +2299,9 @@ microblaze_elf_relax_section (bfd *abfd,
 		  || (ELF32_R_TYPE (irelscan->r_info)
 			      == (int) R_MICROBLAZE_TEXTREL_64))
 		{
+		  if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+		    continue;
+
 		  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
 
 		  /* Look at the reloc only if the value has been resolved.  */
@@ -2331,6 +2346,9 @@ microblaze_elf_relax_section (bfd *abfd,
 		}
 	      else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
 		{
+		  if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+		    continue;
+
 		  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
 
 		  /* Look at the reloc only if the value has been resolved.  */
diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
index 210b84b2a5..bd1c7d3b1f 100644
--- a/bfd/elf64-microblaze.c
+++ b/bfd/elf64-microblaze.c
@@ -2138,6 +2138,8 @@ microblaze_elf_relax_section (bfd *abfd,
               if (1 && ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE)
                 {
                   unsigned int val;
+		  if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+		    continue;
 
                   isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
 
@@ -2180,6 +2182,9 @@ microblaze_elf_relax_section (bfd *abfd,
               if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32 
 		   || ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_IMML_64)
                 {
+		  if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+		    continue;
+
 	          isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
 
                   /* Look at the reloc only if the value has been resolved.  */
@@ -2212,6 +2217,9 @@ microblaze_elf_relax_section (bfd *abfd,
                     }
 		  else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
 		    {
+                      if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+                        continue;
+
 		      isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
 
 		      /* Look at the reloc only if the value has been resolved.  */
@@ -2247,6 +2255,9 @@ microblaze_elf_relax_section (bfd *abfd,
 		       || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO)
                || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_TEXTREL_32_LO))
 		{
+                  if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+                    continue;
+
 		  isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
 
 		  /* Look at the reloc only if the value has been resolved.  */
@@ -2292,6 +2303,9 @@ microblaze_elf_relax_section (bfd *abfd,
 	      if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64
           || (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_TEXTREL_64))
 		{
+                  if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+                    continue;
+
 		  isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
 
 		  /* Look at the reloc only if the value has been resolved.  */
@@ -2339,6 +2353,9 @@ microblaze_elf_relax_section (bfd *abfd,
 		}
 	      else if (ELF64_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
 		{
+                  if (ELF64_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info)
+                    continue;
+
 		  isym = isymbuf + ELF64_R_SYM (irelscan->r_info);
 
 		  /* Look at the reloc only if the value has been resolved.  */
-- 
2.17.1

