17246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm/* libunwind - a platform-independent unwind library
27246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm   Copyright (C) 2003 Hewlett-Packard Co
37246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
46f7b335e89e1b7f9c539fc0ebb3f789e34d0b7e4Konstantin Belousov   Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org>
57246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm
67246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmThis file is part of libunwind.
77246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm
87246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmPermission is hereby granted, free of charge, to any person obtaining
97246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidma copy of this software and associated documentation files (the
107246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm"Software"), to deal in the Software without restriction, including
117246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish,
127246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to
137246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmpermit persons to whom the Software is furnished to do so, subject to
147246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmthe following conditions:
157246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm
167246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmThe above copyright notice and this permission notice shall be
177246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmincluded in all copies or substantial portions of the Software.
187246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm
197246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
207246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
217246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
227246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
237246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
247246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
257246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
267246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm
277246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm#include "_UPT_internal.h"
287246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm
29d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#if HAVE_DECL_PTRACE_POKEUSER || HAVE_TTRACE
307246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidmint
317246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
327246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm		   int write, void *arg)
337246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm{
347246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm  unw_word_t *wp = (unw_word_t *) val;
357246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm  struct UPT_info *ui = arg;
367246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm  pid_t pid = ui->pid;
377246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm  int i;
387246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm
39397f32a378d4b7acc962bf4a0056dca2197077ddTommi Rantala  if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset))
407246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm    return -UNW_EBADREG;
417246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm
427246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm  errno = 0;
437246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm  if (write)
447246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm    for (i = 0; i < (int) (sizeof (*val) / sizeof (wp[i])); ++i)
457246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm      {
467246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm#ifdef HAVE_TTRACE
477246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm#	warning No support for ttrace() yet.
487246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm#else
49d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris        /* ANDROID support update. */
50d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris	ptrace (PTRACE_POKEUSER, pid, (void*) (_UPT_reg_offset[reg] + i * sizeof(wp[i])),
51d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris		(void*) wp[i]);
52d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris        /* End of ANDROID update. */
537246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm#endif
547246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm	if (errno)
557246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm	  return -UNW_EBADREG;
567246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm      }
577246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm  else
587246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm    for (i = 0; i < (int) (sizeof (*val) / sizeof (wp[i])); ++i)
597246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm      {
607246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm#ifdef HAVE_TTRACE
617246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm#	warning No support for ttrace() yet.
627246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm#else
63d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris        /* ANDROID support update. */
647246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm	wp[i] = ptrace (PTRACE_PEEKUSER, pid,
65d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris			(void*) (_UPT_reg_offset[reg] + i * sizeof(wp[i])), 0);
66d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris        /* End of ANDROID update. */
677246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm#endif
687246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm	if (errno)
697246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm	  return -UNW_EBADREG;
707246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm      }
717246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm  return 0;
727246c93bad7e54fe510a20f5559fe17831a0ffb4hp.com!davidm}
73d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#elif HAVE_DECL_PT_GETFPREGS
74d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousovint
75d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
76d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov		   int write, void *arg)
77d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov{
78d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov  struct UPT_info *ui = arg;
79d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov  pid_t pid = ui->pid;
80d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov  fpregset_t fpreg;
81d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov
82397f32a378d4b7acc962bf4a0056dca2197077ddTommi Rantala  if ((unsigned) reg >= ARRAY_SIZE (_UPT_reg_offset))
83d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov    return -UNW_EBADREG;
84d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov
85d7eea914485d5d5d3c7b29a74a68541240b6a090Konstantin Belousov  if (ptrace(PT_GETFPREGS, pid, (caddr_t)&fpreg, 0) == -1)
86d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov	  return -UNW_EBADREG;
87d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov  if (write) {
88d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#if defined(__amd64__)
89d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov	  memcpy(&fpreg.fpr_xacc[reg], val, sizeof(unw_fpreg_t));
90d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#elif defined(__i386__)
91d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov	  memcpy(&fpreg.fpr_acc[reg], val, sizeof(unw_fpreg_t));
92d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#else
93d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#error Fix me
94d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#endif
95d7eea914485d5d5d3c7b29a74a68541240b6a090Konstantin Belousov	  if (ptrace(PT_SETFPREGS, pid, (caddr_t)&fpreg, 0) == -1)
96d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov		  return -UNW_EBADREG;
97d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov  } else
98d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#if defined(__amd64__)
99d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov	  memcpy(val, &fpreg.fpr_xacc[reg], sizeof(unw_fpreg_t));
100d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#elif defined(__i386__)
101d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov	  memcpy(val, &fpreg.fpr_acc[reg], sizeof(unw_fpreg_t));
102d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#else
103d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#error Fix me
104d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#endif
105d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov  return 0;
106d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov}
107fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris/* ANDROID support update. */
108fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris#elif defined(__mips__) || defined(__aarch64__)
109fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferrisint
110fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris_UPT_access_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val,
111fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris		   int write, void *arg)
112fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris{
113d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris# pragma message("_UPT_access_fpreg is not implemented and not currently used.")
114fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris  return -UNW_EBADREG;
115fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris}
116fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris/* End of ANDROID update. */
117d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#else
118d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#error Fix me
119d11456ffbf6dd6f556eb3bc64e8a368e7e3381c5Konstantin Belousov#endif
120