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