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