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]

Re: [PATCH 2/3] lazily read note section data


This patch needed another update.  See the text below for the
py-auto-load.c and cc-with-tweaks details.

Tom

In the next patch, we'll set the BFD_DECOMPRESS flag, so that BFD will
know to decompress compressed sections.

However, doing this means that we can't use bfd_get_section_contents
on a compressed section.  This simply fails in BFD.

One fallout from this that I found is that
generic_elf_osabi_sniff_abi_tag_sections unconditionally calls
bfd_get_section_contents for every section of the BFD.  (This could
use a second pair of eyes to make sure I didn't miss anything.)

This patch changes this code to lazily read the data when it is
actually needed.  This works because, AFAIK, notes are not compressed.

This also makes this code more robust in the (unlikely) situation that
reading the section data fails.

Another needed fix is in xcoffread.c.  Kai Tietz recently added
compressed debug support for PE to BFD, necessitating this change.  He
tested this patch and reported that it was ok.

The final fix I needed is in py-auto-load.c.  I simply changed it to
use bfd_get_full_section_contents.

I also had the idea to run the full test suit with objcopy
--compress-debug-sections.  To do this I added a new option to
cc-with-tweaks.  This is how I found the py-auto-load problem.

In this mode there are still some extra failures: some because prelink
does not support compressed debug sections, and some because valgrind
does not.  The latter is https://bugs.kde.org/show_bug.cgi?id=303877

	* osabi.c (check_note): Add 'sectsize' argument.  Read
	section data.
	(generic_elf_osabi_sniff_abi_tag_sections): Don't read
	section data.  Update for check_note change.
	* xcoffread.c (xcoff_initial_scan): Use
	bfd_get_full_section_contents.
	* py-auto-load.c (auto_load_section_scripts): Use
	bfd_get_full_section_contents.
	* contrib/cc-with-tweaks.sh: Add -Z option.
---
 gdb/contrib/cc-with-tweaks.sh |    9 +++++++++
 gdb/osabi.c                   |   29 ++++++++++++++++++++++-------
 gdb/python/py-auto-load.c     |   23 +++++++++++------------
 gdb/xcoffread.c               |    8 +++-----
 4 files changed, 45 insertions(+), 24 deletions(-)

diff --git a/gdb/contrib/cc-with-tweaks.sh b/gdb/contrib/cc-with-tweaks.sh
index bdbdf7d..f156519 100755
--- a/gdb/contrib/cc-with-tweaks.sh
+++ b/gdb/contrib/cc-with-tweaks.sh
@@ -36,6 +36,7 @@
 # (More documentation is to come.)
 
 # ARGS determine what is done.  They can be:
+# -Z invoke objcopy --compress-debug-sections
 # -z compress using dwz
 # -m compress using dwz -m
 # -i make an index
@@ -71,9 +72,11 @@ output_file=a.out
 want_index=false
 want_dwz=false
 want_multi=false
+want_objcopy_compress=false
 
 while [ $# -gt 0 ]; do
     case "$1" in
+	-Z) want_objcopy_compress=true ;;
 	-z) want_dwz=true ;;
 	-i) want_index=true ;;
 	-m) want_multi=true ;;
@@ -134,6 +137,12 @@ then
     exit 1
 fi
 
+if [ "$want_objcopy_compress" = true ]; then
+    $OBJCOPY --compress-debug-sections "$output_file"
+    rc=$?
+    [ $rc != 0 ] && exit $rc
+fi
+
 if [ "$want_index" = true ]; then
     $GDB --batch-silent -nx -ex "set auto-load no" -ex "file $output_file" -ex "save gdb-index $output_dir"
     rc=$?
diff --git a/gdb/osabi.c b/gdb/osabi.c
index faffe30..7f60984 100644
--- a/gdb/osabi.c
+++ b/gdb/osabi.c
@@ -370,14 +370,23 @@ gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
 /* Limit on the amount of data to be read.  */
 #define MAX_NOTESZ	128
 
-/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE.  */
+/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE.  If
+   *SECTSIZE is non-zero, then this reads that many bytes from
+   the start of the section and clears *SECTSIZE.  */
 
 static int
-check_note (bfd *abfd, asection *sect, const char *note,
+check_note (bfd *abfd, asection *sect, char *note, unsigned int *sectsize,
 	    const char *name, unsigned long descsz, unsigned long type)
 {
   unsigned long notesz;
 
+  if (*sectsize)
+    {
+      if (!bfd_get_section_contents (abfd, sect, note, 0, *sectsize))
+	return 0;
+      *sectsize = 0;
+    }
+
   /* Calculate the size of this note.  */
   notesz = strlen (name) + 1;
   notesz = ((notesz + 3) & ~3);
@@ -424,14 +433,18 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
   if (sectsize > MAX_NOTESZ)
     sectsize = MAX_NOTESZ;
 
+  /* We lazily read the section data here.  Since we use
+     BFD_DECOMPRESS, we can't use bfd_get_section_contents on a
+     compressed section.  But, since note sections are not compressed,
+     deferring the reading until we recognize the section avoids any
+     error.  */
   note = alloca (sectsize);
-  bfd_get_section_contents (abfd, sect, note, 0, sectsize);
 
   /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD.  */
   if (strcmp (name, ".note.ABI-tag") == 0)
     {
       /* GNU.  */
-      if (check_note (abfd, sect, note, "GNU", 16, NT_GNU_ABI_TAG))
+      if (check_note (abfd, sect, note, &sectsize, "GNU", 16, NT_GNU_ABI_TAG))
 	{
 	  unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16);
 
@@ -467,7 +480,8 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
 	}
 
       /* FreeBSD.  */
-      if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_ABI_TAG))
+      if (check_note (abfd, sect, note, &sectsize, "FreeBSD", 4,
+		      NT_FREEBSD_ABI_TAG))
 	{
 	  /* There is no need to check the version yet.  */
 	  *osabi = GDB_OSABI_FREEBSD_ELF;
@@ -479,7 +493,7 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
       
   /* .note.netbsd.ident notes, used by NetBSD.  */
   if (strcmp (name, ".note.netbsd.ident") == 0
-      && check_note (abfd, sect, note, "NetBSD", 4, NT_NETBSD_IDENT))
+      && check_note (abfd, sect, note, &sectsize, "NetBSD", 4, NT_NETBSD_IDENT))
     {
       /* There is no need to check the version yet.  */
       *osabi = GDB_OSABI_NETBSD_ELF;
@@ -488,7 +502,8 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
 
   /* .note.openbsd.ident notes, used by OpenBSD.  */
   if (strcmp (name, ".note.openbsd.ident") == 0
-      && check_note (abfd, sect, note, "OpenBSD", 4, NT_OPENBSD_IDENT))
+      && check_note (abfd, sect, note, &sectsize, "OpenBSD", 4,
+		     NT_OPENBSD_IDENT))
     {
       /* There is no need to check the version yet.  */
       *osabi = GDB_OSABI_OPENBSD_ELF;
diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c
index a018f5f..91bb34d 100644
--- a/gdb/python/py-auto-load.c
+++ b/gdb/python/py-auto-load.c
@@ -197,26 +197,25 @@ auto_load_section_scripts (struct objfile *objfile, const char *section_name)
 {
   bfd *abfd = objfile->obfd;
   asection *scripts_sect;
-  bfd_size_type size;
-  char *p;
-  struct cleanup *cleanups;
+  bfd_byte *data = NULL;
 
   scripts_sect = bfd_get_section_by_name (abfd, section_name);
   if (scripts_sect == NULL)
     return;
 
-  size = bfd_get_section_size (scripts_sect);
-  p = xmalloc (size);
-  
-  cleanups = make_cleanup (xfree, p);
-
-  if (bfd_get_section_contents (abfd, scripts_sect, p, (file_ptr) 0, size))
-    source_section_scripts (objfile, section_name, p, p + size);
-  else
+  if (!bfd_get_full_section_contents (abfd, scripts_sect, &data))
     warning (_("Couldn't read %s section of %s"),
 	     section_name, bfd_get_filename (abfd));
+  else
+    {
+      struct cleanup *cleanups;
+      char *p = (char *) data;
 
-  do_cleanups (cleanups);
+      cleanups = make_cleanup (xfree, p);
+      source_section_scripts (objfile, section_name, p,
+			      p + bfd_get_section_size (scripts_sect));
+      do_cleanups (cleanups);
+    }
 }
 
 /* Load any Python auto-loaded scripts for OBJFILE.  */
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index af93a43..e4d0861 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -2989,7 +2989,7 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags)
       {
 	struct bfd_section *secp;
 	bfd_size_type length;
-	char *debugsec = NULL;
+	bfd_byte *debugsec = NULL;
 
 	secp = bfd_get_section_by_name (abfd, ".debug");
 	if (secp)
@@ -2997,11 +2997,9 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags)
 	    length = bfd_section_size (abfd, secp);
 	    if (length)
 	      {
-		debugsec =
-		  (char *) obstack_alloc (&objfile->objfile_obstack, length);
+		debugsec = obstack_alloc (&objfile->objfile_obstack, length);
 
-		if (!bfd_get_section_contents (abfd, secp, debugsec,
-					       (file_ptr) 0, length))
+		if (!bfd_get_full_section_contents (abfd, secp, &debugsec))
 		  {
 		    error (_("Error reading .debug section of `%s': %s"),
 			   name, bfd_errmsg (bfd_get_error ()));
-- 
1.7.7.6


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