This is the mail archive of the binutils@sources.redhat.com 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]

Re: mainline ld on mingw32/pe is broken, returns 1 without error.


On Mon, Jun 28, 2004 at 03:56:18PM +0930, Alan Modra wrote:
> Sigh.  This has to be the stabstr section created at stabs.c:248 (if
> the section came from an input file, it wouldn't have filepos == 0).
> 
> It looks like the linker relies on raw size being zero for these
> sections.  ie. places where I do o->rawsize ? o->rawsize : o->size
> are broken.  The fix will be to set rawsize for all input sections,
> and remove all the places I test rawsize.

This should fix the stabs breakage.  I decided not to pursue the idea of
setting rawsize when reading sections from disk.  The fewer places that
need to touch rawsize, the better.

bfd/ChangeLog
	* bfd-in.h (struct stab_info): Move from stabs.c.
	* stabs.c (struct stab_link_includes_table): Delete.
	(stab_link_includes_lookup): Delete.
	(_bfd_write_section_stabs, _bfd_write_stab_strings): Remove one
	level of indirection from sinfo parm.
	(_bfd_link_section_stabs): Likewise.  Set SEC_LINKER_CREATED on
	stabstr section.  Adjust hash table accesses.
	* coff-ppc.c (ppc_bfd_coff_final_link): Do include rawsize in contents
	alloc.  Adjust stab_info test.
	* cofflink.c (_bfd_coff_link_hash_table_init): Clear stab_info.
	(_bfd_coff_final_link): Adjust stab_info test.
	(_bfd_coff_link_input_bfd): Ignore SEC_LINKER_CREATED sections.
	* elf-bfd.h (struct elf_link_hash_table): Include struct stab_info
	in place.
	* libcoff-in.h (struct coff_link_hash_table): Likewise.
	* elf.c (_bfd_elf_link_hash_table_init): Clear stab_info.
	* elflink.c (bfd_elf_final_link): Don't attempt to link linker created
	stabstr section.  Adjust stab_info test.
	* libbfd-in.h (_bfd_link_section_stabs, _bfd_write_section_stabs)
	(_bfd_write_stab_strings): Adjust prototypes.
	* libbfd.h: Regenerate.
	* libcoff.h: Regenerate.
	* bfd-in2.h: Regenerate.

Index: bfd/bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.83
diff -u -p -r1.83 bfd-in.h
--- bfd/bfd-in.h	24 Jun 2004 04:46:14 -0000	1.83
+++ bfd/bfd-in.h	28 Jun 2004 13:15:59 -0000
@@ -439,6 +439,19 @@ extern void bfd_hash_traverse
    this size.  */
 extern void bfd_hash_set_default_size (bfd_size_type);
 
+/* This structure is used to keep track of stabs in sections
+   information while linking.  */
+
+struct stab_info
+{
+  /* A hash table used to hold stabs strings.  */
+  struct bfd_strtab_hash *strings;
+  /* The header file hash table.  */
+  struct bfd_hash_table includes;
+  /* The first .stabstr section.  */
+  struct bfd_section *stabstr;
+};
+
 #define COFF_SWAP_TABLE (void *) &bfd_coff_std_swap_table
 
 /* User program access to BFD facilities.  */
Index: bfd/coff-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-ppc.c,v
retrieving revision 1.20
diff -u -p -r1.20 coff-ppc.c
--- bfd/coff-ppc.c	24 Jun 2004 04:46:15 -0000	1.20
+++ bfd/coff-ppc.c	28 Jun 2004 13:16:06 -0000
@@ -2328,6 +2328,8 @@ ppc_bfd_coff_final_link (abfd, info)
 	      if (info->relocatable)
 		o->reloc_count += sec->reloc_count;
 
+	      if (sec->rawsize > max_contents_size)
+		max_contents_size = sec->rawsize;
 	      if (sec->size > max_contents_size)
 		max_contents_size = sec->size;
 	      if (sec->lineno_count > max_lineno_count)
@@ -2663,7 +2665,7 @@ ppc_bfd_coff_final_link (abfd, info)
     }
 
   /* If we have optimized stabs strings, output them.  */
-  if (coff_hash_table (info)->stab_info != NULL)
+  if (coff_hash_table (info)->stab_info.stabstr != NULL)
     {
       if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
 	return FALSE;
Index: bfd/cofflink.c
===================================================================
RCS file: /cvs/src/src/bfd/cofflink.c,v
retrieving revision 1.44
diff -u -p -r1.44 cofflink.c
--- bfd/cofflink.c	24 Jun 2004 04:46:16 -0000	1.44
+++ bfd/cofflink.c	28 Jun 2004 13:16:08 -0000
@@ -96,7 +96,7 @@ _bfd_coff_link_hash_table_init (struct c
 								   struct bfd_hash_table *,
 								   const char *))
 {
-  table->stab_info = NULL;
+  memset (&table->stab_info, 0, sizeof (table->stab_info));
   return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
 }
 
@@ -1082,7 +1082,7 @@ _bfd_coff_final_link (bfd *abfd,
     }
 
   /* If we have optimized stabs strings, output them.  */
-  if (coff_hash_table (info)->stab_info != NULL)
+  if (coff_hash_table (info)->stab_info.stabstr != NULL)
     {
       if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
 	return FALSE;
@@ -2282,6 +2282,9 @@ _bfd_coff_link_input_bfd (struct coff_fi
 	/* This section was omitted from the link.  */
 	continue;
 
+      if ((o->flags & SEC_LINKER_CREATED) != 0)
+	continue;
+
       if ((o->flags & SEC_HAS_CONTENTS) == 0
 	  || (o->size == 0 && (o->flags & SEC_RELOC) == 0))
 	{
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.143
diff -u -p -r1.143 elf-bfd.h
--- bfd/elf-bfd.h	21 Jun 2004 14:45:41 -0000	1.143
+++ bfd/elf-bfd.h	28 Jun 2004 13:16:14 -0000
@@ -356,12 +356,12 @@ struct elf_link_hash_table
   /* The _GLOBAL_OFFSET_TABLE_ symbol.  */
   struct elf_link_hash_entry *hgot;
 
-  /* A pointer to information used to link stabs in sections.  */
-  void *stab_info;
-
   /* A pointer to information used to merge SEC_MERGE sections.  */
   void *merge_info;
 
+  /* Used to link stabs in sections.  */
+  struct stab_info stab_info;
+
   /* Used by eh_frame code when editing .eh_frame.  */
   struct eh_frame_hdr_info eh_info;
 
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.231
diff -u -p -r1.231 elf.c
--- bfd/elf.c	24 Jun 2004 04:46:18 -0000	1.231
+++ bfd/elf.c	28 Jun 2004 13:16:19 -0000
@@ -1466,8 +1466,8 @@ _bfd_elf_link_hash_table_init
   table->bucketcount = 0;
   table->needed = NULL;
   table->hgot = NULL;
-  table->stab_info = NULL;
   table->merge_info = NULL;
+  memset (&table->stab_info, 0, sizeof (table->stab_info));
   memset (&table->eh_info, 0, sizeof (table->eh_info));
   table->dynlocal = NULL;
   table->runpath = NULL;
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.74
diff -u -p -r1.74 elflink.c
--- bfd/elflink.c	24 Jun 2004 04:46:22 -0000	1.74
+++ bfd/elflink.c	28 Jun 2004 13:16:53 -0000
@@ -4124,7 +4124,7 @@ elf_link_add_object_symbols (bfd *abfd, 
 
 		secdata = elf_section_data (stab);
 		if (! _bfd_link_section_stabs (abfd,
-					       & hash_table->stab_info,
+					       &hash_table->stab_info,
 					       stab, stabstr,
 					       &secdata->sec_info,
 					       &string_offset))
@@ -8001,6 +8001,8 @@ bfd_elf_final_link (bfd *abfd, struct bf
 		 created by _bfd_elf_link_create_dynamic_sections.  */
 	      continue;
 	    }
+	  if (elf_hash_table (info)->stab_info.stabstr == o)
+	    continue;
 	  if (elf_hash_table (info)->eh_info.hdr_sec == o)
 	    continue;
 	  if ((elf_section_data (o->output_section)->this_hdr.sh_type
@@ -8036,7 +8038,7 @@ bfd_elf_final_link (bfd *abfd, struct bf
     }
 
   /* If we have optimized stabs strings, output them.  */
-  if (elf_hash_table (info)->stab_info != NULL)
+  if (elf_hash_table (info)->stab_info.stabstr != NULL)
     {
       if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info))
 	goto error_return;
Index: bfd/libbfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd-in.h,v
retrieving revision 1.37
diff -u -p -r1.37 libbfd-in.h
--- bfd/libbfd-in.h	24 Jun 2004 04:46:24 -0000	1.37
+++ bfd/libbfd-in.h	28 Jun 2004 13:17:00 -0000
@@ -498,7 +498,8 @@ extern bfd_reloc_status_type _bfd_reloca
 /* Link stabs in sections in the first pass.  */
 
 extern bfd_boolean _bfd_link_section_stabs
-  (bfd *, void **, asection *, asection *, void **, bfd_size_type *);
+  (bfd *, struct stab_info *, asection *, asection *, void **,
+   bfd_size_type *);
 
 /* Eliminate stabs for discarded functions and symbols.  */
 extern bfd_boolean _bfd_discard_section_stabs
@@ -507,12 +508,12 @@ extern bfd_boolean _bfd_discard_section_
 /* Write out the .stab section when linking stabs in sections.  */
 
 extern bfd_boolean _bfd_write_section_stabs
-  (bfd *, void **, asection *, void **, bfd_byte *);
+  (bfd *, struct stab_info *, asection *, void **, bfd_byte *);
 
 /* Write out the .stabstr string table when linking stabs in sections.  */
 
 extern bfd_boolean _bfd_write_stab_strings
-  (bfd *, void **);
+  (bfd *, struct stab_info *);
 
 /* Find an offset within a .stab section when linking stabs in
    sections.  */
Index: bfd/libcoff-in.h
===================================================================
RCS file: /cvs/src/src/bfd/libcoff-in.h,v
retrieving revision 1.20
diff -u -p -r1.20 libcoff-in.h
--- bfd/libcoff-in.h	20 Oct 2003 14:38:39 -0000	1.20
+++ bfd/libcoff-in.h	28 Jun 2004 13:17:01 -0000
@@ -276,7 +276,7 @@ struct coff_link_hash_table
 {
   struct bfd_link_hash_table root;
   /* A pointer to information used to link stabs in sections.  */
-  PTR stab_info;
+  struct stab_info stab_info;
 };
 
 /* Look up an entry in a COFF linker hash table.  */
Index: bfd/stabs.c
===================================================================
RCS file: /cvs/src/src/bfd/stabs.c,v
retrieving revision 1.19
diff -u -p -r1.19 stabs.c
--- bfd/stabs.c	24 Jun 2004 04:46:26 -0000	1.19
+++ bfd/stabs.c	28 Jun 2004 13:17:05 -0000
@@ -48,13 +48,6 @@
 #define VALOFF (8)
 #define STABSIZE (12)
 
-/* A hash table used for header files with N_BINCL entries.  */
-
-struct stab_link_includes_table
-{
-  struct bfd_hash_table root;
-};
-
 /* A linked list of totals that we have found for a particular header
    file.  A total is a unique identifier for a particular BINCL...EINCL
    sequence of STABs that can be used to identify duplicate sequences.
@@ -80,12 +73,6 @@ struct stab_link_includes_entry
   struct stab_link_includes_totals *totals;
 };
 
-/* Look up an entry in an the header file hash table.  */
-
-#define stab_link_includes_lookup(table, string, create, copy) \
-  ((struct stab_link_includes_entry *) \
-   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
-
 /* This structure is used to hold a list of N_BINCL symbols, some of
    which might be converted into N_EXCL symbols.  */
 
@@ -124,19 +111,6 @@ struct stab_section_info
   bfd_size_type stridxs[1];
 };
 
-/* This structure is used to keep track of stabs in sections
-   information while linking.  */
-
-struct stab_info
-{
-  /* A hash table used to hold stabs strings.  */
-  struct bfd_strtab_hash *strings;
-  /* The header file hash table.  */
-  struct stab_link_includes_table includes;
-  /* The first .stabstr section.  */
-  asection *stabstr;
-};
-
 static struct bfd_hash_entry *stab_link_includes_newfunc
   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
 
@@ -176,16 +150,15 @@ stab_link_includes_newfunc (entry, table
    pass of the linker.  */
 
 bfd_boolean
-_bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_offset)
+_bfd_link_section_stabs (abfd, sinfo, stabsec, stabstrsec, psecinfo, pstring_offset)
      bfd *abfd;
-     PTR *psinfo;
+     struct stab_info *sinfo;
      asection *stabsec;
      asection *stabstrsec;
      PTR *psecinfo;
      bfd_size_type *pstring_offset;
 {
   bfd_boolean first;
-  struct stab_info *sinfo;
   bfd_size_type count, amt;
   struct stab_section_info *secinfo;
   bfd_byte *stabbuf = NULL;
@@ -227,30 +200,26 @@ _bfd_link_section_stabs (abfd, psinfo, s
 
   first = FALSE;
 
-  if (*psinfo == NULL)
+  if (sinfo->stabstr == NULL)
     {
       /* Initialize the stabs information we need to keep track of.  */
       first = TRUE;
-      amt = sizeof (struct stab_info);
-      *psinfo = (PTR) bfd_alloc (abfd, amt);
-      if (*psinfo == NULL)
-	goto error_return;
-      sinfo = (struct stab_info *) *psinfo;
       sinfo->strings = _bfd_stringtab_init ();
       if (sinfo->strings == NULL)
 	goto error_return;
       /* Make sure the first byte is zero.  */
       (void) _bfd_stringtab_add (sinfo->strings, "", TRUE, TRUE);
-      if (! bfd_hash_table_init_n (&sinfo->includes.root,
+      if (! bfd_hash_table_init_n (&sinfo->includes,
 				   stab_link_includes_newfunc,
 				   251))
 	goto error_return;
       sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr");
-      sinfo->stabstr->flags |= SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
+      if (sinfo->stabstr == NULL)
+	goto error_return;
+      sinfo->stabstr->flags |= (SEC_HAS_CONTENTS | SEC_READONLY
+				| SEC_DEBUGGING | SEC_LINKER_CREATED);
     }
 
-  sinfo = (struct stab_info *) *psinfo;
-
   /* Initialize the information we are going to store for this .stab
      section.  */
 
@@ -411,8 +380,8 @@ _bfd_link_section_stabs (abfd, psinfo, s
 
 	  /* If we have already included a header file with the same
 	     value, then replaced this one with an N_EXCL symbol.  */
-	  incl_entry = stab_link_includes_lookup (&sinfo->includes, string,
-						  TRUE, TRUE);
+	  incl_entry = (struct stab_link_includes_entry * )
+	    bfd_hash_lookup (&sinfo->includes, string, TRUE, TRUE);
 	  if (incl_entry == NULL)
 	    goto error_return;
 
@@ -439,7 +408,7 @@ _bfd_link_section_stabs (abfd, psinfo, s
 	      /* This is the first time we have seen this header file
 		 with this set of stabs strings.  */
 	      t = ((struct stab_link_includes_totals *)
-		   bfd_hash_allocate (&sinfo->includes.root, sizeof *t));
+		   bfd_hash_allocate (&sinfo->includes, sizeof *t));
 	      if (t == NULL)
 		goto error_return;
 	      t->sum_chars = sum_chars;
@@ -718,20 +687,18 @@ _bfd_discard_section_stabs (abfd, stabse
    contents.  */
 
 bfd_boolean
-_bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents)
+_bfd_write_section_stabs (output_bfd, sinfo, stabsec, psecinfo, contents)
      bfd *output_bfd;
-     PTR *psinfo;
+     struct stab_info *sinfo;
      asection *stabsec;
      PTR *psecinfo;
      bfd_byte *contents;
 {
-  struct stab_info *sinfo;
   struct stab_section_info *secinfo;
   struct stab_excl_list *e;
   bfd_byte *sym, *tosym, *symend;
   bfd_size_type *pstridx;
 
-  sinfo = (struct stab_info *) *psinfo;
   secinfo = (struct stab_section_info *) *psecinfo;
 
   if (secinfo == NULL)
@@ -792,17 +759,10 @@ _bfd_write_section_stabs (output_bfd, ps
 /* Write out the .stabstr section.  */
 
 bfd_boolean
-_bfd_write_stab_strings (output_bfd, psinfo)
+_bfd_write_stab_strings (output_bfd, sinfo)
      bfd *output_bfd;
-     PTR *psinfo;
+     struct stab_info *sinfo;
 {
-  struct stab_info *sinfo;
-
-  sinfo = (struct stab_info *) *psinfo;
-
-  if (sinfo == NULL)
-    return TRUE;
-
   if (bfd_is_abs_section (sinfo->stabstr->output_section))
     {
       /* The section was discarded from the link.  */
@@ -824,7 +784,7 @@ _bfd_write_stab_strings (output_bfd, psi
 
   /* We no longer need the stabs information.  */
   _bfd_stringtab_free (sinfo->strings);
-  bfd_hash_table_free (&sinfo->includes.root);
+  bfd_hash_table_free (&sinfo->includes);
 
   return TRUE;
 }
Index: opcodes/ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.72
diff -u -p -r1.72 ppc-opc.c
--- opcodes/ppc-opc.c	26 Jun 2004 08:32:12 -0000	1.72
+++ opcodes/ppc-opc.c	28 Jun 2004 13:17:54 -0000
@@ -998,11 +998,22 @@ insert_fxm (unsigned long insn,
 	    int dialect,
 	    const char **errmsg)
 {
+  /* If we're handling the mfocrf and mtocrf insns ensure that exactly
+     one bit of the mask field is set.  */
+  if ((insn & (1 << 20)) != 0)
+    {
+      if (value == 0 || (value & -value) != value)
+	{
+	  *errmsg = _("invalid mask field");
+	  value = 0;
+	}
+    }
+
   /* If the optional field on mfcr is missing that means we want to use
      the old form of the instruction that moves the whole cr.  In that
      case we'll have VALUE zero.  There doesn't seem to be a way to
      distinguish this from the case where someone writes mfcr %r3,0.  */
-  if (value == 0)
+  else if (value == 0)
     ;
 
   /* If only one bit of the FXM field is set, we can use the new form
@@ -1028,7 +1039,7 @@ insert_fxm (unsigned long insn,
 
 static long
 extract_fxm (unsigned long insn,
-	     int dialect,
+	     int dialect ATTRIBUTE_UNUSED,
 	     int *invalid)
 {
   long mask = (insn >> 12) & 0xff;
@@ -1036,14 +1047,9 @@ extract_fxm (unsigned long insn,
   /* Is this a Power4 insn?  */
   if ((insn & (1 << 20)) != 0)
     {
-      if ((dialect & PPC_OPCODE_POWER4) == 0)
+      /* Exactly one bit of MASK should be set.  */
+      if (mask == 0 || (mask & -mask) != mask)
 	*invalid = 1;
-      else
-	{
-	  /* Exactly one bit of MASK should be set.  */
-	  if (mask == 0 || (mask & -mask) != mask)
-	    *invalid = 1;
-	}
     }
 
   /* Check that non-power4 form of mfcr has a zero MASK.  */
@@ -1681,11 +1687,12 @@ extract_tbr (unsigned long insn,
 #define XS_MASK XS (0x3f, 0x1ff, 1)
 
 /* A mask for the FXM version of an XFX form instruction.  */
-#define XFXFXM_MASK (X_MASK | (1 << 11))
+#define XFXFXM_MASK (X_MASK | (1 << 11) | (1 << 20))
 
 /* An XFX form instruction with the FXM field filled in.  */
-#define XFXM(op, xop, fxm) \
-  (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12))
+#define XFXM(op, xop, fxm, p4) \
+  (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12) \
+   | ((unsigned long)(p4) << 20))
 
 /* An XFX form instruction with the SPR field filled in.  */
 #define XSPR(op, xop, spr) \
@@ -3227,6 +3234,7 @@ const struct powerpc_opcode powerpc_opco
 { "iseleq",  X(31,79),      X_MASK,	PPCISEL,	{ RT, RA, RB } },
 { "isel",    XISEL(31,15),  XISEL_MASK,	PPCISEL,	{ RT, RA, RB, CRB } },
 
+{ "mfocrf",  XFXM(31,19,0,1), XFXFXM_MASK, COM,		{ RT, FXM } },
 { "mfcr",    X(31,19),	XRARB_MASK,	NOPOWER4,	{ RT } },
 { "mfcr",    X(31,19),	XFXFXM_MASK,	POWER4,		{ RT, FXM4 } },
 
@@ -3382,7 +3390,8 @@ const struct powerpc_opcode powerpc_opco
 
 { "dcbtstlse",X(31,142),X_MASK,		PPCCHLK64,	{ CT, RA, RB }},
 
-{ "mtcr",    XFXM(31,144,0xff), XRARB_MASK, COM,	{ RS }},
+{ "mtocrf",  XFXM(31,144,0,1), XFXFXM_MASK, COM,	{ FXM, RS } },
+{ "mtcr",    XFXM(31,144,0xff,0), XRARB_MASK, COM,	{ RS }},
 { "mtcrf",   X(31,144),	XFXFXM_MASK,	COM,		{ FXM, RS } },
 
 { "mtmsr",   X(31,146),	XRARB_MASK,	COM,		{ RS } },

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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