12646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov/* libunwind - a platform-independent unwind library 26f7b335e89e1b7f9c539fc0ebb3f789e34d0b7e4Konstantin Belousov Copyright (C) 2010 Konstantin Belousov <kib@freebsd.org> 32646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 42646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovThis file is part of libunwind. 52646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 62646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovPermission is hereby granted, free of charge, to any person obtaining 72646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousova copy of this software and associated documentation files (the 82646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov"Software"), to deal in the Software without restriction, including 92646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousovwithout limitation the rights to use, copy, modify, merge, publish, 102646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousovdistribute, sublicense, and/or sell copies of the Software, and to 112646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousovpermit persons to whom the Software is furnished to do so, subject to 122646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousovthe following conditions: 132646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 142646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovThe above copyright notice and this permission notice shall be 152646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousovincluded in all copies or substantial portions of the Software. 162646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 172646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 182646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 192646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 202646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 212646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 222646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 232646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin BelousovWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 242646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 25e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov#include <sys/param.h> 264de09a9c1569e17132973b801f77bcab8d927480Konstantin Belousov#include <sys/types.h> 27e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov#include <sys/mman.h> 28e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov#include <sys/sysctl.h> 294de09a9c1569e17132973b801f77bcab8d927480Konstantin Belousov#include <sys/user.h> 3063ae8ca8947c67aaa402abbe46a12d118366e1dfKonstantin Belousov#include <stdio.h> 315f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov#include <errno.h> 322646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 332646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov#include "libunwind_i.h" 342646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 35e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousovstatic void * 36e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousovget_mem(size_t sz) 37e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov{ 38e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov void *res; 39e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov 40e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov res = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); 41e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov if (res == MAP_FAILED) 42e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov return (NULL); 43e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov return (res); 44e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov} 45e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov 46e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousovstatic void 47e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousovfree_mem(void *ptr, size_t sz) 48e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov{ 49e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov munmap(ptr, sz); 50e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov} 51e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov 525f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousovstatic int 535f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousovget_pid_by_tid(int tid) 545f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov{ 555f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov int mib[3], error; 565f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov size_t len, len1; 575f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov char *buf; 585f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov struct kinfo_proc *kv; 595f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov int i, pid; 605f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov 615f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov len = 0; 625f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov mib[0] = CTL_KERN; 635f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov mib[1] = KERN_PROC; 645f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov mib[2] = KERN_PROC_ALL; 655f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov 665f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov error = sysctl(mib, 3, NULL, &len, NULL, 0); 675f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov if (error == -1) 685f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov return (-1); 695f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov len1 = len * 4 / 3; 705f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov buf = get_mem(len1); 715f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov if (buf == NULL) 725f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov return (-1); 735f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov len = len1; 745f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov error = sysctl(mib, 3, buf, &len, NULL, 0); 755f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov if (error == -1) { 765f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov free_mem(buf, len1); 775f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov return (-1); 785f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov } 795f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov pid = -1; 805f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov for (i = 0, kv = (struct kinfo_proc *)buf; i < len / sizeof(*kv); 815f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov i++, kv++) { 825f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov if (kv->ki_tid == tid) { 835f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov pid = kv->ki_pid; 845f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov break; 855f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov } 865f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov } 875f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov free_mem(buf, len1); 885f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov return (pid); 895f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov} 905f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov 91f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris/* ANDROID support update. */ 92f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferrisstruct map_info * 93f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferrismap_create_list(pid_t pid) 942646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov{ 95e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov int mib[4], error, ret; 96e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov size_t len, len1; 97e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov char *buf, *bp, *eb; 98e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov struct kinfo_vmentry *kv; 99f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris struct map_info *map_list = NULL; 100e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov 101e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov len = 0; 102e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov mib[0] = CTL_KERN; 103e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov mib[1] = KERN_PROC; 104e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov mib[2] = KERN_PROC_VMMAP; 105e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov mib[3] = pid; 106bd2798805a68eac5491a4b096659a05e61e83580Konstantin Belousov 107e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov error = sysctl(mib, 4, NULL, &len, NULL, 0); 1085f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov if (error == -1) { 109f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris if (errno == ESRCH) 110f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris { 111f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris mib[3] = get_pid_by_tid(pid); 112f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris if (mib[3] != -1) 113f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris error = sysctl(mib, 4, NULL, &len, NULL, 0); 114f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris if (error == -1) 115f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris return (-UNW_EUNSPEC); 116f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris } 117f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris else 1185f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov return (-UNW_EUNSPEC); 1195f440b4af2b5dcae2f15652999b9aca7db55d02cKonstantin Belousov } 120e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov len1 = len * 4 / 3; 121e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov buf = get_mem(len1); 122e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov if (buf == NULL) 1230fac4c8109e23b5363fea3366e35ba17d9f7ea79Konstantin Belousov return (-UNW_EUNSPEC); 12461f4345a9e812713287e9f04949100416180b38fKonstantin Belousov len = len1; 125e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov error = sysctl(mib, 4, buf, &len, NULL, 0); 126f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris if (error == -1) 127f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris { 128f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris free_mem(buf, len1); 129f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris return (-UNW_EUNSPEC); 130f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris } 1310fac4c8109e23b5363fea3366e35ba17d9f7ea79Konstantin Belousov ret = -UNW_EUNSPEC; 132f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) 133f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris { 134f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris kv = (struct kinfo_vmentry *)(uintptr_t)bp; 135f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris if (kv->kve_type != KVME_TYPE_VNODE) 136f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris continue; 137f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris 138f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris cur_map = map_alloc_info (); 139f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris if (cur_map == NULL) 140f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris break; 141f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris cur_map->next = map_list; 142f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris cur_map->start = kv->kve_start; 143f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris cur_map->end = kv->kv_end; 144f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris cur_map->offset = kv->kve_offset; 145f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris cur_map->path = strdup(kv->kve_path); 146f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris mutex_init (&cur_map->ei_lock); 147f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris cur_map->ei.size = 0; 148f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris cur_map->ei.image = NULL; 149f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris cur_map->ei_shared = 0; 150f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris } 151e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov free_mem(buf, len1); 1527d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris 153f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris return map_list; 1547d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris} 155f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris/* End of ANDROID update. */ 156