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