13152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm/* libunwind - a platform-independent unwind library
23152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm   Copyright (C) 2003-2004 Hewlett-Packard Co
33152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
46f7b335e89e1b7f9c539fc0ebb3f789e34d0b7e4Konstantin Belousov   Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org>
53152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm
63152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmThis file is part of libunwind.
73152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm
83152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmPermission is hereby granted, free of charge, to any person obtaining
93152b04bb4d4962ee611a885be76d2443f478688hp.com!davidma copy of this software and associated documentation files (the
103152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm"Software"), to deal in the Software without restriction, including
113152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish,
123152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to
133152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmpermit persons to whom the Software is furnished to do so, subject to
143152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmthe following conditions:
153152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm
163152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmThe above copyright notice and this permission notice shall be
173152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmincluded in all copies or substantial portions of the Software.
183152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm
193152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
203152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
213152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
223152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
233152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
243152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
253152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
263152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm
273152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm#include "_UPT_internal.h"
283152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm
29cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov#if HAVE_DECL_PTRACE_POKEDATA || HAVE_TTRACE
303152b04bb4d4962ee611a885be76d2443f478688hp.com!davidmint
313152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val,
323152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm		 int write, void *arg)
333152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm{
343152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm  struct UPT_info *ui = arg;
353d6f7479b04b153f43bc9918a1bad25e3e8d2cd7Cody P Schafer  if (!ui)
363d6f7479b04b153f43bc9918a1bad25e3e8d2cd7Cody P Schafer	return -UNW_EINVAL;
373d6f7479b04b153f43bc9918a1bad25e3e8d2cd7Cody P Schafer
383152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm  pid_t pid = ui->pid;
393152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm
403152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm  errno = 0;
413152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm  if (write)
423152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm    {
4384109794bd0786cbbec44dd13d7283cfa2652687mostang.com!davidm      Debug (16, "mem[%lx] <- %lx\n", (long) addr, (long) *val);
443152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm#ifdef HAVE_TTRACE
453152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm#	warning No support for ttrace() yet.
463152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm#else
47d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      /* ANDROID support update. */
48d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      ptrace (PTRACE_POKEDATA, pid, (void*) (uintptr_t) addr, (void*) (uintptr_t) *val);
49d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      /* End of ANDROID update. */
503152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm      if (errno)
513152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm	return -UNW_EINVAL;
523152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm#endif
533152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm    }
543152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm  else
553152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm    {
563152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm#ifdef HAVE_TTRACE
573152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm#	warning No support for ttrace() yet.
586efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris/* ANDROID support update. */
596efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris#elif defined(__mips__) && _MIPS_SIM == _ABIO32
606efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris      /* The assumption is that sizeof(long) == sizeof(unw_word_t).
616efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris         This isn't true for this mips abi, so it requires two reads to get
626efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris         the entire 64 bit value. */
636efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris      long reg1, reg2;
64d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      reg1 = ptrace (PTRACE_PEEKDATA, pid, (void*) (uintptr_t) addr, 0);
656efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris      if (errno)
666efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris	return -UNW_EINVAL;
67d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      reg2 = ptrace (PTRACE_PEEKDATA, pid, (void*) (uintptr_t) (addr + sizeof(long)), 0);
686efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris      if (errno)
696efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris	return -UNW_EINVAL;
70d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      *val = ((unw_word_t)(reg2) << 32) | (uint32_t) reg1;
713152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm#else
72d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      /* ANDROID support update. */
73d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      *val = ptrace (PTRACE_PEEKDATA, pid, (void*) addr, 0);
74d1c383c5bb03420decf5cf789cf14ab144b0720dChristopher Ferris      /* End of ANDROID update. */
753152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm      if (errno)
763152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm	return -UNW_EINVAL;
773152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm#endif
786efcda4b51d0aab9709557a1ca2ac8dd92d4f0feChristopher Ferris/* End of ANDROID update. */
7984109794bd0786cbbec44dd13d7283cfa2652687mostang.com!davidm      Debug (16, "mem[%lx] -> %lx\n", (long) addr, (long) *val);
803152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm    }
813152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm  return 0;
823152b04bb4d4962ee611a885be76d2443f478688hp.com!davidm}
83cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov#elif HAVE_DECL_PT_IO
84cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousovint
85cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov_UPT_access_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val,
86cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov		 int write, void *arg)
87cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov{
88cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  struct UPT_info *ui = arg;
893d6f7479b04b153f43bc9918a1bad25e3e8d2cd7Cody P Schafer  if (!ui)
903d6f7479b04b153f43bc9918a1bad25e3e8d2cd7Cody P Schafer	return -UNW_EINVAL;
91cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  pid_t pid = ui->pid;
92cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  struct ptrace_io_desc iod;
93cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov
94cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  iod.piod_offs = (void *)addr;
95cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  iod.piod_addr = val;
96cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  iod.piod_len = sizeof(*val);
97cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  iod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D;
98cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  if (write)
99cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov    Debug (16, "mem[%lx] <- %lx\n", (long) addr, (long) *val);
100cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  if (ptrace(PT_IO, pid, (caddr_t)&iod, 0) == -1)
101cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov    return -UNW_EINVAL;
102cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  if (!write)
103cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov     Debug (16, "mem[%lx] -> %lx\n", (long) addr, (long) *val);
104cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov  return 0;
105cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov}
106cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov#else
107cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov#error Fix me
108cf6ae3548f96fa90da32b96529897cb6257355c1Konstantin Belousov#endif
109