[rfa] ARM dangerous relocations are ... dangerous

Daniel Jacobowitz drow@false.org
Wed Nov 1 19:58:00 GMT 2006


I'm about to post a fix for the bug I reported yesterday.  Before I do
I wanted to fix the fact that I only discovered it in testing.  If we
get a bfd_reloc_dangerous or other internal error, we shouldn't create
an output file.

OK?

-- 
Daniel Jacobowitz
CodeSourcery

2006-11-01  Daniel Jacobowitz  <dan@codesourcery.com>

	* elf32-arm.c (find_thumb_glue): Add ERROR_MESSAGE argument; set it
	on error.
	(find_arm_glue): Likewise.
	(elf32_thumb_to_arm_stub, elf32_arm_create_thumb_stub)
	(elf32_arm_to_thumb_stub, elf32_arm_final_link_relocate): Add
	ERROR_MESSAGE argument and pass it through.
	(elf32_arm_to_thumb_export_stub): Update.
	(elf32_arm_relocate_section): Use ERROR_MESSAGE and reloc_dangerous.

Index: elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.97
diff -u -p -r1.97 elf32-arm.c
--- elf32-arm.c	19 Oct 2006 02:10:41 -0000	1.97
+++ elf32-arm.c	1 Nov 2006 19:54:30 -0000
@@ -2429,7 +2429,7 @@ elf32_arm_link_hash_table_create (bfd *a
 static struct elf_link_hash_entry *
 find_thumb_glue (struct bfd_link_info *link_info,
 		 const char *name,
-		 bfd *input_bfd)
+		 char **error_message)
 {
   char *tmp_name;
   struct elf_link_hash_entry *hash;
@@ -2449,9 +2449,8 @@ find_thumb_glue (struct bfd_link_info *l
     (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
 
   if (hash == NULL)
-    /* xgettext:c-format */
-    (*_bfd_error_handler) (_("%B: unable to find THUMB glue '%s' for `%s'"),
-			   input_bfd, tmp_name, name);
+    asprintf (error_message, _("unable to find THUMB glue '%s' for '%s'"),
+	      tmp_name, name);
 
   free (tmp_name);
 
@@ -2463,7 +2462,7 @@ find_thumb_glue (struct bfd_link_info *l
 static struct elf_link_hash_entry *
 find_arm_glue (struct bfd_link_info *link_info,
 	       const char *name,
-	       bfd *input_bfd)
+	       char **error_message)
 {
   char *tmp_name;
   struct elf_link_hash_entry *myh;
@@ -2483,9 +2482,8 @@ find_arm_glue (struct bfd_link_info *lin
     (&(hash_table)->root, tmp_name, FALSE, FALSE, TRUE);
 
   if (myh == NULL)
-    /* xgettext:c-format */
-    (*_bfd_error_handler) (_("%B: unable to find ARM glue '%s' for `%s'"),
-			   input_bfd, tmp_name, name);
+    asprintf (error_message, _("unable to find ARM glue '%s' for '%s'"),
+	      tmp_name, name);
 
   free (tmp_name);
 
@@ -3116,7 +3114,8 @@ elf32_thumb_to_arm_stub (struct bfd_link
 			 asection *             sym_sec,
 			 bfd_vma                offset,
 			 bfd_signed_vma         addend,
-			 bfd_vma                val)
+			 bfd_vma                val,
+			 char **error_message)
 {
   asection * s = 0;
   bfd_vma my_offset;
@@ -3125,7 +3124,7 @@ elf32_thumb_to_arm_stub (struct bfd_link
   struct elf_link_hash_entry * myh;
   struct elf32_arm_link_hash_table * globals;
 
-  myh = find_thumb_glue (info, name, input_bfd);
+  myh = find_thumb_glue (info, name, error_message);
   if (myh == NULL)
     return FALSE;
 
@@ -3220,14 +3219,15 @@ elf32_arm_create_thumb_stub (struct bfd_
 			     bfd *                  output_bfd,
 			     asection *             sym_sec,
 			     bfd_vma                val,
-			     asection		    *s)
+			     asection		    *s,
+			     char **error_message)
 {
   bfd_vma my_offset;
   long int ret_offset;
   struct elf_link_hash_entry * myh;
   struct elf32_arm_link_hash_table * globals;
 
-  myh = find_arm_glue (info, name, input_bfd);
+  myh = find_arm_glue (info, name, error_message);
   if (myh == NULL)
     return NULL;
 
@@ -3305,7 +3305,8 @@ elf32_arm_to_thumb_stub (struct bfd_link
 			 asection *             sym_sec,
 			 bfd_vma                offset,
 			 bfd_signed_vma         addend,
-			 bfd_vma                val)
+			 bfd_vma                val,
+			 char **error_message)
 {
   unsigned long int tmp;
   bfd_vma my_offset;
@@ -3326,7 +3327,7 @@ elf32_arm_to_thumb_stub (struct bfd_link
   BFD_ASSERT (s->output_section != NULL);
 
   myh = elf32_arm_create_thumb_stub (info, name, input_bfd, output_bfd,
-				     sym_sec, val, s);
+				     sym_sec, val, s, error_message);
   if (!myh)
     return FALSE;
 
@@ -3362,6 +3363,7 @@ elf32_arm_to_thumb_export_stub (struct e
   struct elf32_arm_link_hash_table * globals;
   asection *sec;
   bfd_vma val;
+  char *error_message;
 
   eh = elf32_arm_hash_entry(h);
   /* Allocate stubs for exported Thumb functions on v4t.  */
@@ -3384,7 +3386,8 @@ elf32_arm_to_thumb_export_stub (struct e
 	+ sec->output_section->vma;
   myh = elf32_arm_create_thumb_stub (info, h->root.root.string,
 				     h->root.u.def.section->owner,
-				     globals->obfd, sec, val, s);
+				     globals->obfd, sec, val, s,
+				     &error_message);
   BFD_ASSERT (myh);
   return TRUE;
 }
@@ -3565,7 +3568,8 @@ elf32_arm_final_link_relocate (reloc_how
 			       const char *                 sym_name,
 			       int		            sym_flags,
 			       struct elf_link_hash_entry * h,
-			       bfd_boolean *                unresolved_reloc_p)
+			       bfd_boolean *                unresolved_reloc_p,
+			       char **error_message)
 {
   unsigned long                 r_type = howto->type;
   unsigned long                 r_symndx;
@@ -3834,11 +3838,14 @@ elf32_arm_final_link_relocate (reloc_how
 	      /* Check for Arm calling Thumb function.  */
 	      if (sym_flags == STT_ARM_TFUNC)
 		{
-		  elf32_arm_to_thumb_stub (info, sym_name, input_bfd,
-					   output_bfd, input_section,
-					   hit_data, sym_sec, rel->r_offset,
-					   signed_addend, value);
-		  return bfd_reloc_ok;
+		  if (elf32_arm_to_thumb_stub (info, sym_name, input_bfd,
+					       output_bfd, input_section,
+					       hit_data, sym_sec, rel->r_offset,
+					       signed_addend, value,
+					       error_message))
+		    return bfd_reloc_ok;
+		  else
+		    return bfd_reloc_dangerous;
 		}
 	    }
 
@@ -4130,7 +4137,8 @@ elf32_arm_final_link_relocate (reloc_how
 		  }
 		else if (elf32_thumb_to_arm_stub
 		    (info, sym_name, input_bfd, output_bfd, input_section,
-		     hit_data, sym_sec, rel->r_offset, signed_addend, value))
+		     hit_data, sym_sec, rel->r_offset, signed_addend, value,
+		     error_message))
 		  return bfd_reloc_ok;
 		else
 		  return bfd_reloc_dangerous;
@@ -5641,6 +5649,7 @@ elf32_arm_relocate_section (bfd *       
       arelent                      bfd_reloc;
       char                         sym_type;
       bfd_boolean                  unresolved_reloc = FALSE;
+      char *error_message = NULL;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
       r_type   = ELF32_R_TYPE (rel->r_info);
@@ -5774,7 +5783,7 @@ elf32_arm_relocate_section (bfd *       
 					 relocation, info, sec, name,
 					 (h ? ELF_ST_TYPE (h->type) :
 					  ELF_ST_TYPE (sym->st_info)), h,
-					 &unresolved_reloc);
+					 &unresolved_reloc, &error_message);
 
       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
 	 because such sections are not SEC_ALLOC and thus ld.so will
@@ -5795,8 +5804,6 @@ elf32_arm_relocate_section (bfd *       
 
       if (r != bfd_reloc_ok)
 	{
-	  const char * msg = (const char *) 0;
-
 	  switch (r)
 	    {
 	    case bfd_reloc_overflow:
@@ -5820,24 +5827,25 @@ elf32_arm_relocate_section (bfd *       
 	      break;
 
 	    case bfd_reloc_outofrange:
-	      msg = _("internal error: out of range error");
+	      error_message = _("out of range");
 	      goto common_error;
 
 	    case bfd_reloc_notsupported:
-	      msg = _("internal error: unsupported relocation error");
+	      error_message = _("unsupported relocation");
 	      goto common_error;
 
 	    case bfd_reloc_dangerous:
-	      msg = _("internal error: dangerous error");
+	      /* error_message should already be set.  */
 	      goto common_error;
 
 	    default:
-	      msg = _("internal error: unknown error");
+	      error_message = _("unknown error");
 	      /* fall through */
 
 	    common_error:
-	      if (!((*info->callbacks->warning)
-		    (info, msg, name, input_bfd, input_section,
+	      BFD_ASSERT (error_message != NULL);
+	      if (!((*info->callbacks->reloc_dangerous)
+		    (info, error_message, input_bfd, input_section,
 		     rel->r_offset)))
 		return FALSE;
 	      break;



More information about the Binutils mailing list