xref: /illumos-gate/usr/src/lib/libproc/common/P32ton.c (revision 20a7641f9918de8574b8b3b47dbe35c4bfc78df1)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/types.h>
28 #include <sys/mkdev.h>
29 #include <sys/regset.h>
30 #include <string.h>
31 
32 #if defined(__amd64)
33 #include <sys/fp.h>
34 #include <ieeefp.h>
35 #endif
36 
37 #include "P32ton.h"
38 
39 dev_t
40 prexpldev(dev32_t d)
41 {
42 	if (d != (dev32_t)-1L)
43 		return (makedev((d >> NBITSMINOR32) & MAXMAJ32, d & MAXMIN32));
44 
45 	return ((dev_t)PRNODEV);
46 }
47 
48 
49 dev32_t
50 prcmpldev(dev_t d)
51 {
52 #ifdef _LP64
53 	if (d == PRNODEV) {
54 		return (PRNODEV32);
55 	} else {
56 		major_t maj = major(d);
57 		minor_t min = minor(d);
58 
59 		if (maj == (major_t)PRNODEV || min == (minor_t)PRNODEV)
60 			return (PRNODEV32);
61 
62 		return ((dev32_t)((maj << NBITSMINOR32) | min));
63 	}
64 #else
65 	return ((dev32_t)d);
66 #endif
67 }
68 
69 #ifdef _LP64
70 
71 void
72 timestruc_32_to_n(const timestruc32_t *src, timestruc_t *dst)
73 {
74 	dst->tv_sec = (time_t)(uint32_t)src->tv_sec;
75 	dst->tv_nsec = (long)(uint32_t)src->tv_nsec;
76 }
77 
78 void
79 stack_32_to_n(const stack32_t *src, stack_t *dst)
80 {
81 	dst->ss_sp = (caddr_t)(uintptr_t)src->ss_sp;
82 	dst->ss_size = src->ss_size;
83 	dst->ss_flags = src->ss_flags;
84 }
85 
86 void
87 sigaction_32_to_n(const struct sigaction32 *src, struct sigaction *dst)
88 {
89 	(void) memset(dst, 0, sizeof (struct sigaction));
90 	dst->sa_flags = src->sa_flags;
91 	dst->sa_handler = (void (*)())(uintptr_t)src->sa_handler;
92 	(void) memcpy(&dst->sa_mask, &src->sa_mask, sizeof (dst->sa_mask));
93 }
94 
95 void
96 siginfo_32_to_n(const siginfo32_t *src, siginfo_t *dst)
97 {
98 	(void) memset(dst, 0, sizeof (siginfo_t));
99 
100 	/*
101 	 * The absolute minimum content is si_signo and si_code.
102 	 */
103 	dst->si_signo = src->si_signo;
104 	if ((dst->si_code = src->si_code) == SI_NOINFO)
105 		return;
106 
107 	/*
108 	 * A siginfo generated by user level is structured
109 	 * differently from one generated by the kernel.
110 	 */
111 	if (SI_FROMUSER(src)) {
112 		dst->si_pid = src->si_pid;
113 		dst->si_ctid = src->si_ctid;
114 		dst->si_zoneid = src->si_zoneid;
115 		dst->si_uid = src->si_uid;
116 		if (SI_CANQUEUE(src->si_code)) {
117 			dst->si_value.sival_int =
118 			    (long)(uint32_t)src->si_value.sival_int;
119 		}
120 		return;
121 	}
122 
123 	dst->si_errno = src->si_errno;
124 
125 	switch (src->si_signo) {
126 	default:
127 		dst->si_pid = src->si_pid;
128 		dst->si_ctid = src->si_ctid;
129 		dst->si_zoneid = src->si_zoneid;
130 		dst->si_uid = src->si_uid;
131 		dst->si_value.sival_int =
132 		    (long)(uint32_t)src->si_value.sival_int;
133 		break;
134 	case SIGCLD:
135 		dst->si_pid = src->si_pid;
136 		dst->si_ctid = src->si_ctid;
137 		dst->si_zoneid = src->si_zoneid;
138 		dst->si_status = src->si_status;
139 		dst->si_stime = src->si_stime;
140 		dst->si_utime = src->si_utime;
141 		break;
142 	case SIGSEGV:
143 	case SIGBUS:
144 	case SIGILL:
145 	case SIGTRAP:
146 	case SIGFPE:
147 	case SIGEMT:
148 		dst->si_addr = (void *)(uintptr_t)src->si_addr;
149 		dst->si_trapno = src->si_trapno;
150 		dst->si_pc = (void *)(uintptr_t)src->si_pc;
151 		break;
152 	case SIGPOLL:
153 	case SIGXFSZ:
154 		dst->si_fd = src->si_fd;
155 		dst->si_band = src->si_band;
156 		break;
157 	case SIGPROF:
158 		dst->si_faddr = (void *)(uintptr_t)src->si_faddr;
159 		dst->si_tstamp.tv_sec = src->si_tstamp.tv_sec;
160 		dst->si_tstamp.tv_nsec = src->si_tstamp.tv_nsec;
161 		dst->si_syscall = src->si_syscall;
162 		dst->si_nsysarg = src->si_nsysarg;
163 		dst->si_fault = src->si_fault;
164 		break;
165 	}
166 }
167 
168 void
169 auxv_32_to_n(const auxv32_t *src, auxv_t *dst)
170 {
171 	/*
172 	 * This is a little sketchy: we have three types of values stored
173 	 * in an auxv (long, void *, and void (*)()) so the only sign-extension
174 	 * issue is with the long.  We could case on all possible AT_* types,
175 	 * but this seems silly since currently none of the types which use
176 	 * a_un.a_val actually use negative numbers as a value.  For this
177 	 * reason, it seems simpler to just do an unsigned expansion for now.
178 	 */
179 	dst->a_type = src->a_type;
180 	dst->a_un.a_ptr = (void *)(uintptr_t)src->a_un.a_ptr;
181 }
182 
183 #if defined(__sparc)
184 void
185 rwindow_32_to_n(const struct rwindow32 *src, struct rwindow *dst)
186 {
187 	int i;
188 
189 	for (i = 0; i < 8; i++) {
190 		dst->rw_local[i] = (uint64_t)(uint32_t)src->rw_local[i];
191 		dst->rw_in[i] = (uint64_t)(uint32_t)src->rw_in[i];
192 	}
193 }
194 
195 void
196 gwindows_32_to_n(const gwindows32_t *src, gwindows_t *dst)
197 {
198 	int i;
199 
200 	(void) memset(dst, 0, sizeof (gwindows_t));
201 	dst->wbcnt = src->wbcnt;
202 
203 	for (i = 0; i < src->wbcnt; i++) {
204 		if (src->spbuf[i] != 0) {
205 			rwindow_32_to_n(&src->wbuf[i], &dst->wbuf[i]);
206 			dst->spbuf[i] = (greg_t *)(uintptr_t)src->spbuf[i];
207 		}
208 	}
209 }
210 #endif	/* __sparc */
211 
212 void
213 prgregset_32_to_n(const prgreg32_t *src, prgreg_t *dst)
214 {
215 #ifdef __amd64
216 	(void) memset(dst, 0, NPRGREG * sizeof (prgreg_t));
217 	dst[REG_GS] = (uint32_t)src[GS];
218 	dst[REG_FS] = (uint32_t)src[FS];
219 	dst[REG_DS] = (uint32_t)src[DS];
220 	dst[REG_ES] = (uint32_t)src[ES];
221 	dst[REG_RDI] = (uint32_t)src[EDI];
222 	dst[REG_RSI] = (uint32_t)src[ESI];
223 	dst[REG_RBP] = (uint32_t)src[EBP];
224 	dst[REG_RBX] = (uint32_t)src[EBX];
225 	dst[REG_RDX] = (uint32_t)src[EDX];
226 	dst[REG_RCX] = (uint32_t)src[ECX];
227 	dst[REG_RAX] = (uint32_t)src[EAX];
228 	dst[REG_TRAPNO] = (uint32_t)src[TRAPNO];
229 	dst[REG_ERR] = (uint32_t)src[ERR];
230 	dst[REG_RIP] = (uint32_t)src[EIP];
231 	dst[REG_CS] = (uint32_t)src[CS];
232 	dst[REG_RFL] = (uint32_t)src[EFL];
233 	dst[REG_RSP] = (uint32_t)src[UESP];
234 	dst[REG_SS] = (uint32_t)src[SS];
235 #else
236 	int i;
237 
238 	for (i = 0; i < NPRGREG; i++)
239 		dst[i] = (prgreg_t)(uint32_t)src[i];
240 #endif
241 }
242 
243 void
244 prfpregset_32_to_n(const prfpregset32_t *src, prfpregset_t *dst)
245 {
246 #if defined(__sparc)
247 	int i;
248 
249 	(void) memset(dst, 0, sizeof (prfpregset_t));
250 
251 	for (i = 0; i < 32; i++)
252 		dst->pr_fr.pr_regs[i] = src->pr_fr.pr_regs[i];
253 
254 	/*
255 	 * We deliberately do not convert pr_qcnt or pr_q because it is a long-
256 	 * standing /proc bug that this information is not exported, and another
257 	 * bug further caused these values to be returned as uninitialized data
258 	 * when the 64-bit kernel exported them for a 32-bit process with en=0.
259 	 */
260 	dst->pr_filler = src->pr_filler;
261 	dst->pr_fsr = src->pr_fsr;
262 	dst->pr_q_entrysize = src->pr_q_entrysize;
263 	dst->pr_en = src->pr_en;
264 
265 #elif defined(__amd64)
266 
267 	struct _fpstate32 *src32 = (struct _fpstate32 *)src;
268 	struct _fpchip_state *dst64 = (struct _fpchip_state *)dst;
269 	int i;
270 
271 	(void) memcpy(dst64->st, src32->_st, sizeof (src32->_st));
272 	(void) memcpy(dst64->xmm, src32->xmm, sizeof (src32->xmm));
273 	(void) memset((caddr_t)dst64->xmm + sizeof (src32->xmm), 0,
274 	    sizeof (dst64->xmm) - sizeof (src32->xmm));
275 	dst64->cw = (uint16_t)src32->cw;
276 	dst64->sw = (uint16_t)src32->sw;
277 	dst64->fop = 0;
278 	dst64->rip = src32->ipoff;
279 	dst64->rdp = src32->dataoff;
280 	dst64->mxcsr = src32->mxcsr;
281 	dst64->mxcsr_mask = 0;
282 	dst64->status = src32->status;
283 	dst64->xstatus = src32->xstatus;
284 
285 	/*
286 	 * Converting from the tag field to the compressed fctw is easy.
287 	 * If the two tag bits are 3, then the register is empty and we
288 	 * clear the bit in fctw. Otherwise we set the bit.
289 	 */
290 
291 	dst64->fctw = 0;
292 	for (i = 0; i < 8; i++)
293 		if (((src32->tag >> (i * 2)) & 3) != 3)
294 			dst64->fctw |= 1 << i;
295 #else
296 #error "unrecognized ISA"
297 #endif
298 }
299 
300 void
301 lwpstatus_32_to_n(const lwpstatus32_t *src, lwpstatus_t *dst)
302 {
303 	int i;
304 
305 	dst->pr_flags = src->pr_flags;
306 	dst->pr_lwpid = src->pr_lwpid;
307 	dst->pr_why = src->pr_why;
308 	dst->pr_what = src->pr_what;
309 	dst->pr_cursig = src->pr_cursig;
310 
311 	siginfo_32_to_n(&src->pr_info, &dst->pr_info);
312 
313 	dst->pr_lwppend = src->pr_lwppend;
314 	dst->pr_lwphold = src->pr_lwphold;
315 
316 	sigaction_32_to_n(&src->pr_action, &dst->pr_action);
317 	stack_32_to_n(&src->pr_altstack, &dst->pr_altstack);
318 
319 	dst->pr_oldcontext = src->pr_oldcontext;
320 	dst->pr_syscall = src->pr_syscall;
321 	dst->pr_nsysarg = src->pr_nsysarg;
322 	dst->pr_errno = src->pr_errno;
323 
324 	for (i = 0; i < PRSYSARGS; i++)
325 		dst->pr_sysarg[i] = (long)(uint32_t)src->pr_sysarg[i];
326 
327 	dst->pr_rval1 = (long)(uint32_t)src->pr_rval1;
328 	dst->pr_rval2 = (long)(uint32_t)src->pr_rval2;
329 
330 	(void) memcpy(&dst->pr_clname[0], &src->pr_clname[0], PRCLSZ);
331 	timestruc_32_to_n(&src->pr_tstamp, &dst->pr_tstamp);
332 
333 	dst->pr_ustack = src->pr_ustack;
334 	dst->pr_instr = src->pr_instr;
335 
336 	prgregset_32_to_n(src->pr_reg, dst->pr_reg);
337 	prfpregset_32_to_n(&src->pr_fpreg, &dst->pr_fpreg);
338 }
339 
340 void
341 pstatus_32_to_n(const pstatus32_t *src, pstatus_t *dst)
342 {
343 	dst->pr_flags = src->pr_flags;
344 	dst->pr_nlwp = src->pr_nlwp;
345 	dst->pr_nzomb = src->pr_nzomb;
346 	dst->pr_pid = src->pr_pid;
347 	dst->pr_ppid = src->pr_ppid;
348 	dst->pr_pgid = src->pr_pgid;
349 	dst->pr_sid = src->pr_sid;
350 	dst->pr_taskid = src->pr_taskid;
351 	dst->pr_projid = src->pr_projid;
352 	dst->pr_zoneid = src->pr_zoneid;
353 	dst->pr_aslwpid = src->pr_aslwpid;
354 	dst->pr_agentid = src->pr_agentid;
355 	dst->pr_sigpend = src->pr_sigpend;
356 	dst->pr_brkbase = src->pr_brkbase;
357 	dst->pr_brksize = src->pr_brksize;
358 	dst->pr_stkbase = src->pr_stkbase;
359 	dst->pr_stksize = src->pr_stksize;
360 
361 	timestruc_32_to_n(&src->pr_utime, &dst->pr_utime);
362 	timestruc_32_to_n(&src->pr_stime, &dst->pr_stime);
363 	timestruc_32_to_n(&src->pr_cutime, &dst->pr_cutime);
364 	timestruc_32_to_n(&src->pr_cstime, &dst->pr_cstime);
365 
366 	dst->pr_sigtrace = src->pr_sigtrace;
367 	dst->pr_flttrace = src->pr_flttrace;
368 	dst->pr_sysentry = src->pr_sysentry;
369 	dst->pr_sysexit = src->pr_sysexit;
370 	dst->pr_dmodel = src->pr_dmodel;
371 
372 	lwpstatus_32_to_n(&src->pr_lwp, &dst->pr_lwp);
373 }
374 
375 void
376 lwpsinfo_32_to_n(const lwpsinfo32_t *src, lwpsinfo_t *dst)
377 {
378 	dst->pr_flag = src->pr_flag;
379 	dst->pr_lwpid = src->pr_lwpid;
380 	dst->pr_addr = src->pr_addr;
381 	dst->pr_wchan = src->pr_wchan;
382 	dst->pr_stype = src->pr_stype;
383 	dst->pr_state = src->pr_state;
384 	dst->pr_sname = src->pr_sname;
385 	dst->pr_nice = src->pr_nice;
386 	dst->pr_syscall = src->pr_syscall;
387 	dst->pr_oldpri = src->pr_oldpri;
388 	dst->pr_cpu = src->pr_cpu;
389 	dst->pr_pri = src->pr_pri;
390 	dst->pr_pctcpu = src->pr_pctcpu;
391 
392 	timestruc_32_to_n(&src->pr_start, &dst->pr_start);
393 	timestruc_32_to_n(&src->pr_time, &dst->pr_time);
394 
395 	(void) memcpy(&dst->pr_clname[0], &src->pr_clname[0], PRCLSZ);
396 	(void) memcpy(&dst->pr_name[0], &src->pr_name[0], PRFNSZ);
397 
398 	dst->pr_onpro = src->pr_onpro;
399 	dst->pr_bindpro = src->pr_bindpro;
400 	dst->pr_bindpset = src->pr_bindpset;
401 	dst->pr_lgrp = src->pr_lgrp;
402 }
403 
404 void
405 psinfo_32_to_n(const psinfo32_t *src, psinfo_t *dst)
406 {
407 	dst->pr_flag = src->pr_flag;
408 	dst->pr_nlwp = src->pr_nlwp;
409 	dst->pr_nzomb = src->pr_nzomb;
410 	dst->pr_pid = src->pr_pid;
411 	dst->pr_pgid = src->pr_pgid;
412 	dst->pr_sid = src->pr_sid;
413 	dst->pr_taskid = src->pr_taskid;
414 	dst->pr_projid = src->pr_projid;
415 	dst->pr_zoneid = src->pr_zoneid;
416 	dst->pr_uid = src->pr_uid;
417 	dst->pr_euid = src->pr_euid;
418 	dst->pr_gid = src->pr_gid;
419 	dst->pr_egid = src->pr_egid;
420 	dst->pr_addr = src->pr_addr;
421 	dst->pr_size = src->pr_size;
422 	dst->pr_rssize = src->pr_rssize;
423 
424 	dst->pr_ttydev = prexpldev(src->pr_ttydev);
425 
426 	dst->pr_pctcpu = src->pr_pctcpu;
427 	dst->pr_pctmem = src->pr_pctmem;
428 
429 	timestruc_32_to_n(&src->pr_start, &dst->pr_start);
430 	timestruc_32_to_n(&src->pr_time, &dst->pr_time);
431 	timestruc_32_to_n(&src->pr_ctime, &dst->pr_ctime);
432 
433 	(void) memcpy(&dst->pr_fname[0], &src->pr_fname[0], PRFNSZ);
434 	(void) memcpy(&dst->pr_psargs[0], &src->pr_psargs[0], PRARGSZ);
435 
436 	dst->pr_wstat = src->pr_wstat;
437 	dst->pr_argc = src->pr_argc;
438 	dst->pr_argv = src->pr_argv;
439 	dst->pr_envp = src->pr_envp;
440 	dst->pr_dmodel = src->pr_dmodel;
441 
442 	lwpsinfo_32_to_n(&src->pr_lwp, &dst->pr_lwp);
443 }
444 
445 void
446 timestruc_n_to_32(const timestruc_t *src, timestruc32_t *dst)
447 {
448 	dst->tv_sec = (time32_t)src->tv_sec;
449 	dst->tv_nsec = (int32_t)src->tv_nsec;
450 }
451 
452 void
453 stack_n_to_32(const stack_t *src, stack32_t *dst)
454 {
455 	dst->ss_sp = (caddr32_t)(uintptr_t)src->ss_sp;
456 	dst->ss_size = src->ss_size;
457 	dst->ss_flags = src->ss_flags;
458 }
459 
460 void
461 sigaction_n_to_32(const struct sigaction *src, struct sigaction32 *dst)
462 {
463 	(void) memset(dst, 0, sizeof (struct sigaction32));
464 	dst->sa_flags = src->sa_flags;
465 	dst->sa_handler = (caddr32_t)(uintptr_t)src->sa_handler;
466 	(void) memcpy(&dst->sa_mask, &src->sa_mask, sizeof (dst->sa_mask));
467 }
468 
469 void
470 siginfo_n_to_32(const siginfo_t *src, siginfo32_t *dst)
471 {
472 	(void) memset(dst, 0, sizeof (siginfo32_t));
473 
474 	/*
475 	 * The absolute minimum content is si_signo and si_code.
476 	 */
477 	dst->si_signo = src->si_signo;
478 	if ((dst->si_code = src->si_code) == SI_NOINFO)
479 		return;
480 
481 	/*
482 	 * A siginfo generated by user level is structured
483 	 * differently from one generated by the kernel.
484 	 */
485 	if (SI_FROMUSER(src)) {
486 		dst->si_pid = src->si_pid;
487 		dst->si_ctid = src->si_ctid;
488 		dst->si_zoneid = src->si_zoneid;
489 		dst->si_uid = src->si_uid;
490 		if (SI_CANQUEUE(src->si_code)) {
491 			dst->si_value.sival_int =
492 			    (int32_t)src->si_value.sival_int;
493 		}
494 		return;
495 	}
496 
497 	dst->si_errno = src->si_errno;
498 
499 	switch (src->si_signo) {
500 	default:
501 		dst->si_pid = src->si_pid;
502 		dst->si_ctid = src->si_ctid;
503 		dst->si_zoneid = src->si_zoneid;
504 		dst->si_uid = src->si_uid;
505 		dst->si_value.sival_int =
506 		    (int32_t)src->si_value.sival_int;
507 		break;
508 	case SIGCLD:
509 		dst->si_pid = src->si_pid;
510 		dst->si_ctid = src->si_ctid;
511 		dst->si_zoneid = src->si_zoneid;
512 		dst->si_status = src->si_status;
513 		dst->si_stime = src->si_stime;
514 		dst->si_utime = src->si_utime;
515 		break;
516 	case SIGSEGV:
517 	case SIGBUS:
518 	case SIGILL:
519 	case SIGTRAP:
520 	case SIGFPE:
521 	case SIGEMT:
522 		dst->si_addr = (caddr32_t)(uintptr_t)src->si_addr;
523 		dst->si_trapno = src->si_trapno;
524 		dst->si_pc = (caddr32_t)(uintptr_t)src->si_pc;
525 		break;
526 	case SIGPOLL:
527 	case SIGXFSZ:
528 		dst->si_fd = src->si_fd;
529 		dst->si_band = src->si_band;
530 		break;
531 	case SIGPROF:
532 		dst->si_faddr = (caddr32_t)(uintptr_t)src->si_faddr;
533 		dst->si_tstamp.tv_sec = src->si_tstamp.tv_sec;
534 		dst->si_tstamp.tv_nsec = src->si_tstamp.tv_nsec;
535 		dst->si_syscall = src->si_syscall;
536 		dst->si_nsysarg = src->si_nsysarg;
537 		dst->si_fault = src->si_fault;
538 		break;
539 	}
540 }
541 
542 void
543 auxv_n_to_32(const auxv_t *src, auxv32_t *dst)
544 {
545 	dst->a_type = src->a_type;
546 	dst->a_un.a_ptr = (caddr32_t)(uintptr_t)src->a_un.a_ptr;
547 }
548 
549 void
550 prgregset_n_to_32(const prgreg_t *src, prgreg32_t *dst)
551 {
552 #ifdef __amd64
553 	(void) memset(dst, 0, NPRGREG32 * sizeof (prgreg32_t));
554 	dst[GS] = src[REG_GS];
555 	dst[FS] = src[REG_FS];
556 	dst[DS] = src[REG_DS];
557 	dst[ES] = src[REG_ES];
558 	dst[EDI] = src[REG_RDI];
559 	dst[ESI] = src[REG_RSI];
560 	dst[EBP] = src[REG_RBP];
561 	dst[EBX] = src[REG_RBX];
562 	dst[EDX] = src[REG_RDX];
563 	dst[ECX] = src[REG_RCX];
564 	dst[EAX] = src[REG_RAX];
565 	dst[TRAPNO] = src[REG_TRAPNO];
566 	dst[ERR] = src[REG_ERR];
567 	dst[EIP] = src[REG_RIP];
568 	dst[CS] = src[REG_CS];
569 	dst[EFL] = src[REG_RFL];
570 	dst[UESP] = src[REG_RSP];
571 	dst[SS] = src[REG_SS];
572 #else
573 	int i;
574 
575 	for (i = 0; i < NPRGREG; i++)
576 		dst[i] = (prgreg32_t)src[i];
577 #endif
578 }
579 
580 void
581 prfpregset_n_to_32(const prfpregset_t *src, prfpregset32_t *dst)
582 {
583 #if defined(__sparc)
584 	int i;
585 
586 	(void) memset(dst, 0, sizeof (prfpregset32_t));
587 
588 	for (i = 0; i < 32; i++)
589 		dst->pr_fr.pr_regs[i] = src->pr_fr.pr_regs[i];
590 
591 	dst->pr_filler = src->pr_filler;
592 	dst->pr_fsr = src->pr_fsr;
593 	dst->pr_q_entrysize = src->pr_q_entrysize;
594 	dst->pr_en = src->pr_en;
595 
596 #elif defined(__amd64)
597 
598 	struct _fpstate32 *dst32 = (struct _fpstate32 *)dst;
599 	struct _fpchip_state *src64 = (struct _fpchip_state *)src;
600 	uint32_t top;
601 	int i;
602 
603 	(void) memcpy(dst32->_st, src64->st, sizeof (dst32->_st));
604 	(void) memcpy(dst32->xmm, src64->xmm, sizeof (dst32->xmm));
605 	dst32->cw = src64->cw;
606 	dst32->sw = src64->sw;
607 	dst32->ipoff = (unsigned int)src64->rip;
608 	dst32->cssel = 0;
609 	dst32->dataoff = (unsigned int)src64->rdp;
610 	dst32->datasel = 0;
611 	dst32->status = src64->status;
612 	dst32->mxcsr = src64->mxcsr;
613 	dst32->xstatus = src64->xstatus;
614 
615 	/*
616 	 * AMD64 stores the tag in a compressed form. It is
617 	 * necessary to extract the original 2-bit tag value.
618 	 * See AMD64 Architecture Programmer's Manual Volume 2:
619 	 * System Programming, Chapter 11.
620 	 */
621 
622 	top = (src64->sw & FPS_TOP) >> 11;
623 	dst32->tag = 0;
624 	for (i = 0; i < 8; i++) {
625 		/*
626 		 * Recall that we need to use the current TOP-of-stack value to
627 		 * associate the _st[] index back to a physical register number,
628 		 * since tag word indices are physical register numbers.  Then
629 		 * to get the tag value, we shift over two bits for each tag
630 		 * index, and then grab the bottom two bits.
631 		 */
632 		uint_t tag_index = (i + top) & 7;
633 		uint_t tag_fctw = (src64->fctw >> tag_index) & 1;
634 		uint_t tag_value;
635 		uint_t exp;
636 
637 		/*
638 		 * Union for overlaying _fpreg structure on to quad-precision
639 		 * floating-point value (long double).
640 		 */
641 		union {
642 			struct _fpreg reg;
643 			long double ld;
644 		} fpru;
645 
646 		fpru.ld = src64->st[i].__fpr_pad._q;
647 		exp = fpru.reg.exponent & 0x7fff;
648 
649 		if (tag_fctw == 0) {
650 			tag_value = 3; /* empty */
651 		} else if (exp == 0) {
652 			if (fpru.reg.significand[0] == 0 &&
653 			    fpru.reg.significand[1] == 0 &&
654 			    fpru.reg.significand[2] == 0 &&
655 			    fpru.reg.significand[3] == 0)
656 				tag_value = 1; /* zero */
657 			else
658 				tag_value = 2; /* special: denormal */
659 		} else if (exp == 0x7fff) {
660 			tag_value = 2; /* special: infinity or NaN */
661 		} else if (fpru.reg.significand[3] & 0x8000) {
662 			tag_value = 0; /* valid */
663 		} else {
664 			tag_value = 2; /* special: unnormal */
665 		}
666 		dst32->tag |= tag_value << (tag_index * 2);
667 	}
668 #else
669 #error "unrecognized ISA"
670 #endif
671 }
672 
673 void
674 lwpstatus_n_to_32(const lwpstatus_t *src, lwpstatus32_t *dst)
675 {
676 	int i;
677 
678 	dst->pr_flags = src->pr_flags;
679 	dst->pr_lwpid = src->pr_lwpid;
680 	dst->pr_why = src->pr_why;
681 	dst->pr_what = src->pr_what;
682 	dst->pr_cursig = src->pr_cursig;
683 
684 	siginfo_n_to_32(&src->pr_info, &dst->pr_info);
685 
686 	dst->pr_lwppend = src->pr_lwppend;
687 	dst->pr_lwphold = src->pr_lwphold;
688 
689 	sigaction_n_to_32(&src->pr_action, &dst->pr_action);
690 	stack_n_to_32(&src->pr_altstack, &dst->pr_altstack);
691 
692 	dst->pr_oldcontext = (caddr32_t)src->pr_oldcontext;
693 	dst->pr_syscall = src->pr_syscall;
694 	dst->pr_nsysarg = src->pr_nsysarg;
695 	dst->pr_errno = src->pr_errno;
696 
697 	for (i = 0; i < PRSYSARGS; i++)
698 		dst->pr_sysarg[i] = (int32_t)src->pr_sysarg[i];
699 
700 	dst->pr_rval1 = (int32_t)src->pr_rval1;
701 	dst->pr_rval2 = (int32_t)src->pr_rval2;
702 
703 	(void) memcpy(&dst->pr_clname[0], &src->pr_clname[0], PRCLSZ);
704 	timestruc_n_to_32(&src->pr_tstamp, &dst->pr_tstamp);
705 
706 	dst->pr_ustack = (caddr32_t)src->pr_ustack;
707 	dst->pr_instr = src->pr_instr;
708 
709 	prgregset_n_to_32(src->pr_reg, dst->pr_reg);
710 	prfpregset_n_to_32(&src->pr_fpreg, &dst->pr_fpreg);
711 }
712 
713 void
714 pstatus_n_to_32(const pstatus_t *src, pstatus32_t *dst)
715 {
716 	dst->pr_flags = src->pr_flags;
717 	dst->pr_nlwp = src->pr_nlwp;
718 	dst->pr_nzomb = src->pr_nzomb;
719 	dst->pr_pid = (pid32_t)src->pr_pid;
720 	dst->pr_ppid = (pid32_t)src->pr_ppid;
721 	dst->pr_pgid = (pid32_t)src->pr_pgid;
722 	dst->pr_sid = (pid32_t)src->pr_sid;
723 	dst->pr_taskid = (id32_t)src->pr_taskid;
724 	dst->pr_projid = (id32_t)src->pr_projid;
725 	dst->pr_zoneid = (id32_t)src->pr_zoneid;
726 	dst->pr_aslwpid = (id32_t)src->pr_aslwpid;
727 	dst->pr_agentid = (id32_t)src->pr_agentid;
728 	dst->pr_sigpend = src->pr_sigpend;
729 	dst->pr_brkbase = (caddr32_t)src->pr_brkbase;
730 	dst->pr_brksize = (size32_t)src->pr_brksize;
731 	dst->pr_stkbase = (caddr32_t)src->pr_stkbase;
732 	dst->pr_stksize = (size32_t)src->pr_stksize;
733 
734 	timestruc_n_to_32(&src->pr_utime, &dst->pr_utime);
735 	timestruc_n_to_32(&src->pr_stime, &dst->pr_stime);
736 	timestruc_n_to_32(&src->pr_cutime, &dst->pr_cutime);
737 	timestruc_n_to_32(&src->pr_cstime, &dst->pr_cstime);
738 
739 	dst->pr_sigtrace = src->pr_sigtrace;
740 	dst->pr_flttrace = src->pr_flttrace;
741 	dst->pr_sysentry = src->pr_sysentry;
742 	dst->pr_sysexit = src->pr_sysexit;
743 	dst->pr_dmodel = src->pr_dmodel;
744 
745 	lwpstatus_n_to_32(&src->pr_lwp, &dst->pr_lwp);
746 }
747 
748 void
749 lwpsinfo_n_to_32(const lwpsinfo_t *src, lwpsinfo32_t *dst)
750 {
751 	dst->pr_flag = src->pr_flag;
752 	dst->pr_lwpid = (id32_t)src->pr_lwpid;
753 	dst->pr_addr = (caddr32_t)src->pr_addr;
754 	dst->pr_wchan = (caddr32_t)src->pr_wchan;
755 	dst->pr_stype = src->pr_stype;
756 	dst->pr_state = src->pr_state;
757 	dst->pr_sname = src->pr_sname;
758 	dst->pr_nice = src->pr_nice;
759 	dst->pr_syscall = src->pr_syscall;
760 	dst->pr_oldpri = src->pr_oldpri;
761 	dst->pr_cpu = src->pr_cpu;
762 	dst->pr_pri = src->pr_pri;
763 	dst->pr_pctcpu = src->pr_pctcpu;
764 
765 	timestruc_n_to_32(&src->pr_start, &dst->pr_start);
766 	timestruc_n_to_32(&src->pr_time, &dst->pr_time);
767 
768 	(void) memcpy(&dst->pr_clname[0], &src->pr_clname[0], PRCLSZ);
769 	(void) memcpy(&dst->pr_name[0], &src->pr_name[0], PRFNSZ);
770 
771 	dst->pr_onpro = src->pr_onpro;
772 	dst->pr_bindpro = src->pr_bindpro;
773 	dst->pr_bindpset = src->pr_bindpset;
774 	dst->pr_lgrp = src->pr_lgrp;
775 }
776 
777 void
778 psinfo_n_to_32(const psinfo_t *src, psinfo32_t *dst)
779 {
780 	dst->pr_flag = src->pr_flag;
781 	dst->pr_nlwp = src->pr_nlwp;
782 	dst->pr_nzomb = src->pr_nzomb;
783 	dst->pr_pid = (pid32_t)src->pr_pid;
784 	dst->pr_pgid = (pid32_t)src->pr_pgid;
785 	dst->pr_sid = (pid32_t)src->pr_sid;
786 	dst->pr_taskid = (id32_t)src->pr_taskid;
787 	dst->pr_projid = (id32_t)src->pr_projid;
788 	dst->pr_zoneid = (id32_t)src->pr_zoneid;
789 	dst->pr_uid = (uid32_t)src->pr_uid;
790 	dst->pr_euid = (uid32_t)src->pr_euid;
791 	dst->pr_gid = (gid32_t)src->pr_gid;
792 	dst->pr_egid = (gid32_t)src->pr_egid;
793 	dst->pr_addr = (caddr32_t)src->pr_addr;
794 	dst->pr_size = (size32_t)src->pr_size;
795 	dst->pr_rssize = (size32_t)src->pr_rssize;
796 
797 	dst->pr_ttydev = prcmpldev(src->pr_ttydev);
798 
799 	dst->pr_pctcpu = src->pr_pctcpu;
800 	dst->pr_pctmem = src->pr_pctmem;
801 
802 	timestruc_n_to_32(&src->pr_start, &dst->pr_start);
803 	timestruc_n_to_32(&src->pr_time, &dst->pr_time);
804 	timestruc_n_to_32(&src->pr_ctime, &dst->pr_ctime);
805 
806 	(void) memcpy(&dst->pr_fname[0], &src->pr_fname[0], PRFNSZ);
807 	(void) memcpy(&dst->pr_psargs[0], &src->pr_psargs[0], PRARGSZ);
808 
809 	dst->pr_wstat = src->pr_wstat;
810 	dst->pr_argc = src->pr_argc;
811 	dst->pr_argv = (caddr32_t)src->pr_argv;
812 	dst->pr_envp = (caddr32_t)src->pr_envp;
813 	dst->pr_dmodel = src->pr_dmodel;
814 
815 	lwpsinfo_n_to_32(&src->pr_lwp, &dst->pr_lwp);
816 }
817 
818 
819 #endif	/* _LP64 */
820