diff --git a/contrib/binutils/bfd/elf-bfd.h b/contrib/binutils/bfd/elf-bfd.h index 110dd696c547..0a01867a7091 100644 --- a/contrib/binutils/bfd/elf-bfd.h +++ b/contrib/binutils/bfd/elf-bfd.h @@ -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 diff --git a/contrib/binutils/bfd/elf.c b/contrib/binutils/bfd/elf.c index 2b16f86cd45e..2f4728fabaaf 100644 --- a/contrib/binutils/bfd/elf.c +++ b/contrib/binutils/bfd/elf.c @@ -6316,6 +6316,12 @@ _bfd_elf_rel_vtable_reloc_fn #ifdef HAVE_SYS_PROCFS_H # include + +/* 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_Internal_Note *note) 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_Internal_Note *note) return TRUE; } + +#if defined (HAVE_THRMISC_T) + case NT_THRMISC: + return elfcore_grok_thrmisc (abfd, note); +#endif + } } @@ -7244,6 +7266,22 @@ elfcore_write_prfpreg (bfd *abfd, note_name, NT_FPREGSET, fpregs, size); } +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, diff --git a/contrib/binutils/binutils/readelf.c b/contrib/binutils/binutils/readelf.c index e95a501dabba..921cb35bf908 100644 --- a/contrib/binutils/binutils/readelf.c +++ b/contrib/binutils/binutils/readelf.c @@ -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)"); diff --git a/contrib/binutils/include/elf/common.h b/contrib/binutils/include/elf/common.h index bf233f61dfdb..544e06c16d5c 100644 --- a/contrib/binutils/include/elf/common.h +++ b/contrib/binutils/include/elf/common.h @@ -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". */ diff --git a/contrib/file/readelf.h b/contrib/file/readelf.h index ab4b5d1d60c5..6b3e806ebee6 100644 --- a/contrib/file/readelf.h +++ b/contrib/file/readelf.h @@ -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") */ diff --git a/contrib/gdb/gdb/fbsd-proc.c b/contrib/gdb/gdb/fbsd-proc.c index 16813a9a1c8a..b2dbd5d2ad97 100644 --- a/contrib/gdb/gdb/fbsd-proc.c +++ b/contrib/gdb/gdb/fbsd-proc.c @@ -124,6 +124,7 @@ fbsd_make_corefile_notes (bfd *obfd, int *note_size) 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_size) 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; diff --git a/gnu/usr.bin/gdb/libgdb/fbsd-threads.c b/gnu/usr.bin/gdb/libgdb/fbsd-threads.c index 51890eb48fa0..04a96b0dcdee 100644 --- a/gnu/usr.bin/gdb/libgdb/fbsd-threads.c +++ b/gnu/usr.bin/gdb/libgdb/fbsd-threads.c @@ -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, ""); + 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 { diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h index eebaae67e494..9b56e4bc7d07 100644 --- a/sys/compat/freebsd32/freebsd32.h +++ b/sys/compat/freebsd32/freebsd32.h @@ -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; diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index e29ddfa0ee5d..42f55732d1cf 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -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 *dst, size_t *off, int numsegs) 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 *dst, size_t *off, int numsegs) 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 *dst, size_t *off, int numsegs) 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. diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index af6b2989691f..e5d984292c85 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -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_lwpinfo *pl, 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, pid_t pid, void *addr, int data) 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); diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h index 1e1154f38966..afb7f7606b26 100644 --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -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 */ diff --git a/sys/sys/procfs.h b/sys/sys/procfs.h index a8d862e9a801..cab9c30e44a8 100644 --- a/sys/sys/procfs.h +++ b/sys/sys/procfs.h @@ -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_ */ diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h index f4b25d438b05..f909b865cec4 100644 --- a/sys/sys/ptrace.h +++ b/sys/sys/ptrace.h @@ -34,6 +34,7 @@ #define _SYS_PTRACE_H_ #include +#include #include #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. */ diff --git a/usr.bin/gcore/elfcore.c b/usr.bin/gcore/elfcore.c index 5d655c3d6832..9da22d7cd8fd 100644 --- a/usr.bin/gcore/elfcore.c +++ b/usr.bin/gcore/elfcore.c @@ -284,10 +284,12 @@ elf_getstatus(pid_t pid, prpsinfo_t *psinfo) 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, void *dst, size_t *off, int numsegs) 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, void *dst, size_t *off, int numsegs) 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, void *dst, size_t *off, int numsegs) 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;