xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/nat/linux-osdata.c (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
1 /* Linux-specific functions to retrieve OS data.
2 
3    Copyright (C) 2009-2020 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "gdbsupport/common-defs.h"
21 #include "linux-osdata.h"
22 
23 #include <sys/types.h>
24 #include <sys/sysinfo.h>
25 #include <ctype.h>
26 #include <utmp.h>
27 #include <time.h>
28 #include <unistd.h>
29 #include <pwd.h>
30 #include <grp.h>
31 #include <netdb.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 
35 #include "gdbsupport/xml-utils.h"
36 #include "gdbsupport/buffer.h"
37 #include <dirent.h>
38 #include <sys/stat.h>
39 #include "gdbsupport/filestuff.h"
40 #include <algorithm>
41 
42 #define NAMELEN(dirent) strlen ((dirent)->d_name)
43 
44 /* Define PID_T to be a fixed size that is at least as large as pid_t,
45    so that reading pid values embedded in /proc works
46    consistently.  */
47 
48 typedef long long  PID_T;
49 
50 /* Define TIME_T to be at least as large as time_t, so that reading
51    time values embedded in /proc works consistently.  */
52 
53 typedef long long TIME_T;
54 
55 #define MAX_PID_T_STRLEN  (sizeof ("-9223372036854775808") - 1)
56 
57 /* Returns the CPU core that thread PTID is currently running on.  */
58 
59 /* Compute and return the processor core of a given thread.  */
60 
61 int
62 linux_common_core_of_thread (ptid_t ptid)
63 {
64   char filename[sizeof ("/proc//task//stat") + 2 * MAX_PID_T_STRLEN];
65   char *content = NULL;
66   char *p;
67   char *ts = 0;
68   int content_read = 0;
69   int i;
70   int core;
71 
72   sprintf (filename, "/proc/%lld/task/%lld/stat",
73 	   (PID_T) ptid.pid (), (PID_T) ptid.lwp ());
74   gdb_file_up f = gdb_fopen_cloexec (filename, "r");
75   if (!f)
76     return -1;
77 
78   for (;;)
79     {
80       int n;
81       content = (char *) xrealloc (content, content_read + 1024);
82       n = fread (content + content_read, 1, 1024, f.get ());
83       content_read += n;
84       if (n < 1024)
85 	{
86 	  content[content_read] = '\0';
87 	  break;
88 	}
89     }
90 
91   /* ps command also relies on no trailing fields ever contain ')'.  */
92   p = strrchr (content, ')');
93   if (p != NULL)
94     p++;
95 
96   /* If the first field after program name has index 0, then core number is
97      the field with index 36.  There's no constant for that anywhere.  */
98   if (p != NULL)
99     p = strtok_r (p, " ", &ts);
100   for (i = 0; p != NULL && i != 36; ++i)
101     p = strtok_r (NULL, " ", &ts);
102 
103   if (p == NULL || sscanf (p, "%d", &core) == 0)
104     core = -1;
105 
106   xfree (content);
107 
108   return core;
109 }
110 
111 /* Finds the command-line of process PID and copies it into COMMAND.
112    At most MAXLEN characters are copied.  If the command-line cannot
113    be found, PID is copied into command in text-form.  */
114 
115 static void
116 command_from_pid (char *command, int maxlen, PID_T pid)
117 {
118   std::string stat_path = string_printf ("/proc/%lld/stat", pid);
119   gdb_file_up fp = gdb_fopen_cloexec (stat_path, "r");
120 
121   command[0] = '\0';
122 
123   if (fp)
124     {
125       /* sizeof (cmd) should be greater or equal to TASK_COMM_LEN (in
126 	 include/linux/sched.h in the Linux kernel sources) plus two
127 	 (for the brackets).  */
128       char cmd[18];
129       PID_T stat_pid;
130       int items_read = fscanf (fp.get (), "%lld %17s", &stat_pid, cmd);
131 
132       if (items_read == 2 && pid == stat_pid)
133 	{
134 	  cmd[strlen (cmd) - 1] = '\0'; /* Remove trailing parenthesis.  */
135 	  strncpy (command, cmd + 1, maxlen); /* Ignore leading parenthesis.  */
136 	}
137     }
138   else
139     {
140       /* Return the PID if a /proc entry for the process cannot be found.  */
141       snprintf (command, maxlen, "%lld", pid);
142     }
143 
144   command[maxlen - 1] = '\0'; /* Ensure string is null-terminated.  */
145 }
146 
147 /* Returns the command-line of the process with the given PID. The
148    returned string needs to be freed using xfree after use.  */
149 
150 static char *
151 commandline_from_pid (PID_T pid)
152 {
153   std::string pathname = string_printf ("/proc/%lld/cmdline", pid);
154   char *commandline = NULL;
155   gdb_file_up f = gdb_fopen_cloexec (pathname, "r");
156 
157   if (f)
158     {
159       size_t len = 0;
160 
161       while (!feof (f.get ()))
162 	{
163 	  char buf[1024];
164 	  size_t read_bytes = fread (buf, 1, sizeof (buf), f.get ());
165 
166 	  if (read_bytes)
167 	    {
168 	      commandline = (char *) xrealloc (commandline, len + read_bytes + 1);
169 	      memcpy (commandline + len, buf, read_bytes);
170 	      len += read_bytes;
171 	    }
172 	}
173 
174       if (commandline)
175 	{
176 	  size_t i;
177 
178 	  /* Replace null characters with spaces.  */
179 	  for (i = 0; i < len; ++i)
180 	    if (commandline[i] == '\0')
181 	      commandline[i] = ' ';
182 
183 	  commandline[len] = '\0';
184 	}
185       else
186 	{
187 	  /* Return the command in square brackets if the command-line
188 	     is empty.  */
189 	  commandline = (char *) xmalloc (32);
190 	  commandline[0] = '[';
191 	  command_from_pid (commandline + 1, 31, pid);
192 
193 	  len = strlen (commandline);
194 	  if (len < 31)
195 	    strcat (commandline, "]");
196 	}
197     }
198 
199   return commandline;
200 }
201 
202 /* Finds the user name for the user UID and copies it into USER.  At
203    most MAXLEN characters are copied.  */
204 
205 static void
206 user_from_uid (char *user, int maxlen, uid_t uid)
207 {
208   struct passwd *pwentry;
209   char buf[1024];
210   struct passwd pwd;
211   getpwuid_r (uid, &pwd, buf, sizeof (buf), &pwentry);
212 
213   if (pwentry)
214     {
215       strncpy (user, pwentry->pw_name, maxlen);
216       /* Ensure that the user name is null-terminated.  */
217       user[maxlen - 1] = '\0';
218     }
219   else
220     user[0] = '\0';
221 }
222 
223 /* Finds the owner of process PID and returns the user id in OWNER.
224    Returns 0 if the owner was found, -1 otherwise.  */
225 
226 static int
227 get_process_owner (uid_t *owner, PID_T pid)
228 {
229   struct stat statbuf;
230   char procentry[sizeof ("/proc/") + MAX_PID_T_STRLEN];
231 
232   sprintf (procentry, "/proc/%lld", pid);
233 
234   if (stat (procentry, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
235     {
236       *owner = statbuf.st_uid;
237       return 0;
238     }
239   else
240     return -1;
241 }
242 
243 /* Find the CPU cores used by process PID and return them in CORES.
244    CORES points to an array of NUM_CORES elements.  */
245 
246 static int
247 get_cores_used_by_process (PID_T pid, int *cores, const int num_cores)
248 {
249   char taskdir[sizeof ("/proc/") + MAX_PID_T_STRLEN + sizeof ("/task") - 1];
250   DIR *dir;
251   struct dirent *dp;
252   int task_count = 0;
253 
254   sprintf (taskdir, "/proc/%lld/task", pid);
255   dir = opendir (taskdir);
256   if (dir)
257     {
258       while ((dp = readdir (dir)) != NULL)
259 	{
260 	  PID_T tid;
261 	  int core;
262 
263 	  if (!isdigit (dp->d_name[0])
264 	      || NAMELEN (dp) > MAX_PID_T_STRLEN)
265 	    continue;
266 
267 	  sscanf (dp->d_name, "%lld", &tid);
268 	  core = linux_common_core_of_thread (ptid_t ((pid_t) pid,
269 						      (pid_t) tid, 0));
270 
271 	  if (core >= 0 && core < num_cores)
272 	    {
273 	      ++cores[core];
274 	      ++task_count;
275 	    }
276 	}
277 
278       closedir (dir);
279     }
280 
281   return task_count;
282 }
283 
284 static void
285 linux_xfer_osdata_processes (struct buffer *buffer)
286 {
287   DIR *dirp;
288 
289   buffer_grow_str (buffer, "<osdata type=\"processes\">\n");
290 
291   dirp = opendir ("/proc");
292   if (dirp)
293     {
294       const int num_cores = sysconf (_SC_NPROCESSORS_ONLN);
295       struct dirent *dp;
296 
297       while ((dp = readdir (dirp)) != NULL)
298 	{
299 	  PID_T pid;
300 	  uid_t owner;
301 	  char user[UT_NAMESIZE];
302 	  char *command_line;
303 	  int *cores;
304 	  int task_count;
305 	  char *cores_str;
306 	  int i;
307 
308 	  if (!isdigit (dp->d_name[0])
309 	      || NAMELEN (dp) > MAX_PID_T_STRLEN)
310 	    continue;
311 
312 	  sscanf (dp->d_name, "%lld", &pid);
313 	  command_line = commandline_from_pid (pid);
314 
315 	  if (get_process_owner (&owner, pid) == 0)
316 	    user_from_uid (user, sizeof (user), owner);
317 	  else
318 	    strcpy (user, "?");
319 
320 	  /* Find CPU cores used by the process.  */
321 	  cores = XCNEWVEC (int, num_cores);
322 	  task_count = get_cores_used_by_process (pid, cores, num_cores);
323 	  cores_str = (char *) xcalloc (task_count, sizeof ("4294967295") + 1);
324 
325 	  for (i = 0; i < num_cores && task_count > 0; ++i)
326 	    if (cores[i])
327 	      {
328 		char core_str[sizeof ("4294967295")];
329 
330 		sprintf (core_str, "%d", i);
331 		strcat (cores_str, core_str);
332 
333 		task_count -= cores[i];
334 		if (task_count > 0)
335 		  strcat (cores_str, ",");
336 	      }
337 
338 	  xfree (cores);
339 
340 	  buffer_xml_printf
341 	    (buffer,
342 	     "<item>"
343 	     "<column name=\"pid\">%lld</column>"
344 	     "<column name=\"user\">%s</column>"
345 	     "<column name=\"command\">%s</column>"
346 	     "<column name=\"cores\">%s</column>"
347 	     "</item>",
348 	     pid,
349 	     user,
350 	     command_line ? command_line : "",
351 	     cores_str);
352 
353 	  xfree (command_line);
354 	  xfree (cores_str);
355 	}
356 
357       closedir (dirp);
358     }
359 
360   buffer_grow_str0 (buffer, "</osdata>\n");
361 }
362 
363 /* A simple PID/PGID pair.  */
364 
365 struct pid_pgid_entry
366 {
367   pid_pgid_entry (PID_T pid_, PID_T pgid_)
368   : pid (pid_), pgid (pgid_)
369   {}
370 
371   /* Return true if this pid is the leader of its process group.  */
372 
373   bool is_leader () const
374   {
375     return pid == pgid;
376   }
377 
378   bool operator< (const pid_pgid_entry &other) const
379   {
380     /* Sort by PGID.  */
381     if (this->pgid != other.pgid)
382       return this->pgid < other.pgid;
383 
384     /* Process group leaders always come first...  */
385     if (this->is_leader ())
386       {
387 	if (!other.is_leader ())
388 	  return true;
389       }
390     else if (other.is_leader ())
391       return false;
392 
393     /* ...else sort by PID.  */
394     return this->pid < other.pid;
395   }
396 
397   PID_T pid, pgid;
398 };
399 
400 /* Collect all process groups from /proc in BUFFER.  */
401 
402 static void
403 linux_xfer_osdata_processgroups (struct buffer *buffer)
404 {
405   DIR *dirp;
406 
407   buffer_grow_str (buffer, "<osdata type=\"process groups\">\n");
408 
409   dirp = opendir ("/proc");
410   if (dirp)
411     {
412       std::vector<pid_pgid_entry> process_list;
413       struct dirent *dp;
414 
415       process_list.reserve (512);
416 
417       /* Build list consisting of PIDs followed by their
418 	 associated PGID.  */
419       while ((dp = readdir (dirp)) != NULL)
420 	{
421 	  PID_T pid, pgid;
422 
423 	  if (!isdigit (dp->d_name[0])
424 	      || NAMELEN (dp) > MAX_PID_T_STRLEN)
425 	    continue;
426 
427 	  sscanf (dp->d_name, "%lld", &pid);
428 	  pgid = getpgid (pid);
429 
430 	  if (pgid > 0)
431 	    process_list.emplace_back (pid, pgid);
432 	}
433 
434       closedir (dirp);
435 
436       /* Sort the process list.  */
437       std::sort (process_list.begin (), process_list.end ());
438 
439       for (const pid_pgid_entry &entry : process_list)
440 	{
441 	  PID_T pid = entry.pid;
442 	  PID_T pgid = entry.pgid;
443 	  char leader_command[32];
444 	  char *command_line;
445 
446 	  command_from_pid (leader_command, sizeof (leader_command), pgid);
447 	  command_line = commandline_from_pid (pid);
448 
449 	  buffer_xml_printf
450 	    (buffer,
451 	     "<item>"
452 	     "<column name=\"pgid\">%lld</column>"
453 	     "<column name=\"leader command\">%s</column>"
454 	     "<column name=\"pid\">%lld</column>"
455 	     "<column name=\"command line\">%s</column>"
456 	     "</item>",
457 	     pgid,
458 	     leader_command,
459 	     pid,
460 	     command_line ? command_line : "");
461 
462 	  xfree (command_line);
463 	}
464     }
465 
466   buffer_grow_str0 (buffer, "</osdata>\n");
467 }
468 
469 /* Collect all the threads in /proc by iterating through processes and
470    then tasks within each process in BUFFER.  */
471 
472 static void
473 linux_xfer_osdata_threads (struct buffer *buffer)
474 {
475   DIR *dirp;
476 
477   buffer_grow_str (buffer, "<osdata type=\"threads\">\n");
478 
479   dirp = opendir ("/proc");
480   if (dirp)
481     {
482       struct dirent *dp;
483 
484       while ((dp = readdir (dirp)) != NULL)
485 	{
486 	  struct stat statbuf;
487 	  char procentry[sizeof ("/proc/4294967295")];
488 
489 	  if (!isdigit (dp->d_name[0])
490 	      || NAMELEN (dp) > sizeof ("4294967295") - 1)
491 	    continue;
492 
493 	  xsnprintf (procentry, sizeof (procentry), "/proc/%s",
494 		     dp->d_name);
495 	  if (stat (procentry, &statbuf) == 0
496 	      && S_ISDIR (statbuf.st_mode))
497 	    {
498 	      DIR *dirp2;
499 	      PID_T pid;
500 	      char command[32];
501 
502 	      std::string pathname
503 		= string_printf ("/proc/%s/task", dp->d_name);
504 
505 	      pid = atoi (dp->d_name);
506 	      command_from_pid (command, sizeof (command), pid);
507 
508 	      dirp2 = opendir (pathname.c_str ());
509 
510 	      if (dirp2)
511 		{
512 		  struct dirent *dp2;
513 
514 		  while ((dp2 = readdir (dirp2)) != NULL)
515 		    {
516 		      PID_T tid;
517 		      int core;
518 
519 		      if (!isdigit (dp2->d_name[0])
520 			  || NAMELEN (dp2) > sizeof ("4294967295") - 1)
521 			continue;
522 
523 		      tid = atoi (dp2->d_name);
524 		      core = linux_common_core_of_thread (ptid_t (pid, tid, 0));
525 
526 		      buffer_xml_printf
527 			(buffer,
528 			 "<item>"
529 			 "<column name=\"pid\">%lld</column>"
530 			 "<column name=\"command\">%s</column>"
531 			 "<column name=\"tid\">%lld</column>"
532 			 "<column name=\"core\">%d</column>"
533 			 "</item>",
534 			 pid,
535 			 command,
536 			 tid,
537 			 core);
538 		    }
539 
540 		  closedir (dirp2);
541 		}
542 	    }
543 	}
544 
545       closedir (dirp);
546     }
547 
548   buffer_grow_str0 (buffer, "</osdata>\n");
549 }
550 
551 /* Collect data about the cpus/cores on the system in BUFFER.  */
552 
553 static void
554 linux_xfer_osdata_cpus (struct buffer *buffer)
555 {
556   int first_item = 1;
557 
558   buffer_grow_str (buffer, "<osdata type=\"cpus\">\n");
559 
560   gdb_file_up fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r");
561   if (fp != NULL)
562     {
563       char buf[8192];
564 
565       do
566 	{
567 	  if (fgets (buf, sizeof (buf), fp.get ()))
568 	    {
569 	      char *key, *value;
570 	      int i = 0;
571 
572 	      char *saveptr;
573 	      key = strtok_r (buf, ":", &saveptr);
574 	      if (key == NULL)
575 		continue;
576 
577 	      value = strtok_r (NULL, ":", &saveptr);
578 	      if (value == NULL)
579 		continue;
580 
581 	      while (key[i] != '\t' && key[i] != '\0')
582 		i++;
583 
584 	      key[i] = '\0';
585 
586 	      i = 0;
587 	      while (value[i] != '\t' && value[i] != '\0')
588 		i++;
589 
590 	      value[i] = '\0';
591 
592 	      if (strcmp (key, "processor") == 0)
593 		{
594 		  if (first_item)
595 		    buffer_grow_str (buffer, "<item>");
596 		  else
597 		    buffer_grow_str (buffer, "</item><item>");
598 
599 		  first_item = 0;
600 		}
601 
602 	      buffer_xml_printf (buffer,
603 				 "<column name=\"%s\">%s</column>",
604 				 key,
605 				 value);
606 	    }
607 	}
608       while (!feof (fp.get ()));
609 
610       if (first_item == 0)
611 	buffer_grow_str (buffer, "</item>");
612     }
613 
614   buffer_grow_str0 (buffer, "</osdata>\n");
615 }
616 
617 /* Collect all the open file descriptors found in /proc and put the details
618    found about them into BUFFER.  */
619 
620 static void
621 linux_xfer_osdata_fds (struct buffer *buffer)
622 {
623   DIR *dirp;
624 
625   buffer_grow_str (buffer, "<osdata type=\"files\">\n");
626 
627   dirp = opendir ("/proc");
628   if (dirp)
629     {
630       struct dirent *dp;
631 
632       while ((dp = readdir (dirp)) != NULL)
633 	{
634 	  struct stat statbuf;
635 	  char procentry[sizeof ("/proc/4294967295")];
636 
637 	  if (!isdigit (dp->d_name[0])
638 	      || NAMELEN (dp) > sizeof ("4294967295") - 1)
639 	    continue;
640 
641 	  xsnprintf (procentry, sizeof (procentry), "/proc/%s",
642 		     dp->d_name);
643 	  if (stat (procentry, &statbuf) == 0
644 	      && S_ISDIR (statbuf.st_mode))
645 	    {
646 	      DIR *dirp2;
647 	      PID_T pid;
648 	      char command[32];
649 
650 	      pid = atoi (dp->d_name);
651 	      command_from_pid (command, sizeof (command), pid);
652 
653 	      std::string pathname
654 		= string_printf ("/proc/%s/fd", dp->d_name);
655 	      dirp2 = opendir (pathname.c_str ());
656 
657 	      if (dirp2)
658 		{
659 		  struct dirent *dp2;
660 
661 		  while ((dp2 = readdir (dirp2)) != NULL)
662 		    {
663 		      char buf[1000];
664 		      ssize_t rslt;
665 
666 		      if (!isdigit (dp2->d_name[0]))
667 			continue;
668 
669 		      std::string fdname
670 			= string_printf ("%s/%s", pathname.c_str (),
671 					 dp2->d_name);
672 		      rslt = readlink (fdname.c_str (), buf,
673 				       sizeof (buf) - 1);
674 		      if (rslt >= 0)
675 			buf[rslt] = '\0';
676 
677 		      buffer_xml_printf
678 			(buffer,
679 			 "<item>"
680 			 "<column name=\"pid\">%s</column>"
681 			 "<column name=\"command\">%s</column>"
682 			 "<column name=\"file descriptor\">%s</column>"
683 			 "<column name=\"name\">%s</column>"
684 			 "</item>",
685 			 dp->d_name,
686 			 command,
687 			 dp2->d_name,
688 			 (rslt >= 0 ? buf : dp2->d_name));
689 		    }
690 
691 		  closedir (dirp2);
692 		}
693 	    }
694 	}
695 
696       closedir (dirp);
697     }
698 
699   buffer_grow_str0 (buffer, "</osdata>\n");
700 }
701 
702 /* Returns the socket state STATE in textual form.  */
703 
704 static const char *
705 format_socket_state (unsigned char state)
706 {
707   /* Copied from include/net/tcp_states.h in the Linux kernel sources.  */
708   enum {
709     TCP_ESTABLISHED = 1,
710     TCP_SYN_SENT,
711     TCP_SYN_RECV,
712     TCP_FIN_WAIT1,
713     TCP_FIN_WAIT2,
714     TCP_TIME_WAIT,
715     TCP_CLOSE,
716     TCP_CLOSE_WAIT,
717     TCP_LAST_ACK,
718     TCP_LISTEN,
719     TCP_CLOSING
720   };
721 
722   switch (state)
723     {
724     case TCP_ESTABLISHED:
725       return "ESTABLISHED";
726     case TCP_SYN_SENT:
727       return "SYN_SENT";
728     case TCP_SYN_RECV:
729       return "SYN_RECV";
730     case TCP_FIN_WAIT1:
731       return "FIN_WAIT1";
732     case TCP_FIN_WAIT2:
733       return "FIN_WAIT2";
734     case TCP_TIME_WAIT:
735       return "TIME_WAIT";
736     case TCP_CLOSE:
737       return "CLOSE";
738     case TCP_CLOSE_WAIT:
739       return "CLOSE_WAIT";
740     case TCP_LAST_ACK:
741       return "LAST_ACK";
742     case TCP_LISTEN:
743       return "LISTEN";
744     case TCP_CLOSING:
745       return "CLOSING";
746     default:
747       return "(unknown)";
748     }
749 }
750 
751 union socket_addr
752   {
753     struct sockaddr sa;
754     struct sockaddr_in sin;
755     struct sockaddr_in6 sin6;
756   };
757 
758 /* Auxiliary function used by linux_xfer_osdata_isocket.  Formats
759    information for all open internet sockets of type FAMILY on the
760    system into BUFFER.  If TCP is set, only TCP sockets are processed,
761    otherwise only UDP sockets are processed.  */
762 
763 static void
764 print_sockets (unsigned short family, int tcp, struct buffer *buffer)
765 {
766   const char *proc_file;
767 
768   if (family == AF_INET)
769     proc_file = tcp ? "/proc/net/tcp" : "/proc/net/udp";
770   else if (family == AF_INET6)
771     proc_file = tcp ? "/proc/net/tcp6" : "/proc/net/udp6";
772   else
773     return;
774 
775   gdb_file_up fp = gdb_fopen_cloexec (proc_file, "r");
776   if (fp)
777     {
778       char buf[8192];
779 
780       do
781 	{
782 	  if (fgets (buf, sizeof (buf), fp.get ()))
783 	    {
784 	      uid_t uid;
785 	      unsigned int local_port, remote_port, state;
786 	      char local_address[NI_MAXHOST], remote_address[NI_MAXHOST];
787 	      int result;
788 
789 #if NI_MAXHOST <= 32
790 #error "local_address and remote_address buffers too small"
791 #endif
792 
793 	      result = sscanf (buf,
794 			       "%*d: %32[0-9A-F]:%X %32[0-9A-F]:%X %X %*X:%*X %*X:%*X %*X %d %*d %*u %*s\n",
795 			       local_address, &local_port,
796 			       remote_address, &remote_port,
797 			       &state,
798 			       &uid);
799 
800 	      if (result == 6)
801 		{
802 		  union socket_addr locaddr, remaddr;
803 		  size_t addr_size;
804 		  char user[UT_NAMESIZE];
805 		  char local_service[NI_MAXSERV], remote_service[NI_MAXSERV];
806 
807 		  if (family == AF_INET)
808 		    {
809 		      sscanf (local_address, "%X",
810 			      &locaddr.sin.sin_addr.s_addr);
811 		      sscanf (remote_address, "%X",
812 			      &remaddr.sin.sin_addr.s_addr);
813 
814 		      locaddr.sin.sin_port = htons (local_port);
815 		      remaddr.sin.sin_port = htons (remote_port);
816 
817 		      addr_size = sizeof (struct sockaddr_in);
818 		    }
819 		  else
820 		    {
821 		      sscanf (local_address, "%8X%8X%8X%8X",
822 			      locaddr.sin6.sin6_addr.s6_addr32,
823 			      locaddr.sin6.sin6_addr.s6_addr32 + 1,
824 			      locaddr.sin6.sin6_addr.s6_addr32 + 2,
825 			      locaddr.sin6.sin6_addr.s6_addr32 + 3);
826 		      sscanf (remote_address, "%8X%8X%8X%8X",
827 			      remaddr.sin6.sin6_addr.s6_addr32,
828 			      remaddr.sin6.sin6_addr.s6_addr32 + 1,
829 			      remaddr.sin6.sin6_addr.s6_addr32 + 2,
830 			      remaddr.sin6.sin6_addr.s6_addr32 + 3);
831 
832 		      locaddr.sin6.sin6_port = htons (local_port);
833 		      remaddr.sin6.sin6_port = htons (remote_port);
834 
835 		      locaddr.sin6.sin6_flowinfo = 0;
836 		      remaddr.sin6.sin6_flowinfo = 0;
837 		      locaddr.sin6.sin6_scope_id = 0;
838 		      remaddr.sin6.sin6_scope_id = 0;
839 
840 		      addr_size = sizeof (struct sockaddr_in6);
841 		    }
842 
843 		  locaddr.sa.sa_family = remaddr.sa.sa_family = family;
844 
845 		  result = getnameinfo (&locaddr.sa, addr_size,
846 					local_address, sizeof (local_address),
847 					local_service, sizeof (local_service),
848 					NI_NUMERICHOST | NI_NUMERICSERV
849 					| (tcp ? 0 : NI_DGRAM));
850 		  if (result)
851 		    continue;
852 
853 		  result = getnameinfo (&remaddr.sa, addr_size,
854 					remote_address,
855 					sizeof (remote_address),
856 					remote_service,
857 					sizeof (remote_service),
858 					NI_NUMERICHOST | NI_NUMERICSERV
859 					| (tcp ? 0 : NI_DGRAM));
860 		  if (result)
861 		    continue;
862 
863 		  user_from_uid (user, sizeof (user), uid);
864 
865 		  buffer_xml_printf (
866 		      buffer,
867 		      "<item>"
868 		      "<column name=\"local address\">%s</column>"
869 		      "<column name=\"local port\">%s</column>"
870 		      "<column name=\"remote address\">%s</column>"
871 		      "<column name=\"remote port\">%s</column>"
872 		      "<column name=\"state\">%s</column>"
873 		      "<column name=\"user\">%s</column>"
874 		      "<column name=\"family\">%s</column>"
875 		      "<column name=\"protocol\">%s</column>"
876 		      "</item>",
877 		      local_address,
878 		      local_service,
879 		      remote_address,
880 		      remote_service,
881 		      format_socket_state (state),
882 		      user,
883 		      (family == AF_INET) ? "INET" : "INET6",
884 		      tcp ? "STREAM" : "DGRAM");
885 		}
886 	    }
887 	}
888       while (!feof (fp.get ()));
889     }
890 }
891 
892 /* Collect data about internet sockets and write it into BUFFER.  */
893 
894 static void
895 linux_xfer_osdata_isockets (struct buffer *buffer)
896 {
897   buffer_grow_str (buffer, "<osdata type=\"I sockets\">\n");
898 
899   print_sockets (AF_INET, 1, buffer);
900   print_sockets (AF_INET, 0, buffer);
901   print_sockets (AF_INET6, 1, buffer);
902   print_sockets (AF_INET6, 0, buffer);
903 
904   buffer_grow_str0 (buffer, "</osdata>\n");
905 }
906 
907 /* Converts the time SECONDS into textual form and copies it into a
908    buffer TIME, with at most MAXLEN characters copied.  */
909 
910 static void
911 time_from_time_t (char *time, int maxlen, TIME_T seconds)
912 {
913   if (!seconds)
914     time[0] = '\0';
915   else
916     {
917       time_t t = (time_t) seconds;
918 
919       /* Per the ctime_r manpage, this buffer needs to be at least 26
920          characters long.  */
921       char buf[30];
922       const char *time_str = ctime_r (&t, buf);
923       strncpy (time, time_str, maxlen);
924       time[maxlen - 1] = '\0';
925     }
926 }
927 
928 /* Finds the group name for the group GID and copies it into GROUP.
929    At most MAXLEN characters are copied.  */
930 
931 static void
932 group_from_gid (char *group, int maxlen, gid_t gid)
933 {
934   struct group *grentry = getgrgid (gid);
935 
936   if (grentry)
937     {
938       strncpy (group, grentry->gr_name, maxlen);
939       /* Ensure that the group name is null-terminated.  */
940       group[maxlen - 1] = '\0';
941     }
942   else
943     group[0] = '\0';
944 }
945 
946 /* Collect data about shared memory recorded in /proc and write it
947    into BUFFER.  */
948 
949 static void
950 linux_xfer_osdata_shm (struct buffer *buffer)
951 {
952   buffer_grow_str (buffer, "<osdata type=\"shared memory\">\n");
953 
954   gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
955   if (fp)
956     {
957       char buf[8192];
958 
959       do
960 	{
961 	  if (fgets (buf, sizeof (buf), fp.get ()))
962 	    {
963 	      key_t key;
964 	      uid_t uid, cuid;
965 	      gid_t gid, cgid;
966 	      PID_T cpid, lpid;
967 	      int shmid, size, nattch;
968 	      TIME_T atime, dtime, ctime;
969 	      unsigned int perms;
970 	      int items_read;
971 
972 	      items_read = sscanf (buf,
973 				   "%d %d %o %d %lld %lld %d %u %u %u %u %lld %lld %lld",
974 				   &key, &shmid, &perms, &size,
975 				   &cpid, &lpid,
976 				   &nattch,
977 				   &uid, &gid, &cuid, &cgid,
978 				   &atime, &dtime, &ctime);
979 
980 	      if (items_read == 14)
981 		{
982 		  char user[UT_NAMESIZE], group[UT_NAMESIZE];
983 		  char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
984 		  char ccmd[32], lcmd[32];
985 		  char atime_str[32], dtime_str[32], ctime_str[32];
986 
987 		  user_from_uid (user, sizeof (user), uid);
988 		  group_from_gid (group, sizeof (group), gid);
989 		  user_from_uid (cuser, sizeof (cuser), cuid);
990 		  group_from_gid (cgroup, sizeof (cgroup), cgid);
991 
992 		  command_from_pid (ccmd, sizeof (ccmd), cpid);
993 		  command_from_pid (lcmd, sizeof (lcmd), lpid);
994 
995 		  time_from_time_t (atime_str, sizeof (atime_str), atime);
996 		  time_from_time_t (dtime_str, sizeof (dtime_str), dtime);
997 		  time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
998 
999 		  buffer_xml_printf
1000 		    (buffer,
1001 		     "<item>"
1002 		     "<column name=\"key\">%d</column>"
1003 		     "<column name=\"shmid\">%d</column>"
1004 		     "<column name=\"permissions\">%o</column>"
1005 		     "<column name=\"size\">%d</column>"
1006 		     "<column name=\"creator command\">%s</column>"
1007 		     "<column name=\"last op. command\">%s</column>"
1008 		     "<column name=\"num attached\">%d</column>"
1009 		     "<column name=\"user\">%s</column>"
1010 		     "<column name=\"group\">%s</column>"
1011 		     "<column name=\"creator user\">%s</column>"
1012 		     "<column name=\"creator group\">%s</column>"
1013 		     "<column name=\"last shmat() time\">%s</column>"
1014 		     "<column name=\"last shmdt() time\">%s</column>"
1015 		     "<column name=\"last shmctl() time\">%s</column>"
1016 		     "</item>",
1017 		     key,
1018 		     shmid,
1019 		     perms,
1020 		     size,
1021 		     ccmd,
1022 		     lcmd,
1023 		     nattch,
1024 		     user,
1025 		     group,
1026 		     cuser,
1027 		     cgroup,
1028 		     atime_str,
1029 		     dtime_str,
1030 		     ctime_str);
1031 		}
1032 	    }
1033 	}
1034       while (!feof (fp.get ()));
1035     }
1036 
1037   buffer_grow_str0 (buffer, "</osdata>\n");
1038 }
1039 
1040 /* Collect data about semaphores recorded in /proc and write it
1041    into BUFFER.  */
1042 
1043 static void
1044 linux_xfer_osdata_sem (struct buffer *buffer)
1045 {
1046   buffer_grow_str (buffer, "<osdata type=\"semaphores\">\n");
1047 
1048   gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
1049   if (fp)
1050     {
1051       char buf[8192];
1052 
1053       do
1054 	{
1055 	  if (fgets (buf, sizeof (buf), fp.get ()))
1056 	    {
1057 	      key_t key;
1058 	      uid_t uid, cuid;
1059 	      gid_t gid, cgid;
1060 	      unsigned int perms, nsems;
1061 	      int semid;
1062 	      TIME_T otime, ctime;
1063 	      int items_read;
1064 
1065 	      items_read = sscanf (buf,
1066 				   "%d %d %o %u %d %d %d %d %lld %lld",
1067 				   &key, &semid, &perms, &nsems,
1068 				   &uid, &gid, &cuid, &cgid,
1069 				   &otime, &ctime);
1070 
1071 	      if (items_read == 10)
1072 		{
1073 		  char user[UT_NAMESIZE], group[UT_NAMESIZE];
1074 		  char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1075 		  char otime_str[32], ctime_str[32];
1076 
1077 		  user_from_uid (user, sizeof (user), uid);
1078 		  group_from_gid (group, sizeof (group), gid);
1079 		  user_from_uid (cuser, sizeof (cuser), cuid);
1080 		  group_from_gid (cgroup, sizeof (cgroup), cgid);
1081 
1082 		  time_from_time_t (otime_str, sizeof (otime_str), otime);
1083 		  time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1084 
1085 		  buffer_xml_printf
1086 		    (buffer,
1087 		     "<item>"
1088 		     "<column name=\"key\">%d</column>"
1089 		     "<column name=\"semid\">%d</column>"
1090 		     "<column name=\"permissions\">%o</column>"
1091 		     "<column name=\"num semaphores\">%u</column>"
1092 		     "<column name=\"user\">%s</column>"
1093 		     "<column name=\"group\">%s</column>"
1094 		     "<column name=\"creator user\">%s</column>"
1095 		     "<column name=\"creator group\">%s</column>"
1096 		     "<column name=\"last semop() time\">%s</column>"
1097 		     "<column name=\"last semctl() time\">%s</column>"
1098 		     "</item>",
1099 		     key,
1100 		     semid,
1101 		     perms,
1102 		     nsems,
1103 		     user,
1104 		     group,
1105 		     cuser,
1106 		     cgroup,
1107 		     otime_str,
1108 		     ctime_str);
1109 		}
1110 	    }
1111 	}
1112       while (!feof (fp.get ()));
1113     }
1114 
1115   buffer_grow_str0 (buffer, "</osdata>\n");
1116 }
1117 
1118 /* Collect data about message queues recorded in /proc and write it
1119    into BUFFER.  */
1120 
1121 static void
1122 linux_xfer_osdata_msg (struct buffer *buffer)
1123 {
1124   buffer_grow_str (buffer, "<osdata type=\"message queues\">\n");
1125 
1126   gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
1127   if (fp)
1128     {
1129       char buf[8192];
1130 
1131       do
1132 	{
1133 	  if (fgets (buf, sizeof (buf), fp.get ()))
1134 	    {
1135 	      key_t key;
1136 	      PID_T lspid, lrpid;
1137 	      uid_t uid, cuid;
1138 	      gid_t gid, cgid;
1139 	      unsigned int perms, cbytes, qnum;
1140 	      int msqid;
1141 	      TIME_T stime, rtime, ctime;
1142 	      int items_read;
1143 
1144 	      items_read = sscanf (buf,
1145 				   "%d %d %o %u %u %lld %lld %d %d %d %d %lld %lld %lld",
1146 				   &key, &msqid, &perms, &cbytes, &qnum,
1147 				   &lspid, &lrpid, &uid, &gid, &cuid, &cgid,
1148 				   &stime, &rtime, &ctime);
1149 
1150 	      if (items_read == 14)
1151 		{
1152 		  char user[UT_NAMESIZE], group[UT_NAMESIZE];
1153 		  char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1154 		  char lscmd[32], lrcmd[32];
1155 		  char stime_str[32], rtime_str[32], ctime_str[32];
1156 
1157 		  user_from_uid (user, sizeof (user), uid);
1158 		  group_from_gid (group, sizeof (group), gid);
1159 		  user_from_uid (cuser, sizeof (cuser), cuid);
1160 		  group_from_gid (cgroup, sizeof (cgroup), cgid);
1161 
1162 		  command_from_pid (lscmd, sizeof (lscmd), lspid);
1163 		  command_from_pid (lrcmd, sizeof (lrcmd), lrpid);
1164 
1165 		  time_from_time_t (stime_str, sizeof (stime_str), stime);
1166 		  time_from_time_t (rtime_str, sizeof (rtime_str), rtime);
1167 		  time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1168 
1169 		  buffer_xml_printf
1170 		    (buffer,
1171 		     "<item>"
1172 		     "<column name=\"key\">%d</column>"
1173 		     "<column name=\"msqid\">%d</column>"
1174 		     "<column name=\"permissions\">%o</column>"
1175 		     "<column name=\"num used bytes\">%u</column>"
1176 		     "<column name=\"num messages\">%u</column>"
1177 		     "<column name=\"last msgsnd() command\">%s</column>"
1178 		     "<column name=\"last msgrcv() command\">%s</column>"
1179 		     "<column name=\"user\">%s</column>"
1180 		     "<column name=\"group\">%s</column>"
1181 		     "<column name=\"creator user\">%s</column>"
1182 		     "<column name=\"creator group\">%s</column>"
1183 		     "<column name=\"last msgsnd() time\">%s</column>"
1184 		     "<column name=\"last msgrcv() time\">%s</column>"
1185 		     "<column name=\"last msgctl() time\">%s</column>"
1186 		     "</item>",
1187 		     key,
1188 		     msqid,
1189 		     perms,
1190 		     cbytes,
1191 		     qnum,
1192 		     lscmd,
1193 		     lrcmd,
1194 		     user,
1195 		     group,
1196 		     cuser,
1197 		     cgroup,
1198 		     stime_str,
1199 		     rtime_str,
1200 		     ctime_str);
1201 		}
1202 	    }
1203 	}
1204       while (!feof (fp.get ()));
1205     }
1206 
1207   buffer_grow_str0 (buffer, "</osdata>\n");
1208 }
1209 
1210 /* Collect data about loaded kernel modules and write it into
1211    BUFFER.  */
1212 
1213 static void
1214 linux_xfer_osdata_modules (struct buffer *buffer)
1215 {
1216   buffer_grow_str (buffer, "<osdata type=\"modules\">\n");
1217 
1218   gdb_file_up fp = gdb_fopen_cloexec ("/proc/modules", "r");
1219   if (fp)
1220     {
1221       char buf[8192];
1222 
1223       do
1224 	{
1225 	  if (fgets (buf, sizeof (buf), fp.get ()))
1226 	    {
1227 	      char *name, *dependencies, *status, *tmp, *saveptr;
1228 	      unsigned int size;
1229 	      unsigned long long address;
1230 	      int uses;
1231 
1232 	      name = strtok_r (buf, " ", &saveptr);
1233 	      if (name == NULL)
1234 		continue;
1235 
1236 	      tmp = strtok_r (NULL, " ", &saveptr);
1237 	      if (tmp == NULL)
1238 		continue;
1239 	      if (sscanf (tmp, "%u", &size) != 1)
1240 		continue;
1241 
1242 	      tmp = strtok_r (NULL, " ", &saveptr);
1243 	      if (tmp == NULL)
1244 		continue;
1245 	      if (sscanf (tmp, "%d", &uses) != 1)
1246 		continue;
1247 
1248 	      dependencies = strtok_r (NULL, " ", &saveptr);
1249 	      if (dependencies == NULL)
1250 		continue;
1251 
1252 	      status = strtok_r (NULL, " ", &saveptr);
1253 	      if (status == NULL)
1254 		continue;
1255 
1256 	      tmp = strtok_r (NULL, "\n", &saveptr);
1257 	      if (tmp == NULL)
1258 		continue;
1259 	      if (sscanf (tmp, "%llx", &address) != 1)
1260 		continue;
1261 
1262 	      buffer_xml_printf (buffer,
1263 				 "<item>"
1264 				 "<column name=\"name\">%s</column>"
1265 				 "<column name=\"size\">%u</column>"
1266 				 "<column name=\"num uses\">%d</column>"
1267 				 "<column name=\"dependencies\">%s</column>"
1268 				 "<column name=\"status\">%s</column>"
1269 				 "<column name=\"address\">%llx</column>"
1270 				 "</item>",
1271 				 name,
1272 				 size,
1273 				 uses,
1274 				 dependencies,
1275 				 status,
1276 				 address);
1277 	    }
1278 	}
1279       while (!feof (fp.get ()));
1280     }
1281 
1282   buffer_grow_str0 (buffer, "</osdata>\n");
1283 }
1284 
1285 static void linux_xfer_osdata_info_os_types (struct buffer *buffer);
1286 
1287 struct osdata_type {
1288   const char *type;
1289   const char *title;
1290   const char *description;
1291   void (*take_snapshot) (struct buffer *buffer);
1292   LONGEST len_avail;
1293   struct buffer buffer;
1294 } osdata_table[] = {
1295   { "types", "Types", "Listing of info os types you can list",
1296     linux_xfer_osdata_info_os_types, -1 },
1297   { "cpus", "CPUs", "Listing of all cpus/cores on the system",
1298     linux_xfer_osdata_cpus, -1 },
1299   { "files", "File descriptors", "Listing of all file descriptors",
1300     linux_xfer_osdata_fds, -1 },
1301   { "modules", "Kernel modules", "Listing of all loaded kernel modules",
1302     linux_xfer_osdata_modules, -1 },
1303   { "msg", "Message queues", "Listing of all message queues",
1304     linux_xfer_osdata_msg, -1 },
1305   { "processes", "Processes", "Listing of all processes",
1306     linux_xfer_osdata_processes, -1 },
1307   { "procgroups", "Process groups", "Listing of all process groups",
1308     linux_xfer_osdata_processgroups, -1 },
1309   { "semaphores", "Semaphores", "Listing of all semaphores",
1310     linux_xfer_osdata_sem, -1 },
1311   { "shm", "Shared-memory regions", "Listing of all shared-memory regions",
1312     linux_xfer_osdata_shm, -1 },
1313   { "sockets", "Sockets", "Listing of all internet-domain sockets",
1314     linux_xfer_osdata_isockets, -1 },
1315   { "threads", "Threads", "Listing of all threads",
1316   linux_xfer_osdata_threads, -1 },
1317   { NULL, NULL, NULL }
1318 };
1319 
1320 /* Collect data about all types info os can show in BUFFER.  */
1321 
1322 static void
1323 linux_xfer_osdata_info_os_types (struct buffer *buffer)
1324 {
1325   buffer_grow_str (buffer, "<osdata type=\"types\">\n");
1326 
1327   /* Start the below loop at 1, as we do not want to list ourselves.  */
1328   for (int i = 1; osdata_table[i].type; ++i)
1329     buffer_xml_printf (buffer,
1330 		       "<item>"
1331 		       "<column name=\"Type\">%s</column>"
1332 		       "<column name=\"Description\">%s</column>"
1333 		       "<column name=\"Title\">%s</column>"
1334 		       "</item>",
1335 		       osdata_table[i].type,
1336 		       osdata_table[i].description,
1337 		       osdata_table[i].title);
1338 
1339   buffer_grow_str0 (buffer, "</osdata>\n");
1340 }
1341 
1342 
1343 /*  Copies up to LEN bytes in READBUF from offset OFFSET in OSD->BUFFER.
1344     If OFFSET is zero, first calls OSD->TAKE_SNAPSHOT.  */
1345 
1346 static LONGEST
1347 common_getter (struct osdata_type *osd,
1348 	       gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
1349 {
1350   gdb_assert (readbuf);
1351 
1352   if (offset == 0)
1353     {
1354       if (osd->len_avail != -1 && osd->len_avail != 0)
1355 	buffer_free (&osd->buffer);
1356       osd->len_avail = 0;
1357       buffer_init (&osd->buffer);
1358       (osd->take_snapshot) (&osd->buffer);
1359       osd->len_avail = strlen (osd->buffer.buffer);
1360     }
1361   if (offset >= osd->len_avail)
1362     {
1363       /* Done.  Get rid of the buffer.  */
1364       buffer_free (&osd->buffer);
1365       osd->len_avail = 0;
1366       return 0;
1367     }
1368   if (len > osd->len_avail - offset)
1369     len = osd->len_avail - offset;
1370   memcpy (readbuf, osd->buffer.buffer + offset, len);
1371 
1372   return len;
1373 
1374 }
1375 
1376 LONGEST
1377 linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
1378 			  ULONGEST offset, ULONGEST len)
1379 {
1380   if (!annex || *annex == '\0')
1381     {
1382       return common_getter (&osdata_table[0],
1383 			    readbuf, offset, len);
1384     }
1385   else
1386     {
1387       int i;
1388 
1389       for (i = 0; osdata_table[i].type; ++i)
1390 	{
1391 	  if (strcmp (annex, osdata_table[i].type) == 0)
1392 	    return common_getter (&osdata_table[i],
1393 				  readbuf, offset, len);
1394 	}
1395 
1396       return 0;
1397     }
1398 }
1399