This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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]

[PATCH, cygwin] Internal error when loading dlls without .data section.


Hi all,

Now that shlib tests run on cygwin (with binutils-cvs), the gdb.base/shreloc.exp
test caught a dll loading bug. There is an attempt to get to SECT_OFF_DATA (objfile),
in an objfile without the sect_index_data set.


Here is what happens:

The dlls built from shreloc1.c and shreloc2.c don't have .data sections.
Also, they are both compiled into the same preferred load address using
-Wl,--image-base,0x04000000.  Since only one can load at that image-base,
the other dll will be relocated.

When the first dll is loaded, in symfile.c:init_objfile_sect_indices there is code that
sets objfile->sect_index_data to 0 if no section was found.


symfile.c:init_objfile_sect_indices:

for (i = 0; i < objfile->num_sections; i++)
 {
   if (ANOFFSET (objfile->section_offsets, i) != 0)
     {
       break;
     }
 }
 if (i == objfile->num_sections)
   {
     if (objfile->sect_index_text == -1)
       objfile->sect_index_text = 0;
     if (objfile->sect_index_data == -1)
       objfile->sect_index_data = 0;
     if (objfile->sect_index_bss == -1)
       objfile->sect_index_bss = 0;
     if (objfile->sect_index_rodata == -1)
       objfile->sect_index_rodata = 0;
   }


But, when the second dll is loaded, and since it was relocated,
the 'ANOFFSET (objfile->section_offsets, i) != 0' will be true, thus skipping
the initialization to zero afterwards, thus leaving objfile->sect_index_data with
the default of -1. The internal_error then is called on coffread.c:coff_symtab_read,
while reading the minsyms, where there is code like this:


else if (sec == SECT_OFF_DATA (objfile))
     {
            ms_type =
                cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
                mst_data : mst_file_data;
      }

The attached patch fixes it by not depending on the SECT_OFF_* macros to determine
the minimal_symbol_type of the minsymbol, but using bfd_section flags.


In the process I noted that bss symbols where recorded with mst_data or mst_file_data
types. Fixed that too.


The shreloc.exp needs a little tweak since passing -Wl,--image-base,0x04000000 on
additional_flags when building the .o files ends up giving the unfiltered warning:
"linker input file unused because linking not done"
which causes the test to end up being untested.


Tested on i686-pc-cygwin, where it fixes the crash, makes shreloc.exp pass perfectly, and
introduces no new regressions.


Please review and commit,

Cheers,
Pedro Alves

----
gdb/

2006-12-21 Pedro Alves <pedro_alves@portugalmail.pt>

       * coffread.c (cs_to_section): If bfd_section is found, always
       return it's section index.
       (coff_symtab_read): Determine the minimal_symbol_type using the
       bfd_section flags.

gdb/testsuite/

2006-12-21 Pedro Alves <pedro_alves@portugalmail.pt>

       * gdb.base/shreloc.exp: Use ldflags instead of additional_flags to
       pass --image-base to linker.

--- coffread.c.org	2006-12-21 14:16:22.000000000 +0000
+++ coffread.c	2006-12-21 14:19:08.000000000 +0000
@@ -277,19 +277,9 @@ static int
 cs_to_section (struct coff_symbol *cs, struct objfile *objfile)
 {
   asection *sect = cs_to_bfd_section (cs, objfile);
-  int off = SECT_OFF_TEXT (objfile);
-  if (sect != NULL)
-    {
-      /* This is the section.  Figure out what SECT_OFF_* code it is.  */
-      if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
-	off = SECT_OFF_TEXT (objfile);
-      else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
-	off = SECT_OFF_DATA (objfile);
-      else
-	/* Just return the bfd section index. */
-	off = sect->index;
-    }
-  return off;
+  if (sect == NULL)
+    return SECT_OFF_TEXT (objfile);
+  return sect->index;
 }
 
 /* Return the address of the section of a COFF symbol.  */
@@ -711,6 +701,7 @@ coff_symtab_read (long symtab_offset, un
   long fcn_line_ptr = 0;
   int val;
   CORE_ADDR tmpaddr;
+  struct minimal_symbol *msym;
 
   /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
      it's hard to know I've really worked around it.  The fix should be
@@ -903,6 +894,7 @@ coff_symtab_read (long symtab_offset, un
  	      }
 	    else
 	      {
+		asection *bfd_section = cs_to_bfd_section (cs, objfile);
 		sec = cs_to_section (cs, objfile);
 		tmpaddr = cs->c_value;
  		/* Statics in a PE file also get relocated */
@@ -912,7 +904,7 @@ coff_symtab_read (long symtab_offset, un
  		    || (pe_file && (cs->c_sclass == C_STAT)))
 		  tmpaddr += ANOFFSET (objfile->section_offsets, sec);
 
-		if (sec == SECT_OFF_TEXT (objfile))
+		if (bfd_section->flags & SEC_CODE)
 		  {
 		    ms_type =
 		      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
@@ -920,28 +912,26 @@ coff_symtab_read (long symtab_offset, un
 		      mst_text : mst_file_text;
 		    tmpaddr = SMASH_TEXT_ADDRESS (tmpaddr);
 		  }
-		else if (sec == SECT_OFF_DATA (objfile))
+		else if (bfd_section->flags & SEC_ALLOC
+			 && bfd_section->flags & SEC_LOAD)
 		  {
 		    ms_type =
 		      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
 		      mst_data : mst_file_data;
 		  }
-		else if (sec == SECT_OFF_BSS (objfile))
+		else if (bfd_section->flags & SEC_ALLOC)
 		  {
 		    ms_type =
 		      cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
-		      mst_data : mst_file_data;
+		      mst_bss : mst_file_bss;
 		  }
 		else
 		  ms_type = mst_unknown;
 	      }
 
-	    {
-	      struct minimal_symbol *msym;
-	      msym = record_minimal_symbol (cs, tmpaddr, ms_type, sec, objfile);
-	      if (msym)
-	        COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
-	    }
+	    msym = record_minimal_symbol (cs, tmpaddr, ms_type, sec, objfile);
+	    if (msym)
+	      COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
 
 	    if (SDB_TYPE (cs->c_type))
 	      {
Index: testsuite/gdb.base/shreloc.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/shreloc.exp,v
retrieving revision 1.4
diff -u -p -r1.4 shreloc.exp
--- testsuite/gdb.base/shreloc.exp	19 Feb 2006 20:53:34 -0000	1.4
+++ testsuite/gdb.base/shreloc.exp	21 Dec 2006 21:37:27 -0000
@@ -55,7 +55,7 @@ set lib_opts "debug"
 set exec_opts [list debug shlib=$lib1_sl shlib=$lib2_sl]
 
 if {([istarget "*pc-cygwin"] || [istarget "*pc-mingw32"]) } {
-    lappend lib_opts "additional_flags=-Wl,--image-base,0x04000000"
+    lappend lib_opts "ldflags=-Wl,--image-base,0x04000000"
 }
 
 if [test_compiler_info "xlc-*"] {

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