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

symtab/1786: When debugging arm linux kernel modules some symbols have the wrong address


>Number:         1786
>Category:       symtab
>Synopsis:       When debugging arm linux kernel modules some symbols have the wrong address
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 05 16:58:01 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     welch@cwcom.net
>Release:        6.2.1
>Organization:
>Environment:
gdb 6.2.1 on cygwin, arm linux 2.6.6-rc3, gcc 3.4.0
>Description:
When debugging arm linux kernel modules gdb adds the base address of the .text section to the offsets of dwarf2 symbols in other sections even add-symbol-file has been used to give the other sections different base addresses. Symbols in the elf symbol table are correct.
>How-To-Repeat:
a.c contains
void A() {}
void __attribute__ ((section (".exit.text"))) B() {}

arm-linux-gcc -g -c a.c -o a.o
arm-elf-gdb
(gdb) add-symbol-file a.o 0xbf000000 -s .exit.text 0xbf020000
(gdb) info symbol 0xbf020000
B in section .exit.text [Correct]
(gdb) list *0xbf000000
0xbf000000 is in B (a.c:2). [Wrong, should be A]
>Fix:
I fixed this by changing to symfile_relocate_debug_section to relocate the debug sections based on the addresses supplied in add-symbol-file as in the attached patch.
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="diff.txt"
Content-Disposition: inline; filename="diff.txt"

diff -u -r orig/gdb-6.2.1/gdb/dbxread.c gdb-6.2.1/gdb/dbxread.c
--- orig/gdb-6.2.1/gdb/dbxread.c	2004-07-01 21:25:53.000000000 +0100
+++ gdb-6.2.1/gdb/dbxread.c	2004-10-05 11:41:32.069585600 +0100
@@ -2420,7 +2420,7 @@
       if (DBX_STAB_SECTION (pst->objfile))
 	{
 	  stabs_data
-	    = symfile_relocate_debug_section (pst->objfile->obfd,
+	    = symfile_relocate_debug_section (pst->objfile,
 					      DBX_STAB_SECTION (pst->objfile),
 					      NULL);
 	  if (stabs_data)
@@ -3370,7 +3370,7 @@
 
   symbuf_read = 0;
   symbuf_left = bfd_section_size (objfile->obfd, stabsect);
-  stabs_data = symfile_relocate_debug_section (objfile->obfd, stabsect, NULL);
+  stabs_data = symfile_relocate_debug_section (objfile, stabsect, NULL);
   if (stabs_data)
     back_to = make_cleanup (free_current_contents, (void *) &stabs_data);
 
diff -u -r orig/gdb-6.2.1/gdb/dwarf2read.c gdb-6.2.1/gdb/dwarf2read.c
--- orig/gdb-6.2.1/gdb/dwarf2read.c	2004-07-06 20:29:30.000000000 +0100
+++ gdb-6.2.1/gdb/dwarf2read.c	2004-10-05 11:41:31.438678400 +0100
@@ -4467,7 +4467,7 @@
 
   buf = (char *) obstack_alloc (&objfile->objfile_obstack, size);
   retbuf
-    = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf);
+    = (char *) symfile_relocate_debug_section (objfile, sectp, (bfd_byte *) buf);
   if (retbuf != NULL)
     return retbuf;
 
Only in gdb-6.2.1/gdb: gdb
diff -u -r orig/gdb-6.2.1/gdb/symfile.c gdb-6.2.1/gdb/symfile.c
--- orig/gdb-6.2.1/gdb/symfile.c	2004-06-24 23:09:34.000000000 +0100
+++ gdb-6.2.1/gdb/symfile.c	2004-10-05 14:26:53.215492800 +0100
@@ -3470,6 +3470,44 @@
 {
   sectp->output_section = sectp;
   sectp->output_offset = 0;
+}
+
+static void
+symfile_reloc_outputs (bfd *abfd, asection *sectp, void *dummy)
+{
+  struct objfile *objfile = (struct objfile *)dummy;
+
+  sectp->output_section = sectp;
+  sectp->output_offset = 0;
+
+  if (!(sectp->flags & SEC_DEBUGGING))
+  {
+    unsigned int text_offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+    unsigned int section_offset = ANOFFSET (objfile->section_offsets, sectp->index);
+
+    sectp->symbol = bfd_make_empty_symbol (abfd);
+
+    sectp->symbol->name = sectp->name;
+    sectp->symbol->value = section_offset - text_offset;
+    sectp->symbol->section = sectp;
+    sectp->symbol->flags = BSF_SECTION_SYM;
+  }
+}
+
+static void
+symfile_save_section_symbols (bfd *abfd, asection *sectp, void *dummy)
+{
+    asymbol** saved_section_symbols = (asymbol**)dummy;
+
+    saved_section_symbols[sectp->index] = sectp->symbol;
+}
+
+static void
+symfile_restore_section_symbols (bfd *abfd, asection *sectp, void *dummy)
+{
+    asymbol** saved_section_symbols = (asymbol**)dummy;
+
+    sectp->symbol = saved_section_symbols[sectp->index];
 }
 
 /* Relocate the contents of a debug section SECTP in ABFD.  The
@@ -3484,20 +3522,48 @@
    the relocations in order to get the locations of symbols correct.  */
 
 bfd_byte *
-symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf)
-{
+symfile_relocate_debug_section (struct objfile *objfile, asection *sectp, bfd_byte *buf)
+{
+  bfd *abfd = objfile->obfd;
+  int storage_needed;
+  asymbol **symbol_table;
+  unsigned int i, symcount;
+  asymbol** saved_section_symbols;
+  bfd_byte *contents;
+  unsigned int text_offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
   /* We're only interested in debugging sections with relocation
      information.  */
   if ((sectp->flags & SEC_RELOC) == 0)
     return NULL;
   if ((sectp->flags & SEC_DEBUGGING) == 0)
-    return NULL;
+    return NULL;
+
+  saved_section_symbols = xmalloc(abfd->section_count * sizeof(asymbol*));
+  bfd_map_over_sections (abfd, symfile_save_section_symbols, (void*)saved_section_symbols);
 
   /* We will handle section offsets properly elsewhere, so relocate as if
      all sections begin at 0.  */
-  bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL);
-
-  return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
+  bfd_map_over_sections (abfd, symfile_reloc_outputs, (void*)objfile);
+  
+  storage_needed = bfd_get_symtab_upper_bound (abfd);
+  symbol_table = malloc (storage_needed);
+  bfd_canonicalize_symtab (abfd, symbol_table);
+  symcount = bfd_get_symcount (abfd);
+  for (i = 0; i < symcount; i++)
+  {
+    if (!(symbol_table[i]->section->flags & SEC_DEBUGGING))
+    {
+	  symbol_table[i]->value += ANOFFSET (objfile->section_offsets, symbol_table[i]->section->index) - text_offset;
+    }
+  }
+
+  contents = bfd_simple_get_relocated_section_contents (abfd, sectp, buf, symbol_table);
+
+  bfd_map_over_sections (abfd, symfile_restore_section_symbols, (void*)saved_section_symbols);
+  xfree (saved_section_symbols);
+
+  return contents;
 }
 
 void
diff -u -r orig/gdb-6.2.1/gdb/symfile.h gdb-6.2.1/gdb/symfile.h
--- orig/gdb-6.2.1/gdb/symfile.h	2004-05-25 22:55:43.000000000 +0100
+++ gdb-6.2.1/gdb/symfile.h	2004-10-05 11:41:31.889326400 +0100
@@ -309,7 +309,7 @@
 /* Clear GDB symbol tables.  */
 extern void symbol_file_clear (int from_tty);
 
-extern bfd_byte *symfile_relocate_debug_section (bfd *abfd, asection *sectp,
+extern bfd_byte *symfile_relocate_debug_section (struct objfile *objfile, asection *sectp,
 						 bfd_byte * buf);
 
 /* From dwarfread.c */


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