2009-02-06 Pedro Alves <pedro@codesourcery.com>
[external/binutils.git] / gdb / linux-tdep.c
1 /* Target-dependent code for GNU/Linux, architecture independent.
2
3    Copyright (C) 2009 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 "defs.h"
21 #include "gdbtypes.h"
22
23 /* This function is suitable for architectures that don't
24    extend/override the standard siginfo structure.  */
25
26 struct type *
27 linux_get_siginfo_type (struct gdbarch *gdbarch)
28 {
29   struct type *int_type, *uint_type, *long_type, *void_ptr_type;
30   struct type *uid_type, *pid_type;
31   struct type *sigval_type, *clock_type;
32   struct type *siginfo_type, *sifields_type;
33   struct type *type;
34
35   int_type = init_type (TYPE_CODE_INT,
36                         gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT,
37                         0, "int", NULL);
38   uint_type = init_type (TYPE_CODE_INT,
39                          gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT,
40                          0, "unsigned int", NULL);
41   long_type = init_type (TYPE_CODE_INT,
42                          gdbarch_long_bit (gdbarch) / HOST_CHAR_BIT,
43                          0, "long", NULL);
44   void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
45
46   /* sival_t */
47   sigval_type = init_composite_type (NULL, TYPE_CODE_UNION);
48   TYPE_NAME (sigval_type) = xstrdup ("sigval_t");
49   append_composite_type_field (sigval_type, "sival_int", int_type);
50   append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type);
51
52   /* __pid_t */
53   pid_type = init_type (TYPE_CODE_TYPEDEF, TYPE_LENGTH (int_type),
54                         TYPE_FLAG_TARGET_STUB, NULL, NULL);
55   TYPE_NAME (pid_type) = xstrdup ("__pid_t");
56   TYPE_TARGET_TYPE (pid_type) = int_type;
57
58   /* __uid_t */
59   uid_type = init_type (TYPE_CODE_TYPEDEF, TYPE_LENGTH (uint_type),
60                         TYPE_FLAG_TARGET_STUB, NULL, NULL);
61   TYPE_NAME (uid_type) = xstrdup ("__uid_t");
62   TYPE_TARGET_TYPE (uid_type) = uint_type;
63
64   /* __clock_t */
65   clock_type = init_type (TYPE_CODE_TYPEDEF, TYPE_LENGTH (long_type),
66                           TYPE_FLAG_TARGET_STUB, NULL, NULL);
67   TYPE_NAME (clock_type) = xstrdup ("__clock_t");
68   TYPE_TARGET_TYPE (clock_type) = long_type;
69
70   /* _sifields */
71   sifields_type = init_composite_type (NULL, TYPE_CODE_UNION);
72
73   {
74     const int si_max_size = 128;
75     int si_pad_size;
76     int size_of_int = gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT;
77
78     /* _pad */
79     if (gdbarch_ptr_bit (gdbarch) == 64)
80       si_pad_size = (si_max_size / size_of_int) - 4;
81     else
82       si_pad_size = (si_max_size / size_of_int) - 3;
83     append_composite_type_field (sifields_type, "_pad",
84                                  init_vector_type (int_type, si_pad_size));
85   }
86
87   /* _kill */
88   type = init_composite_type (NULL, TYPE_CODE_STRUCT);
89   append_composite_type_field (type, "si_pid", pid_type);
90   append_composite_type_field (type, "si_uid", uid_type);
91   append_composite_type_field (sifields_type, "_kill", type);
92
93   /* _timer */
94   type = init_composite_type (NULL, TYPE_CODE_STRUCT);
95   append_composite_type_field (type, "si_tid", int_type);
96   append_composite_type_field (type, "si_overrun", int_type);
97   append_composite_type_field (type, "si_sigval", sigval_type);
98   append_composite_type_field (sifields_type, "_timer", type);
99
100   /* _rt */
101   type = init_composite_type (NULL, TYPE_CODE_STRUCT);
102   append_composite_type_field (type, "si_pid", pid_type);
103   append_composite_type_field (type, "si_uid", uid_type);
104   append_composite_type_field (type, "si_sigval", sigval_type);
105   append_composite_type_field (sifields_type, "_rt", type);
106
107   /* _sigchld */
108   type = init_composite_type (NULL, TYPE_CODE_STRUCT);
109   append_composite_type_field (type, "si_pid", pid_type);
110   append_composite_type_field (type, "si_uid", uid_type);
111   append_composite_type_field (type, "si_status", int_type);
112   append_composite_type_field (type, "si_utime", clock_type);
113   append_composite_type_field (type, "si_stime", clock_type);
114   append_composite_type_field (sifields_type, "_sigchld", type);
115
116   /* _sigfault */
117   type = init_composite_type (NULL, TYPE_CODE_STRUCT);
118   append_composite_type_field (type, "si_addr", void_ptr_type);
119   append_composite_type_field (sifields_type, "_sigfault", type);
120
121   /* _sigpoll */
122   type = init_composite_type (NULL, TYPE_CODE_STRUCT);
123   append_composite_type_field (type, "si_band", long_type);
124   append_composite_type_field (type, "si_fd", int_type);
125   append_composite_type_field (sifields_type, "_sigpoll", type);
126
127   /* struct siginfo */
128   siginfo_type = init_composite_type (NULL, TYPE_CODE_STRUCT);
129   TYPE_NAME (siginfo_type) = xstrdup ("siginfo");
130   append_composite_type_field (siginfo_type, "si_signo", int_type);
131   append_composite_type_field (siginfo_type, "si_errno", int_type);
132   append_composite_type_field (siginfo_type, "si_code", int_type);
133   append_composite_type_field_aligned (siginfo_type,
134                                        "_sifields", sifields_type,
135                                        TYPE_LENGTH (long_type));
136
137   return siginfo_type;
138 }