Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Mark Kettenis <kettenis@chello.nl>
To: gdb-patches@sources.redhat.com
Subject: [PATCH/RFC] Reorganize osabi.c:generic_elf_osabi_sniff_abi_tag_sections()
Date: Sun, 18 Jan 2004 20:40:00 -0000	[thread overview]
Message-ID: <200401182040.i0IKeeMu008703@elgar.kettenis.dyndns.org> (raw)

While adding support for OpenBSD ELF, I found myself duplicating the
same bit of code for checking ELF notes again.  This patch puts that
bit of code in its own function.  The new function adds a check
whether the nore section is large enough to contain the note that
we're checked for.

If nobody objects, I'll commit this in a few days,

Mark


Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>

	* osabi.c (MAX_NOTESZ): New define.
	(check_note): New function.
	(generic_elf_osabi_sniff_abi_tag_sections): Reorganize code using
	check_note.

Index: osabi.c
===================================================================
RCS file: /cvs/src/src/gdb/osabi.c,v
retrieving revision 1.25
diff -u -p -r1.25 osabi.c
--- osabi.c 17 Jan 2004 00:13:46 -0000 1.25
+++ osabi.c 18 Jan 2004 20:39:29 -0000
@@ -355,119 +355,126 @@ gdbarch_init_osabi (struct gdbarch_info 
      info.bfd_arch_info->printable_name);
 }
 \f
+/* Limit on the amount of data to be read.  */
+#define MAX_NOTESZ	128
+
+/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE.  */
+
+static int
+check_note (bfd *abfd, asection *sect, const char *note,
+	    const char *name, unsigned long descsz, unsigned long type)
+{
+  unsigned long notesz;
+
+  /* Calculate the size of this note...  */
+  notesz = strlen (name) + 1;
+  notesz = ((notesz + 3) & ~3);
+  notesz += descsz;
+  notesz = ((notesz + 3) & ~3);
+
+  /* ...and check it.  */
+  gdb_assert (notesz <= MAX_NOTESZ);
+  if (notesz > bfd_section_size (abfd, sect))
+    return 0;
+
+  /* Check the note name.  */
+  if (bfd_h_get_32 (abfd, note) != (strlen (name) + 1)
+      || strcmp (note + 12, name) != 0)
+    return 0;
+
+  /* Check the descriptor size.  */
+  if (bfd_h_get_32 (abfd, note + 4) != descsz)
+    return 0;
+
+  /* Check the note type.  */
+  if (bfd_h_get_32 (abfd, note + 8) != type)
+    return 0;
+
+  return 1;
+}
 
 /* Generic sniffer for ELF flavoured files.  */
 
 void
 generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
 {
-  enum gdb_osabi *os_ident_ptr = obj;
+  enum gdb_osabi *osabi = obj;
   const char *name;
   unsigned int sectsize;
+  char *note;
 
   name = bfd_get_section_name (abfd, sect);
   sectsize = bfd_section_size (abfd, sect);
 
-  /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD.  */
-  if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
-    {
-      unsigned int name_length, data_length, note_type;
-      char *note;
+  /* Limit the amount of data to read.  */
+  if (sectsize > MAX_NOTESZ)
+    sectsize = MAX_NOTESZ;
 
-      /* If the section is larger than this, it's probably not what we are
-	 looking for.  */
-      if (sectsize > 128)
-	sectsize = 128;
+  note = alloca (sectsize);
+  bfd_get_section_contents (abfd, sect, note, 0, sectsize);
 
-      note = alloca (sectsize);
-
-      bfd_get_section_contents (abfd, sect, note,
-				(file_ptr) 0, (bfd_size_type) sectsize);
-
-      name_length = bfd_h_get_32 (abfd, note);
-      data_length = bfd_h_get_32 (abfd, note + 4);
-      note_type   = bfd_h_get_32 (abfd, note + 8);
-
-      if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG
-	  && strcmp (note + 12, "GNU") == 0)
+  /* .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))
 	{
-	  int os_number = bfd_h_get_32 (abfd, note + 16);
+	  unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16);
 
-	  switch (os_number)
+	  switch (abi_tag)
 	    {
 	    case GNU_ABI_TAG_LINUX:
-	      *os_ident_ptr = GDB_OSABI_LINUX;
+	      *osabi = GDB_OSABI_LINUX;
 	      break;
 
 	    case GNU_ABI_TAG_HURD:
-	      *os_ident_ptr = GDB_OSABI_HURD;
+	      *osabi = GDB_OSABI_HURD;
 	      break;
 
 	    case GNU_ABI_TAG_SOLARIS:
-	      *os_ident_ptr = GDB_OSABI_SOLARIS;
+	      *osabi = GDB_OSABI_SOLARIS;
 	      break;
 
 	    case GNU_ABI_TAG_FREEBSD:
-	      *os_ident_ptr = GDB_OSABI_FREEBSD_ELF;
+	      *osabi = GDB_OSABI_FREEBSD_ELF;
 	      break;
-	      
+
 	    case GNU_ABI_TAG_NETBSD:
-	      *os_ident_ptr = GDB_OSABI_NETBSD_ELF;
+	      *osabi = GDB_OSABI_NETBSD_ELF;
 	      break;
-	      
+
 	    default:
-	      internal_error
-		(__FILE__, __LINE__,
-		 "generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d",
-		 os_number);
+	      internal_error (__FILE__, __LINE__, "\
+generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d",
+			      abi_tag);
 	    }
 	  return;
 	}
-      else if (name_length == 8 && data_length == 4
-	       && note_type == NT_FREEBSD_ABI_TAG
-	       && strcmp (note + 12, "FreeBSD") == 0)
+
+      /* FreeBSD.  */
+      if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_ABI_TAG))
 	{
-	  /* XXX Should we check the version here?  Probably not
-	     necessary yet.  */
-	  *os_ident_ptr = GDB_OSABI_FREEBSD_ELF;
+	  /* There is no need to check the version yet.  */
+	  *osabi = GDB_OSABI_FREEBSD_ELF;
+	  return;
 	}
+
       return;
     }
-
+      
   /* .note.netbsd.ident notes, used by NetBSD.  */
-  if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
+  if (strcmp (name, ".note.netbsd.ident") == 0
+      && check_note (abfd, sect, note, "NetBSD", 4, NT_NETBSD_IDENT))
     {
-      unsigned int name_length, data_length, note_type;
-      char *note;
-
-      /* If the section is larger than this, it's probably not what we are
-	 looking for.  */
-      if (sectsize > 128) 
-	sectsize = 128;
-
-      note = alloca (sectsize);
-
-      bfd_get_section_contents (abfd, sect, note,
-				(file_ptr) 0, (bfd_size_type) sectsize);
-      
-      name_length = bfd_h_get_32 (abfd, note);
-      data_length = bfd_h_get_32 (abfd, note + 4);
-      note_type   = bfd_h_get_32 (abfd, note + 8);
-
-      if (name_length == 7 && data_length == 4 && note_type == NT_NETBSD_IDENT
-	  && strcmp (note + 12, "NetBSD") == 0)
-	{
-	  /* XXX Should we check the version here?  Probably not
-	     necessary yet.  */
-	  *os_ident_ptr = GDB_OSABI_NETBSD_ELF;
-	}
+      /* There is no need to check the version yet.  */
+      *osabi = GDB_OSABI_NETBSD_ELF;
       return;
     }
 
   /* .note.netbsdcore.procinfo notes, used by NetBSD.  */
-  if (strcmp (name, ".note.netbsdcore.procinfo") == 0 && sectsize > 0)
+  if (strcmp (name, ".note.netbsdcore.procinfo") == 0)
     {
-      *os_ident_ptr = GDB_OSABI_NETBSD_ELF;
+      *osabi = GDB_OSABI_NETBSD_ELF;
       return;
     }
 }


             reply	other threads:[~2004-01-18 20:40 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-18 20:40 Mark Kettenis [this message]
2004-01-18 22:52 ` Daniel Jacobowitz
2004-01-19 18:39   ` Mark Kettenis
2004-01-19 19:15     ` Daniel Jacobowitz
2004-01-21 23:08       ` Mark Kettenis
2004-01-22  7:35         ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200401182040.i0IKeeMu008703@elgar.kettenis.dyndns.org \
    --to=kettenis@chello.nl \
    --cc=gdb-patches@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox