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 3/3 ppc64] the fix


Hi,

the fix.


Thanks,
Jan


gdb/
2011-04-04  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix convert_code_addr_to_desc_addr for ppc64 files after eu-strip.
	* arch-utils.c (default_elf_synthetic_msyms_prep): New function.
	* arch-utils.h (default_elf_synthetic_msyms_prep): New declaration.
	* elfread.c (elf_symfile_read): New variables gdbarch, synth_abfd.
	Call gdbarch_elf_synthetic_msyms_prep when appropriate.  Set
	synth_abfd.  Pass SYNTH_ABFD to bfd_get_synthetic_symtab.
	* gdbarch.c: Regenerated.
	* gdbarch.h: Regenerated.
	* gdbarch.sh (elf_synthetic_msyms_prep): New method.
	* ppc-sysv-tdep.c <HAVE_ELF> (ppc64_sysv_translate_debuginfo_syms)
	<HAVE_ELF> (ppc64_sysv_elf_synthetic_msyms_prep)
	<!HAVE_ELF> (ppc64_sysv_elf_synthetic_msyms_prep): New functions.
	* ppc-tdep.h (ppc64_sysv_elf_synthetic_msyms_prep): New declaration.
	* rs6000-tdep.c (rs6000_gdbarch_init): Install it on ppc64.
	* symfile.c (build_section_addr_info_from_bfd): Set also
	saved_sectindex.
	(symbol_file_add_separate): Set sap->separate_debug_objfile_backlink.
	* symfile.h (struct section_addr_info): New field
	separate_debug_objfile_backlink.
	(struct other_sections): New field saved_sectindex.

gdb/testsuite/
2011-04-04  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix convert_code_addr_to_desc_addr for ppc64 files after eu-strip.
	* gdb.base/eu-strip-infcall.c: New file.
	* gdb.base/eu-strip-infcall.exp: New file.

--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -786,6 +786,17 @@ default_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
   gdbarch_breakpoint_from_pc (gdbarch, pcptr, kindptr);
 }
 
+int
+default_elf_synthetic_msyms_prep (struct section_addr_info *addrs,
+				  struct objfile *objfile,
+				  asymbol **symbol_table, long symcount,
+				  asymbol **dyn_symbol_table,
+				  long dynsymcount)
+{
+  /* Symbols have not been reassociated.  */
+  return 0;
+}
+
 /* */
 
 /* -Wmissing-prototypes */
--- a/gdb/arch-utils.h
+++ b/gdb/arch-utils.h
@@ -167,4 +167,11 @@ extern void default_remote_breakpoint_from_pc (struct gdbarch *,
 extern const char *default_auto_charset (void);
 extern const char *default_auto_wide_charset (void);
 
+extern int default_elf_synthetic_msyms_prep (struct section_addr_info *addrs,
+					     struct objfile *objfile,
+					     asymbol **symbol_table,
+					     long symcount,
+					     asymbol **dyn_symbol_table,
+					     long dynsymcount);
+
 #endif
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1231,7 +1231,8 @@ static void
 elf_symfile_read (struct objfile *objfile, int symfile_flags,
 		  struct section_addr_info *addrs)
 {
-  bfd *abfd = objfile->obfd;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  bfd *synth_abfd, *abfd = objfile->obfd;
   struct elfinfo ei;
   struct cleanup *back_to;
   long symcount = 0, dynsymcount = 0, synthcount, storage_needed;
@@ -1302,9 +1303,21 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags,
       elf_rel_plt_read (objfile, dyn_symbol_table);
     }
 
+  /* This OBJFILE - if it is a separate debug info file - may not have enough
+     information for bfd_get_synthetic_symtab.  Associate OBJFILE's ELF
+     symbols with backlinked BFD.  */
+
+  if (addrs && addrs->separate_debug_objfile_backlink
+      && gdbarch_elf_synthetic_msyms_prep (gdbarch, addrs, objfile,
+					   symbol_table, symcount,
+					   dyn_symbol_table, dynsymcount))
+    synth_abfd = addrs->separate_debug_objfile_backlink->obfd;
+  else
+    synth_abfd = abfd;
+
   /* Add synthetic symbols - for instance, names for any PLT entries.  */
 
-  synthcount = bfd_get_synthetic_symtab (abfd, symcount, symbol_table,
+  synthcount = bfd_get_synthetic_symtab (synth_abfd, symcount, symbol_table,
 					 dynsymcount, dyn_symbol_table,
 					 &synthsyms);
   if (synthcount > 0)
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -815,6 +815,13 @@ v:const char *:solib_symbols_extension:::::::pstring (gdbarch->solib_symbols_ext
 # is, absolute paths include a drive name, and the backslash is
 # considered a directory separator.
 v:int:has_dos_based_file_system:::0:0::0
+
+# Separate debug info OBJFILE may not have enough information for
+# bfd_get_synthetic_symtab.  Associate OBJFILE's ELF symbols with backlinked
+# BFD which is described by ADDRS.  Adjust the ELF symbols.  SYMBOL_TABLE
+# array has SYMCOUNT entries, DYN_SYMBOL_TABLE has DYNSYMCOUNT entries.
+# Return true if the ELF symbols have been reassociated, false otherwise.
+f:int:elf_synthetic_msyms_prep:struct section_addr_info *addrs, struct objfile *objfile, asymbol **symbol_table, long symcount, asymbol **dyn_symbol_table, long dynsymcount:addrs, objfile, symbol_table, symcount, dyn_symbol_table, dynsymcount:default_elf_synthetic_msyms_prep:default_elf_synthetic_msyms_prep::0
 EOF
 }
 
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -1971,3 +1971,116 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *func_type,
   return RETURN_VALUE_STRUCT_CONVENTION;
 }
 
+#ifdef HAVE_ELF
+
+/* Relocate ASYM_COUNT of ASYMS to a new BFD.  Mapping of ASYMS's BFD sections
+   to the new BFD sections is in SYM_TO_NEW_ABFD_SECT.  SYM_TO_NEW_ABFD_SECT
+   size is bfd_count_sections (asyms[0]->the_bfd).  All ASYMS have the same
+   THE_BFD.  */
+
+static void
+ppc64_sysv_translate_debuginfo_syms (asymbol **asyms, long asym_count,
+				     asection **sym_to_new_abfd_sect)
+{
+  for (; asym_count-- > 0; asyms++)
+    {
+      asymbol *asym = *asyms;
+      asection *new_asect = sym_to_new_abfd_sect[asym->section->index];
+
+      if (new_asect == NULL)
+	continue;
+
+      asym->section = new_asect;
+      asym->the_bfd = new_asect->owner;
+    }
+}
+
+/* An implementation for gdbarch_elf_synthetic_msyms_prep_p.
+
+   Contrary to binutils --strip-debug/--only-keep-debug the strip command from
+   elfutils (eu-strip) moves even the .symtab section into the .debug file.
+
+   bfd_get_synthetic_symtab on ppc64 for each function descriptor ELF symbol
+   'name' creates a new BSF_SYNTHETIC ELF symbol '.name' with its code
+   address.  But with eu-strip files bfd_get_synthetic_symtab fails to read
+   the code address from .opd while it reads the .symtab section from
+   a separate debug info file as the .opd section is SHT_NOBITS there.
+
+   This function patches the SECTION and THE_BFD fields of separate debug info
+   ELF symbols to associate them with the backlinked original BFD file where
+   the .opd section content is valid.
+
+   Note the confusion (unrelated) partial/full symbols (typically from DWARF)
+   are named 'name' but they refer to their code address (and not their
+   address of a function descriptor).  This dot/non-dot naming convention does
+   not match the dot/non-dot convention of minimal/ELF symbols.  */
+
+int
+ppc64_sysv_elf_synthetic_msyms_prep (struct section_addr_info *addrs,
+				     struct objfile *objfile,
+				     asymbol **symbol_table, long symcount,
+				     asymbol **dyn_symbol_table,
+				     long dynsymcount)
+{
+  struct objfile *backlink = addrs->separate_debug_objfile_backlink;
+  int i;
+  asection *asect, **asectp;
+
+  /* Table of BACKLINK->obfd sections indexed by their asect->index.  */
+  asection **backlink_sect_table;
+
+  /* Map sections in ABFD to their matching sections from BACKLINK->obfd.
+     If no such section exists the element is NULL.  */
+  asection **abfd_to_backlink_sect;
+
+  /* Fill in backlink_sect_table.  */
+  backlink_sect_table = alloca (sizeof (*backlink_sect_table)
+				* backlink->num_sections);
+  asectp = backlink_sect_table;
+  for (asect = backlink->obfd->sections; asect; asect = asect->next)
+    *asectp++ = asect;
+
+  /* Fill in abfd_to_backlink_sect.  */
+  abfd_to_backlink_sect = alloca (sizeof (*abfd_to_backlink_sect)
+				  * objfile->num_sections);
+  memset (abfd_to_backlink_sect, 0, (sizeof (*abfd_to_backlink_sect)
+				     * objfile->num_sections));
+  for (i = 0; i < addrs->num_sections && addrs->other[i].name != 0; i++)
+    {
+      struct other_sections *addrs_sect = &addrs->other[i];
+
+      gdb_assert (addrs_sect->saved_sectindex < backlink->num_sections);
+
+      if (addrs_sect->sectindex != -1)
+	{
+	  gdb_assert (addrs_sect->sectindex < objfile->num_sections);
+	  abfd_to_backlink_sect[addrs_sect->sectindex]
+	    = backlink_sect_table[addrs_sect->saved_sectindex];
+	}
+    }
+
+  ppc64_sysv_translate_debuginfo_syms (symbol_table, symcount,
+				       abfd_to_backlink_sect);
+  ppc64_sysv_translate_debuginfo_syms (dyn_symbol_table, dynsymcount,
+				       abfd_to_backlink_sect);
+
+  /* Symbols have been reassociated.  */
+  return 1;
+}
+
+#else /* !HAVE_ELF */
+
+/* An no-operation implementation for gdbarch_elf_synthetic_msyms_prep_p.  */
+
+int
+ppc64_sysv_elf_synthetic_msyms_prep (struct section_addr_info *addrs,
+				     struct objfile *objfile,
+				     asymbol **symbol_table, long symcount,
+				     asymbol **dyn_symbol_table,
+				     long dynsymcount)
+{
+  /* Symbols have not been reassociated.  */
+  return 0;
+}
+
+#endif /* !HAVE_ELF */
--- a/gdb/ppc-tdep.h
+++ b/gdb/ppc-tdep.h
@@ -60,6 +60,7 @@ enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarc
 							  struct regcache *regcache,
 							  gdb_byte *readbuf,
 							  const gdb_byte *writebuf);
+gdbarch_elf_synthetic_msyms_prep_ftype ppc64_sysv_elf_synthetic_msyms_prep;
 
 /* From rs6000-tdep.c...  */
 int altivec_register_p (struct gdbarch *gdbarch, int regno);
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -4099,6 +4099,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_max_insn_length (gdbarch, PPC_INSN_SIZE);
 
+  if (wordsize == 8)
+    set_gdbarch_elf_synthetic_msyms_prep (gdbarch,
+					  ppc64_sysv_elf_synthetic_msyms_prep);
+
   /* Hook in ABI-specific overrides, if they have been registered.  */
   info.target_desc = tdesc;
   info.tdep_info = (void *) tdesc_data;
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -336,6 +336,7 @@ build_section_addr_info_from_bfd (bfd *abfd)
 	sap->other[i].addr = bfd_get_section_vma (abfd, sec);
 	sap->other[i].name = xstrdup (bfd_get_section_name (abfd, sec));
 	sap->other[i].sectindex = sec->index;
+	sap->other[i].saved_sectindex = sap->other[i].sectindex;
 	i++;
       }
   return sap;
@@ -1186,6 +1187,7 @@ symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile)
      because sections of BFD may not match sections of OBJFILE and because
      vma may have been modified by tools such as prelink.  */
   sap = build_section_addr_info_from_objfile (objfile);
+  sap->separate_debug_objfile_backlink = objfile;
   my_cleanup = make_cleanup_free_section_addr_info (sap);
 
   new_objfile = symbol_file_add_with_addrs_or_offsets
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -80,6 +80,11 @@ struct section_addr_info
   /* The number of sections for which address information is
      available.  */
   size_t num_sections;
+
+  /* If this array was created for adding a separate debug info file this
+     pointer contains the stripped binary file link.  */
+  struct objfile *separate_debug_objfile_backlink;
+
   /* Sections whose names are file format dependent.  */
   struct other_sections
   {
@@ -88,6 +93,10 @@ struct section_addr_info
 
     /* SECTINDEX must be valid for associated BFD or set to -1.  */
     int sectindex;
+
+    /* Copy of SECTINDEX from the original BFD this struct was created for.
+       SECTINDEX may get for example remapped for a different BFD later.  */
+    int saved_sectindex;
   } other[1];
 };
 
--- /dev/null
+++ b/gdb/testsuite/gdb.base/eu-strip-infcall.c
@@ -0,0 +1,34 @@
+/* Copyright 2011 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+func (void)
+{
+  return 1;
+}
+
+int
+callfunc (int (*funcp) (void))
+{
+  return funcp () * 2;
+}
+
+int
+main (void)
+{
+  return callfunc (func);
+}
--- /dev/null
+++ b/gdb/testsuite/gdb.base/eu-strip-infcall.exp
@@ -0,0 +1,41 @@
+# Copyright (C) 2011 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This testfile requires eu-strip - elfutils strip command.  It moves even the
+# .symtab section into the separate debug info file.  The tested feature is
+# passing a function descriptor as a function address, the FAIL was
+# reproducible only on ppc64 ELF platforms.
+
+set testfile eu-strip-infcall
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[build_executable ${testfile}.exp $testfile] == -1} {
+    return -1
+}
+
+set test "eu-strip"
+set status [remote_exec build "eu-strip -f ${binfile}.debug $binfile"]
+if {[lindex $status 0] != 0} {
+    untested ${testfile}.exp
+    return 0
+}
+
+clean_restart $testfile
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_test "p callfunc (func)" " = 2" "infcall"


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