From 70268d8d38851d06bd66f9c7cc85865f2f3c0e48 Mon Sep 17 00:00:00 2001
From: Mahesh Bodapati <mbodapat@xilinx.com>
Date: Mon, 24 Jan 2022 16:59:19 +0530
Subject: [PATCH 32/34] [Patch,MicroBlaze] : Double free with ld
 --no-keep-memory. Proposed patches from the community member
 (dednev@rambler.ru) for 2021.1. [CR-1115233]

Conflicts:
	bfd/elf32-microblaze.c
	bfd/elf64-microblaze.c
---
 bfd/elf32-microblaze.c | 40 ++++++++++++++++++++++------------------
 bfd/elf64-microblaze.c | 38 ++++++++++++++++++++------------------
 2 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
index 588367ebcbb..28589db662f 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
@@ -1800,10 +1800,8 @@ microblaze_elf_relax_section (bfd *abfd,
 {
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Rela *internal_relocs;
-  Elf_Internal_Rela *free_relocs = NULL;
   Elf_Internal_Rela *irel, *irelend;
   bfd_byte *contents = NULL;
-  bfd_byte *free_contents = NULL;
   int rel_count;
   unsigned int shndx;
   size_t i, sym_index;
@@ -1847,8 +1845,6 @@ microblaze_elf_relax_section (bfd *abfd,
   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
   if (internal_relocs == NULL)
     goto error_return;
-  if (! link_info->keep_memory)
-    free_relocs = internal_relocs;
 
   sdata->relax_count = 0;
   sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
@@ -1876,7 +1872,6 @@ microblaze_elf_relax_section (bfd *abfd,
 	      contents = (bfd_byte *) bfd_malloc (sec->size);
 	      if (contents == NULL)
 		goto error_return;
-	      free_contents = contents;
 
 	      if (!bfd_get_section_contents (abfd, sec, contents,
 					     (file_ptr) 0, sec->size))
@@ -2396,25 +2391,26 @@ microblaze_elf_relax_section (bfd *abfd,
 	}
 
       elf_section_data (sec)->relocs = internal_relocs;
-      free_relocs = NULL;
 
       elf_section_data (sec)->this_hdr.contents = contents;
-      free_contents = NULL;
 
       symtab_hdr->contents = (bfd_byte *) isymbuf;
     }
 
-  free (free_relocs);
-  free_relocs = NULL;
+  if (internal_relocs != NULL
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
 
-  if (free_contents != NULL)
-    {
-      if (!link_info->keep_memory)
-	free (free_contents);
+  if (contents != NULL
+      && elf_section_data (sec)->this_hdr.contents != contents)
+   {
+      if (! link_info->keep_memory)
+	free (contents);
       else
-	/* Cache the section contents for elf_link_input_bfd.  */
-	elf_section_data (sec)->this_hdr.contents = contents;
-      free_contents = NULL;
+	{
+	  /* Cache the section contents for elf_link_input_bfd.  */
+	  elf_section_data (sec)->this_hdr.contents = contents;
+	}
     }
 
   if (sdata->relax_count == 0)
@@ -2428,8 +2424,16 @@ microblaze_elf_relax_section (bfd *abfd,
   return true;
 
  error_return:
-  free (free_relocs);
-  free (free_contents);
+ 
+  if (isymbuf != NULL
+      && symtab_hdr->contents != (unsigned char *) isymbuf)
+    free (isymbuf);
+  if (internal_relocs != NULL
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
+  if (contents != NULL
+      && elf_section_data (sec)->this_hdr.contents != contents)
+    free (contents);
   free (sdata->relax);
   sdata->relax = NULL;
   sdata->relax_count = 0;
diff --git a/bfd/elf64-microblaze.c b/bfd/elf64-microblaze.c
index 76aec43ec7a..77872cef1ab 100644
--- a/bfd/elf64-microblaze.c
+++ b/bfd/elf64-microblaze.c
@@ -1840,10 +1840,8 @@ microblaze_elf_relax_section (bfd *abfd,
 {
   Elf_Internal_Shdr *symtab_hdr;
   Elf_Internal_Rela *internal_relocs;
-  Elf_Internal_Rela *free_relocs = NULL;
   Elf_Internal_Rela *irel, *irelend;
   bfd_byte *contents = NULL;
-  bfd_byte *free_contents = NULL;
   int rel_count;
   unsigned int shndx;
   size_t i, sym_index;
@@ -1887,8 +1885,6 @@ microblaze_elf_relax_section (bfd *abfd,
   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
   if (internal_relocs == NULL)
     goto error_return;
-  if (! link_info->keep_memory)
-    free_relocs = internal_relocs;
 
   sdata->relax_count = 0;
   sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
@@ -1916,8 +1912,6 @@ microblaze_elf_relax_section (bfd *abfd,
 	      contents = (bfd_byte *) bfd_malloc (sec->size);
 	      if (contents == NULL)
 		goto error_return;
-	      free_contents = contents;
-
 	      if (!bfd_get_section_contents (abfd, sec, contents,
 					     (file_ptr) 0, sec->size))
 		goto error_return;
@@ -2449,25 +2443,26 @@ microblaze_elf_relax_section (bfd *abfd,
 	}
 
       elf_section_data (sec)->relocs = internal_relocs;
-      free_relocs = NULL;
 
       elf_section_data (sec)->this_hdr.contents = contents;
-      free_contents = NULL;
 
       symtab_hdr->contents = (bfd_byte *) isymbuf;
     }
 
-  free (free_relocs);
-  free_relocs = NULL;
+  if (internal_relocs != NULL
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
 
-  if (free_contents != NULL)
+  if (contents != NULL
+      && elf_section_data (sec)->this_hdr.contents != contents)
     {
-      if (!link_info->keep_memory)
-	free (free_contents);
+      if (! link_info->keep_memory)
+	free (contents);
       else
-	/* Cache the section contents for elf_link_input_bfd.  */
-	elf_section_data (sec)->this_hdr.contents = contents;
-      free_contents = NULL;
+	{
+	  /* Cache the section contents for elf_link_input_bfd.  */
+	  elf_section_data (sec)->this_hdr.contents = contents;
+	}
     }
 
   if (sdata->relax_count == 0)
@@ -2481,8 +2476,15 @@ microblaze_elf_relax_section (bfd *abfd,
   return true;
 
  error_return:
-  free (free_relocs);
-  free (free_contents);
+  if (isymbuf != NULL
+      && symtab_hdr->contents != (unsigned char *) isymbuf)
+    free (isymbuf);
+  if (internal_relocs != NULL
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
+  if (contents != NULL
+      && elf_section_data (sec)->this_hdr.contents != contents)
+    free (contents);
   free (sdata->relax);
   sdata->relax = NULL;
   sdata->relax_count = 0;
-- 
2.37.1 (Apple Git-137.1)

