This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH, cygwin] Internal error when loading dlls without .data section.
- From: Pedro Alves <pedro_alves at portugalmail dot pt>
- To: GDB Patches <gdb-patches at sourceware dot org>
- Date: Thu, 21 Dec 2006 21:53:31 +0000
- Subject: [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-*"] {