This is the mail archive of the
gdb-prs@sources.redhat.com
mailing list for the GDB project.
symtab/1786: When debugging arm linux kernel modules some symbols have the wrong address
- From: welch at cwcom dot net
- To: gdb-gnats at sources dot redhat dot com
- Date: 5 Oct 2004 16:57:36 -0000
- Subject: symtab/1786: When debugging arm linux kernel modules some symbols have the wrong address
- Reply-to: welch at cwcom dot net
>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 */