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