PATCH: Fix memory leak in MN10300 relax code

Nick Clifton nickc@redhat.com
Fri Nov 16 09:46:00 GMT 2007


Hi Guys,

   I am applying the patch below to fix a memory leak in the MN10300
   relaxation code, and to add a minor tweak to the MN10300 linker
   tests for when they are being run by an am33-linux-gnu toolchain.

Cheers
   Nick

bfd/ChangeLog
2007-11-16  Nick Clifton  <nickc@redhat.com>

	* elf-m10300.c (mn10300_elf_check_relocs): Fix memory leak and
	check that bfd_elf_get_elf_syms is only called once.

ld/testsuite/ChangeLog
2007-11-16  Nick Clifton  <nickc@redhat.com>

	* ld-mn10300/mn10300.exp: Fix the start address of the .bss
	section for the i1127740.s test.

Index: bfd/elf-m10300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10300.c,v
retrieving revision 1.90
diff -c -3 -p -r1.90 elf-m10300.c
*** bfd/elf-m10300.c	13 Nov 2007 10:40:29 -0000	1.90
--- bfd/elf-m10300.c	16 Nov 2007 09:39:05 -0000
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 661,666 ****
--- 661,667 ----
   {
     bfd_boolean sym_diff_reloc_seen;
     Elf_Internal_Shdr *symtab_hdr;
+   Elf_Internal_Sym * isymbuf = NULL;
     struct elf_link_hash_entry **sym_hashes;
     const Elf_Internal_Rela *rel;
     const Elf_Internal_Rela *rel_end;
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 669,674 ****
--- 670,676 ----
     asection * sgot;
     asection * srelgot;
     asection * sreloc;
+   bfd_boolean result = FALSE;

     sgot    = NULL;
     srelgot = NULL;
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 678,683 ****
--- 680,686 ----
       return TRUE;

     symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
     sym_hashes = elf_sym_hashes (abfd);

     dynobj = elf_hash_table (info)->dynobj;
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 689,694 ****
--- 692,698 ----
       {
         struct elf_link_hash_entry *h;
         unsigned long r_symndx;
+       unsigned int r_type;

         r_symndx = ELF32_R_SYM (rel->r_info);
         if (r_symndx < symtab_hdr->sh_info)
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 701,710 ****
   	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   	}

         /* Some relocs require a global offset table.  */
         if (dynobj == NULL)
   	{
! 	  switch (ELF32_R_TYPE (rel->r_info))
   	    {
   	    case R_MN10300_GOT32:
   	    case R_MN10300_GOT24:
--- 705,716 ----
   	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   	}

+       r_type = ELF32_R_TYPE (rel->r_info);
+
         /* Some relocs require a global offset table.  */
         if (dynobj == NULL)
   	{
! 	  switch (r_type)
   	    {
   	    case R_MN10300_GOT32:
   	    case R_MN10300_GOT24:
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 716,722 ****
   	    case R_MN10300_GOTPC16:
   	      elf_hash_table (info)->dynobj = dynobj = abfd;
   	      if (! _bfd_mn10300_elf_create_got_section (dynobj, info))
! 		return FALSE;
   	      break;

   	    default:
--- 722,728 ----
   	    case R_MN10300_GOTPC16:
   	      elf_hash_table (info)->dynobj = dynobj = abfd;
   	      if (! _bfd_mn10300_elf_create_got_section (dynobj, info))
! 		goto fail;
   	      break;

   	    default:
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 724,736 ****
   	    }
   	}

!       switch (ELF32_R_TYPE (rel->r_info))
   	{
   	/* This relocation describes the C++ object vtable hierarchy.
   	   Reconstruct it for later use during GC.  */
   	case R_MN10300_GNU_VTINHERIT:
   	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
! 	    return FALSE;
   	  break;

   	/* This relocation describes which C++ vtable entries are actually
--- 730,742 ----
   	    }
   	}

!       switch (r_type)
   	{
   	/* This relocation describes the C++ object vtable hierarchy.
   	   Reconstruct it for later use during GC.  */
   	case R_MN10300_GNU_VTINHERIT:
   	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
! 	    goto fail;
   	  break;

   	/* This relocation describes which C++ vtable entries are actually
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 739,746 ****
   	  BFD_ASSERT (h != NULL);
   	  if (h != NULL
   	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
! 	    return FALSE;
   	  break;
   	case R_MN10300_GOT32:
   	case R_MN10300_GOT24:
   	case R_MN10300_GOT16:
--- 745,753 ----
   	  BFD_ASSERT (h != NULL);
   	  if (h != NULL
   	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
! 	    goto fail;
   	  break;
+
   	case R_MN10300_GOT32:
   	case R_MN10300_GOT24:
   	case R_MN10300_GOT16:
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 768,774 ****
   							  | SEC_READONLY));
   		  if (srelgot == NULL
   		      || ! bfd_set_section_alignment (dynobj, srelgot, 2))
! 		    return FALSE;
   		}
   	    }

--- 775,781 ----
   							  | SEC_READONLY));
   		  if (srelgot == NULL
   		      || ! bfd_set_section_alignment (dynobj, srelgot, 2))
! 		    goto fail;
   		}
   	    }

*************** mn10300_elf_check_relocs (bfd *abfd,
*** 784,790 ****
   	      if (h->dynindx == -1)
   		{
   		  if (! bfd_elf_link_record_dynamic_symbol (info, h))
! 		    return FALSE;
   		}

   	      srelgot->size += sizeof (Elf32_External_Rela);
--- 791,797 ----
   	      if (h->dynindx == -1)
   		{
   		  if (! bfd_elf_link_record_dynamic_symbol (info, h))
! 		    goto fail;
   		}

   	      srelgot->size += sizeof (Elf32_External_Rela);
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 802,808 ****
   		  local_got_offsets = bfd_alloc (abfd, size);

   		  if (local_got_offsets == NULL)
! 		    return FALSE;
   		  elf_local_got_offsets (abfd) = local_got_offsets;

   		  for (i = 0; i < symtab_hdr->sh_info; i++)
--- 809,816 ----
   		  local_got_offsets = bfd_alloc (abfd, size);

   		  if (local_got_offsets == NULL)
! 		    goto fail;
!
   		  elf_local_got_offsets (abfd) = local_got_offsets;

   		  for (i = 0; i < symtab_hdr->sh_info; i++)
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 878,887 ****
   		 symbol involved in the relocation.  */
   	      if (h == NULL)
   		{
- 		  Elf_Internal_Sym * isymbuf;
   		  Elf_Internal_Sym * isym;

- 		  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   		  if (isymbuf == NULL)
   		    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
   						    symtab_hdr->sh_info, 0,
--- 886,893 ----
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 918,924 ****
   			       elf_elfheader (abfd)->e_shstrndx,
   			       elf_section_data (sec)->rel_hdr.sh_name));
   		      if (name == NULL)
! 			return FALSE;

   		      BFD_ASSERT (CONST_STRNEQ (name, ".rela")
   				  && streq (bfd_get_section_name (abfd, sec), name + 5));
--- 924,930 ----
   			       elf_elfheader (abfd)->e_shstrndx,
   			       elf_section_data (sec)->rel_hdr.sh_name));
   		      if (name == NULL)
! 			goto fail;

   		      BFD_ASSERT (CONST_STRNEQ (name, ".rela")
   				  && streq (bfd_get_section_name (abfd, sec), name + 5));
*************** mn10300_elf_check_relocs (bfd *abfd,
*** 935,941 ****
   			  sreloc = bfd_make_section_with_flags (dynobj, name, flags);
   			  if (sreloc == NULL
   			      || ! bfd_set_section_alignment (dynobj, sreloc, 2))
! 			    return FALSE;
   			}
   		    }

--- 941,947 ----
   			  sreloc = bfd_make_section_with_flags (dynobj, name, flags);
   			  if (sreloc == NULL
   			      || ! bfd_set_section_alignment (dynobj, sreloc, 2))
! 			    goto fail;
   			}
   		    }

*************** mn10300_elf_check_relocs (bfd *abfd,
*** 950,956 ****
   	sym_diff_reloc_seen = FALSE;
       }

!   return TRUE;
   }

   /* Return the section that should be marked against GC for a given
--- 956,967 ----
   	sym_diff_reloc_seen = FALSE;
       }

!   result = TRUE;
!  fail:
!   if (isymbuf != NULL)
!     free (isymbuf);
!
!   return result;
   }

   /* Return the section that should be marked against GC for a given
Index: ld/testsuite/ld-mn10300/mn10300.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-mn10300/mn10300.exp,v
retrieving revision 1.3
diff -c -3 -p -r1.3 mn10300.exp
*** ld/testsuite/ld-mn10300/mn10300.exp	13 Nov 2007 10:40:27 -0000	1.3
--- ld/testsuite/ld-mn10300/mn10300.exp	16 Nov 2007 09:39:06 -0000
*************** set mn10300_tests {
*** 49,55 ****
       }
       {
   	"relaxation and alignment directives"
! 	"-relax -Ttext 100"
   	""
   	{ "i127740.s" }
   	{ {objdump -d i127740.d} }
--- 49,55 ----
       }
       {
   	"relaxation and alignment directives"
! 	"-relax -Ttext 100 -Tbss 300"
   	""
   	{ "i127740.s" }
   	{ {objdump -d i127740.d} }



More information about the Binutils mailing list