svn commit: r215679 - in head: contrib/binutils/bfd contrib/binutils/binutils contrib/binutils/include/elf contrib/file contrib/gdb/gdb gnu/usr.bin/gdb/libgdb sys/compat/freebsd32 sys/kern sys/sys ...

Attilio Rao attilio at FreeBSD.org
Mon Nov 22 14:42:14 UTC 2010


Author: attilio
Date: Mon Nov 22 14:42:13 2010
New Revision: 215679
URL: http://svn.freebsd.org/changeset/base/215679

Log:
  Add the ability for GDB to printout the thread name along with other
  thread specific informations.
  
  In order to do that, and in order to avoid KBI breakage with existing
  infrastructure the following semantic is implemented:
  - For live programs, a new member to the PT_LWPINFO is added (pl_tdname)
  - For cores, a new ELF note is added (NT_THRMISC) that can be used for
    storing thread specific, miscellaneous, informations. Right now it is
    just popluated with a thread name.
  
  GDB, then, retrieves the correct informations from the corefile via the
  BFD interface, as it groks the ELF notes and create appropriate
  pseudo-sections.
  
  Sponsored by:	Sandvine Incorporated
  Tested by:	gianni
  Discussed with:	dim, kan, kib
  MFC after:	2 weeks

Modified:
  head/contrib/binutils/bfd/elf-bfd.h
  head/contrib/binutils/bfd/elf.c
  head/contrib/binutils/binutils/readelf.c
  head/contrib/binutils/include/elf/common.h
  head/contrib/file/readelf.h
  head/contrib/gdb/gdb/fbsd-proc.c
  head/gnu/usr.bin/gdb/libgdb/fbsd-threads.c
  head/sys/compat/freebsd32/freebsd32.h
  head/sys/kern/imgact_elf.c
  head/sys/kern/sys_process.c
  head/sys/sys/elf_common.h
  head/sys/sys/procfs.h
  head/sys/sys/ptrace.h
  head/usr.bin/gcore/elfcore.c

Modified: head/contrib/binutils/bfd/elf-bfd.h
==============================================================================
--- head/contrib/binutils/bfd/elf-bfd.h	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/contrib/binutils/bfd/elf-bfd.h	Mon Nov 22 14:42:13 2010	(r215679)
@@ -1673,6 +1673,8 @@ extern char * elfcore_write_pstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char *elfcore_write_prfpreg
   (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_thrmisc
+  (bfd *, char *, int *, const char *, int);
 extern char *elfcore_write_prxfpreg
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_lwpstatus

Modified: head/contrib/binutils/bfd/elf.c
==============================================================================
--- head/contrib/binutils/bfd/elf.c	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/contrib/binutils/bfd/elf.c	Mon Nov 22 14:42:13 2010	(r215679)
@@ -6316,6 +6316,12 @@ _bfd_elf_rel_vtable_reloc_fn
 
 #ifdef HAVE_SYS_PROCFS_H
 # include <sys/procfs.h>
+
+/* Define HAVE_THRMISC_T for consistency with other similar GNU-type stubs. */
+#undef	HAVE_THRMISC_T
+#if defined (THRMISC_VERSION)
+#define	HAVE_THRMISC_T	1
+#endif
 #endif
 
 /* FIXME: this is kinda wrong, but it's what gdb wants.  */
@@ -6497,6 +6503,16 @@ elfcore_grok_prxfpreg (bfd *abfd, Elf_In
   return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
 }
 
+#if defined (HAVE_THRMISC_T)
+
+static bfd_boolean
+elfcore_grok_thrmisc (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".tname", note);
+}
+
+#endif /* defined (HAVE_THRMISC_T) */
+
 #if defined (HAVE_PRPSINFO_T)
 typedef prpsinfo_t   elfcore_psinfo_t;
 #if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
@@ -6863,6 +6879,12 @@ elfcore_grok_note (bfd *abfd, Elf_Intern
 
 	return TRUE;
       }
+
+#if defined (HAVE_THRMISC_T)
+    case NT_THRMISC:
+      return elfcore_grok_thrmisc (abfd, note);
+#endif
+
     }
 }
 
@@ -7245,6 +7267,22 @@ elfcore_write_prfpreg (bfd *abfd,
 }
 
 char *
+elfcore_write_thrmisc (bfd *abfd,
+		       char *buf,
+		       int *bufsiz,
+		       const char *tname,
+		       int size)
+{
+#if defined (HAVE_THRMISC_T)
+  char *note_name = "CORE";
+  return elfcore_write_note (abfd, buf, bufsiz,
+			     note_name, NT_THRMISC, tname, size);
+#else
+  return buf;
+#endif
+}
+
+char *
 elfcore_write_prxfpreg (bfd *abfd,
 			char *buf,
 			int *bufsiz,

Modified: head/contrib/binutils/binutils/readelf.c
==============================================================================
--- head/contrib/binutils/binutils/readelf.c	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/contrib/binutils/binutils/readelf.c	Mon Nov 22 14:42:13 2010	(r215679)
@@ -9908,6 +9908,7 @@ get_note_type (unsigned e_type)
     case NT_PSTATUS:	return _("NT_PSTATUS (pstatus structure)");
     case NT_FPREGS:	return _("NT_FPREGS (floating point registers)");
     case NT_PSINFO:	return _("NT_PSINFO (psinfo structure)");
+    case NT_THRMISC:	return _("NT_THRMISC (thrmisc structure)");
     case NT_LWPSTATUS:	return _("NT_LWPSTATUS (lwpstatus_t structure)");
     case NT_LWPSINFO:	return _("NT_LWPSINFO (lwpsinfo_t structure)");
     case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus structure)");

Modified: head/contrib/binutils/include/elf/common.h
==============================================================================
--- head/contrib/binutils/include/elf/common.h	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/contrib/binutils/include/elf/common.h	Mon Nov 22 14:42:13 2010	(r215679)
@@ -366,6 +366,7 @@
 #define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
 #define NT_TASKSTRUCT	4		/* Contains copy of task struct */
 #define NT_AUXV		6		/* Contains copy of Elfxx_auxv_t */
+#define NT_THRMISC	7		/* Contains copy of thrmisc struct */
 #define NT_PRXFPREG	0x46e62b7f	/* Contains a user_xfpregs_struct; */
 					/*   note name must be "LINUX".  */
 

Modified: head/contrib/file/readelf.h
==============================================================================
--- head/contrib/file/readelf.h	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/contrib/file/readelf.h	Mon Nov 22 14:42:13 2010	(r215679)
@@ -224,6 +224,7 @@ typedef struct {
 #define NT_TASKSTRUCT	4
 #define	NT_PLATFORM	5
 #define	NT_AUXV		6
+#define	NT_THRMISC	7
 
 /* Note types used in executables */
 /* NetBSD executables (name = "NetBSD") */

Modified: head/contrib/gdb/gdb/fbsd-proc.c
==============================================================================
--- head/contrib/gdb/gdb/fbsd-proc.c	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/contrib/gdb/gdb/fbsd-proc.c	Mon Nov 22 14:42:13 2010	(r215679)
@@ -124,6 +124,7 @@ fbsd_make_corefile_notes (bfd *obfd, int
   fpregset_t fpregs;
   char *note_data = NULL;
   Elf_Internal_Ehdr *i_ehdrp;
+  char fakename;
 
   /* Put a "FreeBSD" label in the ELF header.  */
   i_ehdrp = elf_elfheader (obfd);
@@ -138,6 +139,10 @@ fbsd_make_corefile_notes (bfd *obfd, int
   note_data = elfcore_write_prfpreg (obfd, note_data, note_size,
 				     &fpregs, sizeof (fpregs));
 
+  fakename = '\0';
+  note_data = elfcore_write_thrmisc (obfd, note_data, note_size,
+				     &fakename, sizeof (fakename));
+
   if (get_exec_file (0))
     {
       char *fname = strrchr (get_exec_file (0), '/') + 1;

Modified: head/gnu/usr.bin/gdb/libgdb/fbsd-threads.c
==============================================================================
--- head/gnu/usr.bin/gdb/libgdb/fbsd-threads.c	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/gnu/usr.bin/gdb/libgdb/fbsd-threads.c	Mon Nov 22 14:42:13 2010	(r215679)
@@ -426,6 +426,46 @@ fbsd_thread_deactivate (void)
   init_thread_list ();
 }
 
+static char * 
+fbsd_thread_get_name (lwpid_t lwpid)
+{
+  static char last_thr_name[MAXCOMLEN + 1];
+  char section_name[32];
+  struct ptrace_lwpinfo lwpinfo;
+  bfd_size_type size;
+  struct bfd_section *section;
+
+  if (target_has_execution)
+    {
+      if (ptrace (PT_LWPINFO, lwpid, (caddr_t)&lwpinfo, sizeof (lwpinfo)) == -1)
+        goto fail;
+      strncpy (last_thr_name, lwpinfo.pl_tdname, sizeof (last_thr_name) - 1);
+    }
+  else
+    {
+      snprintf (section_name, sizeof (section_name), ".tname/%u", lwpid);
+      section = bfd_get_section_by_name (core_bfd, section_name);
+      if (! section)
+        goto fail;
+
+      /* Section size fix-up. */
+      size = bfd_section_size (core_bfd, section);
+      if (size > sizeof (last_thr_name))
+        size = sizeof (last_thr_name);
+
+      if (! bfd_get_section_contents (core_bfd, section, last_thr_name,
+	       (file_ptr)0, size))
+        goto fail;
+      if (last_thr_name[0] == '\0')
+        goto fail;
+    }
+    last_thr_name[sizeof (last_thr_name) - 1] = '\0';
+    return last_thr_name;
+fail:
+     strcpy (last_thr_name, "<unknown>");
+     return last_thr_name;
+}
+
 static void
 fbsd_thread_new_objfile (struct objfile *objfile)
 {
@@ -1158,7 +1198,7 @@ fbsd_thread_find_new_threads (void)
 static char *
 fbsd_thread_pid_to_str (ptid_t ptid)
 {
-  static char buf[64];
+  static char buf[64 + MAXCOMLEN];
 
   if (IS_THREAD (ptid))
     {
@@ -1178,8 +1218,9 @@ fbsd_thread_pid_to_str (ptid_t ptid)
 
       if (ti.ti_lid != 0)
         {
-          snprintf (buf, sizeof (buf), "Thread %llx (LWP %d)",
-                    (unsigned long long)th.th_thread, ti.ti_lid);
+          snprintf (buf, sizeof (buf), "Thread %llx (LWP %d/%s)",
+                    (unsigned long long)th.th_thread, ti.ti_lid,
+                    fbsd_thread_get_name (ti.ti_lid));
         }
       else
         {

Modified: head/sys/compat/freebsd32/freebsd32.h
==============================================================================
--- head/sys/compat/freebsd32/freebsd32.h	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/sys/compat/freebsd32/freebsd32.h	Mon Nov 22 14:42:13 2010	(r215679)
@@ -240,6 +240,11 @@ struct prpsinfo32 {
         char    pr_psargs[PRARGSZ+1];
 };
 
+struct thrmisc32 {
+        char    pr_tname[MAXCOMLEN+1];
+        u_int   _pad;
+};
+
 struct mq_attr32 {
 	int	mq_flags;
 	int	mq_maxmsg;

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/sys/kern/imgact_elf.c	Mon Nov 22 14:42:13 2010	(r215679)
@@ -1316,12 +1316,14 @@ typedef struct prpsinfo32 elf_prpsinfo_t
 typedef struct fpreg32 elf_prfpregset_t;
 typedef struct fpreg32 elf_fpregset_t;
 typedef struct reg32 elf_gregset_t;
+typedef struct thrmisc32 elf_thrmisc_t;
 #else
 typedef prstatus_t elf_prstatus_t;
 typedef prpsinfo_t elf_prpsinfo_t;
 typedef prfpregset_t elf_prfpregset_t;
 typedef prfpregset_t elf_fpregset_t;
 typedef gregset_t elf_gregset_t;
+typedef thrmisc_t elf_thrmisc_t;
 #endif
 
 static void
@@ -1331,10 +1333,12 @@ __elfN(puthdr)(struct thread *td, void *
 		elf_prstatus_t status;
 		elf_prfpregset_t fpregset;
 		elf_prpsinfo_t psinfo;
+		elf_thrmisc_t thrmisc;
 	} *tempdata;
 	elf_prstatus_t *status;
 	elf_prfpregset_t *fpregset;
 	elf_prpsinfo_t *psinfo;
+	elf_thrmisc_t *thrmisc;
 	struct proc *p;
 	struct thread *thr;
 	size_t ehoff, noteoff, notesz, phoff;
@@ -1357,11 +1361,13 @@ __elfN(puthdr)(struct thread *td, void *
 		status = &tempdata->status;
 		fpregset = &tempdata->fpregset;
 		psinfo = &tempdata->psinfo;
+		thrmisc = &tempdata->thrmisc;
 	} else {
 		tempdata = NULL;
 		status = NULL;
 		fpregset = NULL;
 		psinfo = NULL;
+		thrmisc = NULL;
 	}
 
 	if (dst != NULL) {
@@ -1401,11 +1407,15 @@ __elfN(puthdr)(struct thread *td, void *
 			fill_regs(thr, &status->pr_reg);
 			fill_fpregs(thr, fpregset);
 #endif
+			memset(&thrmisc->_pad, 0, sizeof (thrmisc->_pad));
+			strcpy(thrmisc->pr_tname, thr->td_name);
 		}
 		__elfN(putnote)(dst, off, "FreeBSD", NT_PRSTATUS, status,
 		    sizeof *status);
 		__elfN(putnote)(dst, off, "FreeBSD", NT_FPREGSET, fpregset,
 		    sizeof *fpregset);
+		__elfN(putnote)(dst, off, "FreeBSD", NT_THRMISC, thrmisc,
+		    sizeof *thrmisc);
 		/*
 		 * Allow for MD specific notes, as well as any MD
 		 * specific preparations for writing MI notes.

Modified: head/sys/kern/sys_process.c
==============================================================================
--- head/sys/kern/sys_process.c	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/sys/kern/sys_process.c	Mon Nov 22 14:42:13 2010	(r215679)
@@ -93,6 +93,7 @@ struct ptrace_lwpinfo32 {
 	sigset_t	pl_sigmask;	/* LWP signal mask */
 	sigset_t	pl_siglist;	/* LWP pending signal */
 	struct siginfo32 pl_siginfo;	/* siginfo for signal */
+	char	pl_tdname[MAXCOMLEN + 1];	/* LWP name. */
 };
 
 #endif
@@ -520,6 +521,7 @@ ptrace_lwpinfo_to32(const struct ptrace_
 	pl32->pl_sigmask = pl->pl_sigmask;
 	pl32->pl_siglist = pl->pl_siglist;
 	siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
+	strcpy(pl32->pl_tdname, pl->pl_tdname);
 }
 #endif /* COMPAT_FREEBSD32 */
 
@@ -1164,6 +1166,7 @@ kern_ptrace(struct thread *td, int req, 
 			pl->pl_flags |= PL_FLAG_EXEC;
 		pl->pl_sigmask = td2->td_sigmask;
 		pl->pl_siglist = td2->td_siglist;
+		strcpy(pl->pl_tdname, td2->td_name);
 #ifdef COMPAT_FREEBSD32
 		if (wrap32)
 			ptrace_lwpinfo_to32(pl, pl32);

Modified: head/sys/sys/elf_common.h
==============================================================================
--- head/sys/sys/elf_common.h	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/sys/sys/elf_common.h	Mon Nov 22 14:42:13 2010	(r215679)
@@ -479,6 +479,7 @@ typedef struct {
 #define	NT_PRSTATUS	1	/* Process status. */
 #define	NT_FPREGSET	2	/* Floating point registers. */
 #define	NT_PRPSINFO	3	/* Process state info. */
+#define	NT_THRMISC	7	/* Thread miscellaneous info. */
 
 /* Symbol Binding - ELFNN_ST_BIND - st_info */
 #define	STB_LOCAL	0	/* Local symbol */

Modified: head/sys/sys/procfs.h
==============================================================================
--- head/sys/sys/procfs.h	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/sys/sys/procfs.h	Mon Nov 22 14:42:13 2010	(r215679)
@@ -80,6 +80,13 @@ typedef struct prpsinfo {
     char	pr_psargs[PRARGSZ+1];	/* Arguments, null terminated (1) */
 } prpsinfo_t;
 
+#define THRMISC_VERSION		1	/* Current version of thrmisc_t */
+
+typedef struct thrmisc {
+    char	pr_tname[MAXCOMLEN+1];	/* Thread name, null terminated (1) */
+    u_int	_pad;			/* Convenience pad, 0-filled (1) */
+} thrmisc_t;
+
 typedef uint64_t psaddr_t;	/* An address in the target process. */
 
 #endif /* _SYS_PROCFS_H_ */

Modified: head/sys/sys/ptrace.h
==============================================================================
--- head/sys/sys/ptrace.h	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/sys/sys/ptrace.h	Mon Nov 22 14:42:13 2010	(r215679)
@@ -34,6 +34,7 @@
 #define	_SYS_PTRACE_H_
 
 #include <sys/signal.h>
+#include <sys/param.h>
 #include <machine/reg.h>
 
 #define	PT_TRACE_ME	0	/* child declares it's being traced */
@@ -106,6 +107,7 @@ struct ptrace_lwpinfo {
 	sigset_t	pl_sigmask;	/* LWP signal mask */
 	sigset_t	pl_siglist;	/* LWP pending signal */
 	struct __siginfo pl_siginfo;	/* siginfo for signal */
+	char		pl_tdname[MAXCOMLEN + 1]; /* LWP name */
 };
 
 /* Argument structure for PT_VM_ENTRY. */

Modified: head/usr.bin/gcore/elfcore.c
==============================================================================
--- head/usr.bin/gcore/elfcore.c	Mon Nov 22 14:36:04 2010	(r215678)
+++ head/usr.bin/gcore/elfcore.c	Mon Nov 22 14:42:13 2010	(r215679)
@@ -284,10 +284,12 @@ elf_getstatus(pid_t pid, prpsinfo_t *psi
 static void
 elf_puthdr(pid_t pid, vm_map_entry_t map, void *dst, size_t *off, int numsegs)
 {
+	struct ptrace_lwpinfo lwpinfo;
 	struct {
 		prstatus_t status;
 		prfpregset_t fpregset;
 		prpsinfo_t psinfo;
+		thrmisc_t thrmisc;
 	} *tempdata;
 	size_t ehoff;
 	size_t phoff;
@@ -300,6 +302,7 @@ elf_puthdr(pid_t pid, vm_map_entry_t map
 	prstatus_t *status;
 	prfpregset_t *fpregset;
 	prpsinfo_t *psinfo;
+	thrmisc_t *thrmisc;
 
 	ehoff = *off;
 	*off += sizeof(Elf_Ehdr);
@@ -315,11 +318,13 @@ elf_puthdr(pid_t pid, vm_map_entry_t map
 		status = &tempdata->status;
 		fpregset = &tempdata->fpregset;
 		psinfo = &tempdata->psinfo;
+		thrmisc = &tempdata->thrmisc;
 	} else {
 		tempdata = NULL;
 		status = NULL;
 		fpregset = NULL;
 		psinfo = NULL;
+		thrmisc = NULL;
 	}
 
 	errno = 0;
@@ -356,11 +361,17 @@ elf_puthdr(pid_t pid, vm_map_entry_t map
 
 			ptrace(PT_GETREGS, tids[i], (void *)&status->pr_reg, 0);
 			ptrace(PT_GETFPREGS, tids[i], (void *)fpregset, 0);
+			ptrace(PT_LWPINFO, tids[i], (void *)&lwpinfo,
+			    sizeof(lwpinfo));
+			memset(&thrmisc->_pad, 0, sizeof(thrmisc->_pad));
+			strcpy(thrmisc->pr_tname, lwpinfo.pl_tdname);
 		}
 		elf_putnote(dst, off, "FreeBSD", NT_PRSTATUS, status,
 		    sizeof *status);
 		elf_putnote(dst, off, "FreeBSD", NT_FPREGSET, fpregset,
 		    sizeof *fpregset);
+		elf_putnote(dst, off, "FreeBSD", NT_THRMISC, thrmisc,
+		    sizeof *thrmisc);
 	}
 
 	notesz = *off - noteoff;


More information about the svn-src-all mailing list