PATCH: PR gas/10531: Strange assembler warning message on section group

H.J. Lu hjl.tools@gmail.com
Tue Aug 18 16:41:00 GMT 2009


On Mon, Aug 17, 2009 at 8:12 PM, Alan Modra<amodra@bigpond.net.au> wrote:
> On Mon, Aug 17, 2009 at 04:07:21PM -0700, H.J. Lu wrote:
>> We can't use bfd_get_section_by_name, subseg_new and subseg_get directly
>> in dwarf2dbg.c since they don't know ELF section groups.  This patch adds
>> obj_get_section_by_name, obj_subseg_new and obj_subseg_get.  Tested on
>> Linux/ia32, Linux/ia64 and Linux/Intel64.  OK to install?
>
> Have you tested this with a multi-obj assembler?  I suspect that
> something like x86-as --em=i386coff --gdwarf-2 will attempt to
> access elf-only data structures.  (That's a slightly ridiculous
> set of command line options for x86, but we shouldn't have gas
> segfault.)  I think the proper patch needs some new fields in
> struct format_ops and defines in obj-multi.h.
>

strcmp can't be used to check if 2 ELF sections have the same name.
I added bfd_section_name_eq.  OK to install?

Thanks.

-- 
H.J.
---
bfd/

2009-08-18  H.J. Lu  <hongjiu.lu@intel.com>

	 PR gas/10531
	 * section.c: Include "elf-bfd.h".
	 (bfd_section_name_eq): New.
	 (bfd_get_section_by_name): Don't use a section in a section
	 group.
	 (bfd_make_section_old_way): Likewise.

	* bfd-in2.h: Regenerated.

gas/

2009-08-18  H.J. Lu  <hongjiu.lu@intel.com>

	 PR gas/10531
	 * ehopt.c (get_cie_info): Use bfd_section_name_eq to check if
	 section names are the same.
	 (check_eh_frame): Likewise.
	 * read.c (emit_expr): Likewise.
	 (stringer): Likewise.
	 * stabs.c (s_stab_generic): Likewise.
	 * subsegs.c (subseg_get): Likewise.

gas/testsuite/

2009-08-18  H.J. Lu  <hongjiu.lu@intel.com>

	 PR gas/10531
	 * gas/elf/group2.d: New.
	 * gas/elf/group2.s: Likewise.
	 * gas/i386/debug1.d: Likewise.
	 * gas/i386/debug1.s: Likewise.

	* gas/elf/elf.exp: Run group2.

	* gas/i386/i386.exp: Run debug1 for both 32bit and 64bit.
-------------- next part --------------
bfd/

2009-08-18  H.J. Lu  <hongjiu.lu@intel.com>

	 PR gas/10531
	 * section.c: Include "elf-bfd.h".
	 (bfd_section_name_eq): New.
	 (bfd_get_section_by_name): Don't use a section in a section
	 group.
	 (bfd_make_section_old_way): Likewise.

	* bfd-in2.h: Regenerated.

gas/

2009-08-18  H.J. Lu  <hongjiu.lu@intel.com>

	 PR gas/10531
	 * ehopt.c (get_cie_info): Use bfd_section_name_eq to check if
	 section name is the same.
	 (check_eh_frame): Likewise.
	 * read.c (emit_expr): Likewise.
	 (stringer): Likewise.
	 * stabs.c (s_stab_generic): Likewise.
	 * subsegs.c (subseg_get): Likewise.

gas/testsuite/

2009-08-18  H.J. Lu  <hongjiu.lu@intel.com>

	 PR gas/10531
	 * gas/elf/group2.d: New.
	 * gas/elf/group2.s: Likewise.
	 * gas/i386/debug1.d: Likewise.
	 * gas/i386/debug1.s: Likewise.

	* gas/elf/elf.exp: Run group2.

	* gas/i386/i386.exp: Run debug1 for both 32bit and 64bit.

Index: gas/read.c
===================================================================
--- gas/read.c	(revision 6552)
+++ gas/read.c	(working copy)
@@ -3979,7 +3979,7 @@ emit_expr (expressionS *exp, unsigned in
   {
     static int dwarf_line = -1;
 
-    if (strcmp (segment_name (now_seg), ".line") != 0)
+    if (bfd_section_name_eq (stdoutput, now_seg, ".line"))
       dwarf_line = -1;
     else if (dwarf_line >= 0
 	     && nbytes == 2
@@ -4002,7 +4002,7 @@ emit_expr (expressionS *exp, unsigned in
   {
     static int dwarf_file = 0;
 
-    if (strcmp (segment_name (now_seg), ".debug") != 0)
+    if (bfd_section_name_eq (stdoutput, now_seg, ".debug"))
       dwarf_file = 0;
     else if (dwarf_file == 0
 	     && nbytes == 2
@@ -5144,7 +5144,7 @@ stringer (int bits_appendzero)
 	     emit_expr for the sequence.  emit_expr will set
 	     dwarf_file_string to non-zero if this string might be a
 	     source file name.  */
-	  if (strcmp (segment_name (now_seg), ".debug") != 0)
+	  if (bfd_section_name_eq (stdoutput, now_seg, ".debug"))
 	    dwarf_file_string = 0;
 	  else if (dwarf_file_string)
 	    {
Index: gas/testsuite/gas/i386/i386.exp
===================================================================
--- gas/testsuite/gas/i386/i386.exp	(revision 6552)
+++ gas/testsuite/gas/i386/i386.exp	(working copy)
@@ -190,6 +190,7 @@ if [expr ([istarget "i*86-*-*"] ||  [ist
 	run_list_test "inval-equ-2" "-al"
 	run_dump_test "ifunc"
 	run_list_test "l1om-inval" "-march=l1om --32"
+	run_dump_test "debug1"
     }
 
     # This is a PE specific test.
@@ -348,6 +349,7 @@ if [expr ([istarget "i*86-*-*"] || [ista
 	run_dump_test "mixed-mode-reloc64"
 	run_dump_test "x86-64-ifunc"
 	run_dump_test "l1om"
+	run_dump_test "debug1"
     }
 
     set ASFLAGS "$old_ASFLAGS"
Index: gas/testsuite/gas/i386/debug1.d
===================================================================
--- gas/testsuite/gas/i386/debug1.d	(revision 0)
+++ gas/testsuite/gas/i386/debug1.d	(revision 0)
@@ -0,0 +1,19 @@
+#as: -g
+#readelf: -SWg
+#name: group section with debug sections
+
+
+#...
+[ 	]*\[.*\][ 	]+foo[ 	]+GROUP.*
+#...
+[ 	]*\[.*\][ 	]+\.debug_info[ 	]+PROGBITS.*[ 	]+G[ 	]+.*
+[ 	]*\[.*\][ 	]+\.debug_line[ 	]+PROGBITS.*[ 	]+G[ 	]+.*
+[ 	]*\[.*\][ 	]+\.debug_line[ 	]+PROGBITS.*[ 	]+.*
+#...
+[ 	]*\[.*\][ 	]+\.debug_info[ 	]+PROGBITS.*[ 	]+.*
+#...
+COMDAT group section \[    1\] `foo' \[foo\] contains 2 sections:
+[ 	]+\[Index\][ 	]+Name
+[ 	]+\[.*\][ 	]+.debug_info
+[ 	]+\[.*\][ 	]+.debug_line
+#pass
Index: gas/testsuite/gas/i386/debug1.s
===================================================================
--- gas/testsuite/gas/i386/debug1.s	(revision 0)
+++ gas/testsuite/gas/i386/debug1.s	(revision 0)
@@ -0,0 +1,11 @@
+	.section .debug_info,"G",%progbits,foo,comdat
+	.byte 0x0
+	.section .debug_line,"G",%progbits,foo,comdat
+	.byte 0x0
+	.section .debug_info,"G",@progbits,foo,comdat
+	.byte 0x0
+	.section .debug_line,"G",@progbits,foo,comdat
+	.byte 0x0
+	.text
+	nop
+	nop
Index: gas/testsuite/gas/elf/group2.s
===================================================================
--- gas/testsuite/gas/elf/group2.s	(revision 0)
+++ gas/testsuite/gas/elf/group2.s	(revision 0)
@@ -0,0 +1,6 @@
+	.section .debug_info
+	.byte 0x0
+	.section .debug_info,"G",%progbits,foo,comdat
+	.byte 0x0
+	.section .debug_line,"G",%progbits,foo,comdat
+	.byte 0x0
Index: gas/testsuite/gas/elf/group2.d
===================================================================
--- gas/testsuite/gas/elf/group2.d	(revision 0)
+++ gas/testsuite/gas/elf/group2.d	(revision 0)
@@ -0,0 +1,16 @@
+#readelf: -SWg
+#name: group section with debug sections
+
+
+#...
+[ 	]*\[.*\][ 	]+foo[ 	]+GROUP.*
+#...
+[ 	]*\[.*\][ 	]+\.debug_info[ 	]+PROGBITS.*[ 	]+G[ 	]+.*
+[ 	]*\[.*\][ 	]+\.debug_line[ 	]+PROGBITS.*[ 	]+G[ 	]+.*
+[ 	]*\[.*\][ 	]+\.debug_line[ 	]+PROGBITS.*[ 	]+.*
+#...
+COMDAT group section \[    1\] `foo' \[foo\] contains 2 sections:
+[ 	]+\[Index\][ 	]+Name
+[ 	]+\[.*\][ 	]+.debug_info
+[ 	]+\[.*\][ 	]+.debug_line
+#pass
Index: gas/testsuite/gas/elf/elf.exp
===================================================================
--- gas/testsuite/gas/elf/elf.exp	(revision 6552)
+++ gas/testsuite/gas/elf/elf.exp	(working copy)
@@ -100,6 +100,7 @@ if { ([istarget "*-*-*elf*"]		
     run_dump_test "group0b" 
     run_dump_test "group1a" 
     run_dump_test "group1b" 
+    run_dump_test "group2" 
     case $target_triplet in {
 	{ alpha*-*-* } { }
 	{ cr16*-*-* } { }
Index: gas/stabs.c
===================================================================
--- gas/stabs.c	(revision 6552)
+++ gas/stabs.c	(working copy)
@@ -307,7 +307,6 @@ s_stab_generic (int what, char *stab_sec
       char *p;
 
       static segT cached_sec;
-      static char *cached_secname;
 
       dot = frag_now_fix ();
 
@@ -315,7 +314,8 @@ s_stab_generic (int what, char *stab_sec
       md_flush_pending_output ();
 #endif
 
-      if (cached_secname && !strcmp (cached_secname, stab_secname))
+      if (cached_sec
+	  && bfd_section_name_eq (stdoutput, cached_sec, stab_secname))
 	{
 	  seg = cached_sec;
 	  subseg_set (seg, 0);
@@ -323,9 +323,6 @@ s_stab_generic (int what, char *stab_sec
       else
 	{
 	  seg = subseg_new (stab_secname, 0);
-	  if (cached_secname)
-	    free (cached_secname);
-	  cached_secname = xstrdup (stab_secname);
 	  cached_sec = seg;
 	}
 
Index: gas/ehopt.c
===================================================================
--- gas/ehopt.c	(revision 6552)
+++ gas/ehopt.c	(working copy)
@@ -120,7 +120,7 @@ get_cie_info (struct cie_info *info)
 
   /* First make sure that the CIE Identifier Tag is 0/-1.  */
 
-  if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
+  if (bfd_section_name_eq (stdoutput, now_seg, ".debug_frame"))
     CIE_id = (char)0xff;
   else
     CIE_id = 0;
@@ -283,9 +283,9 @@ check_eh_frame (expressionS *exp, unsign
 #endif
 
   /* Select the proper section data.  */
-  if (strcmp (segment_name (now_seg), ".eh_frame") == 0)
+  if (bfd_section_name_eq (stdoutput, now_seg, ".eh_frame"))
     d = &eh_frame_data;
-  else if (strcmp (segment_name (now_seg), ".debug_frame") == 0)
+  else if (bfd_section_name_eq (stdoutput, now_seg, ".debug_frame"))
     d = &debug_frame_data;
   else
     return 0;
Index: gas/subsegs.c
===================================================================
--- gas/subsegs.c	(revision 6552)
+++ gas/subsegs.c	(working copy)
@@ -148,14 +148,10 @@ subseg_get (const char *segname, int for
 {
   segT secptr;
   segment_info_type *seginfo;
-  const char *now_seg_name = (now_seg
-			      ? bfd_get_section_name (stdoutput, now_seg)
-			      : 0);
 
   if (!force_new
-      && now_seg_name
-      && (now_seg_name == segname
-	  || !strcmp (now_seg_name, segname)))
+      && now_seg
+      && bfd_section_name_eq (stdoutput, now_seg, segname))
     return now_seg;
 
   if (!force_new)
Index: bfd/section.c
===================================================================
--- bfd/section.c	(revision 6552)
+++ bfd/section.c	(working copy)
@@ -138,6 +138,7 @@ SUBSECTION
 #include "bfd.h"
 #include "libbfd.h"
 #include "bfdlink.h"
+#include "elf-bfd.h"
 
 /*
 DOCDD
@@ -834,6 +835,31 @@ bfd_section_list_clear (bfd *abfd)
 
 /*
 FUNCTION
+	bfd_section_name_eq
+
+SYNOPSIS
+	bfd_boolean bfd_section_name_eq
+	  (bfd *abfd, asection *sec, const char *name);
+
+DESCRIPTION
+	Return <<TRUE>> if the name of section @var{sec} is the same as
+	@var{name}, otherwise <<FALSE>>.
+*/
+
+bfd_boolean
+bfd_section_name_eq (bfd *abfd, asection *sec, const char *name)
+{
+  /* Return FALSE if SEC is a member of ELF section group. */
+  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+      && elf_section_data (sec) != NULL
+      && elf_group_name (sec) != NULL)
+    return FALSE;
+  else
+    return strcmp (bfd_section_name (abfd, sec), name) == 0;
+}
+
+/*
+FUNCTION
 	bfd_get_section_by_name
 
 SYNOPSIS
@@ -854,11 +880,31 @@ asection *
 bfd_get_section_by_name (bfd *abfd, const char *name)
 {
   struct section_hash_entry *sh;
+  unsigned long hash;
+  asection *sec;
 
   sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
-  if (sh != NULL)
+  if (sh == NULL)
+    return NULL;
+
+  /* Only ELF has section group. */
+  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
     return &sh->section;
 
+  hash = sh->root.hash;
+  do
+    {
+      sec = &sh->section;
+      /* Don't return a section in a section group.  */
+      if (elf_section_data (sec) == NULL
+	  || elf_group_name (sec) == NULL)
+	return sec;
+      sh = (struct section_hash_entry *) sh->root.next;
+    }
+  while (sh != NULL
+	 && sh->root.hash == hash
+	 && strcmp (sh->root.string, name) == 0);
+
   return NULL;
 }
 
@@ -1011,7 +1057,43 @@ bfd_make_section_old_way (bfd *abfd, con
       if (sh == NULL)
 	return NULL;
 
-      newsect = &sh->section;
+      /* Only ELF has section group. */
+      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+	{
+	  struct section_hash_entry *old_sh = sh;
+	  unsigned long hash = sh->root.hash;
+
+	  do
+	    {
+	      newsect = &sh->section;
+	      /* Don't use a section in a section group.  */
+	      if (elf_section_data (newsect) == NULL
+		  || elf_group_name (newsect) == NULL)
+		break;
+	      sh = (struct section_hash_entry *) sh->root.next;
+	    }
+	  while (sh != NULL
+		 && sh->root.hash == hash
+		 && strcmp (sh->root.string, name) == 0);
+
+	  if (sh == NULL)
+	    {
+	      /* Allocate a new one since existing sections are in
+		 section groups.  */
+	      struct section_hash_entry *new_sh;
+	      new_sh = (struct section_hash_entry *)
+		bfd_section_hash_newfunc (NULL, &abfd->section_htab, name);
+	      if (new_sh == NULL)
+		return NULL;
+
+	      new_sh->root = old_sh->root;
+	      old_sh->root.next = &new_sh->root;
+	      newsect = &new_sh->section;
+	    }
+	}
+      else
+	newsect = &sh->section;
+
       if (newsect->name != NULL)
 	{
 	  /* Section already exists.  */
Index: bfd/bfd-in2.h
===================================================================
--- bfd/bfd-in2.h	(revision 6552)
+++ bfd/bfd-in2.h	(working copy)
@@ -1674,6 +1674,9 @@ extern asection bfd_ind_section;
 
 void bfd_section_list_clear (bfd *);
 
+bfd_boolean bfd_section_name_eq
+   (bfd *abfd, asection *sec, const char *name);
+
 asection *bfd_get_section_by_name (bfd *abfd, const char *name);
 
 asection *bfd_get_section_by_name_if


More information about the Binutils mailing list