Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c
+++ new/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26 /*
27 27 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
28 + * Copyright 2018 Joyent, Inc.
28 29 */
30 +
29 31 #include <struct_layout.h>
30 32
31 33
32 34 static const sl_auxv_layout_t auxv_layout = {
33 35 { 0, 8, 0, 0 }, /* sizeof (auxv_t) */
34 36 { 0, 4, 0, 1 }, /* a_type */
35 37 { 4, 4, 0, 1 }, /* a_un.a_val */
36 38 { 4, 4, 0, 0 }, /* a_un.a_ptr */
37 39 { 4, 4, 0, 0 }, /* a_un.a_fcn */
38 40 };
39 41
40 42
41 43 static const sl_prgregset_layout_t prgregset_layout = {
42 44 { 0, 152, 0, 0 }, /* sizeof (prgregset_t) */
43 45 { 0, 4, 38, 0 }, /* elt0 */
44 46 };
45 47
46 48
47 49 static const sl_lwpstatus_layout_t lwpstatus_layout = {
48 50 { 0, 896, 0, 0 }, /* sizeof (lwpstatus_t) */
49 51 { 0, 4, 0, 0 }, /* pr_flags */
50 52 { 4, 4, 0, 0 }, /* pr_lwpid */
51 53 { 8, 2, 0, 0 }, /* pr_why */
52 54 { 10, 2, 0, 0 }, /* pr_what */
53 55 { 12, 2, 0, 0 }, /* pr_cursig */
54 56 { 16, 128, 0, 0 }, /* pr_info */
55 57 { 144, 16, 0, 0 }, /* pr_lwppend */
56 58 { 160, 16, 0, 0 }, /* pr_lwphold */
57 59 { 176, 32, 0, 0 }, /* pr_action */
58 60 { 208, 12, 0, 0 }, /* pr_altstack */
59 61 { 220, 4, 0, 0 }, /* pr_oldcontext */
60 62 { 224, 2, 0, 0 }, /* pr_syscall */
61 63 { 226, 2, 0, 0 }, /* pr_nsysarg */
62 64 { 228, 4, 0, 0 }, /* pr_errno */
63 65 { 232, 4, 8, 0 }, /* pr_sysarg[] */
64 66 { 264, 4, 0, 0 }, /* pr_rval1 */
65 67 { 268, 4, 0, 0 }, /* pr_rval2 */
66 68 { 272, 1, 8, 0 }, /* pr_clname[] */
67 69 { 280, 8, 0, 0 }, /* pr_tstamp */
68 70 { 288, 8, 0, 0 }, /* pr_utime */
69 71 { 296, 8, 0, 0 }, /* pr_stime */
70 72 { 332, 4, 0, 0 }, /* pr_errpriv */
71 73 { 336, 4, 0, 0 }, /* pr_ustack */
72 74 { 340, 4, 0, 0 }, /* pr_instr */
73 75 { 344, 152, 0, 0 }, /* pr_reg */
74 76 { 496, 400, 0, 0 }, /* pr_fpreg */
75 77 };
76 78
77 79
78 80 static const sl_pstatus_layout_t pstatus_layout = {
79 81 { 0, 1232, 0, 0 }, /* sizeof (pstatus_t) */
80 82 { 0, 4, 0, 1 }, /* pr_flags */
81 83 { 4, 4, 0, 1 }, /* pr_nlwp */
82 84 { 8, 4, 0, 0 }, /* pr_pid */
83 85 { 12, 4, 0, 0 }, /* pr_ppid */
84 86 { 16, 4, 0, 0 }, /* pr_pgid */
85 87 { 20, 4, 0, 0 }, /* pr_sid */
86 88 { 24, 4, 0, 1 }, /* pr_aslwpid */
87 89 { 28, 4, 0, 1 }, /* pr_agentid */
88 90 { 32, 16, 0, 0 }, /* pr_sigpend */
89 91 { 48, 4, 0, 0 }, /* pr_brkbase */
90 92 { 52, 4, 0, 0 }, /* pr_brksize */
91 93 { 56, 4, 0, 0 }, /* pr_stkbase */
92 94 { 60, 4, 0, 0 }, /* pr_stksize */
93 95 { 64, 8, 0, 0 }, /* pr_utime */
94 96 { 72, 8, 0, 0 }, /* pr_stime */
95 97 { 80, 8, 0, 0 }, /* pr_cutime */
96 98 { 88, 8, 0, 0 }, /* pr_cstime */
97 99 { 96, 16, 0, 0 }, /* pr_sigtrace */
98 100 { 112, 16, 0, 0 }, /* pr_flttrace */
99 101 { 128, 64, 0, 0 }, /* pr_sysentry */
100 102 { 192, 64, 0, 0 }, /* pr_sysexit */
101 103 { 256, 1, 0, 0 }, /* pr_dmodel */
102 104 { 260, 4, 0, 1 }, /* pr_taskid */
103 105 { 264, 4, 0, 1 }, /* pr_projid */
104 106 { 268, 4, 0, 1 }, /* pr_nzomb */
105 107 { 272, 4, 0, 1 }, /* pr_zoneid */
106 108 { 336, 896, 0, 0 }, /* pr_lwp */
107 109 };
108 110
109 111
110 112 static const sl_prstatus_layout_t prstatus_layout = {
111 113 { 0, 508, 0, 0 }, /* sizeof (prstatus_t) */
112 114 { 0, 4, 0, 1 }, /* pr_flags */
113 115 { 4, 2, 0, 1 }, /* pr_why */
114 116 { 6, 2, 0, 1 }, /* pr_what */
115 117 { 8, 128, 0, 0 }, /* pr_info */
116 118 { 136, 2, 0, 1 }, /* pr_cursig */
117 119 { 138, 2, 0, 0 }, /* pr_nlwp */
118 120 { 140, 16, 0, 0 }, /* pr_sigpend */
119 121 { 156, 16, 0, 0 }, /* pr_sighold */
120 122 { 172, 12, 0, 0 }, /* pr_altstack */
121 123 { 184, 32, 0, 0 }, /* pr_action */
122 124 { 216, 4, 0, 0 }, /* pr_pid */
123 125 { 220, 4, 0, 0 }, /* pr_ppid */
124 126 { 224, 4, 0, 0 }, /* pr_pgrp */
125 127 { 228, 4, 0, 0 }, /* pr_sid */
126 128 { 232, 8, 0, 0 }, /* pr_utime */
127 129 { 240, 8, 0, 0 }, /* pr_stime */
128 130 { 248, 8, 0, 0 }, /* pr_cutime */
129 131 { 256, 8, 0, 0 }, /* pr_cstime */
130 132 { 264, 1, 8, 0 }, /* pr_clname[] */
131 133 { 272, 2, 0, 1 }, /* pr_syscall */
132 134 { 274, 2, 0, 1 }, /* pr_nsysarg */
133 135 { 276, 4, 8, 1 }, /* pr_sysarg[] */
134 136 { 308, 4, 0, 0 }, /* pr_who */
135 137 { 312, 16, 0, 0 }, /* pr_lwppend */
136 138 { 328, 4, 0, 0 }, /* pr_oldcontext */
137 139 { 332, 4, 0, 0 }, /* pr_brkbase */
138 140 { 336, 4, 0, 0 }, /* pr_brksize */
139 141 { 340, 4, 0, 0 }, /* pr_stkbase */
140 142 { 344, 4, 0, 0 }, /* pr_stksize */
141 143 { 348, 2, 0, 1 }, /* pr_processor */
142 144 { 350, 2, 0, 1 }, /* pr_bind */
143 145 { 352, 4, 0, 1 }, /* pr_instr */
144 146 { 356, 152, 0, 0 }, /* pr_reg */
145 147 };
146 148
147 149
148 150 static const sl_psinfo_layout_t psinfo_layout = {
149 151 { 0, 336, 0, 0 }, /* sizeof (psinfo_t) */
150 152 { 0, 4, 0, 1 }, /* pr_flag */
151 153 { 4, 4, 0, 1 }, /* pr_nlwp */
152 154 { 8, 4, 0, 0 }, /* pr_pid */
153 155 { 12, 4, 0, 0 }, /* pr_ppid */
154 156 { 16, 4, 0, 0 }, /* pr_pgid */
155 157 { 20, 4, 0, 0 }, /* pr_sid */
156 158 { 24, 4, 0, 0 }, /* pr_uid */
157 159 { 28, 4, 0, 0 }, /* pr_euid */
158 160 { 32, 4, 0, 0 }, /* pr_gid */
159 161 { 36, 4, 0, 0 }, /* pr_egid */
160 162 { 40, 4, 0, 0 }, /* pr_addr */
161 163 { 44, 4, 0, 0 }, /* pr_size */
162 164 { 48, 4, 0, 0 }, /* pr_rssize */
163 165 { 56, 4, 0, 0 }, /* pr_ttydev */
164 166 { 60, 2, 0, 0 }, /* pr_pctcpu */
165 167 { 62, 2, 0, 0 }, /* pr_pctmem */
166 168 { 64, 8, 0, 0 }, /* pr_start */
167 169 { 72, 8, 0, 0 }, /* pr_time */
168 170 { 80, 8, 0, 0 }, /* pr_ctime */
169 171 { 88, 1, 16, 0 }, /* pr_fname[] */
170 172 { 104, 1, 80, 0 }, /* pr_psargs[] */
171 173 { 184, 4, 0, 1 }, /* pr_wstat */
172 174 { 188, 4, 0, 1 }, /* pr_argc */
173 175 { 192, 4, 0, 0 }, /* pr_argv */
174 176 { 196, 4, 0, 0 }, /* pr_envp */
175 177 { 200, 1, 0, 0 }, /* pr_dmodel */
176 178 { 204, 4, 0, 0 }, /* pr_taskid */
177 179 { 208, 4, 0, 0 }, /* pr_projid */
178 180 { 212, 4, 0, 1 }, /* pr_nzomb */
179 181 { 216, 4, 0, 0 }, /* pr_poolid */
180 182 { 220, 4, 0, 0 }, /* pr_zoneid */
181 183 { 224, 4, 0, 0 }, /* pr_contract */
182 184 { 232, 104, 0, 0 }, /* pr_lwp */
183 185 };
184 186
185 187
186 188 static const sl_prpsinfo_layout_t prpsinfo_layout = {
187 189 { 0, 260, 0, 0 }, /* sizeof (prpsinfo_t) */
188 190 { 0, 1, 0, 0 }, /* pr_state */
189 191 { 1, 1, 0, 0 }, /* pr_sname */
190 192 { 2, 1, 0, 0 }, /* pr_zomb */
191 193 { 3, 1, 0, 0 }, /* pr_nice */
192 194 { 4, 4, 0, 0 }, /* pr_flag */
193 195 { 8, 4, 0, 0 }, /* pr_uid */
194 196 { 12, 4, 0, 0 }, /* pr_gid */
195 197 { 16, 4, 0, 0 }, /* pr_pid */
196 198 { 20, 4, 0, 0 }, /* pr_ppid */
197 199 { 24, 4, 0, 0 }, /* pr_pgrp */
198 200 { 28, 4, 0, 0 }, /* pr_sid */
199 201 { 32, 4, 0, 0 }, /* pr_addr */
200 202 { 36, 4, 0, 0 }, /* pr_size */
201 203 { 40, 4, 0, 0 }, /* pr_rssize */
202 204 { 44, 4, 0, 0 }, /* pr_wchan */
203 205 { 48, 8, 0, 0 }, /* pr_start */
204 206 { 56, 8, 0, 0 }, /* pr_time */
205 207 { 64, 4, 0, 1 }, /* pr_pri */
206 208 { 68, 1, 0, 0 }, /* pr_oldpri */
207 209 { 69, 1, 0, 0 }, /* pr_cpu */
208 210 { 70, 2, 0, 0 }, /* pr_ottydev */
209 211 { 72, 4, 0, 0 }, /* pr_lttydev */
210 212 { 76, 1, 8, 0 }, /* pr_clname[] */
211 213 { 84, 1, 16, 0 }, /* pr_fname[] */
212 214 { 100, 1, 80, 0 }, /* pr_psargs[] */
213 215 { 180, 2, 0, 1 }, /* pr_syscall */
214 216 { 184, 8, 0, 0 }, /* pr_ctime */
215 217 { 192, 4, 0, 0 }, /* pr_bysize */
216 218 { 196, 4, 0, 0 }, /* pr_byrssize */
217 219 { 200, 4, 0, 1 }, /* pr_argc */
218 220 { 204, 4, 0, 0 }, /* pr_argv */
219 221 { 208, 4, 0, 0 }, /* pr_envp */
220 222 { 212, 4, 0, 1 }, /* pr_wstat */
221 223 { 216, 2, 0, 0 }, /* pr_pctcpu */
222 224 { 218, 2, 0, 0 }, /* pr_pctmem */
223 225 { 220, 4, 0, 0 }, /* pr_euid */
224 226 { 224, 4, 0, 0 }, /* pr_egid */
225 227 { 228, 4, 0, 0 }, /* pr_aslwpid */
226 228 { 232, 1, 0, 0 }, /* pr_dmodel */
227 229 };
228 230
229 231
230 232 static const sl_lwpsinfo_layout_t lwpsinfo_layout = {
231 233 { 0, 104, 0, 0 }, /* sizeof (lwpsinfo_t) */
232 234 { 0, 4, 0, 1 }, /* pr_flag */
233 235 { 4, 4, 0, 0 }, /* pr_lwpid */
234 236 { 8, 4, 0, 0 }, /* pr_addr */
235 237 { 12, 4, 0, 0 }, /* pr_wchan */
236 238 { 16, 1, 0, 0 }, /* pr_stype */
237 239 { 17, 1, 0, 0 }, /* pr_state */
238 240 { 18, 1, 0, 0 }, /* pr_sname */
239 241 { 19, 1, 0, 0 }, /* pr_nice */
240 242 { 20, 2, 0, 0 }, /* pr_syscall */
241 243 { 22, 1, 0, 0 }, /* pr_oldpri */
242 244 { 23, 1, 0, 0 }, /* pr_cpu */
243 245 { 24, 4, 0, 1 }, /* pr_pri */
244 246 { 28, 2, 0, 0 }, /* pr_pctcpu */
245 247 { 32, 8, 0, 0 }, /* pr_start */
246 248 { 40, 8, 0, 0 }, /* pr_time */
247 249 { 48, 1, 8, 0 }, /* pr_clname[] */
248 250 { 56, 1, 16, 0 }, /* pr_name[] */
249 251 { 72, 4, 0, 1 }, /* pr_onpro */
250 252 { 76, 4, 0, 1 }, /* pr_bindpro */
251 253 { 80, 4, 0, 1 }, /* pr_bindpset */
252 254 { 84, 4, 0, 1 }, /* pr_lgrp */
253 255 };
254 256
255 257
256 258 static const sl_prcred_layout_t prcred_layout = {
257 259 { 0, 32, 0, 0 }, /* sizeof (prcred_t) */
258 260 { 0, 4, 0, 0 }, /* pr_euid */
259 261 { 4, 4, 0, 0 }, /* pr_ruid */
260 262 { 8, 4, 0, 0 }, /* pr_suid */
261 263 { 12, 4, 0, 0 }, /* pr_egid */
262 264 { 16, 4, 0, 0 }, /* pr_rgid */
263 265 { 20, 4, 0, 0 }, /* pr_sgid */
264 266 { 24, 4, 0, 1 }, /* pr_ngroups */
265 267 { 28, 4, 1, 0 }, /* pr_groups[] */
266 268 };
267 269
268 270
269 271 static const sl_prpriv_layout_t prpriv_layout = {
270 272 { 0, 16, 0, 0 }, /* sizeof (prpriv_t) */
271 273 { 0, 4, 0, 0 }, /* pr_nsets */
272 274 { 4, 4, 0, 0 }, /* pr_setsize */
273 275 { 8, 4, 0, 0 }, /* pr_infosize */
274 276 { 12, 4, 1, 0 }, /* pr_sets[] */
275 277 };
276 278
277 279
278 280 static const sl_priv_impl_info_layout_t priv_impl_info_layout = {
279 281 { 0, 28, 0, 0 }, /* sizeof (priv_impl_info_t) */
280 282 { 0, 4, 0, 0 }, /* priv_headersize */
281 283 { 4, 4, 0, 0 }, /* priv_flags */
282 284 { 8, 4, 0, 0 }, /* priv_nsets */
283 285 { 12, 4, 0, 0 }, /* priv_setsize */
284 286 { 16, 4, 0, 0 }, /* priv_max */
285 287 { 20, 4, 0, 0 }, /* priv_infosize */
286 288 { 24, 4, 0, 0 }, /* priv_globalinfosize */
287 289 };
288 290
289 291
290 292 static const sl_fltset_layout_t fltset_layout = {
291 293 { 0, 16, 0, 0 }, /* sizeof (fltset_t) */
292 294 { 0, 4, 4, 0 }, /* word[] */
293 295 };
294 296
295 297
296 298 static const sl_siginfo_layout_t siginfo_layout = {
297 299 { 0, 128, 0, 0 }, /* sizeof (siginfo_t) */
298 300 { 0, 4, 0, 0 }, /* si_signo */
299 301 { 8, 4, 0, 0 }, /* si_errno */
300 302 { 4, 4, 0, 1 }, /* si_code */
301 303 { 20, 4, 0, 0 }, /* si_value.sival_int */
302 304 { 20, 4, 0, 0 }, /* si_value.sival_ptr */
303 305 { 12, 4, 0, 0 }, /* si_pid */
304 306 { 16, 4, 0, 0 }, /* si_uid */
305 307 { 28, 4, 0, 0 }, /* si_ctid */
306 308 { 32, 4, 0, 0 }, /* si_zoneid */
307 309 { 12, 4, 0, 0 }, /* si_entity */
308 310 { 12, 4, 0, 0 }, /* si_addr */
309 311 { 20, 4, 0, 0 }, /* si_status */
310 312 { 16, 4, 0, 0 }, /* si_band */
311 313 };
312 314
313 315
314 316 static const sl_sigset_layout_t sigset_layout = {
315 317 { 0, 16, 0, 0 }, /* sizeof (sigset_t) */
316 318 { 0, 4, 4, 0 }, /* __sigbits[] */
317 319 };
318 320
319 321
320 322 static const sl_sigaction_layout_t sigaction_layout = {
321 323 { 0, 32, 0, 0 }, /* sizeof (struct sigaction) */
322 324 { 0, 4, 0, 0 }, /* sa_flags */
323 325 { 4, 4, 0, 0 }, /* sa_handler */
324 326 { 4, 4, 0, 0 }, /* sa_sigaction */
325 327 { 8, 16, 0, 0 }, /* sa_mask */
326 328 };
327 329
328 330
329 331 static const sl_stack_layout_t stack_layout = {
330 332 { 0, 12, 0, 0 }, /* sizeof (stack_t) */
331 333 { 0, 4, 0, 0 }, /* ss_sp */
332 334 { 4, 4, 0, 0 }, /* ss_size */
333 335 { 8, 4, 0, 0 }, /* ss_flags */
334 336 };
335 337
336 338
337 339 static const sl_sysset_layout_t sysset_layout = {
338 340 { 0, 64, 0, 0 }, /* sizeof (sysset_t) */
339 341 { 0, 4, 16, 0 }, /* word[] */
340 342 };
341 343
342 344
343 345 static const sl_timestruc_layout_t timestruc_layout = {
344 346 { 0, 8, 0, 0 }, /* sizeof (timestruc_t) */
345 347 { 0, 4, 0, 0 }, /* tv_sec */
346 348 { 4, 4, 0, 0 }, /* tv_nsec */
347 349 };
348 350
349 351
350 352 static const sl_utsname_layout_t utsname_layout = {
351 353 { 0, 1285, 0, 0 }, /* sizeof (struct utsname) */
352 354 { 0, 1, 257, 0 }, /* sysname[] */
353 355 { 257, 1, 257, 0 }, /* nodename[] */
354 356 { 514, 1, 257, 0 }, /* release[] */
355 357 { 771, 1, 257, 0 }, /* version[] */
356 358 { 1028, 1, 257, 0 }, /* machine[] */
357 359 };
358 360
359 361
360 362 static const sl_prfdinfo_layout_t prfdinfo_layout = {
361 363 { 0, 1088, 0, 0 }, /* sizeof (prfdinfo_t) */
362 364 { 0, 4, 0, 0 }, /* pr_fd */
363 365 { 4, 4, 0, 0 }, /* pr_mode */
364 366 { 8, 4, 0, 0 }, /* pr_uid */
365 367 { 12, 4, 0, 0 }, /* pr_gid */
366 368 { 16, 4, 0, 0 }, /* pr_major */
367 369 { 20, 4, 0, 0 }, /* pr_minor */
368 370 { 24, 4, 0, 0 }, /* pr_rmajor */
369 371 { 28, 4, 0, 0 }, /* pr_rminor */
370 372 { 32, 8, 0, 0 }, /* pr_ino */
371 373 { 40, 8, 0, 0 }, /* pr_offset */
372 374 { 48, 8, 0, 0 }, /* pr_size */
373 375 { 56, 4, 0, 0 }, /* pr_fileflags */
374 376 { 60, 4, 0, 0 }, /* pr_fdflags */
375 377 { 64, 1, 1024, 0 }, /* pr_path[] */
376 378 };
377 379
378 380
↓ open down ↓ |
340 lines elided |
↑ open up ↑ |
379 381 static const sl_prsecflags_layout_t prsecflags_layout = {
380 382 { 0, 40, 0, 0 }, /* sizeof (prsecflags_t) */
381 383 { 0, 4, 0, 0 }, /* pr_version */
382 384 { 8, 8, 0, 0 }, /* pr_effective */
383 385 { 16, 8, 0, 0 }, /* pr_inherit */
384 386 { 24, 8, 0, 0 }, /* pr_lower */
385 387 { 32, 8, 0, 0 }, /* pr_upper */
386 388 };
387 389
388 390
391 +static const sl_prlwpname_layout_t prlwpname_layout = {
392 + { 0, 40, 0, 0 }, /* sizeof (prlwpname_t) */
393 + { 0, 8, 0, 0 }, /* pr_lwpid */
394 + { 8, 1, 32, 0 }, /* pr_lwpname[] */
395 +};
389 396
390 397
398 +
399 +
391 400 static const sl_arch_layout_t layout_sparc = {
392 401 &auxv_layout,
393 402 &fltset_layout,
394 403 &lwpsinfo_layout,
395 404 &lwpstatus_layout,
396 405 &prcred_layout,
397 406 &priv_impl_info_layout,
398 407 &prpriv_layout,
399 408 &psinfo_layout,
400 409 &pstatus_layout,
401 410 &prgregset_layout,
402 411 &prpsinfo_layout,
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
403 412 &prstatus_layout,
404 413 &sigaction_layout,
405 414 &siginfo_layout,
406 415 &sigset_layout,
407 416 &stack_layout,
408 417 &sysset_layout,
409 418 ×truc_layout,
410 419 &utsname_layout,
411 420 &prfdinfo_layout,
412 421 &prsecflags_layout,
422 + &prlwpname_layout,
413 423 };
414 424
415 425
416 426 const sl_arch_layout_t *
417 427 struct_layout_sparc(void)
418 428 {
419 429 return (&layout_sparc);
420 430 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX