os-freebsd.c revision 298e575f2cbb4616004717812f28879b2633a6ac
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 252646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov#ifndef UNW_REMOTE_ONLY 262646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 27e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov#include <sys/param.h> 284de09a9c1569e17132973b801f77bcab8d927480Konstantin Belousov#include <sys/types.h> 29e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov#include <sys/mman.h> 30e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov#include <sys/sysctl.h> 314de09a9c1569e17132973b801f77bcab8d927480Konstantin Belousov#include <sys/user.h> 3263ae8ca8947c67aaa402abbe46a12d118366e1dfKonstantin Belousov#include <stdio.h> 332646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 342646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov#include "libunwind_i.h" 352646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 36e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousovstatic void * 37e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousovget_mem(size_t sz) 38e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov{ 39e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov void *res; 40e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov 41e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov res = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); 42e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov if (res == MAP_FAILED) 43e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov return (NULL); 44e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov return (res); 45e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov} 46e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov 47e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousovstatic void 48e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousovfree_mem(void *ptr, size_t sz) 49e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov{ 50e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov munmap(ptr, sz); 51e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov} 52e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov 53bd2798805a68eac5491a4b096659a05e61e83580Konstantin BelousovPROTECTED int 542646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousovtdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, 551787a2fd284a786b409af74047a12de02c644cd1Arun Sharma unsigned long *segbase, unsigned long *mapoff, char *path, size_t pathlen) 562646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov{ 57e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov int mib[4], error, ret; 58e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov size_t len, len1; 59e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov char *buf, *bp, *eb; 60e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov struct kinfo_vmentry *kv; 61e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov 62e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov len = 0; 63e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov mib[0] = CTL_KERN; 64e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov mib[1] = KERN_PROC; 65e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov mib[2] = KERN_PROC_VMMAP; 66e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov mib[3] = pid; 67bd2798805a68eac5491a4b096659a05e61e83580Konstantin Belousov 68e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov error = sysctl(mib, 4, NULL, &len, NULL, 0); 69e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov if (error) 70e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov return (-1); 71e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov len1 = len * 4 / 3; 72e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov buf = get_mem(len1); 73e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov if (buf == NULL) 74e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov return (-1); 7561f4345a9e812713287e9f04949100416180b38fKonstantin Belousov len = len1; 76e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov error = sysctl(mib, 4, buf, &len, NULL, 0); 77e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov if (error) { 78e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov free_mem(buf, len1); 79bd2798805a68eac5491a4b096659a05e61e83580Konstantin Belousov return (-1); 80e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov } 81e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov ret = -1; 82e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov for (bp = buf, eb = buf + len; bp < eb; bp += kv->kve_structsize) { 83e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov kv = (struct kinfo_vmentry *)(uintptr_t)bp; 84e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov if (ip < kv->kve_start || ip >= kv->kve_end) 85e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov continue; 86e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov if (kv->kve_type != KVME_TYPE_VNODE) 87e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov break; 88e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov *segbase = kv->kve_start; 89e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov *mapoff = kv->kve_offset; 901787a2fd284a786b409af74047a12de02c644cd1Arun Sharma if (path) 911787a2fd284a786b409af74047a12de02c644cd1Arun Sharma { 92298e575f2cbb4616004717812f28879b2633a6acKonstantin Belousov strncpy(path, kv->kve_path, pathlen); 931787a2fd284a786b409af74047a12de02c644cd1Arun Sharma } 94e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov ret = elf_map_image(ei, kv->kve_path); 95e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov break; 96e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov } 97e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov free_mem(buf, len1); 98e33fa9f73c8eefafc2c1b580e78a5c87bcc4dc44Konstantin Belousov return (ret); 992646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov} 1002646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov 1012646e0fde8a5721ec7356dce38e5341b3080ca62Konstantin Belousov#endif /* UNW_REMOTE_ONLY */ 102