[PATCH 2/3] lazily read note section data

Tom Tromey tromey@redhat.com
Tue Oct 16 20:48:00 GMT 2012


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.

The only 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.

Built & regression tested on x86-64 F16.

	* 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.
---
 gdb/osabi.c |   29 ++++++++++++++++++++++-------
 1 files changed, 22 insertions(+), 7 deletions(-)

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;
-- 
1.7.7.6



More information about the Gdb-patches mailing list