1588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm/* libunwind - a platform-independent unwind library 2588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm Copyright (C) 2002 Hewlett-Packard Co 3e6b9f350f78ecd9ef3b8a3e721f9435c94fc2562David Mosberger-Tang Copyright (C) 2007 David Mosberger-Tang 4e6b9f350f78ecd9ef3b8a3e721f9435c94fc2562David Mosberger-Tang Contributed by David Mosberger-Tang <dmosberger@gmail.com> 5588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 6588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmThis file is part of libunwind. 7588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 8588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmPermission is hereby granted, free of charge, to any person obtaining 9588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidma copy of this software and associated documentation files (the 10588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm"Software"), to deal in the Software without restriction, including 11588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmwithout limitation the rights to use, copy, modify, merge, publish, 12588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmdistribute, sublicense, and/or sell copies of the Software, and to 13588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmpermit persons to whom the Software is furnished to do so, subject to 14588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmthe following conditions: 15588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 16588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmThe above copyright notice and this permission notice shall be 17588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmincluded in all copies or substantial portions of the Software. 18588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 19588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 23588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 26588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 27ee99dbec879212406d813b1bae56b988b4ab1e00Konstantin Belousov#ifdef HAVE_CONFIG_H 28ee99dbec879212406d813b1bae56b988b4ab1e00Konstantin Belousov#include <config.h> 29ee99dbec879212406d813b1bae56b988b4ab1e00Konstantin Belousov#endif 30ee99dbec879212406d813b1bae56b988b4ab1e00Konstantin Belousov 31588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm#include <stdlib.h> 32588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm#include <string.h> 33588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 34588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm#include "unwind_i.h" 35588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 36588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm#ifdef UNW_REMOTE_ONLY 37588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 38588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm/* unw_local_addr_space is a NULL pointer in this case. */ 39588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmPROTECTED unw_addr_space_t unw_local_addr_space; 40588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 41588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm#else /* !UNW_REMOTE_ONLY */ 42588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 43588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmstatic struct unw_addr_space local_addr_space; 44588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 45588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmPROTECTED unw_addr_space_t unw_local_addr_space = &local_addr_space; 46588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 47588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm# ifdef UNW_LOCAL_ONLY 48588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 49588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmHIDDEN void * 50588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmtdep_uc_addr (ucontext_t *uc, int reg) 51588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm{ 520dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov return x86_r_uc_addr (uc, reg); 53588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm} 54588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 55588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm# endif /* UNW_LOCAL_ONLY */ 56588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 57588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmHIDDEN unw_dyn_info_list_t _U_dyn_info_list; 58588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 59588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm/* XXX fix me: there is currently no way to locate the dyn-info list 60588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm by a remote unwinder. On ia64, this is done via a special 61588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm unwind-table entry. Perhaps something similar can be done with 62588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm DWARF2 unwind info. */ 63588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 64588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmstatic void 65588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmput_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg) 66588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm{ 67588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm /* it's a no-op */ 68588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm} 69588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 70588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmstatic int 71588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmget_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr, 72588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm void *arg) 73588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm{ 74588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list; 75588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm return 0; 76588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm} 77588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 78efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris/* ANDROID support update. */ 79efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#ifndef PAGE_SIZE 80ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma#define PAGE_SIZE 4096 81efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#endif 82efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris/* End of ANDROID update. */ 83efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 84ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma#define PAGE_START(a) ((a) & ~(PAGE_SIZE-1)) 85ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma 86ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma/* Cache of already validated addresses */ 87ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma#define NLGA 4 88ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharmastatic unw_word_t last_good_addr[NLGA]; 89ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharmastatic int lga_victim; 90ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma 91ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharmastatic int 92ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharmavalidate_mem (unw_word_t addr) 93ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma{ 94ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma int i, victim; 95ee99dbec879212406d813b1bae56b988b4ab1e00Konstantin Belousov#ifdef HAVE_MINCORE 9699e60be5a4c8bc9076d1b11e89a06f85d9da7b88Arun Sharma unsigned char mvec[2]; /* Unaligned access may cross page boundary */ 97ee99dbec879212406d813b1bae56b988b4ab1e00Konstantin Belousov#endif 9899e60be5a4c8bc9076d1b11e89a06f85d9da7b88Arun Sharma size_t len; 9999e60be5a4c8bc9076d1b11e89a06f85d9da7b88Arun Sharma 10099e60be5a4c8bc9076d1b11e89a06f85d9da7b88Arun Sharma if (PAGE_START(addr + sizeof (unw_word_t) - 1) == PAGE_START(addr)) 10199e60be5a4c8bc9076d1b11e89a06f85d9da7b88Arun Sharma len = PAGE_SIZE; 10299e60be5a4c8bc9076d1b11e89a06f85d9da7b88Arun Sharma else 10399e60be5a4c8bc9076d1b11e89a06f85d9da7b88Arun Sharma len = PAGE_SIZE * 2; 104ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma 105ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma addr = PAGE_START(addr); 106ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma 1070cf76ed0b54f4b64d3a0575a1c85ef8617d4278dPaul Pluzhnikov if (addr == 0) 1080cf76ed0b54f4b64d3a0575a1c85ef8617d4278dPaul Pluzhnikov return -1; 1090cf76ed0b54f4b64d3a0575a1c85ef8617d4278dPaul Pluzhnikov 110ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma for (i = 0; i < NLGA; i++) 111ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma { 112ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma if (last_good_addr[i] && (addr == last_good_addr[i])) 113ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma return 0; 114ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma } 115ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma 116ee99dbec879212406d813b1bae56b988b4ab1e00Konstantin Belousov#ifdef HAVE_MINCORE 11799e60be5a4c8bc9076d1b11e89a06f85d9da7b88Arun Sharma if (mincore ((void *) addr, len, mvec) == -1) 118ee99dbec879212406d813b1bae56b988b4ab1e00Konstantin Belousov#else 11999e60be5a4c8bc9076d1b11e89a06f85d9da7b88Arun Sharma if (msync ((void *) addr, len, MS_ASYNC) == -1) 120ee99dbec879212406d813b1bae56b988b4ab1e00Konstantin Belousov#endif 121ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma return -1; 122ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma 123ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma victim = lga_victim; 124ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma for (i = 0; i < NLGA; i++) { 125ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma if (!last_good_addr[victim]) { 126ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma last_good_addr[victim++] = addr; 127ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma return 0; 128ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma } 129ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma victim = (victim + 1) % NLGA; 130ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma } 131ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma 132ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma /* All slots full. Evict the victim. */ 133ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma last_good_addr[victim] = addr; 134ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma victim = (victim + 1) % NLGA; 135ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma lga_victim = victim; 136ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma 137ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma return 0; 138ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma} 139ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma 140588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmstatic int 141588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmaccess_mem (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, int write, 142588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm void *arg) 143588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm{ 144588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm if (write) 145588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm { 1467d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris /* ANDROID support update. */ 147cdf9ee587b78148c5d48dae1b5ea72ec8df64c96Christopher Ferris#ifdef UNW_LOCAL_ONLY 14818cf8168ef34750ffae6451bded31ff06d2d2763Christopher Ferris if (map_local_is_writable (addr, sizeof(unw_word_t))) 1497d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris { 150cdf9ee587b78148c5d48dae1b5ea72ec8df64c96Christopher Ferris#endif 1517d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris Debug (16, "mem[%x] <- %x\n", addr, *val); 1527d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris *(unw_word_t *) addr = *val; 153cdf9ee587b78148c5d48dae1b5ea72ec8df64c96Christopher Ferris#ifdef UNW_LOCAL_ONLY 1547d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris } 1557d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris else 1567d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris { 1577d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris Debug (16, "Unwritable memory mem[%x] <- %x\n", addr, *val); 1587d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris return -1; 1597d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris } 160cdf9ee587b78148c5d48dae1b5ea72ec8df64c96Christopher Ferris#endif 1617d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris /* End of ANDROID update. */ 162588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm } 163588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm else 164588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm { 16576a0b9f6a9813311ddfd59aaa580339f36a2c510Christopher Ferris /* ANDROID support update. */ 16676a0b9f6a9813311ddfd59aaa580339f36a2c510Christopher Ferris#ifdef CONSERVATIVE_CHECKS 16776a0b9f6a9813311ddfd59aaa580339f36a2c510Christopher Ferris if (validate_mem(addr)) 168ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma return -1; 16976a0b9f6a9813311ddfd59aaa580339f36a2c510Christopher Ferris#endif 17076a0b9f6a9813311ddfd59aaa580339f36a2c510Christopher Ferris /* End of ANDROID update. */ 17176a0b9f6a9813311ddfd59aaa580339f36a2c510Christopher Ferris 1727d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris /* ANDROID support update. */ 173cdf9ee587b78148c5d48dae1b5ea72ec8df64c96Christopher Ferris#ifdef UNW_LOCAL_ONLY 17418cf8168ef34750ffae6451bded31ff06d2d2763Christopher Ferris if (map_local_is_readable (addr, sizeof(unw_word_t))) 1757d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris { 176cdf9ee587b78148c5d48dae1b5ea72ec8df64c96Christopher Ferris#endif 1777d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris *val = *(unw_word_t *) addr; 1787d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris Debug (16, "mem[%x] -> %x\n", addr, *val); 179cdf9ee587b78148c5d48dae1b5ea72ec8df64c96Christopher Ferris#ifdef UNW_LOCAL_ONLY 1807d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris } 1817d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris else 1827d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris { 1837d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris Debug (16, "Unreadable memory mem[%x] -> XXX\n", addr); 1847d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris return -1; 1857d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris } 186cdf9ee587b78148c5d48dae1b5ea72ec8df64c96Christopher Ferris#endif 1877d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris /* End of ANDROID update. */ 188588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm } 189588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm return 0; 190588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm} 191588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 192588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmstatic int 193588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmaccess_reg (unw_addr_space_t as, unw_regnum_t reg, unw_word_t *val, int write, 194588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm void *arg) 195588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm{ 196588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm unw_word_t *addr; 197ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma ucontext_t *uc = ((struct cursor *)arg)->uc; 198588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 199588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm if (unw_is_fpreg (reg)) 200588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm goto badreg; 201588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 2020dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov if (!(addr = x86_r_uc_addr (uc, reg))) 203588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm goto badreg; 204588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 205588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm if (write) 206588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm { 207588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm *(unw_word_t *) addr = *val; 208588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm Debug (12, "%s <- %x\n", unw_regname (reg), *val); 209588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm } 210588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm else 211588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm { 212588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm *val = *(unw_word_t *) addr; 213588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm Debug (12, "%s -> %x\n", unw_regname (reg), *val); 214588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm } 215588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm return 0; 216588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 217588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm badreg: 218588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm Debug (1, "bad register number %u\n", reg); 219588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm return -UNW_EBADREG; 220588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm} 221588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 222588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmstatic int 223588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmaccess_fpreg (unw_addr_space_t as, unw_regnum_t reg, unw_fpreg_t *val, 224588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm int write, void *arg) 225588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm{ 226ff0ae70cc3c3c1498724deed519cd18dde6c1e80Arun Sharma ucontext_t *uc = ((struct cursor *)arg)->uc; 227588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm unw_fpreg_t *addr; 228588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 229588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm if (!unw_is_fpreg (reg)) 230588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm goto badreg; 231588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 2320dbeeeb08dc9a7e46281954e9225a84d4629a3dbKonstantin Belousov if (!(addr = x86_r_uc_addr (uc, reg))) 233588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm goto badreg; 234588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 235588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm if (write) 236588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm { 237588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm Debug (12, "%s <- %08lx.%08lx.%08lx\n", unw_regname (reg), 238588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); 239588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm *(unw_fpreg_t *) addr = *val; 240588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm } 241588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm else 242588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm { 243588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm *val = *(unw_fpreg_t *) addr; 244588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm Debug (12, "%s -> %08lx.%08lx.%08lx\n", unw_regname (reg), 245588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm ((long *)val)[0], ((long *)val)[1], ((long *)val)[2]); 246588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm } 247588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm return 0; 248588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 249588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm badreg: 250588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm Debug (1, "bad register number %u\n", reg); 251588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm /* attempt to access a non-preserved register */ 252588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm return -UNW_EBADREG; 253588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm} 254588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 255588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmstatic int 256588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmget_static_proc_name (unw_addr_space_t as, unw_word_t ip, 257588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm char *buf, size_t buf_len, unw_word_t *offp, 258588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm void *arg) 259588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm{ 260ae38b20031a02d3f6f56a8315c1f097ae5293c56Christopher Ferris return _Uelf32_get_proc_name (as, getpid (), ip, buf, buf_len, offp, arg); 261588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm} 262588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 263849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferrisstatic int 264849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferrisaccess_mem_unrestricted (unw_addr_space_t as, unw_word_t addr, unw_word_t *val, 265849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris int write, void *arg) 266849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris{ 267849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris if (write) 268849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris return -1; 269849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris 270849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris *val = *(unw_word_t *) addr; 271849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris Debug (16, "mem[%x] -> %x\n", addr, *val); 272849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris return 0; 273849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris} 274849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris 275849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris// This initializes just enough of the address space to call the 276849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris// access memory function. 277849a547fb4de698b95c14806ddb3fcad8aa26331Christopher FerrisPROTECTED void 278849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferrisunw_local_access_addr_space_init (unw_addr_space_t as) 279849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris{ 280849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris memset (as, 0, sizeof (*as)); 281849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris as->acc.access_mem = access_mem_unrestricted; 282849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris} 283849a547fb4de698b95c14806ddb3fcad8aa26331Christopher Ferris 284588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmHIDDEN void 285588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidmx86_local_addr_space_init (void) 286588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm{ 287588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm memset (&local_addr_space, 0, sizeof (local_addr_space)); 288588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm local_addr_space.caching_policy = UNW_CACHE_GLOBAL; 289588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm local_addr_space.acc.find_proc_info = dwarf_find_proc_info; 290588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm local_addr_space.acc.put_unwind_info = put_unwind_info; 291588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; 292588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm local_addr_space.acc.access_mem = access_mem; 293588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm local_addr_space.acc.access_reg = access_reg; 294588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm local_addr_space.acc.access_fpreg = access_fpreg; 295588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm local_addr_space.acc.resume = x86_local_resume; 296588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm local_addr_space.acc.get_proc_name = get_static_proc_name; 297588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm unw_flush_cache (&local_addr_space, 0, 0); 298f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris 299f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris map_local_init (); 300588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm} 301588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm 302588192d3015512656c39232cdde53cae24ff0fd0homeip.net!davidm#endif /* !UNW_REMOTE_ONLY */ 303