This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Committed: "fix" ld/12815, SEGV on some inputs when linking to "binary"


A graceful error is better than an abort, though even better would be
to actually handle the case of emitting binary output while linking,
even while doing some kind of relaxation.  But generating binary
output while linking is not the recommended way, so this still seems
the appropriate action.

ld/testsuite:

	PR ld/12815
	* ld-mmix/pr12815-1.d, ld-mmix/pr12815-1.s, ld-mmix/pr12815-1.ld,
	ld-mmix/pr12815-2.d, ld-mmix/pr12815-2.s: New tests.

bfd:
	PR ld/12815
	* elf64-mmix.c (struct _mmix_elf_section_data): New members
	has_warned_bpo and has_warned_pushj.
	(mmix_final_link_relocate): Remove PARAMS and PTR macros,
	converting to ISO C.  Add new parameter error_message.  All
	callers changed.
	(mmix_elf_perform_relocation): Ditto.
	<case R_MMIX_PUSHJ_STUBBABLE, case R_MMIX_BASE_PLUS_OFFSET>:
	Handle the case where mmix_elf_check_common_relocs has not been
	called, missing preparations for relocs of the respective type.


Index: ld-mmix/pr12815-1.d
===================================================================
RCS file: ld-mmix/pr12815-1.d
diff -N ld-mmix/pr12815-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld-mmix/pr12815-1.d	25 Jul 2011 00:47:02 -0000
@@ -0,0 +1,7 @@
+#as: -no-predefined-syms -x
+#ld: -e 0x1000 -m elf64mmix -T $srcdir/$subdir/pr12815-1.ld
+#error: invalid input relocation.*objcopy.*"-mno-base-addresses".*truncated
+
+# Check that we emit a meaningful error message rather than SEGV when
+# someone attempts linking to the "binary" output format with
+# -mbase-addresses in effect.
Index: ld-mmix/pr12815-1.ld
===================================================================
RCS file: ld-mmix/pr12815-1.ld
diff -N ld-mmix/pr12815-1.ld
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld-mmix/pr12815-1.ld	25 Jul 2011 00:47:02 -0000
@@ -0,0 +1,14 @@
+OUTPUT_FORMAT("binary")
+ENTRY(start)
+SECTIONS
+{
+    . = 0x8000000000100000;
+    .text : AT(ADDR(.text) - 0x8000000000100000)
+    {
+        *(.text)
+        *(.data)
+        *(.rodata*)
+        *(COMMON*)
+        *(.bss*)
+    }
+}
Index: ld-mmix/pr12815-1.s
===================================================================
RCS file: ld-mmix/pr12815-1.s
diff -N ld-mmix/pr12815-1.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld-mmix/pr12815-1.s	25 Jul 2011 00:47:02 -0000
@@ -0,0 +1,26 @@
+# 1 "m.c"
+! mmixal:= 8H LOC Data_Section
+	.text ! mmixal:= 9H LOC 8B
+	.data ! mmixal:= 8H LOC 9B
+	.p2align 2
+	LOC @+(4-@)&3
+foo	IS @
+	TETRA	#2
+	.text ! mmixal:= 9H LOC 8B
+	.p2align 2
+	LOC @+(4-@)&3
+	.global main
+main	IS @
+	SUBU $254,$254,8
+	STOU $253,$254,0
+	ADDU $253,$254,8
+	LDT $0,foo
+	ADDU $0,$0,1
+	SET $0,$0
+	STTU $0,foo
+	SETL $0,0
+	LDO $253,$254,0
+	ADDU $254,$254,8
+	POP 1,0
+
+	.data ! mmixal:= 8H LOC 9B
Index: ld-mmix/pr12815-2.d
===================================================================
RCS file: ld-mmix/pr12815-2.d
diff -N ld-mmix/pr12815-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld-mmix/pr12815-2.d	25 Jul 2011 00:47:02 -0000
@@ -0,0 +1,7 @@
+#as: -no-predefined-syms -x
+#ld: -e 0x1000 --defsym bar=0x100000000 -m elf64mmix -T $srcdir/$subdir/pr12815-1.ld
+#error: invalid input relocation.*objcopy.*"-no-expand".*truncated
+
+# Check that we emit a meaningful error message rather than SEGV when
+# someone attempts linking to the "binary" output format with
+# expanding PUSHJ insns, expecting relaxation to work.
Index: ld-mmix/pr12815-2.s
===================================================================
RCS file: ld-mmix/pr12815-2.s
diff -N ld-mmix/pr12815-2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld-mmix/pr12815-2.s	25 Jul 2011 00:47:02 -0000
@@ -0,0 +1,14 @@
+# 1 "m.c"
+! mmixal:= 8H LOC Data_Section
+	.text ! mmixal:= 9H LOC 8B
+	.p2align 2
+	LOC @+(4-@)&3
+	.global main
+main	IS @
+	GET $0,rJ
+	PUSHJ $1,bar
+	PUSHJ $1,bar
+	PUT rJ,$0
+	POP 1,0
+
+	.data ! mmixal:= 8H LOC 9B

Index: elf64-mmix.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-mmix.c,v
retrieving revision 1.63
diff -p -u -r1.63 elf64-mmix.c
--- elf64-mmix.c	25 Oct 2010 15:54:15 -0000	1.63
+++ elf64-mmix.c	25 Jul 2011 00:53:27 -0000
@@ -75,6 +75,13 @@ struct _mmix_elf_section_data
        stubs_size_sum for relocation.  */
     bfd_size_type stub_offset;
   } pjs;
+
+  /* Whether there has been a warning that this section could not be
+     linked due to a specific cause.  FIXME: a way to access the
+     linker info or output section, then stuff the limiter guard
+     there. */
+  bfd_boolean has_warned_bpo;
+  bfd_boolean has_warned_pushj;
 };

 #define mmix_elf_section_data(sec) \
@@ -190,11 +197,11 @@ static bfd_boolean mmix_elf_relocate_sec
 	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));

 static bfd_reloc_status_type mmix_final_link_relocate
-  PARAMS ((reloc_howto_type *, asection *, bfd_byte *,
-	   bfd_vma, bfd_signed_vma, bfd_vma, const char *, asection *));
+  (reloc_howto_type *, asection *, bfd_byte *, bfd_vma, bfd_signed_vma,
+   bfd_vma, const char *, asection *, char **);

 static bfd_reloc_status_type mmix_elf_perform_relocation
-  PARAMS ((asection *, reloc_howto_type *, PTR, bfd_vma, bfd_vma));
+  (asection *, reloc_howto_type *, void *, bfd_vma, bfd_vma, char **);

 static bfd_boolean mmix_elf_section_from_bfd_section
   PARAMS ((bfd *, asection *, int *));
@@ -934,12 +941,9 @@ mmix_elf_new_section_hook (abfd, sec)
    R_MMIX_ADDR19 and R_MMIX_ADDR27 are just filled in.  */

 static bfd_reloc_status_type
-mmix_elf_perform_relocation (isec, howto, datap, addr, value)
-     asection *isec;
-     reloc_howto_type *howto;
-     PTR datap;
-     bfd_vma addr;
-     bfd_vma value;
+mmix_elf_perform_relocation (asection *isec, reloc_howto_type *howto,
+			     void *datap, bfd_vma addr, bfd_vma value,
+			     char **error_message)
 {
   bfd *abfd = isec->owner;
   bfd_reloc_status_type flag = bfd_reloc_ok;
@@ -1013,6 +1017,36 @@ mmix_elf_perform_relocation (isec, howto
 	       + mmix_elf_section_data (isec)->pjs.stub_offset);
 	  bfd_vma stubaddr;

+	  if (mmix_elf_section_data (isec)->pjs.n_pushj_relocs == 0)
+	    {
+	      /* This shouldn't happen when linking to ELF or mmo, so
+		 this is an attempt to link to "binary", right?  We
+		 can't access the output bfd, so we can't verify that
+		 assumption.  We only know that the critical
+		 mmix_elf_check_common_relocs has not been called,
+		 which happens when the output format is different
+		 from the input format (and is not mmo).  */
+	      if (! mmix_elf_section_data (isec)->has_warned_pushj)
+		{
+		  /* For the first such error per input section, produce
+		     a verbose message.  */
+		  *error_message
+		    = _("invalid input relocation when producing"
+			" non-ELF, non-mmo format output."
+			"\n Please use the objcopy program to convert from"
+			" ELF or mmo,"
+			"\n or assemble using"
+			" \"-no-expand\" (for gcc, \"-Wa,-no-expand\"");
+		  mmix_elf_section_data (isec)->has_warned_pushj = TRUE;
+		  return bfd_reloc_dangerous;
+		}
+
+	      /* For subsequent errors, return this one, which is
+		 rate-limited but looks a little bit different,
+		 hopefully without affecting user-friendliness.  */
+	      return bfd_reloc_overflow;
+	    }
+
 	  /* The address doesn't fit, so redirect the PUSHJ to the
 	     location of the stub.  */
 	  r = mmix_elf_perform_relocation (isec,
@@ -1025,7 +1059,8 @@ mmix_elf_perform_relocation (isec, howto
 					   + size
 					   + (mmix_elf_section_data (isec)
 					      ->pjs.stub_offset)
-					   - addr);
+					   - addr,
+					   error_message);
 	  if (r != bfd_reloc_ok)
 	    return r;

@@ -1049,7 +1084,8 @@ mmix_elf_perform_relocation (isec, howto
 					       [R_MMIX_ADDR27],
 					       stubcontents,
 					       stubaddr,
-					       value + addr - stubaddr);
+					       value + addr - stubaddr,
+					       error_message);
 	      mmix_elf_section_data (isec)->pjs.stub_offset += 4;

 	      if (size + mmix_elf_section_data (isec)->pjs.stub_offset
@@ -1161,12 +1197,43 @@ mmix_elf_perform_relocation (isec, howto
       {
 	struct bpo_reloc_section_info *bpodata
 	  = mmix_elf_section_data (isec)->bpo.reloc;
-	asection *bpo_greg_section
-	  = bpodata->bpo_greg_section;
-	struct bpo_greg_section_info *gregdata
-	  = mmix_elf_section_data (bpo_greg_section)->bpo.greg;
-	size_t bpo_index
-	  = gregdata->bpo_reloc_indexes[bpodata->bpo_index++];
+	asection *bpo_greg_section;
+	struct bpo_greg_section_info *gregdata;
+	size_t bpo_index;
+
+	if (bpodata == NULL)
+	  {
+	    /* This shouldn't happen when linking to ELF or mmo, so
+	       this is an attempt to link to "binary", right?  We
+	       can't access the output bfd, so we can't verify that
+	       assumption.  We only know that the critical
+	       mmix_elf_check_common_relocs has not been called, which
+	       happens when the output format is different from the
+	       input format (and is not mmo).  */
+	    if (! mmix_elf_section_data (isec)->has_warned_bpo)
+	      {
+		/* For the first such error per input section, produce
+		   a verbose message.  */
+		*error_message
+		  = _("invalid input relocation when producing"
+		      " non-ELF, non-mmo format output."
+		      "\n Please use the objcopy program to convert from"
+		      " ELF or mmo,"
+		      "\n or compile using the gcc-option"
+		      " \"-mno-base-addresses\".");
+		mmix_elf_section_data (isec)->has_warned_bpo = TRUE;
+		return bfd_reloc_dangerous;
+	      }
+
+	    /* For subsequent errors, return this one, which is
+	       rate-limited but looks a little bit different,
+	       hopefully without affecting user-friendliness.  */
+	    return bfd_reloc_overflow;
+	  }
+
+	bpo_greg_section = bpodata->bpo_greg_section;
+	gregdata = mmix_elf_section_data (bpo_greg_section)->bpo.greg;
+	bpo_index = gregdata->bpo_reloc_indexes[bpodata->bpo_index++];

 	/* A consistency check: The value we now have in "relocation" must
 	   be the same as the value we stored for that relocation.  It
@@ -1260,7 +1327,7 @@ mmix_elf_reloc (abfd, reloc_entry, symbo
      PTR data;
      asection *input_section;
      bfd *output_bfd;
-     char **error_message ATTRIBUTE_UNUSED;
+     char **error_message;
 {
   bfd_vma relocation;
   bfd_reloc_status_type r;
@@ -1322,7 +1389,8 @@ mmix_elf_reloc (abfd, reloc_entry, symbo
 				   data, reloc_entry->address,
 				   reloc_entry->addend, relocation,
 				   bfd_asymbol_name (symbol),
-				   reloc_target_output_section);
+				   reloc_target_output_section,
+				   error_message);
 }

 /* Relocate an MMIX ELF section.  Modified from elf32-fr30.c; look to it
@@ -1454,7 +1522,7 @@ mmix_elf_relocate_section (output_bfd, i
 						+ size
 						+ mmix_elf_section_data (input_section)
 						->pjs.stub_offset,
-						NULL, NULL) != bfd_reloc_ok)
+						NULL, NULL, NULL) != bfd_reloc_ok)
 		    return FALSE;

 		  /* Put a JMP insn at the stub; it goes with the
@@ -1494,7 +1562,7 @@ mmix_elf_relocate_section (output_bfd, i

       r = mmix_final_link_relocate (howto, input_section,
 				    contents, rel->r_offset,
-				    rel->r_addend, relocation, name, sec);
+				    rel->r_addend, relocation, name, sec, NULL);

       if (r != bfd_reloc_ok)
 	{
@@ -1551,16 +1619,11 @@ mmix_elf_relocate_section (output_bfd, i
    routines.  A few relocs we have to do ourselves.  */

 static bfd_reloc_status_type
-mmix_final_link_relocate (howto, input_section, contents,
-			  r_offset, r_addend, relocation, symname, symsec)
-     reloc_howto_type *howto;
-     asection *input_section;
-     bfd_byte *contents;
-     bfd_vma r_offset;
-     bfd_signed_vma r_addend;
-     bfd_vma relocation;
-     const char *symname;
-     asection *symsec;
+mmix_final_link_relocate (reloc_howto_type *howto, asection *input_section,
+			  bfd_byte *contents, bfd_vma r_offset,
+			  bfd_signed_vma r_addend, bfd_vma relocation,
+			  const char *symname, asection *symsec,
+			  char **error_message)
 {
   bfd_reloc_status_type r = bfd_reloc_ok;
   bfd_vma addr
@@ -1587,7 +1650,7 @@ mmix_final_link_relocate (howto, input_s
 	       + r_offset);

       r = mmix_elf_perform_relocation (input_section, howto, contents,
-				       addr, srel);
+				       addr, srel, error_message);
       break;

     case R_MMIX_BASE_PLUS_OFFSET:
@@ -1669,7 +1732,7 @@ mmix_final_link_relocate (howto, input_s
     do_mmix_reloc:
       contents += r_offset;
       r = mmix_elf_perform_relocation (input_section, howto, contents,
-				       addr, srel);
+				       addr, srel, error_message);
       break;

     case R_MMIX_LOCAL:

brgds, H-P


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]